1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_LIBDEXFILE_DEX_STRING_REFERENCE_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_LIBDEXFILE_DEX_STRING_REFERENCE_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <stdint.h> 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h> 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file-inl.h" 25*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_reference.h" 26*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_types.h" 27*795d594fSAndroid Build Coastguard Worker #include "dex/utf-inl.h" 28*795d594fSAndroid Build Coastguard Worker 29*795d594fSAndroid Build Coastguard Worker namespace art { 30*795d594fSAndroid Build Coastguard Worker 31*795d594fSAndroid Build Coastguard Worker // A string is located by its DexFile and the string_ids_ table index into that DexFile. 32*795d594fSAndroid Build Coastguard Worker class StringReference : public DexFileReference { 33*795d594fSAndroid Build Coastguard Worker public: StringReference(const DexFile * file,dex::StringIndex index)34*795d594fSAndroid Build Coastguard Worker StringReference(const DexFile* file, dex::StringIndex index) 35*795d594fSAndroid Build Coastguard Worker : DexFileReference(file, index.index_) {} 36*795d594fSAndroid Build Coastguard Worker StringIndex()37*795d594fSAndroid Build Coastguard Worker dex::StringIndex StringIndex() const { 38*795d594fSAndroid Build Coastguard Worker return dex::StringIndex(index); 39*795d594fSAndroid Build Coastguard Worker } 40*795d594fSAndroid Build Coastguard Worker GetStringData()41*795d594fSAndroid Build Coastguard Worker const char* GetStringData() const { 42*795d594fSAndroid Build Coastguard Worker return dex_file->GetStringData(dex_file->GetStringId(StringIndex())); 43*795d594fSAndroid Build Coastguard Worker } 44*795d594fSAndroid Build Coastguard Worker }; 45*795d594fSAndroid Build Coastguard Worker 46*795d594fSAndroid Build Coastguard Worker // Compare the actual referenced string values. Used for string reference deduplication. 47*795d594fSAndroid Build Coastguard Worker struct StringReferenceValueComparator { operatorStringReferenceValueComparator48*795d594fSAndroid Build Coastguard Worker bool operator()(const StringReference& sr1, const StringReference& sr2) const { 49*795d594fSAndroid Build Coastguard Worker // Note that we want to deduplicate identical strings even if they are referenced 50*795d594fSAndroid Build Coastguard Worker // by different dex files, so we need some (any) total ordering of strings, rather 51*795d594fSAndroid Build Coastguard Worker // than references. However, the references should usually be from the same dex file, 52*795d594fSAndroid Build Coastguard Worker // so we choose the dex file string ordering so that we can simply compare indexes 53*795d594fSAndroid Build Coastguard Worker // and avoid the costly string comparison in the most common case. 54*795d594fSAndroid Build Coastguard Worker if (sr1.dex_file == sr2.dex_file) { 55*795d594fSAndroid Build Coastguard Worker // Use the string order enforced by the dex file verifier. 56*795d594fSAndroid Build Coastguard Worker DCHECK_EQ( 57*795d594fSAndroid Build Coastguard Worker sr1.index < sr2.index, 58*795d594fSAndroid Build Coastguard Worker CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(sr1.GetStringData(), 59*795d594fSAndroid Build Coastguard Worker sr2.GetStringData()) < 0); 60*795d594fSAndroid Build Coastguard Worker return sr1.index < sr2.index; 61*795d594fSAndroid Build Coastguard Worker } else { 62*795d594fSAndroid Build Coastguard Worker // Cannot compare indexes, so do the string comparison. 63*795d594fSAndroid Build Coastguard Worker return CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(sr1.GetStringData(), 64*795d594fSAndroid Build Coastguard Worker sr2.GetStringData()) < 0; 65*795d594fSAndroid Build Coastguard Worker } 66*795d594fSAndroid Build Coastguard Worker } 67*795d594fSAndroid Build Coastguard Worker }; 68*795d594fSAndroid Build Coastguard Worker 69*795d594fSAndroid Build Coastguard Worker } // namespace art 70*795d594fSAndroid Build Coastguard Worker 71*795d594fSAndroid Build Coastguard Worker #endif // ART_LIBDEXFILE_DEX_STRING_REFERENCE_H_ 72