spa: utils: json: add spa_json_encode_stringn()

Add the function `spa_json_encode_stringn()` that works very similarly
to `spa_json_encode_string()`, with the difference that it works with
non-null terminated strings (e.g. `std::string_view`).

`spa_json_encode_string()` is then implemented with this new function.

Additionally, since the input string is no longer null terminated,
escape bytes of value 0. This is probably better that putting
it into the result.
This commit is contained in:
Barnabás Pőcze 2026-07-01 15:16:03 +02:00
parent 85df114eb4
commit 0ac39e0e5d

View file

@ -665,14 +665,18 @@ SPA_API_JSON int spa_json_parse_string(const char *val, int len, char *result)
return spa_json_parse_stringn(val, len, result, len+1); return spa_json_parse_stringn(val, len, result, len+1);
} }
SPA_API_JSON int spa_json_encode_string(char *str, int size, const char *val) SPA_API_JSON size_t spa_json_encode_stringn(char *dst, size_t capacity, const char *src, size_t length)
{ {
int len = 0;
static const char hex[] = { "0123456789abcdef" }; static const char hex[] = { "0123456789abcdef" };
#define __PUT(c) { if (len < size) *str++ = c; len++; }
size_t len = 0;
#define __PUT(c) do { if (len < capacity) *dst++ = c; len++; } while (0)
__PUT('"'); __PUT('"');
while (*val) { for (; length > 0; length--, src++) {
switch (*val) { const char val = *src;
switch (val) {
case '\n': case '\n':
__PUT('\\'); __PUT('n'); __PUT('\\'); __PUT('n');
break; break;
@ -690,19 +694,18 @@ SPA_API_JSON int spa_json_encode_string(char *str, int size, const char *val)
break; break;
case '\\': case '\\':
case '"': case '"':
__PUT('\\'); __PUT(*val); __PUT('\\'); __PUT(val);
break; break;
default: default:
if (*val > 0 && *val < 0x20) { if ((unsigned char) val < 0x20) {
__PUT('\\'); __PUT('u'); __PUT('\\'); __PUT('u');
__PUT('0'); __PUT('0'); __PUT('0'); __PUT('0');
__PUT(hex[((*val)>>4)&0xf]); __PUT(hex[(*val)&0xf]); __PUT(hex[(val>>4)&0xf]); __PUT(hex[val&0xf]);
} else { } else {
__PUT(*val); __PUT(val);
} }
break; break;
} }
val++;
} }
__PUT('"'); __PUT('"');
__PUT('\0'); __PUT('\0');
@ -710,6 +713,11 @@ SPA_API_JSON int spa_json_encode_string(char *str, int size, const char *val)
return len-1; return len-1;
} }
SPA_API_JSON int spa_json_encode_string(char *dst, int capacity, const char *src)
{
return spa_json_encode_stringn(dst, capacity, src, strlen(src));
}
/** /**
* \} * \}
*/ */