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 #include "maple_string.h"
17 #include "securec.h"
18 namespace maple {
MapleString(const char * str,size_t size,MemPool * currMp)19 MapleString::MapleString(const char *str, size_t size, MemPool *currMp)
20 : data(NewData(currMp, str, size)), memPool(currMp), dataLength(size)
21 {
22 }
23
MapleString(const char * str,MemPool * currMp)24 MapleString::MapleString(const char *str, MemPool *currMp) : MapleString(str, StrLen(str), currMp) {}
25
MapleString(size_t size,MemPool * currMp)26 MapleString::MapleString(size_t size, MemPool *currMp) : MapleString(nullptr, size, currMp) {}
27
MapleString(const MapleString & str,MemPool * currMp)28 MapleString::MapleString(const MapleString &str, MemPool *currMp) : MapleString(str.data, str.dataLength, currMp) {}
29
MapleString(const MapleString & str)30 MapleString::MapleString(const MapleString &str) : MapleString(str, str.memPool) {}
31
MapleString(const std::string & str,MemPool * currMp)32 MapleString::MapleString(const std::string &str, MemPool *currMp) : MapleString(str.data(), str.length(), currMp) {}
33
NewData(MemPool * memPool,const char * source,size_t len)34 char *MapleString::NewData(MemPool *memPool, const char *source, size_t len)
35 {
36 MIR_ASSERT(memPool != nullptr);
37 if (source == nullptr && len == 0) {
38 return nullptr;
39 }
40 char *str = static_cast<char *>(memPool->Malloc((len + 1) * sizeof(char)));
41 CHECK_FATAL(str != nullptr, "MemPool::Malloc failed");
42 if (source != nullptr && len != 0) {
43 errno_t err = memcpy_s(str, len, source, len);
44 CHECK_FATAL(err == EOK, "memcpy_s failed");
45 }
46 str[len] = 0;
47 return str;
48 }
49
clear()50 void MapleString::clear()
51 {
52 data = nullptr;
53 dataLength = 0;
54 }
55
find(const MapleString & str,size_t pos) const56 size_t MapleString::find(const MapleString &str, size_t pos) const
57 {
58 if ((dataLength - pos) < str.dataLength) {
59 return std::string::npos;
60 }
61 for (size_t i = pos; i < (dataLength - str.dataLength + 1); ++i) {
62 if (data[i] == str[0]) {
63 size_t j = 0;
64 for (; j < str.dataLength; ++j) {
65 if (data[i + j] == str[j]) {
66 continue;
67 } else {
68 break;
69 }
70 }
71 if (j == str.dataLength) {
72 return i;
73 }
74 }
75 }
76 return std::string::npos;
77 }
78
find(const char * str,size_t pos) const79 size_t MapleString::find(const char *str, size_t pos) const
80 {
81 if (str == nullptr) {
82 return std::string::npos;
83 }
84 size_t strLen = strlen(str);
85 if ((dataLength - pos) < strLen) {
86 return std::string::npos;
87 }
88 for (size_t i = pos; i < (dataLength - strLen + 1); ++i) {
89 if (data[i] == str[0]) {
90 size_t j = 0;
91 for (; j < strLen; ++j) {
92 if (data[i + j] == str[j]) {
93 continue;
94 } else {
95 break;
96 }
97 }
98 if (j == strLen) {
99 return i;
100 }
101 }
102 }
103 return std::string::npos;
104 }
105
find_last_of(const char * str,size_t pos) const106 size_t MapleString::find_last_of(const char *str, size_t pos) const
107 {
108 if (str == nullptr) {
109 return std::string::npos;
110 }
111 size_t strLen = strlen(str);
112 if ((dataLength - pos) < strLen) {
113 return std::string::npos;
114 }
115 for (ssize_t i = static_cast<ssize_t>(dataLength - strLen); i >= static_cast<ssize_t>(pos); --i) {
116 if (data[static_cast<size_t>(i)] == str[0]) {
117 size_t j = 0;
118 for (; j < strLen; ++j) {
119 if (data[static_cast<size_t>(i) + j] == str[j]) {
120 continue;
121 } else {
122 break;
123 }
124 }
125 if (j == strLen) {
126 return i;
127 }
128 }
129 }
130 return std::string::npos;
131 }
132
find(const char * str,size_t pos,size_t n) const133 size_t MapleString::find(const char *str, size_t pos, size_t n) const
134 {
135 if (str == nullptr) {
136 return std::string::npos;
137 }
138 if ((dataLength - pos) < n) {
139 return std::string::npos;
140 }
141 for (size_t i = pos; i < (dataLength - n + 1); ++i) {
142 if (data[i] == str[0]) {
143 size_t j = 0;
144 for (; j < n; ++j) {
145 if (data[i + j] == str[j]) {
146 continue;
147 } else {
148 break;
149 }
150 }
151 if (j == n) {
152 return i;
153 }
154 }
155 }
156 return std::string::npos;
157 }
158
find(char c,size_t pos) const159 size_t MapleString::find(char c, size_t pos) const
160 {
161 if (dataLength == 0 || pos >= dataLength) {
162 return std::string::npos;
163 }
164 size_t i = pos;
165 for (; i < dataLength; ++i) {
166 if (data[i] == c) {
167 return i;
168 }
169 }
170 return std::string::npos;
171 }
172
substr(size_t pos,size_t len) const173 MapleString MapleString::substr(size_t pos, size_t len) const
174 {
175 if (len == 0) {
176 MIR_FATAL("Error: MapleString substr len is 0");
177 }
178 if (pos > dataLength) {
179 MIR_FATAL("Error: MapleString substr pos is out of boundary");
180 }
181 len = (len + pos) > dataLength ? (dataLength - pos) : len;
182 MapleString newStr(memPool);
183 newStr.data = static_cast<char *>(newStr.memPool->Malloc((1 + len) * sizeof(char)));
184 for (size_t i = 0; i < len; ++i) {
185 newStr[i] = this->data[i + pos];
186 }
187 newStr.dataLength = len;
188 newStr.data[newStr.dataLength] = '\0';
189 return newStr;
190 }
191
insert(size_t pos,const MapleString & str)192 MapleString &MapleString::insert(size_t pos, const MapleString &str)
193 {
194 if (pos > dataLength || str.dataLength == 0) {
195 return *this;
196 }
197 data = static_cast<char *>(
198 memPool->Realloc(data, (1 + dataLength) * sizeof(char), (1 + dataLength + str.dataLength) * sizeof(char)));
199 CHECK_FATAL(data != nullptr, "null ptr check ");
200 MapleString temp(memPool);
201 if (dataLength - pos) {
202 temp = this->substr(pos, dataLength - pos);
203 } else {
204 temp = "";
205 }
206 dataLength += str.dataLength;
207 for (size_t i = 0; i < str.dataLength; ++i) {
208 data[pos + i] = str.data[i];
209 }
210 if (temp == nullptr) {
211 CHECK_FATAL(false, "temp null ptr check");
212 }
213 for (size_t j = 0; j < temp.dataLength; ++j) {
214 data[pos + str.dataLength + j] = temp.data[j];
215 }
216 data[dataLength] = '\0';
217 return *this;
218 }
219
insert(size_t pos,const MapleString & str,size_t subPos,size_t subLen)220 MapleString &MapleString::insert(size_t pos, const MapleString &str, size_t subPos, size_t subLen)
221 {
222 MapleString subStr = str.substr(subPos, subLen);
223 this->insert(pos, subStr);
224 return *this;
225 }
226
insert(size_t pos,const char * s)227 MapleString &MapleString::insert(size_t pos, const char *s)
228 {
229 if (s == nullptr) {
230 return *this;
231 }
232 size_t sLen = strlen(s);
233 if (pos > dataLength || sLen == 0) {
234 return *this;
235 }
236 MapleString subStr(s, memPool);
237 this->insert(pos, subStr);
238 return *this;
239 }
240
insert(size_t pos,const char * s,size_t n)241 MapleString &MapleString::insert(size_t pos, const char *s, size_t n)
242 {
243 if (s == nullptr) {
244 return *this;
245 }
246 size_t sLen = strlen(s);
247 if (pos > dataLength || sLen == 0) {
248 return *this;
249 }
250 n = ((n > sLen) ? sLen : n);
251 MapleString subStr(s, memPool);
252 subStr = subStr.substr(0, n);
253 this->insert(pos, subStr);
254 return *this;
255 }
256
insert(size_t pos,size_t n,char c)257 MapleString &MapleString::insert(size_t pos, size_t n, char c)
258 {
259 if (pos > dataLength) {
260 return *this;
261 }
262 MapleString subStr(n, memPool);
263 for (size_t i = 0; i < n; ++i) {
264 subStr[i] = c;
265 }
266 this->insert(pos, subStr);
267 return *this;
268 }
269
push_back(const char c)270 MapleString &MapleString::push_back(const char c)
271 {
272 this->append(1, c);
273 return *this;
274 }
275
append(const MapleString & str)276 MapleString &MapleString::append(const MapleString &str)
277 {
278 if (str.empty()) {
279 return *this;
280 }
281 this->insert(dataLength, str);
282 return *this;
283 }
284
append(const std::string & str)285 MapleString &MapleString::append(const std::string &str)
286 {
287 if (str.length() <= 0) {
288 return *this;
289 }
290 this->insert(dataLength, str.c_str());
291 return *this;
292 }
293
append(const MapleString & str,size_t subPos,size_t subLen)294 MapleString &MapleString::append(const MapleString &str, size_t subPos, size_t subLen)
295 {
296 this->append(str.substr(subPos, subLen));
297 return *this;
298 }
299
append(const char * s)300 MapleString &MapleString::append(const char *s)
301 {
302 if (s == nullptr) {
303 return *this;
304 }
305 MapleString subStr(s, memPool);
306 this->append(subStr);
307 return *this;
308 }
309
append(const char * s,size_t n)310 MapleString &MapleString::append(const char *s, size_t n)
311 {
312 if (s == nullptr) {
313 return *this;
314 }
315 MapleString subStr(s, memPool);
316 this->append(subStr, 0, n);
317 return *this;
318 }
319
append(size_t n,char c)320 MapleString &MapleString::append(size_t n, char c)
321 {
322 MapleString subStr(n, memPool);
323 for (size_t i = 0; i < n; ++i) {
324 subStr[i] = c;
325 }
326 this->append(subStr);
327 return *this;
328 }
329
assign(const MapleString & str)330 MapleString &MapleString::assign(const MapleString &str)
331 {
332 *this = str;
333 return *this;
334 }
335
assign(const MapleString & str,size_t subPos,size_t subLen)336 MapleString &MapleString::assign(const MapleString &str, size_t subPos, size_t subLen)
337 {
338 *this = str.substr(subPos, subLen);
339 return *this;
340 }
341
assign(const char * s)342 MapleString &MapleString::assign(const char *s)
343 {
344 *this = s;
345 return *this;
346 }
347
assign(const char * s,size_t n)348 MapleString &MapleString::assign(const char *s, size_t n)
349 {
350 MapleString subStr(s, memPool);
351 subStr = subStr.substr(0, n);
352 *this = subStr;
353 return *this;
354 }
355
assign(size_t n,char c)356 MapleString &MapleString::assign(size_t n, char c)
357 {
358 MapleString subStr(n, memPool);
359 for (size_t i = 0; i < n; ++i) {
360 subStr[i] = c;
361 }
362 this->assign(subStr);
363 return *this;
364 }
365
366 // global operators
operator ==(const MapleString & str1,const MapleString & str2)367 bool operator==(const MapleString &str1, const MapleString &str2)
368 {
369 if (str1.dataLength != str2.dataLength) {
370 return false;
371 }
372 char *tmp1 = str1.data;
373 char *tmp2 = str2.data;
374 while (*tmp1 != 0) {
375 if (*tmp1 != *tmp2) {
376 return false;
377 }
378 ++tmp1;
379 ++tmp2;
380 }
381 return true;
382 }
383
operator ==(const MapleString & str1,const char * str2)384 bool operator==(const MapleString &str1, const char *str2)
385 {
386 if (str2 == nullptr) {
387 return false; // Should we return str1.dataLength==0 ?
388 }
389 size_t size = strlen(str2);
390 if (str1.dataLength != size) {
391 return false;
392 }
393 char *tmp = str1.data;
394 CHECK_NULL_FATAL(tmp);
395 while (*tmp != 0) {
396 if (*tmp != *str2) {
397 return false;
398 }
399 ++tmp;
400 ++str2;
401 }
402 return true;
403 }
404
operator ==(const char * str1,const MapleString & str2)405 bool operator==(const char *str1, const MapleString &str2)
406 {
407 size_t size = strlen(str1);
408 if (str2.dataLength != size) {
409 return false;
410 }
411 char *tmp = str2.data;
412 CHECK_NULL_FATAL(tmp);
413 while (*tmp != 0) {
414 if (*tmp != *str1) {
415 return false;
416 }
417 ++tmp;
418 ++str1;
419 }
420 return true;
421 }
422
operator !=(const MapleString & str1,const MapleString & str2)423 bool operator!=(const MapleString &str1, const MapleString &str2)
424 {
425 return !(str1 == str2);
426 }
427
operator !=(const MapleString & str1,const char * str2)428 bool operator!=(const MapleString &str1, const char *str2)
429 {
430 return !(str1 == str2);
431 }
432
operator !=(const char * str1,const MapleString & str2)433 bool operator!=(const char *str1, const MapleString &str2)
434 {
435 return !(str1 == str2);
436 }
437
operator <(const MapleString & str1,const MapleString & str2)438 bool operator<(const MapleString &str1, const MapleString &str2)
439 {
440 CHECK_FATAL(!str1.empty(), "empty string check");
441 CHECK_FATAL(!str2.empty(), "empty string check");
442 return (strcmp(str1.c_str(), str2.c_str()) < 0);
443 }
444 } // namespace maple
445