in sdk/src/azure/core/az_json_writer.c [207:283]
static int32_t _az_json_writer_escaped_length(
az_span value,
int32_t* out_index_of_first_escaped_char,
bool break_on_first_escaped)
{
_az_PRECONDITION_NOT_NULL(out_index_of_first_escaped_char);
_az_PRECONDITION_VALID_SPAN(value, 0, true);
int32_t value_size = az_span_size(value);
_az_PRECONDITION(value_size <= _az_MAX_UNESCAPED_STRING_SIZE);
int32_t escaped_length = 0;
*out_index_of_first_escaped_char = -1;
int32_t i = 0;
uint8_t* value_ptr = az_span_ptr(value);
while (i < value_size)
{
uint8_t const ch = value_ptr[i];
switch (ch)
{
case '\\':
case '"':
case '\b':
case '\f':
case '\n':
case '\r':
case '\t':
{
escaped_length += 2; // Use the two-character sequence escape for these.
break;
}
default:
{
// Check if the character has to be escaped as a UNICODE escape sequence.
if (ch < _az_ASCII_SPACE_CHARACTER)
{
escaped_length += _az_MAX_EXPANSION_FACTOR_WHILE_ESCAPING;
}
else
{
escaped_length++; // No escaping required.
}
break;
}
}
i++;
// If this is the first time that we found a character that needs to be escaped,
// set out_index_of_first_escaped_char to the corresponding index.
// If escaped_length == i, then we haven't found a character that needs to be escaped yet.
if (escaped_length != i && *out_index_of_first_escaped_char == -1)
{
*out_index_of_first_escaped_char = i - 1;
if (break_on_first_escaped)
{
break;
}
}
// If the length overflows, in case the precondition is not honored, stop processing and break
// The caller will return AZ_ERROR_NOT_ENOUGH_SPACE since az_span can't contain it.
// TODO: Consider removing this if it is too costly.
if (escaped_length < 0)
{
escaped_length = INT32_MAX;
break;
}
}
// In most common cases, escaped_length will equal value_size and out_index_of_first_escaped_char
// will be -1.
return escaped_length;
}