}
mirror::String* string = obj->AsString();
const uint16_t* utf16_string = string->GetCharArray()->GetData() + string->GetOffset();
+ size_t utf16_length = static_cast<size_t>(string->GetLength());
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
ReaderMutexLock mu(Thread::Current(), *class_linker->DexLock());
size_t dex_cache_count = class_linker->GetDexCacheCount();
DexCache* dex_cache = class_linker->GetDexCache(i);
const DexFile& dex_file = *dex_cache->GetDexFile();
const DexFile::StringId* string_id;
- if (UNLIKELY(string->GetLength() == 0)) {
+ if (UNLIKELY(utf16_length == 0)) {
string_id = dex_file.FindStringId("");
} else {
- string_id = dex_file.FindStringId(utf16_string);
+ string_id = dex_file.FindStringId(utf16_string, utf16_length);
}
if (string_id != nullptr) {
// This string occurs in this dex file, assign the dex cache entry.
return NULL;
}
-const DexFile::StringId* DexFile::FindStringId(const uint16_t* string) const {
+const DexFile::StringId* DexFile::FindStringId(const uint16_t* string, size_t length) const {
int32_t lo = 0;
int32_t hi = NumStringIds() - 1;
while (hi >= lo) {
int32_t mid = (hi + lo) / 2;
const DexFile::StringId& str_id = GetStringId(mid);
const char* str = GetStringData(str_id);
- int compare = CompareModifiedUtf8ToUtf16AsCodePointValues(str, string);
+ int compare = CompareModifiedUtf8ToUtf16AsCodePointValues(str, string, length);
if (compare > 0) {
lo = mid + 1;
} else if (compare < 0) {
const StringId* FindStringId(const char* string) const;
// Looks up a string id for a given utf16 string.
- const StringId* FindStringId(const uint16_t* string) const;
+ const StringId* FindStringId(const uint16_t* string, size_t length) const;
// Returns the number of type identifiers in the .dex file.
uint32_t NumTypeIds() const {
return static_cast<int32_t>(hash);
}
-int CompareModifiedUtf8ToUtf16AsCodePointValues(const char* utf8_1, const uint16_t* utf8_2) {
+int CompareModifiedUtf8ToUtf16AsCodePointValues(const char* utf8, const uint16_t* utf16,
+ size_t utf16_length) {
for (;;) {
- if (*utf8_1 == '\0') {
- return (*utf8_2 == '\0') ? 0 : -1;
- } else if (*utf8_2 == '\0') {
+ if (*utf8 == '\0') {
+ return (utf16_length == 0) ? 0 : -1;
+ } else if (utf16_length == 0) {
return 1;
}
- int c1 = GetUtf16FromUtf8(&utf8_1);
- int c2 = *utf8_2;
+ int c1 = GetUtf16FromUtf8(&utf8);
+ int c2 = *utf16++;
+ --utf16_length;
if (c1 != c2) {
return c1 > c2 ? 1 : -1;
const char* utf8_2);
/*
- * Compare a modified UTF-8 string with a UTF-16 string as code point values in a non-locale
- * sensitive manner.
+ * Compare a null-terminated modified UTF-8 string with a UTF-16 string (not null-terminated)
+ * as code point values in a non-locale sensitive manner.
*/
-int CompareModifiedUtf8ToUtf16AsCodePointValues(const char* utf8_1, const uint16_t* utf8_2);
+int CompareModifiedUtf8ToUtf16AsCodePointValues(const char* utf8, const uint16_t* utf16,
+ size_t utf16_length);
/*
* Convert from UTF-16 to Modified UTF-8. Note that the output is _not_