mirror of
https://github.com/DaveGamble/cJSON.git
synced 2023-08-10 21:13:26 +03:00
reformatting: cJSONUtils_ApplyPatch
This commit is contained in:
parent
284a8017b7
commit
d883f9b9b0
205
cJSON_Utils.c
205
cJSON_Utils.c
@ -300,73 +300,164 @@ static int cJSONUtils_Compare(cJSON *a, cJSON *b)
|
||||
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");
|
||||
path=cJSON_GetObjectItem(patch,"path");
|
||||
if (!op || !path) return 2; /* malformed patch. */
|
||||
op = cJSON_GetObjectItem(patch, "op");
|
||||
path = cJSON_GetObjectItem(patch, "path");
|
||||
if (!op || !path)
|
||||
{
|
||||
/* malformed patch. */
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (!strcmp(op->valuestring,"add")) opcode=0;
|
||||
else if (!strcmp(op->valuestring,"remove")) 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")) return cJSONUtils_Compare(cJSONUtils_GetPointer(object,path->valuestring),cJSON_GetObjectItem(patch,"value"));
|
||||
else return 3; /* unknown opcode. */
|
||||
/* decode operation */
|
||||
if (!strcmp(op->valuestring, "add"))
|
||||
{
|
||||
opcode = 0;
|
||||
}
|
||||
else if (!strcmp(op->valuestring, "remove"))
|
||||
{
|
||||
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 */
|
||||
{
|
||||
cJSON_Delete(cJSONUtils_PatchDetach(object,path->valuestring)); /* Get rid of old. */
|
||||
if (opcode==1) return 0; /* For Remove, this is job done. */
|
||||
}
|
||||
/* Remove/Replace */
|
||||
if ((opcode == 1) || (opcode == 2))
|
||||
{
|
||||
/* 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". */
|
||||
{
|
||||
cJSON *from=cJSON_GetObjectItem(patch,"from"); if (!from) return 4; /* missing "from" for copy/move. */
|
||||
/* Copy/Move uses "from". */
|
||||
if ((opcode == 3) || (opcode == 4))
|
||||
{
|
||||
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==4) value=cJSONUtils_GetPointer(object,from->valuestring);
|
||||
if (!value) return 5; /* missing "from" for copy/move. */
|
||||
if (opcode==4) value=cJSON_Duplicate(value,1);
|
||||
if (!value) return 6; /* out of memory for copy/move. */
|
||||
}
|
||||
else /* Add/Replace uses "value". */
|
||||
{
|
||||
value=cJSON_GetObjectItem(patch,"value");
|
||||
if (!value) return 7; /* missing "value" for add/replace. */
|
||||
value=cJSON_Duplicate(value,1);
|
||||
if (!value) return 8; /* out of memory for add/replace. */
|
||||
}
|
||||
|
||||
/* Now, just add "value" to "path". */
|
||||
if (opcode == 3)
|
||||
{
|
||||
/* move */
|
||||
value = cJSONUtils_PatchDetach(object, from->valuestring);
|
||||
}
|
||||
if (opcode == 4)
|
||||
{
|
||||
/* copy */
|
||||
value = cJSONUtils_GetPointer(object, from->valuestring);
|
||||
}
|
||||
if (!value)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
parentptr=strdup(path->valuestring); childptr=strrchr(parentptr,'/'); if (childptr) *childptr++=0;
|
||||
parent=cJSONUtils_GetPointer(object,parentptr);
|
||||
cJSONUtils_InplaceDecodePointerString(childptr);
|
||||
/* Now, just add "value" to "path". */
|
||||
|
||||
/* add, remove, replace, move, copy, test. */
|
||||
if (!parent) {free(parentptr); cJSON_Delete(value); return 9;} /* Couldn't find object to add to. */
|
||||
else if (parent->type==cJSON_Array)
|
||||
{
|
||||
if (!strcmp(childptr,"-")) cJSON_AddItemToArray(parent,value);
|
||||
else cJSON_InsertItemInArray(parent,atoi(childptr),value);
|
||||
}
|
||||
else if (parent->type==cJSON_Object)
|
||||
{
|
||||
cJSON_DeleteItemFromObject(parent,childptr);
|
||||
cJSON_AddItemToObject(parent,childptr,value);
|
||||
}
|
||||
else
|
||||
{
|
||||
cJSON_Delete(value);
|
||||
}
|
||||
free(parentptr);
|
||||
return 0;
|
||||
/* split pointer in parent and child */
|
||||
parentptr = strdup(path->valuestring);
|
||||
childptr = strrchr(parentptr, '/');
|
||||
if (childptr)
|
||||
{
|
||||
*childptr++ = '\0';
|
||||
}
|
||||
parent = cJSONUtils_GetPointer(object, parentptr);
|
||||
cJSONUtils_InplaceDecodePointerString(childptr);
|
||||
|
||||
/* add, remove, replace, move, copy, test. */
|
||||
if (!parent)
|
||||
{
|
||||
/* Couldn't find object to add to. */
|
||||
free(parentptr);
|
||||
cJSON_Delete(value);
|
||||
return 9;
|
||||
}
|
||||
else if (parent->type == cJSON_Array)
|
||||
{
|
||||
if (!strcmp(childptr, "-"))
|
||||
{
|
||||
cJSON_AddItemToArray(parent, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
cJSON_InsertItemInArray(parent, atoi(childptr), value);
|
||||
}
|
||||
}
|
||||
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 err;
|
||||
|
Loading…
Reference in New Issue
Block a user