[core] buffer_append_string_encoded_json()

personal/stbuehler/tests-path
Glenn Strauss 2021-11-17 15:04:42 -05:00
parent d85ed2a672
commit e1ff1cc871
2 changed files with 81 additions and 0 deletions

View File

@ -667,6 +667,85 @@ void buffer_append_string_encoded(buffer * const restrict b, const char * const
}
}
void buffer_append_string_encoded_json(buffer * const restrict b, const char * const restrict s, const size_t len) {
const unsigned char * const restrict ds = (unsigned char *)s;
size_t dlen = 0;
/* calculate space needed for string including encodings */
for (size_t i = 0; i < len; ++i) {
int c = ds[i];
if (c == '"' || c == '\\' || c < 0x20 || c == 0x7f) {
switch (c) {
case '\b':
case '\t':
case '\n':
case '\f':
case '\r':
case '"':
case '\\':
dlen += 2;
break;
default:
dlen += 6; /* \uCCCC */
break;
}
}
else {
++dlen;
}
}
unsigned char * const d = (unsigned char *)buffer_extend(b, dlen);
if (__builtin_expect( (dlen == len), 1)) {/*(short-circuit; nothing to encode)*/
memcpy(d, ds, len);
return;
}
dlen = 0;
for (size_t i = 0; i < len; ++i) {
int c = ds[i];
if (c == '"' || c == '\\' || c < 0x20 || c == 0x7f) {
d[dlen++] = '\\';
switch (c) {
case '\b':
d[dlen++] = 'b';
break;
case '\t':
d[dlen++] = 't';
break;
case '\n':
d[dlen++] = 'n';
break;
case '\f':
d[dlen++] = 'f';
break;
case '\r':
d[dlen++] = 'r';
break;
case '"':
d[dlen++] = '"';
break;
case '\\':
d[dlen++] = '\\';
break;
default:
d[dlen ] = 'u';
d[dlen+1] = '0';
d[dlen+2] = '0';
d[dlen+3] = hex_chars_lc[(c >> 4) & 0x0F];
d[dlen+4] = hex_chars_lc[c & 0x0F];
dlen += 5;
break;
}
}
else {
d[dlen++] = c;
}
}
}
void buffer_append_string_c_escaped(buffer * const restrict b, const char * const restrict s, size_t s_len) {
unsigned char *ds, *d;
size_t d_len, ndx;

View File

@ -186,6 +186,8 @@ typedef enum {
void buffer_append_string_encoded(buffer * restrict b, const char * restrict s, size_t s_len, buffer_encoding_t encoding);
void buffer_append_string_encoded_json(buffer * restrict b, const char * restrict s, size_t len);
/* escape non-printable characters; simple escapes for \t, \r, \n; fallback to \xCC */
__attribute_nonnull__()
void buffer_append_string_c_escaped(buffer * restrict b, const char * restrict s, size_t s_len);