/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * UTF-8 and Unicode string manipulation, plus java/lang/String convenience
 * functions.
 *
 * In most cases we populate the fields in the String object directly,
 * rather than going through an instance field lookup.
 */
#include "Dalvik.h"
#include <stdlib.h>

/*
 * Initialize string globals.
 *
 * This isn't part of the VM init sequence because it's hard to get the
 * timing right -- we need it to happen after java/lang/String has been
 * loaded, but before anybody wants to use a string.  It's easiest to
 * just initialize it on first use.
 *
 * In some unusual circumstances (e.g. trying to throw an exception because
 * String implements java/lang/CharSequence, but CharSequence doesn't exist)
 * we can try to create an exception string internally before anything has
 * really tried to use String.  In that case we basically self-destruct.
 *
 * We're expecting to be essentially single-threaded at this point.
 * We employ atomics to ensure everything is observed correctly, and also
 * to guarantee that we do detect a problem if our assumption is wrong.
 */
static bool stringStartup()
{
    if (gDvm.javaLangStringReady < 0) {
        LOGE("ERROR: reentrant string initialization\n");
        assert(false);
        return false;
    }

    if (android_atomic_acquire_cas(0, -1, &gDvm.javaLangStringReady) != 0) {
        LOGE("ERROR: initial string-ready state not 0 (%d)\n",
            gDvm.javaLangStringReady);
        return false;
    }

    if (gDvm.classJavaLangString == NULL)
        gDvm.classJavaLangString =
            dvmFindSystemClassNoInit("Ljava/lang/String;");

    gDvm.offJavaLangString_value =
        dvmFindFieldOffset(gDvm.classJavaLangString, "value", "[C");
    gDvm.offJavaLangString_count =
        dvmFindFieldOffset(gDvm.classJavaLangString, "count", "I");
    gDvm.offJavaLangString_offset =
        dvmFindFieldOffset(gDvm.classJavaLangString, "offset", "I");
    gDvm.offJavaLangString_hashCode =
        dvmFindFieldOffset(gDvm.classJavaLangString, "hashCode", "I");

    if (gDvm.offJavaLangString_value < 0 ||
        gDvm.offJavaLangString_count < 0 ||
        gDvm.offJavaLangString_offset < 0 ||
        gDvm.offJavaLangString_hashCode < 0)
    {
        LOGE("VM-required field missing from java/lang/String\n");
        return false;
    }

    bool badValue = false;
    if (gDvm.offJavaLangString_value != STRING_FIELDOFF_VALUE) {
        LOGE("InlineNative: String.value offset = %d, expected %d\n",
            gDvm.offJavaLangString_value, STRING_FIELDOFF_VALUE);
        badValue = true;
    }
    if (gDvm.offJavaLangString_count != STRING_FIELDOFF_COUNT) {
        LOGE("InlineNative: String.count offset = %d, expected %d\n",
            gDvm.offJavaLangString_count, STRING_FIELDOFF_COUNT);
        badValue = true;
    }
    if (gDvm.offJavaLangString_offset != STRING_FIELDOFF_OFFSET) {
        LOGE("InlineNative: String.offset offset = %d, expected %d\n",
            gDvm.offJavaLangString_offset, STRING_FIELDOFF_OFFSET);
        badValue = true;
    }
    if (gDvm.offJavaLangString_hashCode != STRING_FIELDOFF_HASHCODE) {
        LOGE("InlineNative: String.hashCode offset = %d, expected %d\n",
            gDvm.offJavaLangString_hashCode, STRING_FIELDOFF_HASHCODE);
        badValue = true;
    }
    if (badValue)
        return false;

    android_atomic_release_store(1, &gDvm.javaLangStringReady);

    return true;
}

/*
 * Discard heap-allocated storage.
 */
void dvmStringShutdown()
{
    // currently unused
}

/*
 * Compute a hash code on a UTF-8 string, for use with internal hash tables.
 *
 * This may or may not yield the same results as the java/lang/String
 * computeHashCode() function.  (To make sure this doesn't get abused,
 * I'm initializing the hash code to 1 so they *don't* match up.)
 *
 * It would be more correct to invoke dexGetUtf16FromUtf8() here and compute
 * the hash with the result.  That way, if something encoded the same
 * character in two different ways, the hash value would be the same.  For
 * our purposes that isn't necessary.
 */
