AZ_NODISCARD az_result az_iot_hub_client_properties_get_next_component_property()

in sdk/src/azure/iot/az_iot_hub_client_properties.c [409:486]


AZ_NODISCARD az_result az_iot_hub_client_properties_get_next_component_property(
    az_iot_hub_client const* client,
    az_json_reader* ref_json_reader,
    az_iot_hub_client_properties_message_type message_type,
    az_iot_hub_client_property_type property_type,
    az_span* out_component_name)
{
  _az_PRECONDITION_NOT_NULL(client);
  _az_PRECONDITION_NOT_NULL(ref_json_reader);
  _az_PRECONDITION_NOT_NULL(out_component_name);
  _az_PRECONDITION(
      (message_type == AZ_IOT_HUB_CLIENT_PROPERTIES_MESSAGE_TYPE_WRITABLE_UPDATED)
      || (message_type == AZ_IOT_HUB_CLIENT_PROPERTIES_MESSAGE_TYPE_GET_RESPONSE));
  _az_PRECONDITION(
      (property_type == AZ_IOT_HUB_CLIENT_PROPERTY_REPORTED_FROM_DEVICE)
      || (property_type == AZ_IOT_HUB_CLIENT_PROPERTY_WRITABLE));
  _az_PRECONDITION(
      (property_type == AZ_IOT_HUB_CLIENT_PROPERTY_WRITABLE)
      || ((property_type == AZ_IOT_HUB_CLIENT_PROPERTY_REPORTED_FROM_DEVICE)
          && (message_type == AZ_IOT_HUB_CLIENT_PROPERTIES_MESSAGE_TYPE_GET_RESPONSE)));

  _az_RETURN_IF_FAILED(
      verify_valid_json_position(ref_json_reader, message_type, *out_component_name));
  _az_RETURN_IF_FAILED(process_first_move_if_needed(ref_json_reader, message_type, property_type));

  while (true)
  {
    _az_RETURN_IF_FAILED(skip_metadata_if_needed(ref_json_reader, message_type));

    if (ref_json_reader->token.kind == AZ_JSON_TOKEN_END_OBJECT)
    {
      // We've read all the children of the current object we're traversing.
      if ((message_type == AZ_IOT_HUB_CLIENT_PROPERTIES_MESSAGE_TYPE_WRITABLE_UPDATED
           && ref_json_reader->current_depth == 0)
          || (message_type == AZ_IOT_HUB_CLIENT_PROPERTIES_MESSAGE_TYPE_GET_RESPONSE
              && ref_json_reader->current_depth == 1))
      {
        // We've read the last child the root of the JSON tree we're traversing.  We're done.
        return AZ_ERROR_IOT_END_OF_PROPERTIES;
      }

      // There are additional tokens to read.  Continue.
      _az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
      continue;
    }

    break;
  }

  if ((message_type == AZ_IOT_HUB_CLIENT_PROPERTIES_MESSAGE_TYPE_WRITABLE_UPDATED
       && ref_json_reader->current_depth == 1)
      || (message_type == AZ_IOT_HUB_CLIENT_PROPERTIES_MESSAGE_TYPE_GET_RESPONSE
          && ref_json_reader->current_depth == 2))
  {
    // Retrieve the next property/component pair.
    if (is_component_in_model(client, &ref_json_reader->token, out_component_name))
    {
      // Properties that are children of components are simply modeled as JSON children
      // in the underlying twin.  Traverse into the object.
      _az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));

      if (ref_json_reader->token.kind != AZ_JSON_TOKEN_BEGIN_OBJECT)
      {
        return AZ_ERROR_UNEXPECTED_CHAR;
      }

      _az_RETURN_IF_FAILED(az_json_reader_next_token(ref_json_reader));
      _az_RETURN_IF_FAILED(skip_metadata_if_needed(ref_json_reader, message_type));
    }
    else
    {
      // The current property is not the child of a component.
      *out_component_name = AZ_SPAN_EMPTY;
    }
  }

  return AZ_OK;
}