-
-
Notifications
You must be signed in to change notification settings - Fork 175
/
Copy pathsentry_string.h
218 lines (189 loc) · 4.97 KB
/
sentry_string.h
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#ifndef SENTRY_STRING_H_INCLUDED
#define SENTRY_STRING_H_INCLUDED
#include "sentry_boot.h"
#include <ctype.h>
#include <stdio.h>
#include <string.h>
/**
* A string builder, which can be used as a mutable, growable string buffer.
*/
typedef struct sentry_stringbuilder_s {
char *buf;
size_t allocated;
size_t len;
} sentry_stringbuilder_t;
/**
* Initializes a new string builder, which is typically allocated on the stack.
*/
void sentry__stringbuilder_init(sentry_stringbuilder_t *sb);
/**
* Resizes the stringbuilder buffer to make sure there is at least `len` bytes
* available at the end, and returns a pointer *to the reservation*.
*/
char *sentry__stringbuilder_reserve(sentry_stringbuilder_t *sb, size_t len);
/**
* Appends a sized buffer.
*/
static inline int
sentry__stringbuilder_append_buf(
sentry_stringbuilder_t *sb, const char *s, size_t len)
{
size_t needed = sb->len + len + 1;
char *buf = sb->buf;
if (!sb->buf || needed > sb->allocated) {
buf = sentry__stringbuilder_reserve(sb, len + 1);
if (!buf) {
return 1;
}
} else {
buf = buf + sb->len;
}
memcpy(buf, s, len);
sb->len += len;
// make sure we're always zero terminated
sb->buf[sb->len] = '\0';
return 0;
}
/**
* Appends a zero terminated string to the builder.
*/
static inline int
sentry__stringbuilder_append(sentry_stringbuilder_t *sb, const char *s)
{
return sentry__stringbuilder_append_buf(sb, s, strlen(s));
}
/**
* Appends a single character.
*/
static inline int
sentry__stringbuilder_append_char(sentry_stringbuilder_t *sb, char c)
{
return sentry__stringbuilder_append_buf(sb, &c, 1);
}
/**
* Appends an int64 value.
*/
static inline int
sentry__stringbuilder_append_int64(sentry_stringbuilder_t *sb, int64_t val)
{
char buf[24];
snprintf(buf, sizeof(buf), "%" PRId64, val);
return sentry__stringbuilder_append(sb, buf);
}
/**
* Detaches the buffer from the string builder and deallocates it.
*/
char *sentry__stringbuilder_into_string(sentry_stringbuilder_t *sb);
/**
* Detaches the buffer from the string builder.
*/
char *sentry_stringbuilder_take_string(sentry_stringbuilder_t *sb);
/**
* Deallocates the string builder.
*/
void sentry__stringbuilder_cleanup(sentry_stringbuilder_t *sb);
/**
* Returns the number of bytes in the string builder.
*/
size_t sentry__stringbuilder_len(const sentry_stringbuilder_t *sb);
/**
* Sets the number of used bytes in the string builder, to be used together with
* `sentry__stringbuilder_reserve` to avoid copying from an intermediate buffer.
*/
void sentry__stringbuilder_set_len(sentry_stringbuilder_t *sb, size_t len);
/**
* Duplicates a zero terminated string with a length limit. Does not check
* if `str` is NULL.
*/
static inline char *
sentry__string_clone_n_unchecked(const char *str, size_t n)
{
size_t len = n + 1;
char *rv = (char *)sentry_malloc(len);
if (rv) {
memcpy(rv, str, n);
rv[n] = 0;
}
return rv;
}
/**
* Duplicates a ptr/len string into a zero terminated string.
*/
static inline char *
sentry__string_clone_n(const char *str, size_t n)
{
return str ? sentry__string_clone_n_unchecked(str, n) : NULL;
}
/**
* Duplicates a zero terminated string.
*/
static inline char *
sentry__string_clone(const char *str)
{
return str ? sentry__string_clone_n_unchecked(str, strlen(str)) : NULL;
}
static inline char *
sentry__string_clone_max_n(const char *str, size_t str_len, size_t max_len)
{
if (!str) {
return NULL;
}
size_t min_len = str_len < max_len ? str_len : max_len;
return sentry__string_clone_n_unchecked(str, min_len);
}
/**
* Converts a string to lowercase.
*/
static inline void
sentry__string_ascii_lower(char *s)
{
for (; *s; s++) {
*s = (char)tolower((char)*s);
}
}
/**
* Shortcut for string compare.
*/
static inline bool
sentry__string_eq(const char *a, const char *b)
{
return strcmp(a, b) == 0;
}
/**
* Guards strlen() against NULL pointers
*/
static inline size_t
sentry__guarded_strlen(const char *s)
{
return s ? strlen(s) : 0;
}
/**
* Converts an int64_t into a string.
*/
static inline char *
sentry__int64_to_string(int64_t val)
{
char buf[24];
snprintf(buf, sizeof(buf), "%" PRId64, val);
return sentry__string_clone(buf);
}
#ifdef SENTRY_PLATFORM_WINDOWS
/**
* Create a utf-8 string from a Wide String.
*/
char *sentry__string_from_wstr(const wchar_t *s);
/**
* Convert a normal string to a Wide String.
*/
wchar_t *sentry__string_to_wstr(const char *s);
#endif
/**
* Writes the utf-8 encoding of unicode character `c` into `buf`, and returns
* the number of bytes written.
*/
size_t sentry__unichar_to_utf8(uint32_t c, char *buf);
#define sentry__is_lead_surrogate(c) ((c) >= 0xd800 && (c) < 0xdc00)
#define sentry__is_trail_surrogate(c) ((c) >= 0xdc00 && (c) < 0xe000)
#define sentry__surrogate_value(lead, trail) \
(((((lead) - 0xd800) << 10) | ((trail) - 0xdc00)) + 0x10000)
#endif