AZ_NODISCARD bool az_json_token_is_text_equal()

in sdk/src/azure/core/az_json_token.c [151:244]


AZ_NODISCARD bool az_json_token_is_text_equal(
    az_json_token const* json_token,
    az_span expected_text)
{
  _az_PRECONDITION_NOT_NULL(json_token);

  // Cannot compare the value of non-string token kinds
  if (json_token->kind != AZ_JSON_TOKEN_STRING && json_token->kind != AZ_JSON_TOKEN_PROPERTY_NAME)
  {
    return false;
  }

  az_span token_slice = json_token->slice;

  // There is nothing to unescape here, compare directly.
  if (!json_token->_internal.string_has_escaped_chars)
  {
    // Contiguous token
    if (!json_token->_internal.is_multisegment)
    {
      return az_span_is_content_equal(token_slice, expected_text);
    }

    // Token straddles more than one segment
    for (int32_t i = json_token->_internal.start_buffer_index;
         i <= json_token->_internal.end_buffer_index;
         i++)
    {
      az_span source = json_token->_internal.pointer_to_first_buffer[i];
      if (i == json_token->_internal.start_buffer_index)
      {
        source = az_span_slice_to_end(source, json_token->_internal.start_buffer_offset);
      }
      else if (i == json_token->_internal.end_buffer_index)
      {
        source = az_span_slice(source, 0, json_token->_internal.end_buffer_offset);
      }

      int32_t source_size = az_span_size(source);
      if (az_span_size(expected_text) < source_size
          || !az_span_is_content_equal(source, az_span_slice(expected_text, 0, source_size)))
      {
        return false;
      }
      expected_text = az_span_slice_to_end(expected_text, source_size);
    }
    // Only return true if we have gone through and compared the entire expected_text.
    return az_span_size(expected_text) == 0;
  }

  int32_t token_size = json_token->size;
  int32_t expected_size = az_span_size(expected_text);

  // No need to try to unescape the token slice, since the lengths won't match anyway.
  // Unescaping always shrinks the string, at most by a factor of 6.
  if (token_size < expected_size
      || (token_size / _az_MAX_EXPANSION_FACTOR_WHILE_ESCAPING) > expected_size)
  {
    return false;
  }

  bool next_char_escaped = false;

  // Contiguous token
  if (!json_token->_internal.is_multisegment)
  {
    return _az_json_token_is_text_equal_helper(token_slice, &expected_text, &next_char_escaped);
  }

  // Token straddles more than one segment
  for (int32_t i = json_token->_internal.start_buffer_index;
       i <= json_token->_internal.end_buffer_index;
       i++)
  {
    az_span source = json_token->_internal.pointer_to_first_buffer[i];
    if (i == json_token->_internal.start_buffer_index)
    {
      source = az_span_slice_to_end(source, json_token->_internal.start_buffer_offset);
    }
    else if (i == json_token->_internal.end_buffer_index)
    {
      source = az_span_slice(source, 0, json_token->_internal.end_buffer_offset);
    }

    if (!_az_json_token_is_text_equal_helper(source, &expected_text, &next_char_escaped)
        && az_span_size(expected_text) == 0)
    {
      return false;
    }
  }

  // Only return true if we have gone through and compared the entire expected_text.
  return az_span_size(expected_text) == 0;
}