# micro-CDR **Repository Path**: sdkmsdn_admin/micro-CDR ## Basic Information - **Project Name**: micro-CDR - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2021-07-20 - **Last Updated**: 2023-04-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # eProsima Micro CDR [![Releases](https://img.shields.io/github/release/eProsima/Micro-CDR.svg)](https://github.com/eProsima/Micro-CDR/releases) [![License](https://img.shields.io/github/license/eProsima/Micro-CDR.svg)](https://github.com/eProsima/Micro-CDR/blob/master/LICENSE) [![Issues](https://img.shields.io/github/issues/eProsima/Micro-CDR.svg)](https://github.com/eProsima/Micro-CDR/issues) [![Forks](https://img.shields.io/github/forks/eProsima/Micro-CDR.svg)](https://github.com/eProsima/Micro-CDR/network/members) [![Stars](https://img.shields.io/github/stars/eProsima/Micro-CDR.svg)](https://github.com/eProsima/Micro-CDR/stargazers) *eProsima MicroCDR* is a *C* library implementing the *CDR* standard serialization methods. This library is focused on embedded and resource-limited systems. *MicroCDR* uses a static buffer, and allow to serialize and deserialize in both, big endianness and little endianness. ## Usage examples This is a code example showing the serialization and deserialization of a string. As *MicroCDR* uses a static buffer, that means the user has to provide a defined buffer and its size during the *ucdrBuffer* creation. ```c #include #include #define BUFFER_LENGTH 256 int main(int argc, char** args) { // Data buffer uint8_t buffer[BUFFER_LENGTH]; // Structs for handle the buffer. ucdrBuffer writer; ucdrBuffer reader; // Initialize the MicroBuffers for working with an user-managed buffer. ucdr_init_buffer(&writer, buffer, BUFFER_LENGTH); ucdr_init_buffer(&reader, buffer, BUFFER_LENGTH); // Serialize data char input[16] = "Hello MicroCDR!"; //16 characters ucdr_serialize_array_char(&writer, input, 16); // Deserialize data char output[16]; ucdr_deserialize_array_char(&reader, output, 16); printf("Input: %s\n", input); printf("Output: %s\n", output); return 0; } ``` ## API functions ```c void ucdr_init_buffer (ucdrBuffer* ub, uint8_t* data, size_t size); void ucdr_init_buffer_offset (ucdrBuffer* ub, uint8_t* data, size_t size, size_t offset); ``` Initialize a `ucdrBuffer` structure, the main struct of *MicroCDR*. - `ub`: the `ucdrBuffer` struct - `data`: the buffer that the `ucdrBuffer` will use. - `size`: the size of the buffer that the `ucdrBuffer` will use. - `offset`: where the serialization/deserialization will start. Initially, the serialization/deserialization starts at the beginning of the buffer. --- ```c void ucdr_copy_buffer (ucdrBuffer* ub_dest, const ucdrBuffer* ub_source); ``` Copy a `ucdrBuffer` structure data to another `ucdrBuffer` structure. - `ub_dest`: the destination `ucdrBuffer` struct. - `ub_source`: the origin initialized `ucdrBuffer` struct. --- ```c void ucdr_reset_buffer (ucdrBuffer* ub); void ucdr_reset_buffer_offset(ucdrBuffer* ub, size_t offset); ``` Reset the `ucdrBuffer` as the same state that it was created. - `ub`: the `ucdrBuffer` struct. - `offset`: where the serialization/deserialization will start. Initially, the serialization/deserialization starts at the beginning of the buffer. --- ```c void ucdr_align_to (ucdrBuffer* ub, size_t size); ``` Align the ucdrBuffer to the size `size`. After call this function, the serialization pointer will be moved only if the current `ucdrBuffer` was not alignment to the passed value. - `ub`: the `ucdrBuffer` struct - `size`: the target size alignment. --- ```c size_t ucdr_alignment(size_t buffer_position, size_t data_size); ``` Returns the alignment necessary to serialize/deserialize a type with `data_size` size. - `buffer_position`: the current serialization/deserialization position of the `ucdrBuffer`. (Typically `ub->iterator - ub->init`). - `data_size`: the bytes of the data that you are asking for. --- ```c size_t ucdr_buffer_alignment(const ucdrBuffer* ub, size_t data_size); ``` Returns the alignment necessary to serialize/deserialize a type with `data_size` size into the `ucdrBuffer` given. - `ub`: the `ucdrBuffer` struct to ask the alignment. - `data_size`: the bytes of the data that you are asking for. --- ```c size_t ucdr_buffer_size(const ucdrBuffer* ub); ``` Returns the memory size of the buffer. - `ub`: the `ucdrBuffer` struct --- ```c size_t ucdr_buffer_length(const ucdrBuffer* ub); ``` Returns the size of the serialized/deserialized data. - `ub`: the `ucdrBuffer` struct --- ```c size_t ucdr_buffer_remaining(const ucdrBuffer* ub); ``` Returns the remaining size for the serializing/deserializing. - `ub`: the `ucdrBuffer` struct --- ```c ucdrEndianness ucdr_buffer_endianness(const ucdrBuffer* ub); ``` Returns the serialization/deserialization endianness. - `ub`: the `ucdrBuffer` struct --- ```c bool ucdr_buffer_error(const ucdrBuffer* ub); ``` Returns the status error of the `ucdrBuffer`. - `ub`: the `ucdrBuffer` struct ### Serialization/deserialization functions Adding to this, there is a big set of functions for deserialize and deserialize different kind of types: - Basics: `bool`, `char`, `int8_t`, `uint8_t`,`int16_t`, `uint16_t`,`int32_t`, `uint32_t`,`int64_t`, `uint64_t`,`float`, `double`. - Arrays: Any fixed size of basics types. - Sequence: Similar to arrays, but the information about the size is serialized along with the data. - String: Wrapper of char sequence, but easily to use. ### Endianness *MicroCDR* supports little and big endianness. The **machine endianness** can be set by the cmake variable: `CONFIG_BIG_ENDIANNESS`. By default, if this varible is `OFF` which means that the machine endianness is little endianness. The `ucdrBuffer` endianness can be set by the `endianness` parameter of the structure to `UCDR_BIG_ENDIANNESS` or `UCDR_LITTLE_ENDIANNESS`. Also, there are a functions that allow to force an endianness independiently of the `ucdrBuffer` endianness in their serialization/deserialization. These functions contains the name `endianness` in their signature. ### Error All serialization/deserialization functions return a boolean indicating the result of their operations. When a serialization/deserialization could not be possible (the type can not be serialized, or the capacity of the destination buffer is not enough), an status error is setted into the `ucdrBuffer`. If a `ucdrBuffer` has an error state, the next serialization/deserialization operations will not works and will return `false` in their execution. A buffer marked with an error can be used, but any serialization/deserialization operation over it will not produce any effect. If is kwown that an operation can fails over a `ucdrBuffer`, and its necessary to continue with the serialization/deserialization if it happens, the `ucdrBuffer` state can be saved using the `ucdr_copy_buffer` function. After the application of the wrong serialization/deserialization, only the `ucdrBuffer` that performed the operation will have a dirty state. ## Serialization/deserialization list The available modes of serialization/deserializations in *MicroCDR* are shown in the following table. | Type | Endianness | | -------------------- | ---------- | | bool | | | char | | | int8 | | | uint8 | | | int16 | | | int16 | endianness | | uint16 | | | uint16 | endianness | | int32 | | | int32 | endianness | | uint32 | | | uint32 | endianness | | int64 | | | int64 | endianness | | uint64 | | | uint64 | endianness | | float | | | float | endianness | | double | | | double | endianness | | string | | | string | endianness | | bool array | | | char array | | | int8 array | | | uint8 array | | | int16 array | | | int16 array | endianness | | uint16 array | | | uint16 array | endianness | | int32 array | | | int32 array | endianness | | uint32 array | | | uint32 array | endianness | | int64 array | | | int64 array | endianness | | uint64 array | | | uint64 array | endianness | | float array | | | float array | endianness | | double array | | | double array | endianness | | bool sequence | | | bool sequence | endianness | | char sequence | | | char sequence | endianness | | int8 sequence | | | int8 sequence | endianness | | uint8 sequence | | | uint8 sequence | endianness | | int16 sequence | | | int16 sequence | endianness | | uint16 sequence | | | uint16 sequence | endianness | | int32 sequence | | | int32 sequence | endianness | | uint32 sequence | | | uint32 sequence | endianness | | int64 sequence | | | int64 sequence | endianness | | uint64 sequence | | | uint64 sequence | endianness | | float sequence | | | float sequence | endianness | | double sequence | | | double sequence | endianness | ## Additional features ### Endianness *MicroCDR* supports little and big endianness. The configuration can be done by cmake with the cmake `__BIG_ENDIAN__` variable. A `0` value implies that the serialization will performed into a little endian machine, and `1` into a big endian machine. The default endianness serialization can be choosen by setting the `endianness` parameter of a `ucdrBuffer` to `UCDR_BIG_ENDIANNESS` or `UCDR_LITTLE_ENDIANNESS`. Also, there are a functions that allow to force an endianness in their serialization/deserialization. These functions contains the name `endiannness` in their signature. ### Error All serialization/deserialization functions return a boolean indicating the result of their operations. When a serialization/deserialization could not be possible (the type can not be serialized, or the capacity of the destination buffer is not enough), an status error is setted into the `ucdrBuffer`. If a `ucdrBuffer` has an error state, the next serialization/deserialization operations will not works and will return `false` in their execution. A buffer marked with an error can be used, but any serialization/deserialization operation over it will not produce any effect. If is kwown that an operation can fails over a `ucdrBuffer`, and its necessary to continue with the serialization/deserialization if it happens, the `ucdrBuffer` state can be saved using the `ucdr_copy_buffer` function. After the application of the wrong serialization/deserialization, only the `ucdrBuffer` that performed the operation will have a dirty state. ### Full buffer callback MicroCDR provides a callback that the user can set in order to control the behavior when the `ucdrBuffer` can not serialize/deserialize anymore because the buffer is full. This allows to create a better management error and/or modify the buffer location of the `ucdrBuffer`. The last possibility gives the user the capacity to use several small buffers for a big serialization (see the *fragmentation* example).