1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "ecmascript/hprof/string_hashmap.h" 17 18 namespace panda::ecmascript { FindOrInsertString(CString * string)19CString *StringHashMap::FindOrInsertString(CString *string) 20 { 21 StringKey key = GenerateStringKey(string); 22 auto it = hashmap_.find(key); 23 if (it != hashmap_.end()) { 24 return it->second; 25 } else { // NOLINT(readability-else-after-return) 26 index_++; 27 hashmap_.insert(std::make_pair(key, string)); 28 orderedKey_.emplace_back(key); 29 indexMap_.insert(std::make_pair(key, index_)); 30 return string; 31 } 32 } 33 GetStringId(const CString * string) const34StringId StringHashMap::GetStringId(const CString *string) const 35 { 36 auto it = indexMap_.find(GenerateStringKey(string)); 37 return it != indexMap_.end() ? it->second : 1; // "" 38 } 39 GetStringByKey(StringKey key) const40CString *StringHashMap::GetStringByKey(StringKey key) const 41 { 42 auto it = hashmap_.find(key); 43 if (it != hashmap_.end()) { 44 return FormatString(it->second); 45 } 46 return nullptr; 47 } 48 FormatString(CString * string) const49CString *StringHashMap::FormatString(CString *string) const 50 { 51 // remove "\"" | "\r\n" | "\\" | "\t" | "\f" 52 int length = string->length(); 53 char *charSeq = const_cast<char *>(string->c_str()); 54 for (int i = 0; i < length; i++) { 55 if (charSeq[i] == '\"') { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 56 charSeq[i] = '`'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 57 } else if (charSeq[i] == '\r') { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 58 charSeq[i] = '`'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 59 } else if (charSeq[i] == '\n') { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 60 charSeq[i] = '`'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 61 } else if (charSeq[i] == '\\') { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 62 charSeq[i] = '`'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 63 } else if (charSeq[i] == '\t') { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 64 charSeq[i] = '`'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 65 } else if (charSeq[i] == '\f') { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 66 charSeq[i] = '`'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 67 } else if (charSeq[i] < ' ') { // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 68 // ctrl chars 0~31 69 charSeq[i] = '`'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 70 } 71 } 72 *string = charSeq; 73 return string; 74 } 75 GenerateStringKey(const CString * string) const76StringKey StringHashMap::GenerateStringKey(const CString *string) const 77 { 78 return std::hash<std::string>{}(std::string(*string)); 79 } 80 GetString(CString as)81CString *StringHashMap::GetString(CString as) 82 { 83 auto *tempString = const_cast<NativeAreaAllocator *>(heap_->GetNativeAreaAllocator())->New<CString>(std::move(as)); 84 CString *oldString = FindOrInsertString(tempString); 85 if (tempString != oldString) { 86 const_cast<NativeAreaAllocator *>(heap_->GetNativeAreaAllocator())->Delete(tempString); 87 return oldString; 88 } 89 return tempString; 90 } 91 Clear()92void StringHashMap::Clear() 93 { 94 for (auto it : hashmap_) { 95 if (it.second != nullptr) { 96 const_cast<NativeAreaAllocator *>(heap_->GetNativeAreaAllocator())->Delete(it.second); 97 } 98 } 99 } 100 } // namespace panda::ecmascript 101