u4 dvmComputeUtf8Hash(const char* utf8Str)
{
    u4 hash = 1;

    while (*utf8Str != '\0')
        hash = hash * 31 + *utf8Str++;

    return hash;
}

/*
 * Like "strlen", but for strings encoded with "modified" UTF-8.
 *
 * The value returned is the number of characters, which may or may not
 * be the same as the number of bytes.
 *
 * (If this needs optimizing, try: mask against 0xa0, shift right 5,
 * get increment {1-3} from table of 8 values.)
 */
int dvmUtf8Len(const char* utf8Str)
{
    int ic, len = 0;

    while ((ic = *utf8Str++) != '\0') {
        len++;
        if ((ic & 0x80) != 0) {
            /* two- or three-byte encoding */
            utf8Str++;
            if ((ic & 0x20) != 0) {
                /* three-byte encoding */
                utf8Str++;
            }
        }
    }

    return len;
}

/*
 * Convert a "modified" UTF-8 string to UTF-16.
 */
void dvmConvertUtf8ToUtf16(u2* utf16Str, const char* utf8Str)
{
    while (*utf8Str != '\0')
        *utf16Str++ = dexGetUtf16FromUtf8(&utf8Str);
}

/*
 * Given a UTF-16 string, compute the length of the corresponding UTF-8
 * string in bytes.
 */
static int utf16_utf8ByteLen(const u2* utf16Str, int len)
{
    int utf8Len = 0;

    while (len--) {
        unsigned int uic = *utf16Str++;

        /*
         * The most common case is (uic > 0 && uic <= 0x7f).
         */
        if (uic == 0 || uic > 0x7f) {
            if (uic > 0x07ff)
                utf8Len += 3;
            else /*(uic > 0x7f || uic == 0) */
                utf8Len += 2;
        } else
            utf8Len++;
    }
    return utf8Len;
}

/*
 * Convert a UTF-16 string to UTF-8.
 *
 * Make sure you allocate "utf8Str" with the result of utf16_utf8ByteLen(),
 * not just "len".
 */
static void convertUtf16ToUtf8(char* utf8Str, const u2* utf16Str, int len)
{
    assert(len >= 0);

    while (len--) {
        unsigned int uic = *utf16Str++;

        /*
         * The most common case is (uic > 0 && uic <= 0x7f).
         */
        if (uic == 0 || uic > 0x7f) {
            if (uic > 0x07ff) {
                *utf8Str++ = (uic >> 12) | 0xe0;
                *utf8Str++ = ((uic >> 6) & 0x3f) | 0x80;
                *utf8Str++ = (uic & 0x3f) | 0x80;
            } else /*(uic > 0x7f || uic == 0)*/ {
                *utf8Str++ = (uic >> 6) | 0xc0;
                *utf8Str++ = (uic & 0x3f) | 0x80;
            }
        } else {
            *utf8Str++ = uic;
        }
    }

    *utf8Str = '\0';
}

/*
 * Use the java/lang/String.computeHashCode() algorithm.
 */
static inline u4 dvmComputeUtf16Hash(const u2* utf16Str, int len)
{
    u4 hash = 0;

    while (len--)
        hash = hash * 31 + *utf16Str++;

    return hash;
}
u4 dvmComputeStringHash(StringObject* strObj) {
    ArrayObject* chars = (ArrayObject*) dvmGetFieldObject((Object*) strObj,
                                STRING_FIELDOFF_VALUE);
    int offset, len;

    len = dvmGetFieldInt((Object*) strObj, STRING_FIELDOFF_COUNT);
    offset = dvmGetFieldInt((Object*) strObj, STRING_FIELDOFF_OFFSET);

    return dvmComputeUtf16Hash((u2*) chars->contents + offset, len);
}

/*
 * Create a new java/lang/String object, using the string data in "utf8Str".
 *
 * The caller must call dvmReleaseTrackedAlloc() on the return value.
 *
 * Returns NULL and throws an exception on failure.
 */
StringObject* dvmCreateStringFromCstr(const char* utf8Str)
{
    assert(utf8Str != NULL);
    return dvmCreateStringFromCstrAndLength(utf8Str, dvmUtf8Len(utf8Str));
}

/*
 * Create a java/lang/String from a C string, given its UTF-16 length
 * (number of UTF-16 code points).
 *
 * The caller must call dvmReleaseTrackedAlloc() on the return value.
 *
 * Returns NULL and throws an exception on failure.
 */
