reformatting: cJSONUtils_ApplyPatch

This commit is contained in:
Max Bruckner 2016-10-17 11:32:47 +07:00
parent 284a8017b7
commit d883f9b9b0

View File

@ -300,73 +300,164 @@ static int cJSONUtils_Compare(cJSON *a, cJSON *b)
return 0; return 0;
} }
static int cJSONUtils_ApplyPatch(cJSON *object,cJSON *patch) static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch)
{ {
cJSON *op=0,*path=0,*value=0,*parent=0;int opcode=0;char *parentptr=0,*childptr=0; cJSON *op = 0;
cJSON *path = 0;
cJSON *value = 0;
cJSON *parent = 0;
int opcode = 0;
char *parentptr = 0;
char *childptr = 0;
op=cJSON_GetObjectItem(patch,"op"); op = cJSON_GetObjectItem(patch, "op");
path=cJSON_GetObjectItem(patch,"path"); path = cJSON_GetObjectItem(patch, "path");
if (!op || !path) return 2; /* malformed patch. */ if (!op || !path)
{
/* malformed patch. */
return 2;
}
if (!strcmp(op->valuestring,"add")) opcode=0; /* decode operation */
else if (!strcmp(op->valuestring,"remove")) opcode=1; if (!strcmp(op->valuestring, "add"))
else if (!strcmp(op->valuestring,"replace"))opcode=2; {
else if (!strcmp(op->valuestring,"move")) opcode=3; opcode = 0;
else if (!strcmp(op->valuestring,"copy")) opcode=4; }
else if (!strcmp(op->valuestring,"test")) return cJSONUtils_Compare(cJSONUtils_GetPointer(object,path->valuestring),cJSON_GetObjectItem(patch,"value")); else if (!strcmp(op->valuestring, "remove"))
else return 3; /* unknown opcode. */ {
opcode = 1;
}
else if (!strcmp(op->valuestring, "replace"))
{
opcode = 2;
}
else if (!strcmp(op->valuestring, "move"))
{
opcode = 3;
}
else if (!strcmp(op->valuestring, "copy"))
{
opcode = 4;
}
else if (!strcmp(op->valuestring, "test"))
{
/* compare value: {...} with the given path */
return cJSONUtils_Compare(cJSONUtils_GetPointer(object, path->valuestring), cJSON_GetObjectItem(patch, "value"));
}
else
{
/* unknown opcode. */
return 3;
}
if (opcode==1 || opcode==2) /* Remove/Replace */ /* Remove/Replace */
{ if ((opcode == 1) || (opcode == 2))
cJSON_Delete(cJSONUtils_PatchDetach(object,path->valuestring)); /* Get rid of old. */ {
if (opcode==1) return 0; /* For Remove, this is job done. */ /* Get rid of old. */
} cJSON_Delete(cJSONUtils_PatchDetach(object, path->valuestring));
if (opcode == 1)
{
/* For Remove, this is job done. */
return 0;
}
}
if (opcode==3 || opcode==4) /* Copy/Move uses "from". */ /* Copy/Move uses "from". */
{ if ((opcode == 3) || (opcode == 4))
cJSON *from=cJSON_GetObjectItem(patch,"from"); if (!from) return 4; /* missing "from" for copy/move. */ {
cJSON *from = cJSON_GetObjectItem(patch, "from");
if (!from)
{
/* missing "from" for copy/move. */
return 4;
}
if (opcode==3) value=cJSONUtils_PatchDetach(object,from->valuestring); if (opcode == 3)
if (opcode==4) value=cJSONUtils_GetPointer(object,from->valuestring); {
if (!value) return 5; /* missing "from" for copy/move. */ /* move */
if (opcode==4) value=cJSON_Duplicate(value,1); value = cJSONUtils_PatchDetach(object, from->valuestring);
if (!value) return 6; /* out of memory for copy/move. */ }
} if (opcode == 4)
else /* Add/Replace uses "value". */ {
{ /* copy */
value=cJSON_GetObjectItem(patch,"value"); value = cJSONUtils_GetPointer(object, from->valuestring);
if (!value) return 7; /* missing "value" for add/replace. */ }
value=cJSON_Duplicate(value,1); if (!value)
if (!value) return 8; /* out of memory for add/replace. */ {
} /* missing "from" for copy/move. */
return 5;
}
if (opcode == 4)
{
value = cJSON_Duplicate(value, 1);
}
if (!value)
{
/* out of memory for copy/move. */
return 6;
}
}
else /* Add/Replace uses "value". */
{
value = cJSON_GetObjectItem(patch, "value");
if (!value)
{
/* missing "value" for add/replace. */
return 7;
}
value = cJSON_Duplicate(value, 1);
if (!value)
{
/* out of memory for add/replace. */
return 8;
}
}
/* Now, just add "value" to "path". */ /* Now, just add "value" to "path". */
parentptr=strdup(path->valuestring); childptr=strrchr(parentptr,'/'); if (childptr) *childptr++=0; /* split pointer in parent and child */
parent=cJSONUtils_GetPointer(object,parentptr); parentptr = strdup(path->valuestring);
cJSONUtils_InplaceDecodePointerString(childptr); childptr = strrchr(parentptr, '/');
if (childptr)
{
*childptr++ = '\0';
}
parent = cJSONUtils_GetPointer(object, parentptr);
cJSONUtils_InplaceDecodePointerString(childptr);
/* add, remove, replace, move, copy, test. */ /* add, remove, replace, move, copy, test. */
if (!parent) {free(parentptr); cJSON_Delete(value); return 9;} /* Couldn't find object to add to. */ if (!parent)
else if (parent->type==cJSON_Array) {
{ /* Couldn't find object to add to. */
if (!strcmp(childptr,"-")) cJSON_AddItemToArray(parent,value); free(parentptr);
else cJSON_InsertItemInArray(parent,atoi(childptr),value); cJSON_Delete(value);
} return 9;
else if (parent->type==cJSON_Object) }
{ else if (parent->type == cJSON_Array)
cJSON_DeleteItemFromObject(parent,childptr); {
cJSON_AddItemToObject(parent,childptr,value); if (!strcmp(childptr, "-"))
} {
else cJSON_AddItemToArray(parent, value);
{ }
cJSON_Delete(value); else
} {
free(parentptr); cJSON_InsertItemInArray(parent, atoi(childptr), value);
return 0; }
}
else if (parent->type == cJSON_Object)
{
cJSON_DeleteItemFromObject(parent, childptr);
cJSON_AddItemToObject(parent, childptr, value);
}
else
{
cJSON_Delete(value);
}
free(parentptr);
return 0;
} }
int cJSONUtils_ApplyPatches(cJSON *object,cJSON *patches) int cJSONUtils_ApplyPatches(cJSON *object,cJSON *patches)
{ {
int err; int err;