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