Architecture Overview
Architecture of Message and Data Manipulation explains the stratification of data, field and message operations into four layers.
Layer |
Description |
|||||||||
4. Convenience Functions |
Type-specific functions manipulate message field data. This layer contains three functions per datatype—add, get and update. For example, see Add String. All convenience functions call the corresponding generic functions of layer 3 for their main functionality. When defining a custom datatype, a program can implement these three functions (optional). |
|||||||||
3. Generic Field Functions |
Field functions add, get or update a message field. This layer consists of only three functions: tibrvMsg_AddField(), tibrvMsg_GetField(), tibrvMsg_UpdateField(). Field functions call the datatype handler functions of layer 2 whenever data enters or leaves a message. |
|||||||||
2. Datatype Handler Functions |
Type-specific handler functions translate data between C format and Rendezvous wire format, and convert it to other datatypes. This layer contains three functions per datatype:
To define a custom datatype, a program must implement these functions. |
|||||||||
1. Utility Functions |
Utility functions ease and standardize the implementation of datatype handler functions in layer 2. For example, tibrvMsgData_CopyBytes(). |
At the top of the table, programs call functions in layer 4 (and sometimes layer 3) to move data in and out of messages. The remaining lower layers are generally invisible to most programs. That is, most programs do not call functions below layers 3.
However, a program that defines custom datatypes must implement the three functions in layer 2. Nevertheless, the program never calls layer 2 functions directly. Instead the program can define optional convenience functions at layer 4, and call them to move the custom datatype in and out of messages.
Adding Data
This narrative illustrates the interaction of functions at all four layers as they cooperate to add data to a message. The narrative for updating data within a message is parallel.
A program begins by calling a layer 4 convenience function to add data. The convenience function creates a field object (tibrvMsgField) that contains the data, the field name and identifier, a datatype token, and the element count (for arrays only). Then the convenience function calls the layer 3 field function tibrvMsg_AddField() to add that field to the message.
Among its other tasks, tibrvMsg_AddField() must write the field into wire buffer storage within the message object; to accomplish this step, it calls the layer 2 encoder function specific to the datatype.
The encoder transforms the data into its wire format, using layer 1 utility functions to copy that data into the message’s wire buffer.
Each write operation updates the message’s wire buffer pointer to the location where the next write will begin.
Figure 192: Writing Fields into a Message’s Wire Buffer
Extracting Data
This narrative illustrates the interaction of functions at all four layers as they cooperate to get data from a message.
A program begins by calling a layer 4 convenience function to get data. The convenience function calls the layer 3 field function tibrvMsg_GetField() to find the field in the message.
Among its other tasks, tibrvMsg_GetField() must read the data from the message’s wire buffer; to accomplish this step, it calls the layer 2 decoder function for the datatype (as specified in the message field).
The decoder uses layer 1 utility functions to extract that data from the message’s wire buffer, and transforms the data into its C format.
Returning to layer 3, tibrvMsg_GetField() receives the data from the decoder, packaged in the data part of a field object (tibrvMsgField).
Returning to layer 4, the convenience function receives the field object from tibrvMsg_GetField(). The next task is to convert the data from its actual datatype to the target datatype (notice that the program, in effect, explicitly requested a target datatype by calling a particular type-specific convenience function). When the actual data does not already match the target datatype, the convenience function calls down into layer 2, to the converter function associated with the actual datatype.
If legal, the converter transforms the actual data to the target type, and modifies the field object accordingly.
Returning once again to layer 4, the convenience function extracts the modified data from the field object, and passes it back to the calling program.