CompareResult LocalView::KeyAndDocId::compare(const KeyAndDocId& other) const { CompareResult c = compareJson(key,other.key); if (c == cmpResultEqual) { return compareStringsUnicode(docId,other.docId); } else { return c; } }
int CollateJSON(const sized_buf *buf1, const sized_buf *buf2, CollateJSONMode mode) { const char* str1 = buf1->buf; const char* str2 = buf2->buf; int depth = 0; do { /* Get the types of the next token in each string: */ ValueType type1 = valueTypeOf(*str1); ValueType type2 = valueTypeOf(*str2); /* If types don't match, stop and return their relative ordering: */ if (type1 != type2) { if (mode != kCollateJSON_Raw) return cmp(type1, type2); else return cmp(kRawOrderOfValueType[type1], kRawOrderOfValueType[type2]); /* If types match, compare the actual token values: */ } else switch (type1) { case kNull: case kTrue: str1 += 4; str2 += 4; break; case kFalse: str1 += 5; str2 += 5; break; case kNumber: { char* next1, *next2; int diff; if (depth == 0) { /* At depth 0, be careful not to fall off the end of the input, because there won't be any delimiters (']' or '}') after the number! */ diff = dcmp( readNumber(str1, buf1->buf + buf1->size, &next1), readNumber(str2, buf2->buf + buf2->size, &next2) ); } else { diff = dcmp( strtod(str1, &next1), strtod(str2, &next2) ); } if (diff) return diff; /* Numbers don't match */ str1 = next1; str2 = next2; break; } case kString: { int diff; if (mode == kCollateJSON_Unicode) diff = compareStringsUnicode(&str1, &str2); else diff = compareStringsASCII(&str1, &str2); if (diff) return diff; /* Strings don't match */ break; } case kArray: case kObject: ++str1; ++str2; ++depth; break; case kEndArray: case kEndObject: ++str1; ++str2; --depth; break; case kComma: case kColon: ++str1; ++str2; break; case kIllegal: return 0; } /* Keep going as long as we're inside an array or object */ } while (depth > 0); return 0; }
int CollateJSON(void *context, int len1, const void * chars1, int len2, const void * chars2) { static bool charPriorityMapInitialized = false; if(!charPriorityMapInitialized){ initializeCharPriorityMap(); charPriorityMapInitialized = true; } const char* str1 = (const char*) chars1; const char* str2 = (const char*) chars2; int depth = 0; do { // Get the types of the next token in each string: ValueType type1 = valueTypeOf(*str1); ValueType type2 = valueTypeOf(*str2); // If types don't match, stop and return their relative ordering: if (type1 != type2) { if (context != kJsonCollator_Raw) return cmp(type1, type2); else return cmp(kRawOrderOfValueType[type1], kRawOrderOfValueType[type2]); // If types match, compare the actual token values: } else switch (type1) { case kNull: case kTrue: str1 += 4; str2 += 4; break; case kFalse: str1 += 5; str2 += 5; break; case kNumber: { char* next1, *next2; int diff; if (depth == 0) { diff = dcmp( readNumber(str1, str1 + len1, &next1), readNumber(str2, str2 + len2, &next2) ); } else { diff = dcmp(strtod(str1, &next1), strtod(str2, &next2)); } if (diff) { return diff; // Numbers don't match } str1 = next1; str2 = next2; break; } case kString: { int diff; if (context == kJsonCollator_Unicode) diff = compareStringsUnicode(&str1, &str2); else diff = compareStringsASCII(&str1, &str2); if (diff) return diff; // Strings don't match break; } case kArray: case kObject: ++str1; ++str2; ++depth; break; case kEndArray: case kEndObject: ++str1; ++str2; --depth; break; case kComma: case kColon: ++str1; ++str2; break; case kIllegal: return 0; } } while (depth > 0); // Keep going as long as we're inside an array or object return 0; }