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() const37 size_t length() const
38 {
39 return dataLength;
40 }
41
c_str()42 char *c_str()
43 {
44 return data;
45 }
46
c_str() const47 const char *c_str() const
48 {
49 if (dataLength <= 0) {
50 return nullptr;
51 }
52 return data;
53 }
54
operator [](const size_t x)55 char &operator[](const size_t x)
56 {
57 return data[x];
58 }
59
operator [](const size_t x) const60 const char &operator[](const size_t x) const
61 {
62 return data[x];
63 }
64
operator =(const char c)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
operator =(const char *str)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
operator =(const std::string &str)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
operator =(const MapleString &str)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
operator +=(const char c)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
operator +=(const char *str)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
operator +=(const MapleString &str)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
operator +=(const std::string &str)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() const206 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>
operator <<(OS &os, const MapleString &data)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