sead
Loading...
Searching...
No Matches
seadSafeString.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <basis/seadAssert.h>
4#include <prim/seadMemUtil.h>
5
6namespace sead {
7
8template <typename CharType>
9inline const CharType&
11{
12 s32 len = calcLength();
13 if (idx < 0 || idx > len)
14 {
15 SEAD_ASSERT_MSG(false, "index(%d) out of range[0, %d]", idx, len);
16 return cNullChar;
17 }
18
19 return mStringTop[idx];
20}
21
22template <typename CharType>
23inline s32
25{
27
29 s32 length = 0;
30
31 for (;;)
32 {
34 break;
35
36 length++;
37 }
38
40 {
41 SEAD_ASSERT_MSG(false, "too long string\n");
42 return 0;
43 }
44
45 return length;
46}
47
48template <typename CharType>
49inline const SafeStringBase<CharType>
51{
52 s32 len = calcLength();
53 if (at < 0 || at > len)
54 {
55 SEAD_ASSERT_MSG(false, "index(%d) out of range[0, %d]", at, len);
56 return cEmptyString;
57 }
58
60}
61
62template <typename CharType>
63inline bool
65{
67
68 for (s32 i = 0; i <= cMaximumLength; i++)
69 {
70 if (unsafeAt_(i) == 0)
71 return false;
72
73 if (unsafeAt_(i) == c)
74 return true;
75 }
76
77 return false;
78}
79
80template <typename CharType>
81inline bool
83{
85 if (cstr() == rhs.cstr())
86 return true;
87
88 for (s32 i = 0; i <= cMaximumLength; i++)
89 {
90 if (unsafeAt_(i) != rhs.unsafeAt_(i))
91 return false;
92
93 else if (unsafeAt_(i) == 0)
94 return true;
95 }
96
97 SEAD_ASSERT_MSG(false, "too long string\n");
98 return false;
99}
100
101template <typename CharType>
102inline s32
104{
106 if (cstr() == rhs.cstr())
107 return 0;
108
109 if (n > cMaximumLength)
110 {
111 SEAD_ASSERT_MSG(false, "paramater(%d) out of bounds [0, %d]", n, cMaximumLength);
113 }
114
115 for (s32 i = 0; i < n; i++)
116 {
117 if (unsafeAt_(i) == 0 && rhs.unsafeAt_(i) == 0)
118 return 0;
119
120 else if (unsafeAt_(i) == 0)
121 return -1;
122
123 else if (rhs.unsafeAt_(i) == 0)
124 return 1;
125
126 else if (unsafeAt_(i) < rhs.unsafeAt_(i))
127 return -1;
128
129 else if (unsafeAt_(i) > rhs.unsafeAt_(i))
130 return 1;
131 }
132
133 return 0;
134}
135
136template <typename CharType>
137inline s32
139{
140 s32 len = calcLength();
142
143 for (s32 i = 0; i <= len - token_len; i++)
145 return i;
146
147 return -1;
148}
149
150template <typename CharType>
151inline s32
153{
154 s32 len = calcLength();
156 len -= token_len;
157 if (len < 0)
158 return -1;
160 for (; len >= 0; len--)
162 break;
163
164 return len;
165}
167template <typename CharType>
170{
171 s32 index = this->getIndex();
172 s32 length = this->mString->calcLength();
173 if (!(0 <= index && index <= length))
174 {
175 SEAD_ASSERT_MSG(false, "index(%d) out of range [0, %d].\n", index, length);
176 return *this;
177 }
178 for (;;)
179 {
180 SEAD_ASSERT(0 <= index && index <= length);
181 const CharType& c = this->mString->unsafeAt_(index);
182 if (c == 0 || mDelimiter.include(c))
183 break;
184
185 index++;
186 }
187 this->mIndex = index + 1;
188 return *this;
189}
190
191template <typename CharType>
192inline s32
196 ++next_delim;
197 s32 size = next_delim.getIndex() - this->getIndex() - 1;
198 return out->copy(this->mString->getPart(*this), size);
199}
200
201template <typename CharType>
202inline s32
204{
205 s32 index = this->getIndex();
206 s32 length = this->mString->calcLength();
207 if (!(0 <= index && index <= length))
208 {
209 SEAD_ASSERT_MSG(false, "index(%d) out of range [0, %d].\n", index, length);
210 return 0;
211 }
212 s32 i = 0;
214 for (;;)
215 {
216 SEAD_ASSERT(0 <= index && index <= length);
217 const CharType& c = this->mString->unsafeAt_(index);
218 if (c == 0 || mDelimiter.include(c))
219 {
220 raw_out[i] = 0;
221 break;
222 }
223 raw_out[i] = c;
224 ++i;
225 ++index;
226 }
227 this->mIndex = index + 1;
228 return i;
229}
230
231template <typename CharType>
232inline s32
234{
236 if (size < 0)
237 size = rhs.calcLength();
238
239 if (size >= getBufferSize())
240 {
241 SEAD_ASSERT_MSG(false, "Buffer overflow. (Buffer Size: %d, Copy Size: %d)", getBufferSize(), size);
242 size = getBufferSize() - 1;
243 }
244
245 MemUtil::copy(mutable_string_top, rhs.cstr(), static_cast<size_t>(size) * sizeof(CharType));
247
248 return size;
249}
250
251template <typename CharType>
252inline s32
254{
256 s32 len = this->calcLength();
257
258 if (at < 0)
259 {
260 at = len + at + 1;
261 if (at < 0)
262 {
263 SEAD_ASSERT_MSG(false, "at(%d) out of range[0, %d]", at, len);
264 at = 0;
265 }
266 }
267
268 if (cpy_length < 0)
270
271 if (at + cpy_length >= getBufferSize())
272 {
273 SEAD_ASSERT_MSG(false, "Buffer overflow. (Buffer Size: %d, At: %d, Copy Length: %d)", getBufferSize(), at, cpy_length);
274 cpy_length = getBufferSize() - at - 1;
275 }
276
277 if (cpy_length <= 0)
278 return 0;
279
281 if (at + cpy_length > len)
283
284 return cpy_length;
285}
286
287template <typename CharType>
288inline s32
293
294template <typename CharType>
295inline s32
297{
298 s32 len = this->calcLength();
299 if (len >= getBufferSize() - 1)
300 {
301 SEAD_ASSERT_MSG(false, "Buffer overflow. (Buffer Size: %d, Length: %d)", getBufferSize(), len);
302 return 0;
303 }
304
307 mutable_string_top[len + 1] = 0;
309 return 1;
310}
311
312template <typename CharType>
313inline s32
315{
317 {
318 SEAD_ASSERT_MSG(false, "trim_length(%d) out of bounds. [0,%d) \n", trim_length, getBufferSize());
319 return this->calcLength();
320 }
321
322 if (trim_length < 0)
323 {
324 SEAD_ASSERT_MSG(false, "trim_length(%d) out of bounds. [0,%d) \n", trim_length, getBufferSize());
325 trim_length = 0;
326 }
327
331 return trim_length;
332}
333
334template <s32 N>
336 : FixedSafeStringBase<char, N>()
337{
338 va_list va;
340 (void)this->formatV(format_string, va);
341 va_end(va);
342}
343
344template <s32 N>
353
354} // namespace sead
Definition seadAssert.h:44
#define SEAD_ASSERT(condition)
Definition seadAssert.h:24
#define SEAD_ASSERT_MSG(condition, format,...)
Definition seadAssert.h:33