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;
}
예제 #5
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;
}