StringObject* dvmCreateStringFromCstrAndLength(const char* utf8Str,
    u4 utf16Length)
{
    StringObject* newObj;
    ArrayObject* chars;
    u4 hashCode = 0;

    //LOGV("Creating String from '%s'\n", utf8Str);
    assert(utf8Str != NULL);

    if (gDvm.javaLangStringReady <= 0) {
        if (!stringStartup())
            return NULL;
    }

    /* init before alloc */
    if (!dvmIsClassInitialized(gDvm.classJavaLangString) &&
        !dvmInitClass(gDvm.classJavaLangString))
    {
        return NULL;
    }

    newObj = (StringObject*) dvmAllocObject(gDvm.classJavaLangString,
                ALLOC_DEFAULT);
    if (newObj == NULL)
        return NULL;

    chars = dvmAllocPrimitiveArray('C', utf16Length, ALLOC_DEFAULT);
    if (chars == NULL) {
        dvmReleaseTrackedAlloc((Object*) newObj, NULL);
        return NULL;
    }
    dvmConvertUtf8ToUtf16((u2*)chars->contents, utf8Str);
    hashCode = dvmComputeUtf16Hash((u2*) chars->contents, utf16Length);

    dvmSetFieldObject((Object*)newObj, STRING_FIELDOFF_VALUE,
        (Object*)chars);
    dvmReleaseTrackedAlloc((Object*) chars, NULL);
    dvmSetFieldInt((Object*)newObj, STRING_FIELDOFF_COUNT, utf16Length);
    dvmSetFieldInt((Object*)newObj, STRING_FIELDOFF_HASHCODE, hashCode);
    /* leave offset set to zero */

    /* debugging stuff */
    //dvmDumpObject((Object*)newObj);
    //printHexDumpEx(ANDROID_LOG_DEBUG, chars->contents, utf16Length * 2,
    //    kHexDumpMem);

    /* caller may need to dvmReleaseTrackedAlloc(newObj) */
    return newObj;
}

/*
 * Create a new java/lang/String object, using the Unicode data.
 */
StringObject* dvmCreateStringFromUnicode(const u2* unichars, int len)
{
    StringObject* newObj;
    ArrayObject* chars;
    u4 hashCode = 0;

    /* we allow a null pointer if the length is zero */
    assert(len == 0 || unichars != NULL);

    if (gDvm.javaLangStringReady <= 0) {
        if (!stringStartup())
            return NULL;
    }

    /* init before alloc */
    if (!dvmIsClassInitialized(gDvm.classJavaLangString) &&
        !dvmInitClass(gDvm.classJavaLangString))
    {
        return NULL;
    }

    newObj = (StringObject*) dvmAllocObject(gDvm.classJavaLangString,
        ALLOC_DEFAULT);
    if (newObj == NULL)
        return NULL;

    chars = dvmAllocPrimitiveArray('C', len, ALLOC_DEFAULT);
    if (chars == NULL) {
        dvmReleaseTrackedAlloc((Object*) newObj, NULL);
        return NULL;
    }
    if (len > 0)
        memcpy(chars->contents, unichars, len * sizeof(u2));
    hashCode = dvmComputeUtf16Hash((u2*) chars->contents, len);

    dvmSetFieldObject((Object*)newObj, STRING_FIELDOFF_VALUE,
        (Object*)chars);
    dvmReleaseTrackedAlloc((Object*) chars, NULL);
    dvmSetFieldInt((Object*)newObj, STRING_FIELDOFF_COUNT, len);
    dvmSetFieldInt((Object*)newObj, STRING_FIELDOFF_HASHCODE, hashCode);
    /* leave offset set to zero */

    /* debugging stuff */
    //dvmDumpObject((Object*)newObj);
    //printHexDumpEx(ANDROID_LOG_DEBUG, chars->contents, len*2, kHexDumpMem);

    /* caller must dvmReleaseTrackedAlloc(newObj) */
    return newObj;
}

/*
 * Create a new C string from a java/lang/String object.
 *
 * Returns NULL if the object is NULL.
 */
