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
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); } }