Creating Structured Data Maps and Streams

The memory that must be allocated to create maps and streams can either be allocated by the client application to create message-independent maps and streams (see Message-Independent Maps and Streams), or it can be automatically allocated by the API to create message‑dependent maps and streams (see Message-Dependent Maps and Streams).

Message-Independent Maps and Streams

Typically, a map or stream is created in application memory that is independent of a particular message. This allows a container to be added to other containers or to the binary message parts of more than just one message. Using a message‑independent container can be useful if you want to add it repeatedly to different messages or to existing containers as a common container.

For the Solace C API, you must pass in pointers to the location to receive the container pointer and to the location to create the container.

The following sections discuss how to use containers that are message‑independent:

Creating Structured Data Maps

To create structured data maps, call solClient_container_createMap().

Creating Structured Data Streams

To create structured data streams, call solClient_container_createStream(...).

Copying Content from Containers to Messages

To copy data from a container into a message’s binary attachment, call solClient_msg_setBinaryAttachmentContainer(...). Pass in pointers to the message the content is for and the container with the content to be copied in.

If a binary attachment is present before the function is called, it is removed before the new data is copied in.

After the function is called, any further changes to the container contents are not propagated to the referenced message.

Adding Content from Containers to Messages by Reference

To add data from a map or a stream into a message’s binary attachment through a container reference, call solClient_msg_setBinaryAttachmentContainerPtr(solClient_opaqueMsg_pt msg_p, solClient_opaqueContainer_pt cont_p) and pass a reference to the message to receive the contents and the container with the contents that are to be added.

If the message already has a binary attachment, it is removed and only the referenced map is transmitted.

Adding data from a map or a stream into a message’s binary attachment through an opaque container pointer reference can improve system performance because it avoids copying application memory into the message binary attachment.

When the solClient_session_sendMsg() function is called, and the message is sent, the binary attachment contents are copied directly from the application memory to the transmit socket or buffer.

After solClient_msg_setBinaryAttachmentContainerPtr() is called, any further changes to the container data can result in corrupt container contents for the transmitted message, so the container must not be modified until the message has been successfully transmitted and acknowledged (if it is a Guaranteed message).

Adding Containers to Existing Containers

To add an existing container to a map or stream, call solClient_container_addContainer(...) and pass in the parent container and the subcontainers that you want to add to it.

Pointers to the message and the container are used. In addition, if the parent container is a map, you must also pass in the name of the field to add the container, and if the parent container is a stream, the name parameter must be NULL.

Message-Dependent Maps and Streams

Containers can also be created directly in the binary attachment of a message using the memory block managed by the Solace C API; the container is then dependent on that particular message and cannot be reused by other messages.

Creating Message-Dependent Maps and Streams

A client can create a map or stream of structured data directly in the binary attachment of a message. Structured data added in this manner is not created in an application memory-based container that can be reused. However, it does avoid a memory copy operation, and it off-loads the task of memory management from the application so that the API is responsible for managing the memory allocated for the container.

To create message-dependent maps or streams, call one of the following functions to create a map or stream directly in the binary attachment of a specific message:

  • solClient_msg_createBinaryAttachmentMap(...)
  • solClient_msg_createBinaryAttachmentStream(...)

When using one of these functions, you must specify the size (in bytes) of the datablock to allocate for the creation of the map or stream.

If a specific datablock size is set, and it is too small for the subsequently created map or stream, a larger datablock is allocated when data is added, and the existing structured data is copied into the new buffer. This reallocation can negatively affect performance.

If you want to use the smallest amount of API memory, set a value of 0 for the size parameter. In this case, the API uses the smallest possible datablock (by default 10,240 bytes) to build the containers. If this is not enough, a reallocation occurs, and all existing data is copied into the new, larger buffer.

Data fields, submaps, and substreams can be created using SDT add functions. Applications that receive messages can also do this before retransmitting or forwarding the data. For a comprehensive list of the available container functions, see the Solace Messaging APIs documentation for the Solace C API.

Deleting fields results in a buffer copy of the remainder of the map.