static int compareStringsASCII(const char** in1, const char** in2) { const char* str1 = *in1, *str2 = *in2; while (true) { char c1 = *++str1; char c2 = *++str2; // If one string ends, the other is greater; if both end, they're equal: if (c1 == '"') { if (c2 == '"') break; else return -1; } else if (c2 == '"') return 1; // Un-escape the next character after a backslash: if (c1 == '\\') c1 = convertEscape(&str1); if (c2 == '\\') c2 = convertEscape(&str2); // Compare the next characters: int s = cmp(c1, c2); if (s) return s; } // Strings are equal, so update the positions: *in1 = str1 + 1; *in2 = str2 + 1; return 0; }
JNIEXPORT jchar JNICALL Java_com_couchbase_lite_android_SQLiteJsonCollator_testEscape (JNIEnv *env, jclass clazz, jstring source) { jboolean isCopy; const char* cstring = env->GetStringUTFChars(source, &isCopy); char result = convertEscape(&cstring); return result; }
static const char* createStringFromJSON(const char** in) { // Scan the JSON string to find its end and whether it contains escapes: const char* start = ++*in; unsigned escapes = 0; const char* str; for (str = start; *str != '"'; ++str) { if (*str == '\\') { ++str; if (*str == 'u') { escapes += 5; // \uxxxx adds 5 bytes str += 4; } else escapes += 1; } } *in = str + 1; size_t length = str - start; char* buf = NULL; length -= escapes; buf = (char*) malloc(length + 1); char* dst = buf; char c; for (str = start; (c = *str) != '"'; ++str) { if (c == '\\') c = convertEscape(&str); *dst++ = c; } *dst++ = 0; //null terminate return (const char *)buf; }
// Unicode collation, but fails (returns -2) if non-ASCII characters are found. // Basic rule is to compare case-insensitively, but if the strings compare equal, let the one that's // higher case-sensitively win (where uppercase is _greater_ than lowercase, unlike in ASCII.) static int compareStringsUnicodeFast(const char** in1, const char** in2) { const char* str1 = *in1, *str2 = *in2; int resultIfEqual = 0; while(true) { char c1 = *++str1; char c2 = *++str2; // If one string ends, the other is greater; if both end, they're equal: if (c1 == '"') { if (c2 == '"') break; else return -1; } else if (c2 == '"') return 1; // Handle escape sequences: if (c1 == '\\') c1 = convertEscape(&str1); if (c2 == '\\') c2 = convertEscape(&str2); if ((c1 & 0x80) || (c2 & 0x80)) return -2; // fail: I only handle ASCII // Compare the next characters, according to case-insensitive Unicode character priority: int s = cmp(kCharPriorityCaseInsensitive[(uint8_t)c1], kCharPriorityCaseInsensitive[(uint8_t)c2]); if (s) return s; // Remember case-sensitive result too if (resultIfEqual == 0 && c1 != c2) resultIfEqual = cmp(kCharPriority[(uint8_t)c1], kCharPriority[(uint8_t)c2]); } if (resultIfEqual) return resultIfEqual; // Strings are equal, so update the positions: *in1 = str1 + 1; *in2 = str2 + 1; return 0; }
static void unescapeStr(struct gff3Ann *g3a, char *dest, char *src) /* remove URL-style escapes from a string. dest need only have enough * memory to hold src, as unescaping will not grow the string */ { char *s = src, *d = dest; while (*s != '\0') { if (*s == '%') { *d++ = convertEscape(g3a, s, src); s += 3; } else *d++ = *s++; } *d = '\0'; }
static jstring createJavaStringFromJSON(const char** in) { // Scan the JSON string to find its end and whether it contains escapes: const char* start = ++*in; unsigned escapes = 0; const char* str; for (str = start; *str != '"'; ++str) { if (*str == '\\') { ++str; if (*str == 'u') { escapes += 5; // \uxxxx adds 5 bytes str += 4; } else escapes += 1; } } *in = str + 1; size_t length = str - start; char* buf = NULL; length -= escapes; buf = (char*) malloc(length + 1); char* dst = buf; char c; for (str = start; (c = *str) != '"'; ++str) { if (c == '\\') c = convertEscape(&str); *dst++ = c; } *dst++ = 0; //null terminate start = buf; //LOGV("After stripping escapes string is: %s", start); JNIEnv *env = getEnv(); jstring result = env->NewStringUTF(start); if (buf != NULL) { free(buf); } if (result == NULL) { LOGE("Failed to convert to string: start=%p, length=%u", start, length); } return result; }