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
6
namespace
sead
{
7
8
template
<
typename
CharType
>
9
inline
const
CharType
&
10
SafeStringBase
<
CharType
>::
at
(
s32
idx
)
const
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
22
template
<
typename
CharType
>
23
inline
s32
24
SafeStringBase
<
CharType
>::
calcLength
()
const
25
{
26
SEAD_ASSERT
(
mStringTop
);
27
28
assureTerminationImpl_
();
29
s32
length
= 0;
30
31
for
(;;)
32
{
33
if
(
length
>
cMaximumLength
||
mStringTop
[
length
] == 0)
34
break
;
35
36
length
++;
37
}
38
39
if
(
length
>
cMaximumLength
)
40
{
41
SEAD_ASSERT_MSG
(
false
,
"too long string\n"
);
42
return
0;
43
}
44
45
return
length
;
46
}
47
48
template
<
typename
CharType
>
49
inline
const
SafeStringBase
<
CharType
>
50
SafeStringBase
<
CharType
>::
getPart
(
s32
at
)
const
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
59
return
SafeStringBase
<
CharType
>(
mStringTop
+
at
);
60
}
61
62
template
<
typename
CharType
>
63
inline
bool
64
SafeStringBase
<
CharType
>::
include
(
const
CharType
&
c
)
const
65
{
66
assureTerminationImpl_
();
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
80
template
<
typename
CharType
>
81
inline
bool
82
SafeStringBase
<
CharType
>::
isEqual
(
const
SafeStringBase
<
CharType
>&
rhs
)
const
83
{
84
assureTerminationImpl_
();
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
101
template
<
typename
CharType
>
102
inline
s32
103
SafeStringBase
<
CharType
>::
comparen
(
const
SafeStringBase
<
CharType
>&
rhs
,
s32
n
)
const
104
{
105
assureTerminationImpl_
();
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
);
112
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
136
template
<
typename
CharType
>
137
inline
s32
138
SafeStringBase
<
CharType
>::
findIndex
(
const
SafeStringBase
<
CharType
>&
token
)
const
139
{
140
s32
len
=
calcLength
();
141
s32
token_len
=
token
.
calcLength
();
142
143
for
(
s32
i
= 0;
i
<=
len
-
token_len
;
i
++)
144
if
(
SafeStringBase
<
CharType
>(&
mStringTop
[
i
]).
comparen
(
token
,
token_len
) == 0)
145
return
i
;
146
147
return
-1;
148
}
149
150
template
<
typename
CharType
>
151
inline
s32
152
SafeStringBase
<
CharType
>::
rfindIndex
(
const
SafeStringBase
<
CharType
>&
token
)
const
153
{
154
s32
len
=
calcLength
();
155
s32
token_len
=
token
.
calcLength
();
156
len
-=
token_len
;
157
if
(
len
< 0)
158
return
-1;
159
160
for
(;
len
>= 0;
len
--)
161
if
(
SafeStringBase
<
CharType
>(&
mStringTop
[
len
]).
comparen
(
token
,
token_len
) == 0)
162
break
;
163
164
return
len
;
165
}
166
167
template
<
typename
CharType
>
168
inline
typename
SafeStringBase
<
CharType
>::
token_iterator
&
169
SafeStringBase
<
CharType
>::
token_iterator
::
operator
++()
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
191
template
<
typename
CharType
>
192
inline
s32
193
SafeStringBase
<
CharType
>::
token_iterator
::
get
(
BufferedSafeStringBase
<
CharType
>*
out
)
const
194
{
195
token_iterator
next_delim
= *
this
;
196
++
next_delim
;
197
s32
size
=
next_delim
.
getIndex
() -
this
->
getIndex
() - 1;
198
return
out
->
copy
(
this
->
mString
->
getPart
(*
this
),
size
);
199
}
200
201
template
<
typename
CharType
>
202
inline
s32
203
SafeStringBase
<
CharType
>::
token_iterator
::
getAndForward
(
BufferedSafeStringBase
<
CharType
>*
out
)
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;
213
CharType
*
raw_out
=
out
->
getBuffer
();
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
231
template
<
typename
CharType
>
232
inline
s32
233
BufferedSafeStringBase
<
CharType
>::
copy
(
const
SafeStringBase
<
CharType
>&
rhs
,
s32
size
)
234
{
235
CharType
*
mutable_string_top
=
getMutableStringTop_
();
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
));
246
mutable_string_top
[
size
] = 0;
247
248
return
size
;
249
}
250
251
template
<
typename
CharType
>
252
inline
s32
253
BufferedSafeStringBase
<
CharType
>::
copyAt
(
s32
at
,
const
SafeStringBase
<
CharType
>&
src
,
s32
cpy_length
)
254
{
255
CharType
*
mutable_string_top
=
getMutableStringTop_
();
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)
269
cpy_length
=
src
.
calcLength
();
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
280
MemUtil
::
copy
(
mutable_string_top
+
at
,
src
.
cstr
(),
cpy_length
*
sizeof
(
CharType
));
281
if
(
at
+
cpy_length
>
len
)
282
mutable_string_top
[
at
+
cpy_length
] = 0;
283
284
return
cpy_length
;
285
}
286
287
template
<
typename
CharType
>
288
inline
s32
289
BufferedSafeStringBase
<
CharType
>::
append
(
const
SafeStringBase
<
CharType
>&
src
,
s32
append_length
)
290
{
291
return
copyAt
(-1,
src
,
append_length
);
292
}
293
294
template
<
typename
CharType
>
295
inline
s32
296
BufferedSafeStringBase
<
CharType
>::
append
(
CharType
src_chr
)
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
305
CharType
*
mutable_string_top
=
getMutableStringTop_
();
306
mutable_string_top
[
len
] =
src_chr
;
307
mutable_string_top
[
len
+ 1] = 0;
308
309
return
1;
310
}
311
312
template
<
typename
CharType
>
313
inline
s32
314
BufferedSafeStringBase
<
CharType
>::
trim
(
s32
trim_length
)
315
{
316
if
(
trim_length
>=
getBufferSize
())
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
328
CharType
*
mutable_string_top
=
getMutableStringTop_
();
329
mutable_string_top
[
trim_length
] = 0;
330
331
return
trim_length
;
332
}
333
334
template
<
s32
N
>
335
FormatFixedSafeString
<
N
>::
FormatFixedSafeString
(
const
char
*
format_string
, ...)
336
:
FixedSafeStringBase
<
char
,
N
>()
337
{
338
va_list
va
;
339
va_start
(
va
,
format_string
);
340
(
void
)
this
->
formatV
(
format_string
,
va
);
341
va_end
(
va
);
342
}
343
344
template
<
s32
N
>
345
WFormatFixedSafeString
<
N
>::
WFormatFixedSafeString
(
const
char16
*
format_string
, ...)
346
:
FixedSafeStringBase
<
char16
,
N
>()
347
{
348
va_list
va
;
349
va_start
(
va
,
format_string
);
350
(
void
)
this
->
formatV
(
format_string
,
va
);
351
va_end
(
va
);
352
}
353
354
}
// namespace sead
sead
Definition
seadAssert.h:44
SEAD_ASSERT
#define SEAD_ASSERT(condition)
Definition
seadAssert.h:24
SEAD_ASSERT_MSG
#define SEAD_ASSERT_MSG(condition, format,...)
Definition
seadAssert.h:33
engine
library
include
prim
seadSafeString.hpp
Generated by
1.14.0