void MediaScannerClient::endFile()
{
#ifndef ANDROID_DEFAULT_CODE   
   ALOGV("endFile mLocaleEncoding:%d \n",mLocaleEncoding);   
    {      
#else
    if (mLocaleEncoding != kEncodingNone) {
#endif         
        int size = mNames->size();
        uint32_t encoding = kEncodingAll;

#ifndef ANDROID_DEFAULT_CODE   
        
        ALOGV("endFile +possibleEncodings size: %d \n",size);     
        //// compute a bit mask containing all possible encodings
        for (int i = 0; i < mNames->size(); i++)
        { 
        	char const*s=mValues->getEntry(i);
		//	if((s[0]==0xFF)|(!ISUTF8(s))){
            encoding = possibleEncodings(s);
            ALOGD("endFile +possibleEncodings: %d \n",encoding);    
			if(!(encoding==0xFFFFFFFF))
            convertValues(encoding,i);
		//}
			
        }

#else
        // compute a bit mask containing all possible encodings
        for (int i = 0; i < mNames->size(); i++)
            encoding &= possibleEncodings(mValues->getEntry(i));

        // if the locale encoding matches, then assume we have a native encoding.
        if (encoding & mLocaleEncoding)
            convertValues(mLocaleEncoding);
#endif

        // finally, push all name/value pairs to the client
        for (int i = 0; i < mNames->size(); i++) {
            status_t status = handleStringTag(mNames->getEntry(i), mValues->getEntry(i));
            if (status) {
                break;
            }
        }
    }
    // else addStringTag() has done all the work so we have nothing to do

    delete mNames;
    delete mValues;
    mNames = NULL;
    mValues = NULL;
}

}  // namespace android
Example #2
0
jstring possibleEncoding(JNIEnv* env, jobject thiz, jbyteArray jbArr) {
    // get the test string.
    char *chArr = (char*)env->GetByteArrayElements(jbArr,0);
    int nArrLen = env->GetArrayLength(jbArr);

    char *szStrBuf =(char*)malloc(nArrLen + 1);
    memset(szStrBuf, 0, nArrLen + 1);
    memcpy(szStrBuf, chArr, nArrLen);
    env->ReleaseByteArrayElements(jbArr, (jbyte*)chArr, JNI_ABORT);

    // convert \0 which in the middle of string.
    char *ptr = szStrBuf + strlen(szStrBuf) + 1;
    while ((size_t)(ptr - szStrBuf) <= nArrLen) {
            *(ptr - 1) = 0X02;
            ptr += strlen(ptr) + 1;
    }

    // detect.
    const char *enc = "UTF-8";
    int gbkcount = 0;
    if (CharacterEncoder::is_ascii(szStrBuf)) {
        enc = "ASCII";
    } else if(CharacterEncoder::isUTF8(szStrBuf)) {
        enc = "UTF-8";
    } else if (CharacterEncoder::is_gbk_code(szStrBuf, &gbkcount)) {
        enc = "gbk";
    } else {
        uint32_t encoding = possibleEncodings(szStrBuf);
        // LOGD("20, szStrBuf len = %d, %d, encoding = %u",
        //     strlen(szStrBuf), nArrLen, encoding);
        switch (encoding) {
        case kEncodingShiftJIS:
            enc = "shift-jis";
            break;
        case kEncodingGBK:
            enc = "gbk";
            break;
        case kEncodingBig5:
            enc = "Big5";
            break;
        case kEncodingEUCKR:
            enc = "EUC-KR";
            break;
        }
    }

    // return the result.
    jstring rtn;
    rtn = (env)->NewStringUTF(enc);
    return rtn;
}
void MediaScannerClient::convertValues(uint32_t encoding)
{
    const char* enc = NULL;
    switch (encoding) {
        case kEncodingShiftJIS:
            enc = "shift-jis";
            break;
        case kEncodingGBK:
            enc = "gbk";
            break;
        case kEncodingBig5:
            enc = "Big5";
            break;
        case kEncodingEUCKR:
            enc = "EUC-KR";
            break;
    }

    if (enc) {
        UErrorCode status = U_ZERO_ERROR;

        UConverter *conv = ucnv_open(enc, &status);
        if (U_FAILURE(status)) {
            LOGE("could not create UConverter for %s\n", enc);
            return;
        }
        UConverter *utf8Conv = ucnv_open("UTF-8", &status);
        if (U_FAILURE(status)) {
            LOGE("could not create UConverter for UTF-8\n");
            ucnv_close(conv);
            return;
        }

        // for each value string, convert from native encoding to UTF-8
        for (int i = 0; i < mNames->size(); i++) {
            // first we need to untangle the utf8 and convert it back to the original bytes
			// since we are reducing the length of the string, we can do this in place
			uint32_t encoding = kEncodingAll;
			// compute a bit mask containing all possible encodings
			encoding &= possibleEncodings(mValues->getEntry(i));
			if (!(encoding & mLocaleEncoding))
				continue;

            uint8_t* src = (uint8_t *)mValues->getEntry(i);
            int len = strlen((char *)src);
            uint8_t* dest = src;

            uint8_t uch;
            while ((uch = *src++)) {
                if (uch & 0x80)
                    *dest++ = ((uch << 6) & 0xC0) | (*src++ & 0x3F);
                else
                    *dest++ = uch;
            }
            *dest = 0;

            // now convert from native encoding to UTF-8
            const char* source = mValues->getEntry(i);
            int targetLength = len * 3 + 1;
            char* buffer = new char[targetLength];
            if (!buffer)
                break;
            char* target = buffer;

            ucnv_convertEx(utf8Conv, conv, &target, target + targetLength,
                    &source, (const char *)dest, NULL, NULL, NULL, NULL, TRUE, TRUE, &status);
            if (U_FAILURE(status)) {
                LOGE("ucnv_convertEx failed: %d\n", status);
                mValues->setEntry(i, "???");
            } else {
                // zero terminate
                *target = 0;
                mValues->setEntry(i, buffer);
            }

            delete[] buffer;
        }

        ucnv_close(conv);
        ucnv_close(utf8Conv);
    }
}