static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch) { 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) { /* malformed patch. */ return 2; } /* 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; } /* 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; } } /* 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) { /* 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; } } /* Now, just add "value" to "path". */ /* split pointer in parent and child */ parentptr = cJSONUtils_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; }
static int set_value(cJSON *root, const char *json_pointer, cJSON *value) { if (root == NULL) { return -1; } const int len = strlen(json_pointer); int offset = 0; if (offset == len) { //如果为"" return -1; } cJSON *parent = root; char *key = NULL; while (1) { free(key); key = get_key(json_pointer, &offset); if (key == NULL) { return -1; } if (offset >= len) { //表示没有下一个key了 break; } cJSON *child = NULL; if (parent->type == cJSON_Object) { child = cJSON_GetObjectItem(parent, key); if (child == NULL) { //总是创建object而不是数组 child = cJSON_CreateObject(); cJSON_AddItemToObject(parent, key, child); } else if (child->type != cJSON_Object && child->type != cJSON_Array) { child = cJSON_CreateObject(); cJSON_ReplaceItemInObject(parent, key, child); } else { //do nothing } } else if (parent->type == cJSON_Array) { int index = atoi(key); child = cJSON_GetArrayItem(parent, index); if (child == NULL) { //总是创建object而不是数组 child = cJSON_CreateObject(); cJSON_InsertItemInArray(parent, index, child); } else if (child->type != cJSON_Object && child->type != cJSON_Array) { child = cJSON_CreateObject(); cJSON_ReplaceItemInArray(parent, index, child); } else { //do nothing } } else { //不应该执行到这里 printf("===>not impossible\n"); } parent = child; } if (parent->type == cJSON_Array) { //key必须为0 or 123,456, '-'表示添加到最后面 if (strcmp("-", key) == 0) { cJSON_AddItemToArray(parent, value); } else { int index = atoi(key); //strtol() cJSON_InsertItemInArray(parent, index, value); } } else if (parent->type == cJSON_Object) { //cJSON_AddItemToObject(parent,key,value); cJSON *oldValue = cJSON_GetObjectItem(parent, key); if (oldValue == NULL) { cJSON_AddItemToObject(parent, key, value); } else { cJSON_ReplaceItemInObject(parent, key, value); } //cJSON *kk = cJSON_GetObjectItem(parent, key); } else { //null,number,string,boolean //不能够添加 printf("=====>noooo\n"); } free(key); return 0; }