UniqueMessageHandle _detail::AmqpMessageFactory::ToImplementation()

in sdk/core/azure-core-amqp/src/models/amqp_message.cpp [313:525]


  UniqueMessageHandle _detail::AmqpMessageFactory::ToImplementation(AmqpMessage const& message)
  {
#if ENABLE_UAMQP
    UniqueMessageHandle rv(message_create());

    // AMQP 1.0 specifies a message format of 0, but EventHubs uses other values.
    if (message_set_message_format(rv.get(), message.MessageFormat))
    {
      throw std::runtime_error("Could not set destination message format.");
    }
    if (message_set_header(
            rv.get(), _detail::MessageHeaderFactory::ToImplementation(message.Header).get()))
    {
      throw std::runtime_error("Could not set message header.");
    }
    if (message_set_properties(
            rv.get(),
            _detail::MessagePropertiesFactory::ToImplementation(message.Properties).get()))
    {
      throw std::runtime_error("Could not set message properties.");
    }
    if (!message.DeliveryAnnotations.empty())
    {
      if (message_set_delivery_annotations(
              rv.get(),
              _detail::AmqpValueFactory::ToImplementation(
                  message.DeliveryAnnotations.AsAmqpValue())))
      {
        throw std::runtime_error("Could not set delivery annotations.");
      }
    }

    if (!message.MessageAnnotations.empty())
    {
      if (message_set_message_annotations(
              rv.get(),
              _detail::AmqpValueFactory::ToImplementation(
                  message.MessageAnnotations.AsAmqpValue())))
      {
        throw std::runtime_error("Could not set message annotations.");
      }
    }

    if (!message.ApplicationProperties.empty())
    {
      AmqpMap appProperties;
      for (auto const& val : message.ApplicationProperties)
      {
        if ((val.second.GetType() == AmqpValueType::List)
            || (val.second.GetType() == AmqpValueType::Map)
            || (val.second.GetType() == AmqpValueType::Composite)
            || (val.second.GetType() == AmqpValueType::Described))
        {
          throw std::runtime_error(
              "Message Application Property values must be simple value types");
        }
        appProperties.emplace(val);
      }
      if (message_set_application_properties(
              rv.get(), _detail::AmqpValueFactory::ToImplementation(appProperties.AsAmqpValue())))
      {
        throw std::runtime_error("Could not set application properties.");
      }
    }

#if ENABLE_UAMQP
    if (!message.DeliveryTag.IsNull())
    {
      if (message_set_delivery_tag(
              rv.get(), _detail::AmqpValueFactory::ToImplementation(message.DeliveryTag)))
      {
        throw std::runtime_error("Could not set delivery tag.");
      }
    }
#endif

    if (!message.Footer.empty())
    {
      if (message_set_footer(
              rv.get(), _detail::AmqpValueFactory::ToImplementation(message.Footer.AsAmqpValue())))
      {
        throw std::runtime_error("Could not set message annotations.");
      }
    }
    switch (message.BodyType)
    {
      case MessageBodyType::None:
        break;
      case MessageBodyType::Data:
        for (auto const& binaryVal : message.m_binaryDataBody)
        {
#if ENABLE_UAMQP
          BINARY_DATA valueData{};
          valueData.bytes = binaryVal.data();
          valueData.length = static_cast<uint32_t>(binaryVal.size());
          if (message_add_body_amqp_data(rv.get(), valueData))
#elif ENABLE_RUST_AMQP
          if (message_add_body_amqp_data(rv.get(), binaryVal.data(), binaryVal.size()))
#endif
          {
            throw std::runtime_error("Could not set message body AMQP sequence value.");
          }
        }
        break;
      case MessageBodyType::Sequence:
        for (auto const& sequenceVal : message.m_amqpSequenceBody)
        {
          if (message_add_body_amqp_sequence(
                  rv.get(), _detail::AmqpValueFactory::ToImplementation(sequenceVal.AsAmqpValue())))
          {
            throw std::runtime_error("Could not set message body AMQP sequence value.");
          }
        }
        break;
      case MessageBodyType::Value:
        if (message_set_body_amqp_value(
                rv.get(), _detail::AmqpValueFactory::ToImplementation(message.m_amqpValueBody)))
        {
          throw std::runtime_error("Could not set message body AMQP value.");
        }
        break;
      case MessageBodyType::Invalid:
      default:
        throw std::runtime_error("Unknown message body type.");
    }
#else
    UniqueMessageBuilderHandle builder(messagebuilder_create());

    InvokeBuilderApi(
        messagebuilder_set_header,
        builder,
        _detail::MessageHeaderFactory::ToImplementation(message.Header).get());
    InvokeBuilderApi(
        messagebuilder_set_properties,
        builder,
        _detail::MessagePropertiesFactory::ToImplementation(message.Properties).get());
    if (!message.DeliveryAnnotations.empty())
    {
      InvokeBuilderApi(
          messagebuilder_set_delivery_annotations,
          builder,
          _detail::AmqpValueFactory::ToImplementation(message.DeliveryAnnotations.AsAmqpValue()));
    }
    if (!message.MessageAnnotations.empty())
    {
      InvokeBuilderApi(
          messagebuilder_set_message_annotations,
          builder,
          _detail::AmqpValueFactory::ToImplementation(message.MessageAnnotations.AsAmqpValue()));
    }

    if (!message.ApplicationProperties.empty())
    {
      AmqpMap appProperties;
      for (auto const& val : message.ApplicationProperties)
      {
        if ((val.second.GetType() == AmqpValueType::List)
            || (val.second.GetType() == AmqpValueType::Map)
            || (val.second.GetType() == AmqpValueType::Composite)
            || (val.second.GetType() == AmqpValueType::Described))
        {
          throw std::runtime_error(
              "Message Application Property values must be simple value types");
        }
        appProperties.emplace(val);
      }
      InvokeBuilderApi(
          messagebuilder_set_application_properties,
          builder,
          _detail::AmqpValueFactory::ToImplementation(appProperties.AsAmqpValue()));
    }

    if (!message.Footer.empty())
    {
      InvokeBuilderApi(
          messagebuilder_set_footer,
          builder,
          _detail::AmqpValueFactory::ToImplementation(message.Footer.AsAmqpValue()));
    }
    switch (message.BodyType)
    {
      case MessageBodyType::None:
        break;
      case MessageBodyType::Data:
        for (auto const& binaryVal : message.m_binaryDataBody)
        {
          InvokeBuilderApi(
              messagebuilder_add_body_amqp_data, builder, binaryVal.data(), binaryVal.size());
        }
        break;
      case MessageBodyType::Sequence:
        for (auto const& sequenceVal : message.m_amqpSequenceBody)
        {
          InvokeBuilderApi(
              messagebuilder_add_body_amqp_sequence,
              builder,
              _detail::AmqpValueFactory::ToImplementation(sequenceVal.AsAmqpValue()));
        }
        break;
      case MessageBodyType::Value:
        InvokeBuilderApi(
            messagebuilder_set_body_amqp_value,
            builder,
            _detail::AmqpValueFactory::ToImplementation(message.m_amqpValueBody));
        break;
      case MessageBodyType::Invalid:
      default:
        throw std::runtime_error("Unknown message body type.");
    }
    UniqueMessageHandle rv{messagebuilder_build_and_destroy(builder.release())};
#endif
    return rv;
  }