sead
Loading...
Searching...
No Matches
seadSafeString.h
Go to the documentation of this file.
1#ifndef SEAD_SAFE_STRING_H_
2#define SEAD_SAFE_STRING_H_
3
4#include <stdarg.h>
5
6#include <basis/seadAssert.h>
7#include <basis/seadTypes.h>
8
9namespace sead {
10
11template <typename CharType>
13
14template <typename CharType>
16{
17public:
18 static const CharType cNullChar;
19 static const CharType cLineBreakChar;
20 static const SafeStringBase<CharType> cEmptyString;
21 static const s32 cMaximumLength = 256*1024;
22
23public:
28
29 SafeStringBase(const CharType* str)
30 : mStringTop(str)
31 {
32 SEAD_ASSERT_MSG(mStringTop, "str must not be nullptr.");
33 }
34
35 SafeStringBase(const SafeStringBase& other) = default;
36 SafeStringBase& operator=(const SafeStringBase& other) = default;
37
38 virtual ~SafeStringBase()
39 {
40 }
41
42public:
44 {
45 public:
46 explicit iterator(const SafeStringBase<CharType>* str)
47 : mString(str)
48 , mIndex(0)
49 {
50 }
51
52 iterator(const SafeStringBase<CharType>* str, s32 idx)
53 : mString(str)
54 , mIndex(idx)
55 {
56 }
57
58 virtual ~iterator()
59 {
60 }
61
62 public:
63 inline iterator& operator++()
64 {
65 ++mIndex;
66 return *this;
67 }
68
69 inline iterator& operator--()
70 {
71 --mIndex;
72 return *this;
73 }
74
75 friend bool operator==(const iterator& a, const iterator& b)
76 {
77 return a.mString == b.mString && a.mIndex == b.mIndex;
78 }
79
80 friend bool operator!=(const iterator& a_, const iterator& b_)
81 {
82 return !(a_ == b_);
83 }
84
85 const CharType& operator*() const
86 {
87 return mString->at(mIndex);
88 }
89
90 s32 getIndex() const
91 {
92 return mIndex;
93 }
94
95 protected:
98 };
99
101 {
102 public:
103 token_iterator(const SafeStringBase* str, const SafeStringBase& delimiter)
104 : iterator(str)
105 , mDelimiter(delimiter)
106 {
107 }
108
109 token_iterator(const SafeStringBase* str, s32 idx, const SafeStringBase& delimiter)
110 : iterator(str, idx)
111 , mDelimiter(delimiter)
112 {
113 }
114
115 virtual ~token_iterator()
116 {
117 }
118
119 public:
122
123 inline s32 get(BufferedSafeStringBase<CharType>* out) const;
125
126 private:
128 };
129
130public:
132 {
133 return iterator(this, 0);
134 }
135
136 iterator end() const
137 {
138 return iterator(this, calcLength() + 1);
139 }
140
141public:
142 token_iterator tokenBegin(const SafeStringBase<CharType>& delimiter) const
143 {
144 return token_iterator(this, 0, delimiter);
145 }
146
147 token_iterator tokenEnd(const SafeStringBase<CharType>& delimiter = SafeStringBase<CharType>()) const
148 {
149 return token_iterator(this, calcLength() + 1, delimiter);
150 }
151
152public:
153 const CharType* cstr() const
154 {
156 return mStringTop;
157 }
158
159 inline const CharType& at(s32 idx) const;
160
161 inline const CharType& operator[](s32 idx) const
162 {
163 return at(idx);
164 }
165
166 inline s32 calcLength() const;
167 inline const SafeStringBase<CharType> getPart(s32 at) const;
168 inline const SafeStringBase<CharType> getPart(const iterator& it) const;
169 inline bool include(const CharType& c) const;
170 inline bool include(const SafeStringBase<CharType>& str) const;
171 inline bool isEqual(const SafeStringBase<CharType>& rhs) const;
172
173 friend bool operator==(const SafeStringBase<CharType>& lhs, const SafeStringBase<CharType>& rhs)
174 {
175 return lhs.isEqual(rhs);
176 }
177
178 friend bool operator!=(const SafeStringBase<CharType>& lhs, const SafeStringBase<CharType>& rhs)
179 {
180 return !lhs.isEqual(rhs);
181 }
182
183 inline s32 comparen(const SafeStringBase<CharType>& rhs, s32 n) const;
184
185 inline s32 compare(const SafeStringBase<CharType>& rhs) const
186 {
187 return comparen(rhs, cMaximumLength);
188 }
189
190 friend bool operator>(const SafeStringBase<CharType>& lhs, const SafeStringBase<CharType>& rhs)
191 {
192 return lhs.compare(rhs) > 0;
193 }
194
195 friend bool operator<(const SafeStringBase<CharType>& lhs, const SafeStringBase<CharType>& rhs)
196 {
197 return lhs.compare(rhs) < 0;
198 }
199
200 inline iterator findIterator(const SafeStringBase<CharType>& token) const;
201 s32 findIndex(const SafeStringBase<CharType>& token) const;
202 inline iterator rfindIterator(const SafeStringBase<CharType>& token) const;
203 s32 rfindIndex(const SafeStringBase<CharType>& token) const;
204
205 bool isEmpty() const
206 {
207 return unsafeAt_(0) == 0;
208 }
209
210private:
211 const CharType& unsafeAt_(s32 idx) const
212 {
213 return mStringTop[idx];
214 }
215
216protected:
217 virtual void assureTerminationImpl_() const
218 {
219 }
220
221protected:
222 const CharType* mStringTop;
223};
224
225template <>
226const char SafeStringBase<char>::cNullChar;
227
228template <>
230
231template <>
233
234template <>
236
237template <>
239
240template <>
242
243template <typename CharType>
245{
246public:
247 BufferedSafeStringBase(CharType* buffer, s32 size)
248 : SafeStringBase<CharType>(buffer)
250 {
251 if (size <= 0)
252 {
253 SEAD_ASSERT_MSG(false, "Invalied buffer size(%d).\n", size);
254 this->mStringTop = nullptr;
255 mBufferSize = 0;
256 return;
257 }
258
260 }
261
262 BufferedSafeStringBase(BufferedSafeStringBase<CharType>* original, s32 pos)
263 : SafeStringBase<CharType>(original->cstr())
264 , mBufferSize(0)
265 {
266 SEAD_ASSERT_MSG(original, "original string must not be nullptr.");
267
268 if (pos >= original->getBufferSize() || pos < 0)
269 {
270 SEAD_ASSERT_MSG(false, "pos(%d) out of bounds[0,%d)", pos, original->getBufferSize());
271 this->mStringTop = nullptr;
272 mBufferSize = 0;
273 return;
274 }
275
276 this->mStringTop = original->mStringTop + pos;
277 mBufferSize = original->getBufferSize() - pos;
279 }
280
281private:
284
285public:
287 {
288 }
289
290 inline const CharType& operator[](s32 idx) const;
291
293 {
294 return mBufferSize;
295 }
296
297 inline s32 copy(const SafeStringBase<CharType>& rhs, s32 size = -1);
298 inline s32 copyAt(s32 at, const SafeStringBase<CharType>& src, s32 cpy_length = -1);
299
300 s32 format(const CharType* format_string, ...);
301 s32 formatV(const CharType* format_string, va_list varg);
302 s32 appendWithFormat(const CharType* format_string, ...);
303 s32 appendWithFormatV(const CharType* format_string, va_list varg);
304
305 inline s32 append(const SafeStringBase<CharType>& src, s32 append_length = -1);
306 inline s32 append(CharType src_chr);
307 inline s32 chop(s32 chop_num = 1);
308 inline s32 chopMatchedChar(CharType chop_char);
309 inline s32 chopMatchedChar(const SafeStringBase<CharType>& chop_char_list);
310
311 inline s32 chomp()
312 {
313 return chopMatchedChar(SafeStringBase<CharType>::cLineBreakChar);
314 }
315
317 inline s32 rstrip(const SafeStringBase<CharType>& strip_char_list);
319 inline s32 trim(s32 trim_length);
320 inline s32 trimMatchedString(const SafeStringBase<CharType>& trim_string);
321
322 inline void clear()
323 {
325 }
326
327 s32 convertFromMultiByteString(const SafeStringBase<CharType>& src, s32 src_size = -1)
328 {
329 return convertFromOtherType_(src, src_size);
330 }
331
332 s32 convertFromWideCharString(const SafeStringBase<char16>& src, s32 src_size = -1)
333 {
334 return convertFromOtherType_(src, src_size);
335 }
336
337 CharType* getBuffer()
338 {
341 }
342
343private:
345 {
346 return const_cast<CharType*>(this->mStringTop);
347 }
348
349 template <typename Other>
350 inline s32 convertFromOtherType_(const SafeStringBase<Other>& src, s32 src_size);
351
352 inline bool isUnprintableChar_(CharType c) const;
353
354 static s32 formatImpl_(CharType* dst, s32 dst_size, const CharType* format_string, va_list varg);
355
356protected:
357 void assureTerminationImpl_() const override
358 {
359 BufferedSafeStringBase<CharType>* mutable_ptr = const_cast<BufferedSafeStringBase<CharType>*>(this);
360 mutable_ptr->getMutableStringTop_()[getBufferSize() - 1] = 0;
361 }
362
363private:
365};
366
367template <typename CharType, s32 N>
369{
370public:
372 : BufferedSafeStringBase<CharType>(mBuffer, N)
373 {
374 this->clear();
375 }
376
377 explicit FixedSafeStringBase(const SafeStringBase<CharType>& rhs)
378 : BufferedSafeStringBase<CharType>(mBuffer, N)
379 {
380 this->copy(rhs);
381 }
382
384 : BufferedSafeStringBase<CharType>(mBuffer, N)
385 {
386 this->copy(rhs);
387 }
388
390 {
391 }
392
393 FixedSafeStringBase<CharType, N>& operator=(const FixedSafeStringBase<CharType, N>& rhs)
394 {
395 this->copy(rhs);
396 return *this;
397 }
398
399 FixedSafeStringBase<CharType, N>& operator=(const SafeStringBase<CharType>& rhs)
400 {
401 this->copy(rhs);
402 return *this;
403 }
404
405private:
406 CharType mBuffer[N];
407};
408
413
414#ifdef cafe
415static_assert(sizeof(SafeString) == 8, "sead::SafeStringBase<T> size mismatch");
416static_assert(sizeof(BufferedSafeString) == 0xC, "sead::BufferedSafeStringBase<T> size mismatch");
417#endif // cafe
418
419template <s32 N>
421{
422public:
424 : FixedSafeStringBase<char, N>()
425 {
426 }
427
428 explicit FixedSafeString(const SafeString& rhs)
429 : FixedSafeStringBase<char, N>(rhs)
430 {
431 }
432
433 // Nintendo did not implement this
434 //
435 //FixedSafeString(const FixedSafeString<N>& rhs)
436 // : FixedSafeStringBase<char, N>(rhs)
437 //{
438 //}
439
441 {
442 this->copy(rhs);
443 return *this;
444 }
445
447 {
448 this->copy(rhs);
449 return *this;
450 }
451};
452
453template <s32 N>
455{
456public:
461
462 explicit WFixedSafeString(const WSafeString& rhs)
464 {
465 }
466
467 // Nintendo did not implement this
468 //
469 //WFixedSafeString(const WFixedSafeString<N>& rhs)
470 // : FixedSafeStringBase<char16, N>(rhs)
471 //{
472 //}
473
475 {
476 copy(rhs);
477 return *this;
478 }
479
481 {
482 this->copy(rhs);
483 return *this;
484 }
485};
486
487template <s32 N>
489{
490public:
491 FormatFixedSafeString(const char* format_string, ...);
492
493private:
496};
497
498template <s32 N>
500{
501public:
502 WFormatFixedSafeString(const char16* format_string, ...);
503
504private:
507};
508
509class Heap;
510
511template <typename T>
513{
514public:
515 HeapSafeStringBase(Heap* heap, const SafeStringBase<T>& string, s32 size)
516 : BufferedSafeStringBase<T>(new (heap, 4) T[size](),
517 size)
518 {
519 copy(string);
520 }
521
522 HeapSafeStringBase(Heap* heap, const SafeStringBase<T>& string)
523 : BufferedSafeStringBase<T>(new (heap, 4) T[string.calcLength() + 1](),
524 string.calcLength() + 1)
525 {
526 copy(string);
527 }
528
530 {
531 if (this->mStringTop)
532 delete[] this->mStringTop;
533 }
534
535private:
538};
539
542
543template <>
545template <>
547template <>
549template <>
551template <>
553template <>
555template <>
557template <>
559template <>
561template <>
563
564} // namespace sead
565
566#ifdef __cplusplus
567
568#include <prim/seadSafeString.hpp>
569
570#endif // __cplusplus
571
572#endif // SEAD_SAFE_STRING_H_
Definition seadSafeString.h:245
CharType * getMutableStringTop_()
Definition seadSafeString.h:344
CharType * getBuffer()
Definition seadSafeString.h:337
s32 append(const SafeStringBase< CharType > &src, s32 append_length=-1)
Definition seadSafeString.hpp:190
BufferedSafeStringBase(CharType *buffer, s32 size)
Definition seadSafeString.h:247
s32 append(CharType src_chr)
Definition seadSafeString.hpp:197
s32 rstrip(const SafeStringBase< CharType > &strip_char_list)
s32 mBufferSize
Definition seadSafeString.h:364
static s32 formatImpl_(CharType *dst, s32 dst_size, const CharType *format_string, va_list varg)
s32 appendWithFormat(const CharType *format_string,...)
~BufferedSafeStringBase() override
Definition seadSafeString.h:286
BufferedSafeStringBase(BufferedSafeStringBase< CharType > *original, s32 pos)
Definition seadSafeString.h:262
s32 convertFromOtherType_(const SafeStringBase< Other > &src, s32 src_size)
void assureTerminationImpl_() const override
Definition seadSafeString.h:357
s32 chopMatchedChar(CharType chop_char)
s32 appendWithFormatV(const CharType *format_string, va_list varg)
void clear()
Definition seadSafeString.h:322
s32 trim(s32 trim_length)
Definition seadSafeString.hpp:215
s32 chomp()
Definition seadSafeString.h:311
s32 getBufferSize() const
Definition seadSafeString.h:292
s32 copyAt(s32 at, const SafeStringBase< CharType > &src, s32 cpy_length=-1)
Definition seadSafeString.hpp:154
s32 formatV(const CharType *format_string, va_list varg)
s32 chopMatchedChar(const SafeStringBase< CharType > &chop_char_list)
s32 format(const CharType *format_string,...)
s32 convertFromMultiByteString(const SafeStringBase< CharType > &src, s32 src_size=-1)
Definition seadSafeString.h:327
s32 copy(const SafeStringBase< CharType > &rhs, s32 size=-1)
Definition seadSafeString.hpp:134
s32 chop(s32 chop_num=1)
const CharType & operator[](s32 idx) const
bool isUnprintableChar_(CharType c) const
s32 trimMatchedString(const SafeStringBase< CharType > &trim_string)
BufferedSafeStringBase< CharType > & operator=(const BufferedSafeStringBase< CharType > &)
BufferedSafeStringBase(const BufferedSafeStringBase< CharType > &)
s32 convertFromWideCharString(const SafeStringBase< char16 > &src, s32 src_size=-1)
Definition seadSafeString.h:332
Definition seadSafeString.h:369
FixedSafeStringBase()
Definition seadSafeString.h:371
FixedSafeStringBase< CharType, N > & operator=(const FixedSafeStringBase< CharType, N > &rhs)
Definition seadSafeString.h:393
FixedSafeStringBase< CharType, N > & operator=(const SafeStringBase< CharType > &rhs)
Definition seadSafeString.h:399
FixedSafeStringBase(const SafeStringBase< CharType > &rhs)
Definition seadSafeString.h:377
CharType mBuffer[N]
Definition seadSafeString.h:406
FixedSafeStringBase(const FixedSafeStringBase< CharType, N > &rhs)
Definition seadSafeString.h:383
~FixedSafeStringBase() override
Definition seadSafeString.h:389
Definition seadSafeString.h:421
FixedSafeString()
Definition seadSafeString.h:423
FixedSafeString(const SafeString &rhs)
Definition seadSafeString.h:428
FixedSafeString< N > & operator=(const FixedSafeString< N > &rhs)
Definition seadSafeString.h:440
FixedSafeString< N > & operator=(const SafeString &rhs)
Definition seadSafeString.h:446
Definition seadSafeString.h:489
FormatFixedSafeString(const char *format_string,...)
Definition seadSafeString.hpp:236
FormatFixedSafeString< N > & operator=(const FormatFixedSafeString< N > &)
FormatFixedSafeString(const FormatFixedSafeString< N > &)
Definition seadSafeString.h:513
HeapSafeStringBase< T > & operator=(const HeapSafeStringBase< T > &)
virtual ~HeapSafeStringBase()
Definition seadSafeString.h:529
HeapSafeStringBase(const HeapSafeStringBase< T > &)
HeapSafeStringBase(Heap *heap, const SafeStringBase< T > &string, s32 size)
Definition seadSafeString.h:515
HeapSafeStringBase(Heap *heap, const SafeStringBase< T > &string)
Definition seadSafeString.h:522
Definition seadHeap.h:23
Definition seadSafeString.h:44
const SafeStringBase * mString
Definition seadSafeString.h:96
iterator(const SafeStringBase< CharType > *str)
Definition seadSafeString.h:46
iterator & operator++()
Definition seadSafeString.h:63
s32 mIndex
Definition seadSafeString.h:97
s32 getIndex() const
Definition seadSafeString.h:90
virtual ~iterator()
Definition seadSafeString.h:58
friend bool operator==(const iterator &a, const iterator &b)
Definition seadSafeString.h:75
iterator & operator--()
Definition seadSafeString.h:69
iterator(const SafeStringBase< CharType > *str, s32 idx)
Definition seadSafeString.h:52
friend bool operator!=(const iterator &a_, const iterator &b_)
Definition seadSafeString.h:80
const CharType & operator*() const
Definition seadSafeString.h:85
Definition seadSafeString.h:101
token_iterator(const SafeStringBase *str, s32 idx, const SafeStringBase &delimiter)
Definition seadSafeString.h:109
s32 get(BufferedSafeStringBase< CharType > *out) const
s32 getAndForward(BufferedSafeStringBase< CharType > *out)
virtual ~token_iterator()
Definition seadSafeString.h:115
SafeStringBase mDelimiter
Definition seadSafeString.h:127
token_iterator(const SafeStringBase *str, const SafeStringBase &delimiter)
Definition seadSafeString.h:103
Definition seadSafeString.h:16
friend bool operator>(const SafeStringBase< CharType > &lhs, const SafeStringBase< CharType > &rhs)
Definition seadSafeString.h:190
static const CharType cLineBreakChar
Definition seadSafeString.h:19
virtual ~SafeStringBase()
Definition seadSafeString.h:38
token_iterator tokenBegin(const SafeStringBase< CharType > &delimiter) const
Definition seadSafeString.h:142
SafeStringBase()
Definition seadSafeString.h:24
iterator findIterator(const SafeStringBase< CharType > &token) const
iterator end() const
Definition seadSafeString.h:136
static const SafeStringBase< CharType > cEmptyString
Definition seadSafeString.h:20
iterator rfindIterator(const SafeStringBase< CharType > &token) const
SafeStringBase(const SafeStringBase &other)=default
const CharType * mStringTop
Definition seadSafeString.h:222
s32 rfindIndex(const SafeStringBase< CharType > &token) const
bool include(const SafeStringBase< CharType > &str) const
bool isEqual(const SafeStringBase< CharType > &rhs) const
Definition seadSafeString.hpp:64
const SafeStringBase< CharType > getPart(s32 at) const
Definition seadSafeString.hpp:50
bool isEmpty() const
Definition seadSafeString.h:205
const CharType & at(s32 idx) const
Definition seadSafeString.hpp:10
friend bool operator<(const SafeStringBase< CharType > &lhs, const SafeStringBase< CharType > &rhs)
Definition seadSafeString.h:195
token_iterator tokenEnd(const SafeStringBase< CharType > &delimiter=SafeStringBase< CharType >()) const
Definition seadSafeString.h:147
SafeStringBase & operator=(const SafeStringBase &other)=default
s32 comparen(const SafeStringBase< CharType > &rhs, s32 n) const
Definition seadSafeString.hpp:85
const CharType & unsafeAt_(s32 idx) const
Definition seadSafeString.h:211
friend bool operator!=(const SafeStringBase< CharType > &lhs, const SafeStringBase< CharType > &rhs)
Definition seadSafeString.h:178
friend bool operator==(const SafeStringBase< CharType > &lhs, const SafeStringBase< CharType > &rhs)
Definition seadSafeString.h:173
virtual void assureTerminationImpl_() const
Definition seadSafeString.h:217
const CharType & operator[](s32 idx) const
Definition seadSafeString.h:161
SafeStringBase(const CharType *str)
Definition seadSafeString.h:29
iterator begin() const
Definition seadSafeString.h:131
const SafeStringBase< CharType > getPart(const iterator &it) const
s32 findIndex(const SafeStringBase< CharType > &token) const
Definition seadSafeString.hpp:120
const CharType * cstr() const
Definition seadSafeString.h:153
static const s32 cMaximumLength
Definition seadSafeString.h:21
bool include(const CharType &c) const
s32 calcLength() const
Definition seadSafeString.hpp:24
static const CharType cNullChar
Definition seadSafeString.h:18
s32 compare(const SafeStringBase< CharType > &rhs) const
Definition seadSafeString.h:185
Definition seadSafeString.h:455
WFixedSafeString(const WSafeString &rhs)
Definition seadSafeString.h:462
WFixedSafeString()
Definition seadSafeString.h:457
WFixedSafeString< N > & operator=(const WSafeString &rhs)
Definition seadSafeString.h:480
WFixedSafeString< N > & operator=(const WFixedSafeString< N > &rhs)
Definition seadSafeString.h:474
Definition seadSafeString.h:500
WFormatFixedSafeString< N > & operator=(const WFormatFixedSafeString< N > &)
WFormatFixedSafeString(const WFormatFixedSafeString< N > &)
WFormatFixedSafeString(const char16 *format_string,...)
Definition seadSafeString.hpp:246
Definition seadAssert.h:44
SafeStringBase< char16 > WSafeString
Definition seadSafeString.h:410
HeapSafeStringBase< char > HeapSafeString
Definition seadSafeString.h:540
HeapSafeStringBase< char16 > WHeapSafeString
Definition seadSafeString.h:541
SafeStringBase< char > SafeString
Definition seadSafeString.h:409
BufferedSafeStringBase< char > BufferedSafeString
Definition seadSafeString.h:411
BufferedSafeStringBase< char16 > WBufferedSafeString
Definition seadSafeString.h:412
#define SEAD_ASSERT_MSG(condition, format,...)
Definition seadAssert.h:33