private static void TestCollateEquals(JsonCollationMode mode, String input1, String input2, int expectedValue) { TestCollateEquals(mode, input1, input2, int.MaxValue, expectedValue); }
private static void TestCollateEquals(JsonCollationMode mode, String input1, String input2, int arrayLimit, int expectedValue) { int result = JsonCollator.Compare(mode, input1, input2, arrayLimit); Assert.AreEqual(expectedValue, result); }
/// /// <summary> /// Compare two JSON Strings. /// </summary> /// <remarks> /// The comparison result is based on the specification linked below. /// http://wiki.apache.org/couchdb/View_collation#Collation_Specification. /// /// The method assumes that both input JSON strings parameters do not include /// any whitespace characters between each part of the JSON components. /// </remarks> /// <param name="mode"> /// JsonCollationMode.Unicode: Unicode JSON String /// JsonCollationMode.Ascii: ASCII JSON String /// JsonCollationMode.Raw: Raw JSON String /// </param> /// <param name="param1">the first json string to compare.</param> /// <param name="param2">the second json string to compare.</param> /// <param name="arrayLimit">the maximum number of the array element inside the json string to compare.</param> /// <returns> /// The value 0 if the param1 string is equal to the param2 string; /// a value -1 if the param1 is less than the param2 string; /// a value 1 if this string is greater than the string argument. /// </returns> /// public static int Compare(JsonCollationMode mode, String param1, String param2, int arrayLimit) { int index1 = 0; int index2 = 0; int depth = 0; int arrayIndex = 0; int diff; do { var type1 = ValueTypeOf(index1 < param1.Length ? param1[index1] : '\0'); var type2 = ValueTypeOf(index2 < param2.Length ? param2[index2] : '\0'); if (type1 != type2) { if (depth == 1 && (type1 == ValueType.Comma || type2 == ValueType.Comma)) { if (++arrayIndex >= arrayLimit) { return(0); } } if (mode != JsonCollationMode.Raw) { return(Cmp((int)type1, (int)type2)); } else { return(Cmp(RawOrderOfValueType(type1), RawOrderOfValueType(type2))); } } else { switch (type1) { case ValueType.Null: case ValueType.True: index1 += 4; index2 += 4; break; case ValueType.False: index1 += 5; index2 += 5; break; case ValueType.Number: int next1; int next2; diff = DCmp(ReadNumber(param1, index1, out next1), ReadNumber(param2, index2, out next2)); if (diff != 0) { return(diff); } index1 = next1; index2 = next2; break; case ValueType.String: int endPos1; int endPos2; if (mode == JsonCollationMode.Unicode) { diff = CompareStringsUnicode(param1, index1, out endPos1, param2, index2, out endPos2); } else { diff = CompareStringsAscii(param1, index1, out endPos1, param2, index2, out endPos2); } if (diff != 0) { return(diff); } index1 = endPos1 + 1; index2 = endPos2 + 1; break; case ValueType.Array: case ValueType.Object: ++index1; ++index2; ++depth; break; case ValueType.EndArray: case ValueType.EndObject: ++index1; ++index2; --depth; break; case ValueType.Comma: if (depth == 1 && (++arrayIndex >= arrayLimit)) { return(0); } ++index1; ++index2; break; case ValueType.Colon: ++index1; ++index2; break; case ValueType.Illegal: return(0); } } } while (depth > 0); return(0); }
/// /// <summary> /// Compare two JSON Strings. /// </summary> /// <remarks> /// The comparison result is based on the specification linked below. /// http://wiki.apache.org/couchdb/View_collation#Collation_Specification. /// /// The method assumes that both input JSON strings parameters do not include /// any whitespace characters between each part of the JSON components. /// </remarks> /// <param name="mode"> /// JsonCollationMode.Unicode: Unicode JSON String /// JsonCollationMode.Ascii: ASCII JSON String /// JsonCollationMode.Raw: Raw JSON String /// </param> /// <param name="param1">the first json string to compare.</param> /// <param name="param2">the second json string to compare.</param> /// <param name="arrayLimit">the maximum number of the array element inside the json string to compare.</param> /// <returns> /// The value 0 if the param1 string is equal to the param2 string; /// a value -1 if the param1 is less than the param2 string; /// a value 1 if this string is greater than the string argument. /// </returns> /// public static int Compare(JsonCollationMode mode, String param1, String param2, int arrayLimit) { int index1 = 0; int index2 = 0; int depth = 0; int arrayIndex = 0; int diff; do { var type1 = ValueTypeOf(index1 < param1.Length ? param1[index1] : '\0'); var type2 = ValueTypeOf(index2 < param2.Length ? param2[index2] : '\0'); if (type1 != type2) { if (depth == 1 && (type1 == ValueType.Comma || type2 == ValueType.Comma)) { if (++arrayIndex >= arrayLimit) return 0; } if (mode != JsonCollationMode.Raw) return Cmp((int)type1, (int)type2); else return Cmp(RawOrderOfValueType(type1), RawOrderOfValueType(type2)); } else { switch(type1) { case ValueType.Null: case ValueType.True: index1 += 4; index2 += 4; break; case ValueType.False: index1 += 5; index2 += 5; break; case ValueType.Number: int next1; int next2; diff = DCmp(ReadNumber(param1, index1, out next1), ReadNumber(param2, index2, out next2)); if (diff != 0) return diff; index1 = next1; index2 = next2; break; case ValueType.String: int endPos1; int endPos2; if (mode == JsonCollationMode.Unicode) diff = CompareStringsUnicode(param1, index1, out endPos1, param2, index2, out endPos2); else diff = CompareStringsAscii(param1, index1, out endPos1, param2, index2, out endPos2); if (diff != 0) return diff; index1 = endPos1 + 1; index2 = endPos2 + 1; break; case ValueType.Array: case ValueType.Object: ++index1; ++index2; ++depth; break; case ValueType.EndArray: case ValueType.EndObject: ++index1; ++index2; --depth; break; case ValueType.Comma: if (depth == 1 && (++arrayIndex >= arrayLimit)) return 0; ++index1; ++index2; break; case ValueType.Colon: ++index1; ++index2; break; case ValueType.Illegal: return 0; } } } while (depth > 0); return 0; }
private static void TestCollateEquals(JsonCollationMode mode, String input1, String input2, int expectedValue) { TestCollateEquals(mode, input1, input2, int.MaxValue, expectedValue); }
private static void TestCollateEquals(JsonCollationMode mode, String input1, String input2, int arrayLimit, int expectedValue) { int result = JsonCollator.Compare(mode, input1, input2, arrayLimit); Assert.AreEqual(expectedValue, result); }