@@ -370,6 +370,66 @@ static int json_object_equal(const json_t *object1, const json_t *object2) {
370370 return 1 ;
371371}
372372
373+ static int json_strnncmp (const char * s1 , size_t s1_len , const char * s2 , size_t s2_len )
374+ {
375+ int result = strncmp (s1 , s2 , (s1_len > s2_len ? s2_len : s1_len ));
376+
377+ if (result > 1 )
378+ result = 1 ;
379+ else if (result < -1 )
380+ result = -1 ;
381+
382+ if (result == 0 ) {
383+ if (s1_len < s2_len )
384+ result = -1 ;
385+ else if (s1_len > s2_len )
386+ result = 1 ;
387+ }
388+
389+ return result ;
390+ }
391+
392+ static void json_object_next_key (const json_t * object , const char * * next_key , size_t * next_key_len , const char * prev_key , size_t prev_key_len ) {
393+ const char * key ;
394+ size_t key_len ;
395+ const json_t * value ;
396+
397+ * next_key = NULL ;
398+
399+ /* Linear search through the object to find the smallest key which is >prev_key */
400+ json_object_keylen_foreach ((json_t * )object , key , key_len , value ) {
401+ if ((* next_key == NULL || json_strnncmp (* next_key , * next_key_len , key , key_len ) < 0 )
402+ && (prev_key == NULL || json_strnncmp (prev_key , prev_key_len , key , key_len ) > 0 )) {
403+ * next_key = key ;
404+ * next_key_len = key_len ;
405+ }
406+ }
407+ }
408+
409+ static int json_object_compare (const json_t * object1 , const json_t * object2 ) {
410+ const char * key1 = NULL , * key2 = NULL ;
411+ size_t key1_len , key2_len ;
412+
413+ json_object_next_key (object1 , & key1 , & key1_len , key1 , key1_len );
414+ json_object_next_key (object2 , & key2 , & key2_len , key2 , key2_len );
415+
416+ while (key1 != NULL && key2 != NULL ) {
417+ int cmp = json_strnncmp (key1 , key1_len , key2 , key2_len );
418+ if (cmp != 0 )
419+ return cmp ;
420+
421+ json_object_next_key (object1 , & key1 , & key1_len , key1 , key1_len );
422+ json_object_next_key (object2 , & key2 , & key2_len , key2 , key2_len );
423+ }
424+
425+ if (key1 != NULL )
426+ return 1 ;
427+ else if (key2 != NULL )
428+ return -1 ;
429+ else
430+ return 0 ;
431+ }
432+
373433static json_t * json_object_copy (json_t * object ) {
374434 json_t * result ;
375435
@@ -670,6 +730,33 @@ static int json_array_equal(const json_t *array1, const json_t *array2) {
670730 return 1 ;
671731}
672732
733+ static int json_array_compare (const json_t * array1 , const json_t * array2 ) {
734+ size_t a1_size , a2_size , min_size , i ;
735+
736+ a1_size = json_array_size (array1 );
737+ a2_size = json_array_size (array2 );
738+ min_size = a1_size > a2_size ? a2_size : a1_size ;
739+
740+ for (i = 0 ; i < min_size ; i ++ ) {
741+ json_t * value1 , * value2 ;
742+ int result ;
743+
744+ value1 = json_array_get (array1 , i );
745+ value2 = json_array_get (array2 , i );
746+
747+ result = json_compare (value1 , value2 );
748+ if (result != 0 )
749+ return result ;
750+ }
751+
752+ if (a1_size < a2_size )
753+ return 1 ;
754+ else if (a1_size > a2_size )
755+ return -1 ;
756+
757+ return 0 ;
758+ }
759+
673760static json_t * json_array_copy (json_t * array ) {
674761 json_t * result ;
675762 size_t i ;
@@ -838,6 +925,15 @@ static int json_string_equal(const json_t *string1, const json_t *string2) {
838925 return s1 -> length == s2 -> length && !memcmp (s1 -> value , s2 -> value , s1 -> length );
839926}
840927
928+ static int json_string_compare (const json_t * string1 , const json_t * string2 ) {
929+ json_string_t * s1 , * s2 ;
930+
931+ s1 = json_to_string (string1 );
932+ s2 = json_to_string (string2 );
933+
934+ return json_strnncmp (s1 -> value , s1 -> length , s2 -> value , s2 -> length );
935+ }
936+
841937static json_t * json_string_copy (const json_t * string ) {
842938 json_string_t * s ;
843939
@@ -922,6 +1018,15 @@ static int json_integer_equal(const json_t *integer1, const json_t *integer2) {
9221018 return json_integer_value (integer1 ) == json_integer_value (integer2 );
9231019}
9241020
1021+ static int json_integer_compare (const json_t * integer1 , const json_t * integer2 ) {
1022+ if (json_integer_value (integer1 ) < json_integer_value (integer2 ))
1023+ return -1 ;
1024+ else if (json_integer_value (integer1 ) > json_integer_value (integer2 ))
1025+ return 1 ;
1026+ else
1027+ return 0 ;
1028+ }
1029+
9251030static json_t * json_integer_copy (const json_t * integer ) {
9261031 return json_integer (json_integer_value (integer ));
9271032}
@@ -965,6 +1070,15 @@ static int json_real_equal(const json_t *real1, const json_t *real2) {
9651070 return json_real_value (real1 ) == json_real_value (real2 );
9661071}
9671072
1073+ static int json_real_compare (const json_t * real1 , const json_t * real2 ) {
1074+ if (json_real_value (real1 ) < json_real_value (real2 ))
1075+ return -1 ;
1076+ else if (json_real_value (real1 ) > json_real_value (real2 ))
1077+ return 1 ;
1078+ else
1079+ return 0 ;
1080+ }
1081+
9681082static json_t * json_real_copy (const json_t * real ) {
9691083 return json_real (json_real_value (real ));
9701084}
@@ -1055,6 +1169,43 @@ int json_equal(const json_t *json1, const json_t *json2) {
10551169 }
10561170}
10571171
1172+ /*** comparison ***/
1173+
1174+ int json_compare (const json_t * json1 , const json_t * json2 ) {
1175+ if (!json1 && !json2 )
1176+ return 0 ;
1177+
1178+ if (!json1 )
1179+ return -1 ;
1180+
1181+ if (!json2 )
1182+ return 1 ;
1183+
1184+ if (json_typeof (json1 ) < json_typeof (json2 ))
1185+ return -1 ;
1186+ else if (json_typeof (json1 ) > json_typeof (json2 ))
1187+ return 1 ;
1188+
1189+ /* this covers true, false and null as they are singletons */
1190+ if (json1 == json2 )
1191+ return 0 ;
1192+
1193+ switch (json_typeof (json1 )) {
1194+ case JSON_OBJECT :
1195+ return json_object_compare (json1 , json2 );
1196+ case JSON_ARRAY :
1197+ return json_array_compare (json1 , json2 );
1198+ case JSON_STRING :
1199+ return json_string_compare (json1 , json2 );
1200+ case JSON_INTEGER :
1201+ return json_integer_compare (json1 , json2 );
1202+ case JSON_REAL :
1203+ return json_real_compare (json1 , json2 );
1204+ default :
1205+ return 0 ;
1206+ }
1207+ }
1208+
10581209/*** copying ***/
10591210
10601211json_t * json_copy (json_t * json ) {
0 commit comments