|
|
|
@ -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;
|
|
|
|
|