MediaScannerClient.cpp revision 7188e55f54a43c55fd6b96454720c447f1dc454e
1413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber/* 2413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * Copyright (C) 2009 The Android Open Source Project 3413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * 4413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * you may not use this file except in compliance with the License. 6413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * You may obtain a copy of the License at 7413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * 8413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * 10413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * Unless required by applicable law or agreed to in writing, software 11413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * See the License for the specific language governing permissions and 14413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * limitations under the License. 15413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber */ 16413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 17413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber#include <media/mediascanner.h> 18413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 19413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber#include <utils/StringArray.h> 20413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 21413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber#include "autodetect.h" 22413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber#include "unicode/ucnv.h" 23413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber#include "unicode/ustring.h" 24413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 25413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Hubernamespace android { 26413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 27413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas HuberMediaScannerClient::MediaScannerClient() 28413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber : mNames(NULL), 29413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber mValues(NULL), 30413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber mLocaleEncoding(kEncodingNone) 31413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber{ 32413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber} 33413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 34413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas HuberMediaScannerClient::~MediaScannerClient() 35413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber{ 36413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber delete mNames; 37413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber delete mValues; 38413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber} 39413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 40413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Hubervoid MediaScannerClient::setLocale(const char* locale) 41413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber{ 42413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber if (!locale) return; 43413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 44413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber if (!strncmp(locale, "ja", 2)) 45413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber mLocaleEncoding = kEncodingShiftJIS; 46413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber else if (!strncmp(locale, "ko", 2)) 47413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber mLocaleEncoding = kEncodingEUCKR; 48413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber else if (!strncmp(locale, "zh", 2)) { 49413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber if (!strcmp(locale, "zh_CN")) { 50413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // simplified chinese for mainland China 51413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber mLocaleEncoding = kEncodingGBK; 52413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } else { 53413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // assume traditional for non-mainland Chinese locales (Taiwan, Hong Kong, Singapore) 54413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber mLocaleEncoding = kEncodingBig5; 55413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } 56413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } 57413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber} 58413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 59413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Hubervoid MediaScannerClient::beginFile() 60413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber{ 61413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber mNames = new StringArray; 62413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber mValues = new StringArray; 63413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber} 64413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 657188e55f54a43c55fd6b96454720c447f1dc454eJeff Brownstatus_t MediaScannerClient::addStringTag(const char* name, const char* value) 66413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber{ 67b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen if (mLocaleEncoding != kEncodingNone) { 68b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen // don't bother caching strings that are all ASCII. 69b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen // call handleStringTag directly instead. 70b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen // check to see if value (which should be utf8) has any non-ASCII characters 71b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen bool nonAscii = false; 72b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen const char* chp = value; 73b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen char ch; 74b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen while ((ch = *chp++)) { 75b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen if (ch & 0x80) { 76b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen nonAscii = true; 77b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen break; 78b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen } 79413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } 80413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 81b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen if (nonAscii) { 82b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen // save the strings for later so they can be used for native encoding detection 83b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen mNames->push_back(name); 84b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen mValues->push_back(value); 85b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen return true; 86b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen } 87b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen // else fall through 88413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } 89413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 90413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // autodetection is not necessary, so no need to cache the values 91413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // pass directly to the client instead 92413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber return handleStringTag(name, value); 93413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber} 94413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 95413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huberstatic uint32_t possibleEncodings(const char* s) 96413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber{ 97413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber uint32_t result = kEncodingAll; 98413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // if s contains a native encoding, then it was mistakenly encoded in utf8 as if it were latin-1 99413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // so we need to reverse the latin-1 -> utf8 conversion to get the native chars back 100413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber uint8_t ch1, ch2; 101413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber uint8_t* chp = (uint8_t *)s; 102413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 103413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber while ((ch1 = *chp++)) { 104413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber if (ch1 & 0x80) { 105413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber ch2 = *chp++; 106413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber ch1 = ((ch1 << 6) & 0xC0) | (ch2 & 0x3F); 107413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // ch1 is now the first byte of the potential native char 108413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 109413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber ch2 = *chp++; 110413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber if (ch2 & 0x80) 111413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber ch2 = ((ch2 << 6) & 0xC0) | (*chp++ & 0x3F); 112413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // ch2 is now the second byte of the potential native char 113413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber int ch = (int)ch1 << 8 | (int)ch2; 114413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber result &= findPossibleEncodings(ch); 115413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } 116413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // else ASCII character, which could be anything 117413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } 118413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 119413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber return result; 120413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber} 121413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 122413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Hubervoid MediaScannerClient::convertValues(uint32_t encoding) 123413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber{ 124413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber const char* enc = NULL; 125413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber switch (encoding) { 126413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber case kEncodingShiftJIS: 127413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber enc = "shift-jis"; 128413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber break; 129413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber case kEncodingGBK: 130413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber enc = "gbk"; 131413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber break; 132413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber case kEncodingBig5: 133413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber enc = "Big5"; 134413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber break; 135413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber case kEncodingEUCKR: 136413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber enc = "EUC-KR"; 137413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber break; 138413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } 139413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 140413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber if (enc) { 141413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber UErrorCode status = U_ZERO_ERROR; 142413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 143413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber UConverter *conv = ucnv_open(enc, &status); 144413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber if (U_FAILURE(status)) { 145413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber LOGE("could not create UConverter for %s\n", enc); 146413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber return; 147413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } 148413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber UConverter *utf8Conv = ucnv_open("UTF-8", &status); 149413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber if (U_FAILURE(status)) { 150413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber LOGE("could not create UConverter for UTF-8\n"); 151413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber ucnv_close(conv); 152413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber return; 153413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } 154413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 155413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // for each value string, convert from native encoding to UTF-8 156413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber for (int i = 0; i < mNames->size(); i++) { 157413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // first we need to untangle the utf8 and convert it back to the original bytes 158413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // since we are reducing the length of the string, we can do this in place 159413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber uint8_t* src = (uint8_t *)mValues->getEntry(i); 160413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber int len = strlen((char *)src); 161413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber uint8_t* dest = src; 162413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 163413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber uint8_t uch; 164413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber while ((uch = *src++)) { 165413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber if (uch & 0x80) 166413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber *dest++ = ((uch << 6) & 0xC0) | (*src++ & 0x3F); 167413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber else 168413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber *dest++ = uch; 169413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } 170413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber *dest = 0; 171413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 172413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // now convert from native encoding to UTF-8 173413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber const char* source = mValues->getEntry(i); 174413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber int targetLength = len * 3 + 1; 175413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber char* buffer = new char[targetLength]; 176413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber if (!buffer) 177413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber break; 178413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber char* target = buffer; 179413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 180413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber ucnv_convertEx(utf8Conv, conv, &target, target + targetLength, 181413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber &source, (const char *)dest, NULL, NULL, NULL, NULL, TRUE, TRUE, &status); 182413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber if (U_FAILURE(status)) { 183413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber LOGE("ucnv_convertEx failed: %d\n", status); 184413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber mValues->setEntry(i, "???"); 185413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } else { 186413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // zero terminate 187413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber *target = 0; 188413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber mValues->setEntry(i, buffer); 189413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } 190413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 191413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber delete[] buffer; 192413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } 193413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 194413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber ucnv_close(conv); 195413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber ucnv_close(utf8Conv); 196413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } 197413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber} 198413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 199413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Hubervoid MediaScannerClient::endFile() 200413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber{ 201b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen if (mLocaleEncoding != kEncodingNone) { 202b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen int size = mNames->size(); 203b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen uint32_t encoding = kEncodingAll; 204413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 205b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen // compute a bit mask containing all possible encodings 206b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen for (int i = 0; i < mNames->size(); i++) 207b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen encoding &= possibleEncodings(mValues->getEntry(i)); 208b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen 209b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen // if the locale encoding matches, then assume we have a native encoding. 210b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen if (encoding & mLocaleEncoding) 211b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen convertValues(mLocaleEncoding); 212b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen 213b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen // finally, push all name/value pairs to the client 214b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen for (int i = 0; i < mNames->size(); i++) { 2157188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown status_t status = handleStringTag(mNames->getEntry(i), mValues->getEntry(i)); 2167188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown if (status) { 217b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen break; 2187188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown } 219b5c3107262fdf82aef4bd5ee8b8c60dd3e4725feMarco Nelissen } 220413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber } 221413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber // else addStringTag() has done all the work so we have nothing to do 222413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 223413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber delete mNames; 224413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber delete mValues; 225413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber mNames = NULL; 226413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber mValues = NULL; 227413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber} 228413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 229413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber} // namespace android 230413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 231