瀏覽代碼

reformatting: cJSONUtils_CompareToPatch

Max Bruckner 8 年之前
父節點
當前提交
8879ed5dbc
共有 1 個文件被更改,包括 89 次插入53 次删除
  1. 89 53
      cJSON_Utils.c

+ 89 - 53
cJSON_Utils.c

@@ -509,63 +509,99 @@ void cJSONUtils_AddPatchToArray(cJSON *array, const char *op, const char *path,
     cJSONUtils_GeneratePatch(array, op, path, 0, val);
 }
 
-static void cJSONUtils_CompareToPatch(cJSON *patches,const char *path,cJSON *from,cJSON *to)
+static void cJSONUtils_CompareToPatch(cJSON *patches, const char *path, cJSON *from, cJSON *to)
 {
-	if (from->type!=to->type)	{cJSONUtils_GeneratePatch(patches,"replace",path,0,to);	return;	}
-	
-	switch (from->type)
-	{
-	case cJSON_Number:	
-		if (from->valueint!=to->valueint || from->valuedouble!=to->valuedouble)
-			cJSONUtils_GeneratePatch(patches,"replace",path,0,to);
-		return;
-						
-	case cJSON_String:	
-		if (strcmp(from->valuestring,to->valuestring)!=0)
-			cJSONUtils_GeneratePatch(patches,"replace",path,0,to);
-		return;
-
-	case cJSON_Array:
-	{
-		int c;char *newpath=(char*)malloc(strlen(path)+23);	/* Allow space for 64bit int. */
-		for (c=0,from=from->child,to=to->child;from && to;from=from->next,to=to->next,c++){
-										sprintf(newpath,"%s/%d",path,c);	cJSONUtils_CompareToPatch(patches,newpath,from,to);
-		}
-		for (;from;from=from->next,c++)	{sprintf(newpath,"%d",c);	cJSONUtils_GeneratePatch(patches,"remove",path,newpath,0);	}
-		for (;to;to=to->next,c++)		cJSONUtils_GeneratePatch(patches,"add",path,"-",to);
-		free(newpath);
-		return;
-	}
+    if (from->type != to->type)
+    {
+        cJSONUtils_GeneratePatch(patches, "replace", path, 0, to);
+        return;
+    }
 
-	case cJSON_Object:
-	{
-		cJSON *a,*b;
-		cJSONUtils_SortObject(from);
-		cJSONUtils_SortObject(to);
-		
-		a=from->child,b=to->child;
-		while (a || b)
-		{
-			int diff=(!a)?1:(!b)?-1:cJSONUtils_strcasecmp(a->string,b->string);
-			if (!diff)
-			{
-				char *newpath=(char*)malloc(strlen(path)+cJSONUtils_PointerEncodedstrlen(a->string)+2);
-				cJSONUtils_PointerEncodedstrcpy(newpath+sprintf(newpath,"%s/",path),a->string);
-				cJSONUtils_CompareToPatch(patches,newpath,a,b);
-				free(newpath);
-				a=a->next;
-				b=b->next;
-			}
-			else if (diff<0)	{cJSONUtils_GeneratePatch(patches,"remove",path,a->string,0);	a=a->next;}
-			else				{cJSONUtils_GeneratePatch(patches,"add",path,b->string,b);		b=b->next;}
-		}
-		return;
-	}
+    switch (from->type)
+    {
+        case cJSON_Number:
+            if ((from->valueint != to->valueint) || (from->valuedouble != to->valuedouble))
+            {
+                cJSONUtils_GeneratePatch(patches, "replace", path, 0, to);
+            }
+            return;
 
-	default:			break;
-	}
-}
+        case cJSON_String:
+            if (strcmp(from->valuestring, to->valuestring) != 0)
+            {
+                cJSONUtils_GeneratePatch(patches, "replace", path, 0, to);
+            }
+            return;
+
+        case cJSON_Array:
+        {
+            int c;
+            char *newpath = (char*)malloc(strlen(path) + 23); /* Allow space for 64bit int. */
+            /* generate patches for all array elements that exist in "from" and "to" */
+            for (c = 0, from = from->child, to = to->child; from && to; from = from->next, to = to->next, c++)
+            {
+                sprintf(newpath, "%s/%d", path, c); /* path of the current array element */
+                cJSONUtils_CompareToPatch(patches, newpath, from, to);
+            }
+            /* remove leftover elements from 'from' that are not in 'to' */
+            for (; from; from = from->next, c++)
+            {
+                sprintf(newpath, "%d", c);
+                cJSONUtils_GeneratePatch(patches, "remove", path, newpath, 0);
+            }
+            /* add new elements in 'to' that were not in 'from' */
+            for (; to; to = to->next, c++)
+            {
+                cJSONUtils_GeneratePatch(patches, "add", path, "-", to);
+            }
+            free(newpath);
+            return;
+        }
 
+        case cJSON_Object:
+        {
+            cJSON *a;
+            cJSON *b;
+            cJSONUtils_SortObject(from);
+            cJSONUtils_SortObject(to);
+
+            a = from->child;
+            b = to->child;
+            /* for all object values in the object with more of them */
+            while (a || b)
+            {
+                int diff = (!a) ? 1 : ((!b) ? -1 : cJSONUtils_strcasecmp(a->string, b->string));
+                if (!diff)
+                {
+                    /* both object keys are the same */
+                    char *newpath = (char*)malloc(strlen(path) + cJSONUtils_PointerEncodedstrlen(a->string) + 2);
+                    cJSONUtils_PointerEncodedstrcpy(newpath + sprintf(newpath, "%s/", path), a->string);
+                    /* create a patch for the element */
+                    cJSONUtils_CompareToPatch(patches, newpath, a, b);
+                    free(newpath);
+                    a = a->next;
+                    b = b->next;
+                }
+                else if (diff < 0)
+                {
+                    /* object element doesn't exist in 'to' --> remove it */
+                    cJSONUtils_GeneratePatch(patches, "remove", path, a->string, 0);
+                    a = a->next;
+                }
+                else
+                {
+                    /* object element doesn't exist in 'from' --> add it */
+                    cJSONUtils_GeneratePatch(patches, "add", path, b->string, b);
+                    b = b->next;
+                }
+            }
+            return;
+        }
+
+        default:
+            break;
+    }
+}
 
 cJSON* cJSONUtils_GeneratePatches(cJSON *from,cJSON *to)
 {