char* dvmCreateCstrFromString(StringObject* jstr)
{
    char* newStr;
    ArrayObject* chars;
    int len, byteLen, offset;
    const u2* data;

    assert(gDvm.javaLangStringReady > 0);

    if (jstr == NULL)
        return NULL;

    len = dvmGetFieldInt((Object*) jstr, STRING_FIELDOFF_COUNT);
    offset = dvmGetFieldInt((Object*) jstr, STRING_FIELDOFF_OFFSET);
    chars = (ArrayObject*) dvmGetFieldObject((Object*) jstr,
                                STRING_FIELDOFF_VALUE);
    data = (const u2*) chars->contents + offset;
    assert(offset + len <= (int) chars->length);

    byteLen = utf16_utf8ByteLen(data, len);
    newStr = (char*) malloc(byteLen+1);
    if (newStr == NULL)
        return NULL;
    convertUtf16ToUtf8(newStr, data, len);

    return newStr;
}

/*
 * Create a UTF-8 C string from a region of a java/lang/String.  (Used by
 * the JNI GetStringUTFRegion call.)
 */
void dvmCreateCstrFromStringRegion(StringObject* jstr, int start, int len,
    char* buf)
{
    const u2* data;

    data = dvmStringChars(jstr) + start;
    convertUtf16ToUtf8(buf, data, len);
}

/*
 * Compute the length, in modified UTF-8, of a java/lang/String object.
 *
 * Does not include the terminating null byte.
 */
int dvmStringUtf8ByteLen(StringObject* jstr)
{
    ArrayObject* chars;
    int len, offset;
    const u2* data;

    assert(gDvm.javaLangStringReady > 0);

    if (jstr == NULL)
        return 0;       // should we throw something?  assert?

    len = dvmGetFieldInt((Object*) jstr, STRING_FIELDOFF_COUNT);
    offset = dvmGetFieldInt((Object*) jstr, STRING_FIELDOFF_OFFSET);
    chars = (ArrayObject*) dvmGetFieldObject((Object*) jstr,
                                STRING_FIELDOFF_VALUE);
    data = (const u2*) chars->contents + offset;
    assert(offset + len <= (int) chars->length);

    return utf16_utf8ByteLen(data, len);
}

/*
 * Get the string's length.
 */
int dvmStringLen(StringObject* jstr)
{
    return dvmGetFieldInt((Object*) jstr, STRING_FIELDOFF_COUNT);
}

/*
 * Get the char[] object from the String.
 */
ArrayObject* dvmStringCharArray(StringObject* jstr)
{
    return (ArrayObject*) dvmGetFieldObject((Object*) jstr,
                                STRING_FIELDOFF_VALUE);
}

/*
 * Get the string's data.
 */
const u2* dvmStringChars(StringObject* jstr)
{
    ArrayObject* chars;
    int offset;

    offset = dvmGetFieldInt((Object*) jstr, STRING_FIELDOFF_OFFSET);
    chars = (ArrayObject*) dvmGetFieldObject((Object*) jstr,
                                STRING_FIELDOFF_VALUE);
    return (const u2*) chars->contents + offset;
}


/*
 * Compare two String objects.
 *
 * This is a dvmHashTableLookup() callback.  The function has already
 * compared their hash values; we need to do a full compare to ensure
 * that the strings really match.
 */
int dvmHashcmpStrings(const void* vstrObj1, const void* vstrObj2)
{
    const StringObject* strObj1 = (const StringObject*) vstrObj1;
    const StringObject* strObj2 = (const StringObject*) vstrObj2;
    ArrayObject* chars1;
    ArrayObject* chars2;
    int len1, len2, offset1, offset2;

    assert(gDvm.javaLangStringReady > 0);

    /* get offset and length into char array; all values are in 16-bit units */
    len1 = dvmGetFieldInt((Object*) strObj1, STRING_FIELDOFF_COUNT);
    offset1 = dvmGetFieldInt((Object*) strObj1, STRING_FIELDOFF_OFFSET);
    len2 = dvmGetFieldInt((Object*) strObj2, STRING_FIELDOFF_COUNT);
    offset2 = dvmGetFieldInt((Object*) strObj2, STRING_FIELDOFF_OFFSET);
    if (len1 != len2)
        return len1 - len2;

    chars1 = (ArrayObject*) dvmGetFieldObject((Object*) strObj1,
                                STRING_FIELDOFF_VALUE);
    chars2 = (ArrayObject*) dvmGetFieldObject((Object*) strObj2,
                                STRING_FIELDOFF_VALUE);

    /* damage here actually indicates a broken java/lang/String */
    assert(offset1 + len1 <= (int) chars1->length);
    assert(offset2 + len2 <= (int) chars2->length);

    return memcmp((const u2*) chars1->contents + offset1,
                  (const u2*) chars2->contents + offset2,
                  len1 * sizeof(u2));
}
