1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
#ifndef SIZED_STRING_H
#define SIZED_STRING_H
#include "__va_arg.h"
#include "common.h"
#include "string.h"
#include "wstring.h"
#include "printf.h"
extern "C" bool strequals(const char *a, const char *b);
/**
* A statically sized string buffer used for resource
* identification where strings are guaranteed to be short.
*
* Note: We aren't aware of any other projects that use a similar
* class and given that SS has no debugging info anywhere it's hard
* to be certain about anything.
*/
template <size_t Size>
struct SizedString {
SizedString() {
mChars[0] = '\0';
}
SizedString(const char *src) {
operator=(src);
}
char mChars[Size];
operator char *() {
return mChars;
}
operator const char *() const {
return mChars;
}
void empty() {
mChars[0] = '\0';
}
void operator=(const char *src) {
if (src != mChars) {
mChars[0] = '\0';
operator+=(src);
}
}
void set(const char *src) {
if (src != mChars) {
mChars[0] = '\0';
append(src);
}
}
void operator+=(const char *src) {
if (src != nullptr) {
append(src);
}
}
void append(const char *src) {
size_t destLen = strlen(mChars);
size_t copyLen = strlen(src);
// Make sure copy length isnt more than destination length
if (destLen + copyLen + 1 >= Size) {
size_t tmpLen = Size - destLen;
copyLen = tmpLen - 1;
}
strncpy(mChars + destLen, src, copyLen);
// make sure string is null terminated
size_t offset = destLen + copyLen;
mChars[offset] = '\0';
}
bool operator==(const char *other) const {
return strequals(mChars, other);
}
int sprintf(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
int printed = vsnprintf(this->mChars, Size, fmt, args);
if (printed != strlen(this->mChars)) {
this->mChars[0] = '\0';
}
va_end(list);
return printed;
}
size_t len() const {
return strlen(mChars);
}
};
// TODO this might be a shared template with SizedString but I'm
// not sure how to write the inline functions
template <size_t Size>
struct SizedWString {
SizedWString() {
mChars[0] = L'\0';
}
wchar_t mChars[Size];
operator wchar_t *() {
return mChars;
}
operator const wchar_t *() const {
return mChars;
}
void empty() {
mChars[0] = L'\0';
}
int sprintf(const wchar_t *fmt, ...) {
va_list args;
va_start(args, fmt);
int printed = vswprintf(this->mChars, Size, fmt, args);
if (printed != wcslen(this->mChars)) {
this->mChars[0] = '\0';
}
va_end(list);
return printed;
}
};
#endif
|