1ca0551cfSopenharmony_ci/* 2ca0551cfSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3ca0551cfSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4ca0551cfSopenharmony_ci * you may not use this file except in compliance with the License. 5ca0551cfSopenharmony_ci * You may obtain a copy of the License at 6ca0551cfSopenharmony_ci * 7ca0551cfSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8ca0551cfSopenharmony_ci * 9ca0551cfSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10ca0551cfSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11ca0551cfSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12ca0551cfSopenharmony_ci * See the License for the specific language governing permissions and 13ca0551cfSopenharmony_ci * limitations under the License. 14ca0551cfSopenharmony_ci */ 15ca0551cfSopenharmony_ci 16ca0551cfSopenharmony_ci#include "util/string_pool.h" 17ca0551cfSopenharmony_ci#include "securec.h" 18ca0551cfSopenharmony_ci#include "util/logger.h" 19ca0551cfSopenharmony_ci 20ca0551cfSopenharmony_cinamespace OHOS { 21ca0551cfSopenharmony_cinamespace Idl { 22ca0551cfSopenharmony_ciconst char* StringPool::TAG = "StringPool"; 23ca0551cfSopenharmony_ci 24ca0551cfSopenharmony_ciStringPool::StringPool() 25ca0551cfSopenharmony_ci{ 26ca0551cfSopenharmony_ci data_ = reinterpret_cast<uint8_t *>(calloc(1, dataCapacity_)); 27ca0551cfSopenharmony_ci if (data_ == nullptr) { 28ca0551cfSopenharmony_ci Logger::E(TAG, "Out of memory."); 29ca0551cfSopenharmony_ci } 30ca0551cfSopenharmony_ci} 31ca0551cfSopenharmony_ci 32ca0551cfSopenharmony_ciStringPool::~StringPool() 33ca0551cfSopenharmony_ci{ 34ca0551cfSopenharmony_ci if (data_ != nullptr) { 35ca0551cfSopenharmony_ci free(data_); 36ca0551cfSopenharmony_ci } 37ca0551cfSopenharmony_ci} 38ca0551cfSopenharmony_ci 39ca0551cfSopenharmony_civoid StringPool::Add(const std::string& string) 40ca0551cfSopenharmony_ci{ 41ca0551cfSopenharmony_ci if (string.empty() || stringOffsets_.find(string) != stringOffsets_.end()) { 42ca0551cfSopenharmony_ci return; 43ca0551cfSopenharmony_ci } 44ca0551cfSopenharmony_ci 45ca0551cfSopenharmony_ci ptrdiff_t offset = AddInternal(string); 46ca0551cfSopenharmony_ci if (offset != -1) { 47ca0551cfSopenharmony_ci stringOffsets_[string] = offset; 48ca0551cfSopenharmony_ci } 49ca0551cfSopenharmony_ci} 50ca0551cfSopenharmony_ci 51ca0551cfSopenharmony_ciptrdiff_t StringPool::GetOffset(const std::string& string) 52ca0551cfSopenharmony_ci{ 53ca0551cfSopenharmony_ci return stringOffsets_[string]; 54ca0551cfSopenharmony_ci} 55ca0551cfSopenharmony_ci 56ca0551cfSopenharmony_ciptrdiff_t StringPool::AddInternal(const std::string& string) 57ca0551cfSopenharmony_ci{ 58ca0551cfSopenharmony_ci if (!Grow(string.length() + 1)) { 59ca0551cfSopenharmony_ci return -1; 60ca0551cfSopenharmony_ci } 61ca0551cfSopenharmony_ci 62ca0551cfSopenharmony_ci uint8_t* addr = data_ + dataOffset_; 63ca0551cfSopenharmony_ci if (strcpy_s(reinterpret_cast<char *>(addr), dataCapacity_ - dataOffset_, string.c_str())) { 64ca0551cfSopenharmony_ci Logger::E(TAG, "Error to copy str"); 65ca0551cfSopenharmony_ci return -1; 66ca0551cfSopenharmony_ci } 67ca0551cfSopenharmony_ci dataOffset_ += static_cast<ptrdiff_t>(string.length()) + 1; 68ca0551cfSopenharmony_ci return addr - data_; 69ca0551cfSopenharmony_ci} 70ca0551cfSopenharmony_ci 71ca0551cfSopenharmony_cibool StringPool::Grow(size_t expand) 72ca0551cfSopenharmony_ci{ 73ca0551cfSopenharmony_ci size_t newSize = dataOffset_ + expand; 74ca0551cfSopenharmony_ci if (newSize < dataCapacity_) { 75ca0551cfSopenharmony_ci return true; 76ca0551cfSopenharmony_ci } 77ca0551cfSopenharmony_ci // 3->3x capacity expansion 78ca0551cfSopenharmony_ci size_t step = dataCapacity_ * 3; 79ca0551cfSopenharmony_ci newSize = step > newSize ? step : step + newSize; 80ca0551cfSopenharmony_ci uint8_t* newData = reinterpret_cast<uint8_t *>(calloc(1, newSize)); 81ca0551cfSopenharmony_ci if (newData == nullptr) { 82ca0551cfSopenharmony_ci Logger::E(TAG, "Out of memory."); 83ca0551cfSopenharmony_ci return false; 84ca0551cfSopenharmony_ci } 85ca0551cfSopenharmony_ci errno_t ret = memcpy_s(newData, newSize, data_, dataOffset_); 86ca0551cfSopenharmony_ci if (ret != EOK) { 87ca0551cfSopenharmony_ci free(newData); 88ca0551cfSopenharmony_ci newData = nullptr; 89ca0551cfSopenharmony_ci return false; 90ca0551cfSopenharmony_ci } 91ca0551cfSopenharmony_ci free(data_); 92ca0551cfSopenharmony_ci data_ = newData; 93ca0551cfSopenharmony_ci dataCapacity_ = newSize; 94ca0551cfSopenharmony_ci return true; 95ca0551cfSopenharmony_ci} 96ca0551cfSopenharmony_ci} 97ca0551cfSopenharmony_ci} 98