瀏覽代碼

refactor cJSONUtils_GenerateMergePatch

Max Bruckner 8 年之前
父節點
當前提交
bb2f868126
共有 2 個文件被更改,包括 41 次插入18 次删除
  1. 39 17
      cJSON_Utils.c
  2. 2 1
      cJSON_Utils.h

+ 39 - 17
cJSON_Utils.c

@@ -1180,10 +1180,12 @@ CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatch(cJSON *target, const cJSON * const p
     return target;
 }
 
-CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatch(cJSON *from, cJSON *to)
+CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatch(cJSON * const from, cJSON * const to)
 {
+    cJSON *from_child = NULL;
+    cJSON *to_child = NULL;
     cJSON *patch = NULL;
-    if (!to)
+    if (to == NULL)
     {
         /* patch to delete everything */
         return cJSON_CreateNull();
@@ -1196,39 +1198,59 @@ CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatch(cJSON *from, cJSON *to)
     cJSONUtils_SortObject(from);
     cJSONUtils_SortObject(to);
 
-    from = from->child;
-    to = to->child;
+    from_child = from->child;
+    to_child = to->child;
     patch = cJSON_CreateObject();
-    while (from || to)
+    while (from_child || to_child)
     {
-        int compare = from ? (to ? strcmp(from->string, to->string) : -1) : 1;
-        if (compare < 0)
+        int diff;
+        if (from_child != NULL)
+        {
+            if (to_child != NULL)
+            {
+                diff = strcmp(from_child->string, to_child->string);
+            }
+            else
+            {
+                diff = -1;
+            }
+        }
+        else
+        {
+            diff = 1;
+        }
+
+        if (diff < 0)
         {
             /* from has a value that to doesn't have -> remove */
-            cJSON_AddItemToObject(patch, from->string, cJSON_CreateNull());
-            from = from->next;
+            cJSON_AddItemToObject(patch, from_child->string, cJSON_CreateNull());
+
+            from_child = from_child->next;
         }
-        else if (compare > 0)
+        else if (diff > 0)
         {
             /* to has a value that from doesn't have -> add to patch */
-            cJSON_AddItemToObject(patch, to->string, cJSON_Duplicate(to, 1));
-            to = to->next;
+            cJSON_AddItemToObject(patch, to_child->string, cJSON_Duplicate(to_child, 1));
+
+            to_child = to_child->next;
         }
         else
         {
             /* object key exists in both objects */
-            if (cJSONUtils_Compare(from, to))
+            if (cJSONUtils_Compare(from_child, to_child))
             {
                 /* not identical --> generate a patch */
-                cJSON_AddItemToObject(patch, to->string, cJSONUtils_GenerateMergePatch(from, to));
+                cJSON_AddItemToObject(patch, to_child->string, cJSONUtils_GenerateMergePatch(from_child, to_child));
             }
+
             /* next key in the object */
-            from = from->next;
-            to = to->next;
+            from_child = from_child->next;
+            to_child = to_child->next;
         }
     }
-    if (!patch->child)
+    if (patch->child == NULL)
     {
+        /* no patch generated */
         cJSON_Delete(patch);
         return NULL;
     }

+ 2 - 1
cJSON_Utils.h

@@ -58,7 +58,8 @@ CJSON_PUBLIC(int) cJSONUtils_ApplyPatches(cJSON * const object, const cJSON * co
 /* target will be modified by patch. return value is new ptr for target. */
 CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatch(cJSON *target, const cJSON * const patch);
 /* generates a patch to move from -> to */
-CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatch(cJSON *from, cJSON *to);
+/* NOTE: This modifies objects in 'from' and 'to' by sorting the elements by their key */
+CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatch(cJSON * const from, cJSON * const to);
 
 /* Given a root object and a target object, construct a pointer from one to the other. */
 CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const object, const cJSON * const target);