1 /* 2 * Copyright (c) 2023 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 #ifndef MEMPOOL_INCLUDE_MAPLE_STRING_H 17 #define MEMPOOL_INCLUDE_MAPLE_STRING_H 18 #include <cstring> 19 #include <climits> 20 #include "mempool.h" 21 #include "securec.h" 22 #include "mpl_logging.h" 23 24 namespace maple { 25 class MapleString { 26 public: 27 MapleString() = default; MapleString(MemPool * currMp)28 explicit MapleString(MemPool *currMp) : memPool(currMp) {} 29 MapleString(const MapleString &str); 30 MapleString(const char *str, MemPool *memPool); 31 MapleString(const char *str, size_t size, MemPool *memPool); // copyin 32 MapleString(size_t size, MemPool *memPool); 33 MapleString(const MapleString &str, MemPool *memPool); 34 MapleString(const std::string &str, MemPool *memPool); 35 ~MapleString() = default; 36 length()37 size_t length() const 38 { 39 return dataLength; 40 } 41 c_str()42 char *c_str() 43 { 44 return data; 45 } 46 c_str()47 const char *c_str() const 48 { 49 if (dataLength <= 0) { 50 return nullptr; 51 } 52 return data; 53 } 54 55 char &operator[](const size_t x) 56 { 57 return data[x]; 58 } 59 60 const char &operator[](const size_t x) const 61 { 62 return data[x]; 63 } 64 65 MapleString &operator=(const char c) 66 { 67 data = static_cast<char *>(memPool->Malloc(sizeof(char) << 1)); 68 CHECK_FATAL(data != nullptr, "nullptr check"); 69 data[0] = c; 70 data[1] = '\0'; 71 dataLength = 1; 72 return *this; 73 } 74 75 MapleString &operator=(const char *str) 76 { 77 if (str == nullptr) { 78 return *this; 79 } 80 size_t size = strlen(str); 81 CHECK_FATAL(size <= UINT_MAX - 1, "str too large"); 82 83 // if data is null, old_size = 0, else +1 84 size_t oldSize = ((data == nullptr) ? 0 : (dataLength + 1)); 85 if (oldSize < (1 + size)) { 86 data = static_cast<char *>(memPool->Realloc(data, oldSize * sizeof(char), (1 + size) * sizeof(char))); 87 } 88 CHECK_FATAL(data != nullptr, "null ptr check "); 89 if (size == 0) { 90 data[0] = '\0'; 91 return *this; 92 } 93 errno_t eNum = memcpy_s(data, size + 1, str, size); 94 CHECK_FATAL(eNum == EOK, "memcpy_s failed"); 95 dataLength = size; 96 CHECK_FATAL(data != nullptr, "null ptr check "); 97 data[dataLength] = '\0'; 98 return *this; 99 } 100 101 MapleString &operator=(const std::string &str) 102 { 103 size_t size = str.length(); 104 CHECK_FATAL(size <= UINT_MAX - 1, "str too large"); 105 106 size_t oldSize = (data == nullptr) ? 0 : (dataLength + 1); 107 if (oldSize < (1 + size)) { 108 data = static_cast<char *>(memPool->Realloc(data, oldSize * sizeof(char), (1 + size) * sizeof(char))); 109 } 110 CHECK_FATAL(data != nullptr, "null ptr check "); 111 if (size == 0) { 112 data[0] = '\0'; 113 return *this; 114 } 115 errno_t eNum = memcpy_s(data, size, str.data(), size); 116 CHECK_FATAL(eNum == EOK, "memcpy_s failed"); 117 dataLength = size; 118 data[dataLength] = '\0'; 119 return *this; 120 } 121 122 MapleString &operator=(const MapleString &str) 123 { 124 if (&str == this) { 125 return *this; 126 } 127 size_t size = str.dataLength; 128 CHECK_FATAL(size <= UINT_MAX - 1, "str too large"); 129 130 size_t oldSize = (data == nullptr) ? 0 : (dataLength + 1); 131 data = static_cast<char *>(memPool->Realloc(data, oldSize * sizeof(char), (1 + size) * sizeof(char))); 132 CHECK_FATAL(data != nullptr, "null ptr check"); 133 if (size == 0) { 134 data[0] = '\0'; 135 return *this; 136 } 137 errno_t eNum = memcpy_s(data, size, str.data, size); 138 CHECK_FATAL(eNum == EOK, "memcpy_s failed"); 139 dataLength = size; 140 data[dataLength] = '\0'; 141 return *this; 142 } 143 144 MapleString &operator+=(const char c) 145 { 146 size_t oldSize = ((data == nullptr) ? 0 : (dataLength + 1)); 147 CHECK_FATAL(oldSize <= UINT_MAX - 1, "str too large"); 148 149 data = static_cast<char *>(memPool->Realloc(data, oldSize * sizeof(char), (dataLength + 1 + 1) * sizeof(char))); 150 ++dataLength; 151 data[dataLength - 1] = c; 152 data[dataLength] = '\0'; 153 return *this; 154 } 155 156 MapleString &operator+=(const char *str) 157 { 158 if (str == nullptr) { 159 return *this; 160 } 161 size_t size = strlen(str); 162 size_t oldSize = ((data == nullptr) ? 0 : (dataLength + 1)); 163 CHECK_FATAL(size <= UINT_MAX - oldSize, "str too large"); 164 165 data = 166 static_cast<char *>(memPool->Realloc(data, oldSize * sizeof(char), (dataLength + size + 1) * sizeof(char))); 167 CHECK_FATAL(data != nullptr, "null ptr check"); 168 errno_t eNum = memcpy_s(data + dataLength, size, str, size); 169 CHECK_FATAL(eNum == EOK, "memcpy_s failed"); 170 dataLength += size; 171 data[dataLength] = '\0'; 172 return *this; 173 } 174 175 MapleString &operator+=(const MapleString &str) 176 { 177 size_t oldSize = ((data == nullptr) ? 0 : (dataLength + 1)); 178 CHECK_FATAL(str.dataLength <= UINT_MAX - oldSize, "str too large"); 179 180 data = static_cast<char *>( 181 memPool->Realloc(data, oldSize * sizeof(char), (dataLength + str.dataLength + 1) * sizeof(char))); 182 errno_t eNum = memcpy_s(data + dataLength, str.dataLength, str.data, str.dataLength); 183 CHECK_FATAL(eNum == EOK, "memcpy_s failed"); 184 dataLength += str.dataLength; 185 data[dataLength] = '\0'; 186 return *this; 187 } 188 189 MapleString &operator+=(const std::string &str) 190 { 191 size_t size = str.length(); 192 size_t oldSize = ((data == nullptr) ? 0 : (dataLength + 1)); 193 CHECK_FATAL(size <= UINT_MAX - oldSize, "str too large"); 194 195 data = 196 static_cast<char *>(memPool->Realloc(data, oldSize * sizeof(char), (dataLength + size + 1) * sizeof(char))); 197 CHECK_FATAL(data != nullptr, " null ptr check"); 198 errno_t eNum = memcpy_s(data + dataLength, size, str.data(), size); 199 CHECK_FATAL(eNum == EOK, "memcpy_s failed"); 200 dataLength += size; 201 data[dataLength] = '\0'; 202 return *this; 203 } 204 205 void clear(); empty()206 bool empty() const 207 { 208 if (dataLength <= 0 || data == nullptr) { 209 return true; 210 } else { 211 return false; 212 } 213 } 214 215 MapleString &push_back(const char c); 216 MapleString &append(const MapleString &str); 217 MapleString &append(const MapleString &str, size_t subPos, size_t subLen); 218 MapleString &append(const char *s); 219 MapleString &append(const char *s, size_t n); 220 MapleString &append(size_t n, char c); 221 MapleString &append(const std::string &str); 222 size_t find(const MapleString &str, size_t pos = 0) const; 223 size_t find(const char *s, size_t pos = 0) const; 224 size_t find(const char *s, size_t pos, size_t n) const; 225 size_t find(char c, size_t pos = 0) const; 226 size_t find_last_of(const char *, size_t pos = 0) const; 227 MapleString substr(size_t pos, size_t len) const; 228 MapleString &insert(size_t pos, const MapleString &str); 229 MapleString &insert(size_t pos, const MapleString &str, size_t subPos, size_t subLen); 230 MapleString &insert(size_t pos, const char *s); 231 MapleString &insert(size_t pos, const char *s, size_t n); 232 MapleString &insert(size_t pos, size_t n, char c); 233 MapleString &assign(const MapleString &str); 234 MapleString &assign(const MapleString &str, size_t subPos, size_t subLen); 235 MapleString &assign(const char *s); 236 MapleString &assign(const char *s, size_t n); 237 MapleString &assign(size_t n, char c); 238 239 private: StrLen(const char * s)240 inline static size_t StrLen(const char *s) 241 { 242 if (s == nullptr) { 243 return 0; 244 } 245 return ::strlen(s); 246 } 247 248 inline static char *NewData(MemPool *memPool, const char *source, size_t len); 249 250 friend bool operator==(const MapleString &, const MapleString &); 251 friend bool operator==(const MapleString &, const char *); 252 friend bool operator==(const char *, const MapleString &); 253 friend bool operator<(const MapleString &str1, const MapleString &str2); 254 255 char *data = nullptr; 256 MemPool *memPool = nullptr; 257 size_t dataLength = 0; 258 }; 259 260 template <typename OS> 261 inline OS &operator<<(OS &os, const MapleString &data) 262 { 263 os << data.c_str(); 264 return os; 265 } 266 267 // global operators 268 bool operator==(const MapleString &str1, const MapleString &str2); 269 bool operator==(const MapleString &str1, const char *str2); 270 bool operator==(const char *str1, const MapleString &str2); 271 bool operator!=(const MapleString &str1, const MapleString &str2); 272 bool operator!=(const MapleString &str1, const char *str2); 273 bool operator!=(const char *str1, const MapleString &str2); 274 bool operator<(const MapleString &str1, const MapleString &str2); 275 } // namespace maple 276 #endif // MEMPOOL_INCLUDE_MAPLE_STRING_H 277