diff --git a/CMakeLists.txt b/CMakeLists.txt index 79af8d6..9f5f650 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima). +# Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,12 +15,7 @@ ############################################################################### # CMake build rules for Micro CDR ############################################################################### -cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) - -set(IS_TOP_LEVEL TRUE) -if(PROJECT_SOURCE_DIR) - set(IS_TOP_LEVEL FALSE) -endif() +cmake_minimum_required(VERSION 3.5.0 FATAL_ERROR) # Set CMAKE_BUILD_TYPE to Release by default. if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) @@ -34,26 +29,15 @@ endif() ############################################################################### # Product information ############################################################################### -if(CMAKE_VERSION VERSION_LESS 3.0) - project(microcdr C) - set(PROJECT_VERSION_MAJOR 1) - set(PROJECT_VERSION_MINOR 0) - set(PROJECT_VERSION_PATCH 1) - set(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) -else() - cmake_policy(SET CMP0048 NEW) - project(microcdr VERSION "1.0.1" LANGUAGES C) -endif() +cmake_policy(SET CMP0048 NEW) +project(microcdr VERSION "1.1.0" LANGUAGES C) ############################################################################### -# eProsima build options +# Build options ############################################################################### -option(EPROSIMA_BUILD "Activate internal building" OFF) -option(EPROSIMA_BUILD_TESTS "Activate the building of tests" OFF) - -if(EPROSIMA_BUILD) - set(EPROSIMA_BUILD_TESTS ON) -endif() +option(UCDR_BUILD_TESTS "Build tests" OFF) +option(UCDR_BUILD_EXAMPLES "Build examples" OFF) +option(BUILD_SHARED_LIBS "Control shared/static library building." OFF) ############################################################################### # Check MSVC architecture @@ -66,7 +50,6 @@ endif() ############################################################################### # Targets ############################################################################### - # Library add_library(${PROJECT_NAME} src/c/common.c @@ -76,13 +59,40 @@ add_library(${PROJECT_NAME} src/c/types/sequence.c ) +# Set common properties set_common_compile_options(${PROJECT_NAME}) set_target_properties(${PROJECT_NAME} PROPERTIES - VERSION ${PROJECT_VERSION} - C_STANDARD 99 - C_STANDARD_REQUIRED YES + VERSION + ${PROJECT_VERSION} + C_STANDARD + 99 + C_STANDARD_REQUIRED + YES ) +target_compile_options(${PROJECT_NAME} + PRIVATE + $<$:-fdata-sections -ffunction-sections> + ) + +# Set Windows shared libraries name +get_target_property(UCDR_TARGET_TYPE ${PROJECT_NAME} TYPE) +if((CMAKE_SYSTEM_NAME STREQUAL "Windows") AND (UCDR_TARGET_TYPE STREQUAL "SHARED_LIBRARY")) + set_target_properties(${PROJECT_NAME} PROPERTIES + RELEASE_POSTFIX + -${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + RELWITHDEBINFO_POSTFIX + -${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + DEBUG_POSTFIX + d-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + ) + + target_compile_definitions(${PROJECT_NAME} + PUBLIC + ${PROJECT_NAME}_SHARED + ) +endif() + # Define public headers target_include_directories(${PROJECT_NAME} PUBLIC @@ -94,12 +104,12 @@ target_include_directories(${PROJECT_NAME} ############################################################################### # Config ############################################################################### - # Install path -set(BIN_INSTALL_DIR bin/ CACHE PATH "Installation directory for binaries") -set(INCLUDE_INSTALL_DIR include/ CACHE PATH "Installation directory for C headers") -set(LIB_INSTALL_DIR lib/ CACHE PATH "Installation directory for libraries") -set(DATA_INSTALL_DIR share/ CACHE PATH "Installation directory for data") +include(GNUInstallDirs) +set(BIN_INSTALL_DIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Installation directory for binaries") +set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Installation directory for C headers") +set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Installation directory for libraries") +set(DATA_INSTALL_DIR ${CMAKE_INSTALL_DATADIR} CACHE PATH "Installation directory for data") if(WIN32) set(LICENSE_INSTALL_DIR . CACHE PATH "Installation directory for licenses") else() @@ -109,9 +119,9 @@ endif() # Config.h set(CONFIG_BIG_ENDIANNESS OFF CACHE BOOL "Set the machine endianness to big endianness (by default is little endianness)") if(CONFIG_BIG_ENDIANNESS) - set(CONFIG_MACHINE_ENDIANNESS 0) #big + set(CONFIG_MACHINE_ENDIANNESS UCDR_BIG_ENDIANNESS) #big else() - set(CONFIG_MACHINE_ENDIANNESS 1) #little + set(CONFIG_MACHINE_ENDIANNESS UCDR_LITTLE_ENDIANNESS) #little endif() configure_file(${PROJECT_SOURCE_DIR}/include/ucdr/config.h.in @@ -119,22 +129,17 @@ configure_file(${PROJECT_SOURCE_DIR}/include/ucdr/config.h.in ) ############################################################################### -# Compile settings +# Examples ############################################################################### - -# Definitions -get_target_property(TARGET_TYPE ${PROJECT_NAME} TYPE) -if((MSVC OR MSVC_IDE) AND (TARGET_TYPE STREQUAL "SHARED_LIBRARY")) - target_compile_definitions(${PROJECT_NAME} - PUBLIC - -D${PROJECT_NAME}_SHARED - ) +if(UCDR_BUILD_EXAMPLES) + add_subdirectory(examples/basic) + add_subdirectory(examples/fragmentation) endif() ############################################################################### # Testing ############################################################################### -if(EPROSIMA_BUILD_TESTS AND IS_TOP_LEVEL) +if(UCDR_BUILD_TESTS) include(${PROJECT_SOURCE_DIR}/cmake/common/gtest.cmake) enable_testing() add_subdirectory(test) @@ -143,39 +148,75 @@ endif() ############################################################################### # Packaging ############################################################################### - # Install library -install(TARGETS ${PROJECT_NAME} - EXPORT ${PROJECT_NAME}Targets - ARCHIVE DESTINATION ${LIB_INSTALL_DIR} - LIBRARY DESTINATION ${LIB_INSTALL_DIR} - RUNTIME DESTINATION ${BIN_INSTALL_DIR} - COMPONENT libraries +install( + TARGETS + ${PROJECT_NAME} + EXPORT + ${PROJECT_NAME}Targets + ARCHIVE DESTINATION + ${LIB_INSTALL_DIR} + LIBRARY DESTINATION + ${LIB_INSTALL_DIR} + RUNTIME DESTINATION + ${BIN_INSTALL_DIR} + COMPONENT + libraries ) # Install includes -install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ucdr/ - DESTINATION ${INCLUDE_INSTALL_DIR}/ucdr - FILES_MATCHING PATTERN "*.h" +install( + DIRECTORY + ${PROJECT_SOURCE_DIR}/include/ucdr/ + DESTINATION + ${INCLUDE_INSTALL_DIR}/ucdr + FILES_MATCHING + PATTERN "*.h" ) # Install config.h -install(FILES ${PROJECT_BINARY_DIR}/include/ucdr/config.h - DESTINATION ${INCLUDE_INSTALL_DIR}/ucdr +install( + FILES + ${PROJECT_BINARY_DIR}/include/ucdr/config.h + DESTINATION + ${INCLUDE_INSTALL_DIR}/ucdr ) # Export library -install(EXPORT ${PROJECT_NAME}Targets - DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}/cmake +install( + EXPORT + ${PROJECT_NAME}Targets + DESTINATION + ${DATA_INSTALL_DIR}/${PROJECT_NAME}/cmake ) # Package configuration include(CMakePackageConfigHelpers) -configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/packaging/Config.cmake.in - ${PROJECT_BINARY_DIR}/cmake/config/${PROJECT_NAME}Config.cmake - INSTALL_DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}/cmake - PATH_VARS BIN_INSTALL_DIR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR DATA_INSTALL_DIR + +configure_package_config_file( + ${PROJECT_SOURCE_DIR}/cmake/packaging/Config.cmake.in + ${PROJECT_BINARY_DIR}/cmake/config/${PROJECT_NAME}Config.cmake + INSTALL_DESTINATION + ${DATA_INSTALL_DIR}/${PROJECT_NAME}/cmake + PATH_VARS + BIN_INSTALL_DIR + INCLUDE_INSTALL_DIR + LIB_INSTALL_DIR + DATA_INSTALL_DIR ) -install(FILES ${PROJECT_BINARY_DIR}/cmake/config/${PROJECT_NAME}Config.cmake - DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}/cmake + +write_basic_package_version_file( + ${PROJECT_BINARY_DIR}/cmake/config/${PROJECT_NAME}ConfigVersion.cmake + VERSION + ${PROJECT_VERSION} + COMPATIBILITY + SameMajorVersion + ) + +install( + FILES + ${PROJECT_BINARY_DIR}/cmake/config/${PROJECT_NAME}Config.cmake + ${PROJECT_BINARY_DIR}/cmake/config/${PROJECT_NAME}ConfigVersion.cmake + DESTINATION + ${DATA_INSTALL_DIR}/${PROJECT_NAME}/cmake ) diff --git a/README.md b/README.md index 0ed0f80..78634be 100644 --- a/README.md +++ b/README.md @@ -54,11 +54,11 @@ As *MicroCDR* uses a static buffer, that means the user has to provide a defined ## API functions ```c -void ucdr_init_buffer (ucdrBuffer* mb, uint8_t* data, const uint32_t size); -void ucdr_init_buffer_offset (ucdrBuffer* mb, uint8_t* data, const uint32_t size, uint32_t offset); +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*. -- `mb`: the `ucdrBuffer` struct +- `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. @@ -67,99 +67,99 @@ Initially, the serialization/deserialization starts at the beginning of the buff --- ```c -void ucdr_copy_buffer (ucdrBuffer* mb_dest, const ucdrBuffer* mb_source); +void ucdr_copy_buffer (ucdrBuffer* ub_dest, const ucdrBuffer* ub_source); ``` Copy a `ucdrBuffer` structure data to another `ucdrBuffer` structure. -- `mb_dest`: the destination `ucdrBuffer` struct. -- `mb_source`: the origin initialized `ucdrBuffer` struct. +- `ub_dest`: the destination `ucdrBuffer` struct. +- `ub_source`: the origin initialized `ucdrBuffer` struct. --- ```c -void ucdr_reset_buffer (ucdrBuffer* mb); -void ucdr_reset_buffer_offset(ucdrBuffer* mb, const uint32_t offset); +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. -- `mb`: the `ucdrBuffer` struct. +- `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* mb, const uint32_t alignment); +void ucdr_align_to (ucdrBuffer* ub, size_t size); ``` -Align the ucdrBuffer to an `alignment` position. -After call this function, the serialization pointer will be moved only if the current `ucdrBuffer` was not aligment to the passed value. +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. -- `mb`: the `ucdrBuffer` struct -- `alignment`: the alignment value used. +- `ub`: the `ucdrBuffer` struct +- `size`: the target size alignment. --- ```c -uint32_t ucdr_aligment(uint32_t buffer_position, const uint32_t data_size); +size_t ucdr_alignment(size_t buffer_position, size_t data_size); ``` -Returns the aligment necessary to serialize/deserialize a type with `data_size` 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 `mb->iterator - mb->init`). +- `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 -uint32_t ucdr_buffer_alignment(const ucdrBuffer* mb, const uint32_t data_size); +size_t ucdr_buffer_alignment(const ucdrBuffer* ub, size_t data_size); ``` -Returns the aligment necessary to serialize/deserialize a type with `data_size` size into the `ucdrBuffer` given. +Returns the alignment necessary to serialize/deserialize a type with `data_size` size into the `ucdrBuffer` given. -- `mb`: the `ucdrBuffer` struct to ask the alignment. +- `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* mb); +size_t ucdr_buffer_size(const ucdrBuffer* ub); ``` Returns the memory size of the buffer. -- `mb`: the `ucdrBuffer` struct +- `ub`: the `ucdrBuffer` struct --- ```c -size_t ucdr_buffer_length(const ucdrBuffer* mb); +size_t ucdr_buffer_length(const ucdrBuffer* ub); ``` Returns the size of the serialized/deserialized data. -- `mb`: the `ucdrBuffer` struct +- `ub`: the `ucdrBuffer` struct --- ```c -size_t ucdr_buffer_remaining(const ucdrBuffer* mb); +size_t ucdr_buffer_remaining(const ucdrBuffer* ub); ``` Returns the remaining size for the serializing/deserializing. -- `mb`: the `ucdrBuffer` struct +- `ub`: the `ucdrBuffer` struct --- ```c -ucdrEndianness ucdr_buffer_endianness(const ucdrBuffer* mb); +ucdrEndianness ucdr_buffer_endianness(const ucdrBuffer* ub); ``` Returns the serialization/deserialization endianness. -- `mb`: the `ucdrBuffer` struct +- `ub`: the `ucdrBuffer` struct --- ```c -bool ucdr_buffer_error(const ucdrBuffer* mb); +bool ucdr_buffer_error(const ucdrBuffer* ub); ``` Returns the status error of the `ucdrBuffer`. -- `mb`: the `ucdrBuffer` struct - +- `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. @@ -184,7 +184,6 @@ After the application of the wrong serialization/deserialization, only the `ucdr ## Serialization/deserialization list The available modes of serialization/deserializations in *MicroCDR* are shown in the following table. - | Type | Endianness | | -------------------- | ---------- | | bool | | @@ -254,3 +253,29 @@ The available modes of serialization/deserializations in *MicroCDR* are shown in | 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). + diff --git a/cmake/common/check_configuration.cmake b/cmake/common/check_configuration.cmake index 0dbf31f..7d98e97 100644 --- a/cmake/common/check_configuration.cmake +++ b/cmake/common/check_configuration.cmake @@ -128,8 +128,8 @@ function(set_common_compile_options target) $<$:-Woverloaded-virtual> -Wconversion -Wsign-conversion - -Wlogical-op - $<$:-Wuseless-cast> + $<$:-Wlogical-op> + $<$,$>:-Wuseless-cast> -Wdouble-promotion $<$:-Wold-style-cast> $<$,$,6.0.0>>>,$,$,6.0.0>>>>:-Wnull-dereference> diff --git a/cmake/common/eprosima_libraries.cmake b/cmake/common/eprosima_libraries.cmake index d326e81..108b70d 100644 --- a/cmake/common/eprosima_libraries.cmake +++ b/cmake/common/eprosima_libraries.cmake @@ -55,7 +55,11 @@ macro(eprosima_find_package package) foreach(opt_ ${FIND_OPTIONS}) set(${opt_} ON) endforeach() + # Keep temp value in order to avoid call packages' installer. + set(EPROSIMA_INSTALLER_TEMP ${EPROSIMA_INSTALLER}) + unset(EPROSIMA_INSTALLER CACHE) add_subdirectory(${PROJECT_SOURCE_DIR}/thirdparty/${package}) + set(EPROSIMA_INSTALLER ${EPROSIMA_INSTALLER_TEMP}) set(${package}_FOUND TRUE) if(NOT IS_TOP_LEVEL) set(${package}_FOUND TRUE PARENT_SCOPE) @@ -78,7 +82,9 @@ macro(eprosima_find_thirdparty package thirdparty_name) option(THIRDPARTY_${package} "Activate the use of internal thirdparty ${package}" OFF) - if(THIRDPARTY OR THIRDPARTY_${package}) + find_package(${package} QUIET) + + if(NOT ${package}_FOUND AND (THIRDPARTY OR THIRDPARTY_${package})) execute_process( COMMAND git submodule update --recursive --init "thirdparty/${thirdparty_name}" WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} @@ -86,14 +92,13 @@ macro(eprosima_find_thirdparty package thirdparty_name) ) if(EXECUTE_RESULT EQUAL 0) + set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${PROJECT_SOURCE_DIR}/thirdparty/${thirdparty_name}) + set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${PROJECT_SOURCE_DIR}/thirdparty/${thirdparty_name}/${thirdparty_name}) + find_package(${package} REQUIRED) else() message(FATAL_ERROR "Cannot configure Git submodule ${package}") endif() - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${PROJECT_SOURCE_DIR}/thirdparty/${thirdparty_name}) - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${PROJECT_SOURCE_DIR}/thirdparty/${thirdparty_name}/${thirdparty_name}) endif() - find_package(${package} REQUIRED QUIET) - endif() endmacro() diff --git a/cmake/common/gtest.cmake b/cmake/common/gtest.cmake index 9afe5f7..b8b8fa1 100644 --- a/cmake/common/gtest.cmake +++ b/cmake/common/gtest.cmake @@ -98,19 +98,48 @@ macro(add_gtest test) foreach(GTEST_SOURCE_FILE ${GTEST_SOURCES}) file(STRINGS ${GTEST_SOURCE_FILE} GTEST_NAMES REGEX ^TEST) + + # Search for google value-parameterized tests instantiations + unset(GTEST_INSTANTATIONS) # list of instantiations names + file(STRINGS ${GTEST_SOURCE_FILE} GTEST_INSTANTIATION_NAMES REGEX ^INSTANTIATE_TEST_CASE_P) + foreach(GTEST_INSTANTIATION_NAME ${GTEST_INSTANTIATION_NAMES}) + # Search and append all instantiation names + string(REGEX REPLACE ["\) \(,"] ";" GTEST_INSTANTIATION_NAME ${GTEST_INSTANTIATION_NAME}) + list(GET GTEST_INSTANTIATION_NAME 1 GTEST_INSTANTIATION_NAME) + list(APPEND GTEST_INSTANTATIONS ${GTEST_INSTANTIATION_NAME}) + endforeach() + foreach(GTEST_NAME ${GTEST_NAMES}) + unset(GTEST_TEMPLATE_TEST) # flag if current test is a value-parametrized one + string(REGEX MATCH ^TEST_P GTEST_TEMPLATE_TEST ${GTEST_NAME}) string(REGEX REPLACE ["\) \(,"] ";" GTEST_NAME ${GTEST_NAME}) + list(GET GTEST_NAME 1 GTEST_GROUP_NAME) list(GET GTEST_NAME 3 GTEST_NAME) - add_test(NAME ${GTEST_GROUP_NAME}.${GTEST_NAME} - COMMAND ${test} - --gtest_filter=${GTEST_GROUP_NAME}.${GTEST_NAME}) + if (GTEST_INSTANTATIONS AND GTEST_TEMPLATE_TEST) + # In case is a value-paremetrized test and there are instantiations generate test calls per instantiation + # Note the /*. This test will execute all the parameters combinations + foreach(GTEST_INSTATATION_NAME ${GTEST_INSTANTATIONS}) + add_test(NAME ${GTEST_INSTATATION_NAME}.${GTEST_GROUP_NAME}.${GTEST_NAME} + COMMAND ${test} + --gtest_filter=${GTEST_INSTATATION_NAME}/${GTEST_GROUP_NAME}.${GTEST_NAME}/*) + # Add environment + if(WIN32) + set_property(TEST ${GTEST_INSTATATION_NAME}.${GTEST_GROUP_NAME}.${GTEST_NAME} APPEND PROPERTY ENVIRONMENT "PATH=${WIN_PATH}") + endif() + endforeach() - # Add environment - if(WIN32) - set_property(TEST ${GTEST_GROUP_NAME}.${GTEST_NAME} APPEND PROPERTY ENVIRONMENT "PATH=${WIN_PATH}") + else() + add_test(NAME ${GTEST_GROUP_NAME}.${GTEST_NAME} + COMMAND ${test} + --gtest_filter=${GTEST_GROUP_NAME}.${GTEST_NAME}) + # Add environment + if(WIN32) + set_property(TEST ${GTEST_GROUP_NAME}.${GTEST_NAME} APPEND PROPERTY ENVIRONMENT "PATH=${WIN_PATH}") + endif() endif() + foreach(property ${GTEST_ENVIRONMENTS}) set_property(TEST ${GTEST_GROUP_NAME}.${GTEST_NAME} APPEND PROPERTY ENVIRONMENT "${property}") endforeach() diff --git a/examples/basic/CMakeLists.txt b/examples/basic/CMakeLists.txt new file mode 100644 index 0000000..6605cce --- /dev/null +++ b/examples/basic/CMakeLists.txt @@ -0,0 +1,23 @@ +project(basic_example) + +add_executable(${PROJECT_NAME} basic.c) +if(MSVC OR MSVC_IDE) + target_compile_options(${PROJECT_NAME} PRIVATE /wd4996) +endif() + +set_target_properties(${PROJECT_NAME} PROPERTIES + C_STANDARD 99 + C_STANDARD_REQUIRED YES + ) + +target_link_libraries(${PROJECT_NAME} microcdr) + +install(TARGETS ${PROJECT_NAME} + RUNTIME DESTINATION examples/ucdr/${PROJECT_NAME}/${BIN_INSTALL_DIR} + ) + +install(DIRECTORY ${PROJECT_SOURCE_DIR}/ + DESTINATION examples/ucdr/${PROJECT_NAME} + FILES_MATCHING PATTERN "*.h" + PATTERN "*.c" + ) diff --git a/examples/basic.c b/examples/basic/basic.c similarity index 100% rename from examples/basic.c rename to examples/basic/basic.c diff --git a/examples/fragmentation/CMakeLists.txt b/examples/fragmentation/CMakeLists.txt new file mode 100644 index 0000000..7ff177e --- /dev/null +++ b/examples/fragmentation/CMakeLists.txt @@ -0,0 +1,23 @@ +project(fragmentation_example) + +add_executable(${PROJECT_NAME} fragmentation.c) +if(MSVC OR MSVC_IDE) + target_compile_options(${PROJECT_NAME} PRIVATE /wd4996) +endif() + +set_target_properties(${PROJECT_NAME} PROPERTIES + C_STANDARD 99 + C_STANDARD_REQUIRED YES + ) + +target_link_libraries(${PROJECT_NAME} microcdr) + +install(TARGETS ${PROJECT_NAME} + RUNTIME DESTINATION examples/ucdr/${PROJECT_NAME}/${BIN_INSTALL_DIR} + ) + +install(DIRECTORY ${PROJECT_SOURCE_DIR}/ + DESTINATION examples/ucdr/${PROJECT_NAME} + FILES_MATCHING PATTERN "*.h" + PATTERN "*.c" + ) diff --git a/examples/fragmentation/fragmentation.c b/examples/fragmentation/fragmentation.c new file mode 100644 index 0000000..3db3252 --- /dev/null +++ b/examples/fragmentation/fragmentation.c @@ -0,0 +1,83 @@ +// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include + +#define BUFFER_LENGTH 12 +#define SLOTS 12 +#define STRING_MAX 128 + +bool on_full_buffer(ucdrBuffer* ub, void* args) +{ + uint8_t* buffer = (uint8_t*) args; + + // This value correspong with the ub->error, and will be returned by this function to indicates + // if the serialization must continue or must stop because of an error. + bool error = true; + + // Leave the odd slots empty. + uint32_t next_slot = 2 + (uint32_t)(ub->init - buffer) / BUFFER_LENGTH; + if(next_slot < SLOTS) + { + // Modify the internal buffer + ub->init = buffer + BUFFER_LENGTH * next_slot; + ub->iterator = ub->init; + ub->final = ub->init + BUFFER_LENGTH; + + printf(" Extend buffer to slot %u\n", next_slot); + + // As we want to continue the serialization without errors, we return false. + error = false; + } + + return error; +} + +int main() +{ + // Data buffer + uint8_t buffer[SLOTS * 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); + + // Add a full buffer behavior to the writer and the reader + ucdr_set_on_full_buffer_callback(&writer, on_full_buffer, buffer); + ucdr_set_on_full_buffer_callback(&reader, on_full_buffer, buffer); + + // Serialize data + printf("Serializing...\n"); + char input[STRING_MAX] = "Hello MicroCDR! this message is fragmented"; + ucdr_serialize_string(&writer, input); + printf("\n"); + + // Deserialize data + printf("Deserializing...\n"); + char output[STRING_MAX]; + ucdr_deserialize_string(&reader, output, STRING_MAX); + printf("\n"); + + printf("Input: %s\n", input); + printf("Output: %s\n", output); + + return 0; +} diff --git a/include/ucdr/common.h b/include/ucdr/common.h deleted file mode 100644 index 1af8534..0000000 --- a/include/ucdr/common.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef _MICROCDR_COMMON_H_ -#define _MICROCDR_COMMON_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#include -#include -#include - -typedef enum ucdrEndianness { - UCDR_BIG_ENDIANNESS = 0, - UCDR_LITTLE_ENDIANNESS = 1 - -} ucdrEndianness; - -typedef struct ucdrBuffer -{ - uint8_t *init; - uint8_t *final; - uint8_t *iterator; - - ucdrEndianness endianness; - uint32_t last_data_size; - - bool error; - -} ucdrBuffer; - -// ------------------------------------------------ -// Main library functions -// ------------------------------------------------ -UCDRDLLAPI void ucdr_init_buffer (ucdrBuffer* mb, uint8_t* data, const uint32_t size); -UCDRDLLAPI void ucdr_init_buffer_offset (ucdrBuffer* mb, uint8_t* data, const uint32_t size, uint32_t offset); -UCDRDLLAPI void ucdr_init_buffer_offset_endian (ucdrBuffer* mb, uint8_t* data, const uint32_t size, uint32_t offset, ucdrEndianness endianness); -UCDRDLLAPI void ucdr_copy_buffer (ucdrBuffer* mb_dest, const ucdrBuffer* mb_source); - -UCDRDLLAPI void ucdr_reset_buffer (ucdrBuffer* mb); -UCDRDLLAPI void ucdr_reset_buffer_offset (ucdrBuffer* mb, const uint32_t offset); - -UCDRDLLAPI void ucdr_align_to (ucdrBuffer* mb, const uint32_t alignment); -UCDRDLLAPI uint32_t ucdr_alignment (uint32_t buffer_position, const uint32_t data_size); -UCDRDLLAPI uint32_t ucdr_buffer_alignment(const ucdrBuffer* mb, const uint32_t data_size); - -UCDRDLLAPI size_t ucdr_buffer_size (const ucdrBuffer* mb); -UCDRDLLAPI size_t ucdr_buffer_length (const ucdrBuffer* mb); -UCDRDLLAPI size_t ucdr_buffer_remaining (const ucdrBuffer* mb); -UCDRDLLAPI ucdrEndianness ucdr_buffer_endianness(const ucdrBuffer* mb); -UCDRDLLAPI bool ucdr_buffer_has_error (const ucdrBuffer* mb); - -#ifdef __cplusplus -} -#endif - -#endif //_MICROCDR_COMMON_H_ diff --git a/include/ucdr/microcdr.h b/include/ucdr/microcdr.h index e79f60f..cd7ab68 100644 --- a/include/ucdr/microcdr.h +++ b/include/ucdr/microcdr.h @@ -19,11 +19,134 @@ extern "C" { #endif -#include -#include -#include -#include -#include +#include +#include + +#include +#include +#include + +// ------------------------------------------------ +// Types +// ------------------------------------------------ + +struct ucdrBuffer; +typedef bool (*OnFullBuffer)(struct ucdrBuffer* buffer, void* args); + +typedef enum ucdrEndianness { + UCDR_BIG_ENDIANNESS = 0, + UCDR_LITTLE_ENDIANNESS = 1 + +} ucdrEndianness; + +typedef struct ucdrBuffer +{ + uint8_t *init; + uint8_t *final; + uint8_t *iterator; + + ucdrEndianness endianness; + uint8_t last_data_size; + + bool error; + + OnFullBuffer on_full_buffer; + void* args; + +} ucdrBuffer; + +// ------------------------------------------------ +// Main functions +// ------------------------------------------------ + +UCDRDLLAPI void ucdr_init_buffer (ucdrBuffer* ub, uint8_t* data, size_t size); +UCDRDLLAPI void ucdr_init_buffer_offset (ucdrBuffer* ub, uint8_t* data, size_t size, size_t offset); +UCDRDLLAPI void ucdr_init_buffer_offset_endian (ucdrBuffer* ub, uint8_t* data, size_t size, size_t offset, ucdrEndianness endianness); +UCDRDLLAPI void ucdr_copy_buffer (ucdrBuffer* ub_dest, const ucdrBuffer* ub_source); +UCDRDLLAPI void ucdr_set_on_full_buffer_callback (ucdrBuffer* ub, OnFullBuffer on_full_buffer, void* args); + +UCDRDLLAPI void ucdr_reset_buffer (ucdrBuffer* ub); +UCDRDLLAPI void ucdr_reset_buffer_offset (ucdrBuffer* ub, size_t offset); + +UCDRDLLAPI void ucdr_align_to (ucdrBuffer* ub, size_t alignment); +UCDRDLLAPI size_t ucdr_alignment (size_t buffer_position, size_t data_size); +UCDRDLLAPI size_t ucdr_buffer_alignment (const ucdrBuffer* ub, size_t data_size); + +UCDRDLLAPI size_t ucdr_buffer_size (const ucdrBuffer* ub); +UCDRDLLAPI size_t ucdr_buffer_length (const ucdrBuffer* ub); +UCDRDLLAPI size_t ucdr_buffer_remaining (const ucdrBuffer* ub); +UCDRDLLAPI ucdrEndianness ucdr_buffer_endianness (const ucdrBuffer* ub); +UCDRDLLAPI bool ucdr_buffer_has_error (const ucdrBuffer* ub); + +// ------------------------------------------------------------------- +// PUBLIC DE-SERIALIZATION DECLARATIONS +// ------------------------------------------------------------------- + +#define UCDR_BASIC_TYPE_DECLARATIONS(SUFFIX, TYPE) \ + UCDRDLLAPI bool ucdr_serialize ## SUFFIX(ucdrBuffer* ub, TYPE value); \ + UCDRDLLAPI bool ucdr_serialize_endian ## SUFFIX(ucdrBuffer* ub, ucdrEndianness endianness, TYPE value); \ + UCDRDLLAPI bool ucdr_deserialize ## SUFFIX(ucdrBuffer* ub, TYPE* value); \ + UCDRDLLAPI bool ucdr_deserialize_endian ## SUFFIX(ucdrBuffer* ub, ucdrEndianness endianness, TYPE* value); \ + +#define UCDR_ARRAY_DECLARATIONS(SUFFIX, TYPE) \ + UCDRDLLAPI bool ucdr_serialize_array ## SUFFIX(ucdrBuffer* ub, const TYPE* array, size_t size); \ + UCDRDLLAPI bool ucdr_serialize_endian_array ## SUFFIX(ucdrBuffer* ub, ucdrEndianness endianness, const TYPE* array, size_t size); \ + UCDRDLLAPI bool ucdr_deserialize_array ## SUFFIX(ucdrBuffer* ub, TYPE* array, size_t size); \ + UCDRDLLAPI bool ucdr_deserialize_endian_array ## SUFFIX(ucdrBuffer* ub, ucdrEndianness endianness, TYPE* array, size_t size); \ + +#define UCDR_SEQUENCE_DECLARATIONS(SUFFIX, TYPE) \ + UCDRDLLAPI bool ucdr_serialize_sequence ## SUFFIX(ucdrBuffer* ub, const TYPE* array, uint32_t length); \ + UCDRDLLAPI bool ucdr_serialize_endian_sequence ## SUFFIX(ucdrBuffer* ub, ucdrEndianness endianness, const TYPE* array, uint32_t length); \ + UCDRDLLAPI bool ucdr_deserialize_sequence ## SUFFIX(ucdrBuffer* ub, TYPE* array, size_t array_capacity, uint32_t* length); \ + UCDRDLLAPI bool ucdr_deserialize_endian_sequence ## SUFFIX(ucdrBuffer* ub, ucdrEndianness endianness, TYPE* array, size_t array_capacity, uint32_t* length); \ + +UCDRDLLAPI bool ucdr_serialize_string(ucdrBuffer* ub, const char* string); +UCDRDLLAPI bool ucdr_serialize_endian_string(ucdrBuffer* ub, ucdrEndianness endianness, const char* string); +UCDRDLLAPI bool ucdr_deserialize_string(ucdrBuffer* ub, char* string, size_t string_capacity); +UCDRDLLAPI bool ucdr_deserialize_endian_string(ucdrBuffer* ub, ucdrEndianness endianness, char* string, size_t string_capacity); + +// ------------------------------------------------------------------- +// VALID TYPES DECLARATIONS +// ------------------------------------------------------------------- + +UCDR_BASIC_TYPE_DECLARATIONS(_char, char) +UCDR_BASIC_TYPE_DECLARATIONS(_bool, bool) +UCDR_BASIC_TYPE_DECLARATIONS(_uint8_t, uint8_t) +UCDR_BASIC_TYPE_DECLARATIONS(_uint16_t, uint16_t) +UCDR_BASIC_TYPE_DECLARATIONS(_uint32_t, uint32_t) +UCDR_BASIC_TYPE_DECLARATIONS(_uint64_t, uint64_t) +UCDR_BASIC_TYPE_DECLARATIONS(_int8_t, int8_t) +UCDR_BASIC_TYPE_DECLARATIONS(_int16_t, int16_t) +UCDR_BASIC_TYPE_DECLARATIONS(_int32_t, int32_t) +UCDR_BASIC_TYPE_DECLARATIONS(_int64_t, int64_t) +UCDR_BASIC_TYPE_DECLARATIONS(_float, float) +UCDR_BASIC_TYPE_DECLARATIONS(_double, double) + +UCDR_ARRAY_DECLARATIONS(_char, char) +UCDR_ARRAY_DECLARATIONS(_bool, bool) +UCDR_ARRAY_DECLARATIONS(_uint8_t, uint8_t) +UCDR_ARRAY_DECLARATIONS(_uint16_t, uint16_t) +UCDR_ARRAY_DECLARATIONS(_uint32_t, uint32_t) +UCDR_ARRAY_DECLARATIONS(_uint64_t, uint64_t) +UCDR_ARRAY_DECLARATIONS(_int8_t, int8_t) +UCDR_ARRAY_DECLARATIONS(_int16_t, int16_t) +UCDR_ARRAY_DECLARATIONS(_int32_t, int32_t) +UCDR_ARRAY_DECLARATIONS(_int64_t, int64_t) +UCDR_ARRAY_DECLARATIONS(_float, float) +UCDR_ARRAY_DECLARATIONS(_double, double) + +UCDR_SEQUENCE_DECLARATIONS(_char, char) +UCDR_SEQUENCE_DECLARATIONS(_bool, bool) +UCDR_SEQUENCE_DECLARATIONS(_uint8_t, uint8_t) +UCDR_SEQUENCE_DECLARATIONS(_uint16_t, uint16_t) +UCDR_SEQUENCE_DECLARATIONS(_uint32_t, uint32_t) +UCDR_SEQUENCE_DECLARATIONS(_uint64_t, uint64_t) +UCDR_SEQUENCE_DECLARATIONS(_int8_t, int8_t) +UCDR_SEQUENCE_DECLARATIONS(_int16_t, int16_t) +UCDR_SEQUENCE_DECLARATIONS(_int32_t, int32_t) +UCDR_SEQUENCE_DECLARATIONS(_int64_t, int64_t) +UCDR_SEQUENCE_DECLARATIONS(_float, float) +UCDR_SEQUENCE_DECLARATIONS(_double, double) #ifdef __cplusplus } diff --git a/include/ucdr/types/array.h b/include/ucdr/types/array.h deleted file mode 100644 index 7fb56bd..0000000 --- a/include/ucdr/types/array.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef _MICROCDR_TYPES_ARRAY_H_ -#define _MICROCDR_TYPES_ARRAY_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -// ------------------------------------------------------------------- -// PUBLIC SERIALIZATION FUNCTIONS -// ------------------------------------------------------------------- - -UCDRDLLAPI bool ucdr_serialize_array_char(ucdrBuffer* mb, const char* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_array_bool(ucdrBuffer* mb, const bool* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_array_uint8_t(ucdrBuffer* mb, const uint8_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_array_uint16_t(ucdrBuffer* mb, const uint16_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_array_uint32_t(ucdrBuffer* mb, const uint32_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_array_uint64_t(ucdrBuffer* mb, const uint64_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_array_int8_t(ucdrBuffer* mb, const int8_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_array_int16_t(ucdrBuffer* mb, const int16_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_array_int32_t(ucdrBuffer* mb, const int32_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_array_int64_t(ucdrBuffer* mb, const int64_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_array_float(ucdrBuffer* mb, const float* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_array_double(ucdrBuffer* mb, const double* array, const uint32_t size); - -UCDRDLLAPI bool ucdr_deserialize_array_char(ucdrBuffer* mb, char* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_array_bool(ucdrBuffer* mb, bool* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_array_uint8_t(ucdrBuffer* mb, uint8_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_array_uint16_t(ucdrBuffer* mb, uint16_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_array_uint32_t(ucdrBuffer* mb, uint32_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_array_uint64_t(ucdrBuffer* mb, uint64_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_array_int8_t(ucdrBuffer* mb, int8_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_array_int16_t(ucdrBuffer* mb, int16_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_array_int32_t(ucdrBuffer* mb, int32_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_array_int64_t(ucdrBuffer* mb, int64_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_array_float(ucdrBuffer* mb, float* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_array_double(ucdrBuffer* mb, double* array, const uint32_t size); - -UCDRDLLAPI bool ucdr_serialize_endian_array_uint16_t(ucdrBuffer* mb, ucdrEndianness endianness, const uint16_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_array_uint32_t(ucdrBuffer* mb, ucdrEndianness endianness, const uint32_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_array_uint64_t(ucdrBuffer* mb, ucdrEndianness endianness, const uint64_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_array_int16_t(ucdrBuffer* mb, ucdrEndianness endianness, const int16_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_array_int32_t(ucdrBuffer* mb, ucdrEndianness endianness, const int32_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_array_int64_t(ucdrBuffer* mb, ucdrEndianness endianness, const int64_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_array_float(ucdrBuffer* mb, ucdrEndianness endianness, const float* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_array_double(ucdrBuffer* mb, ucdrEndianness endianness, const double* array, const uint32_t size); - -UCDRDLLAPI bool ucdr_deserialize_endian_array_uint16_t(ucdrBuffer* mb, ucdrEndianness endianness, uint16_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_endian_array_uint32_t(ucdrBuffer* mb, ucdrEndianness endianness, uint32_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_endian_array_uint64_t(ucdrBuffer* mb, ucdrEndianness endianness, uint64_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_endian_array_int16_t(ucdrBuffer* mb, ucdrEndianness endianness, int16_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_endian_array_int32_t(ucdrBuffer* mb, ucdrEndianness endianness, int32_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_endian_array_int64_t(ucdrBuffer* mb, ucdrEndianness endianness, int64_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_endian_array_float(ucdrBuffer* mb, ucdrEndianness endianness, float* array, const uint32_t size); -UCDRDLLAPI bool ucdr_deserialize_endian_array_double(ucdrBuffer* mb, ucdrEndianness endianness, double* array, const uint32_t size); - -#ifdef __cplusplus -} -#endif - -#endif //_MICROCDR_TYPES_ARRAY_H_ diff --git a/include/ucdr/types/basic.h b/include/ucdr/types/basic.h deleted file mode 100644 index 5e66d46..0000000 --- a/include/ucdr/types/basic.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef _MICROCDR_TYPES_BASIC_H_ -#define _MICROCDR_TYPES_BASIC_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -// ------------------------------------------------------------------- -// PUBLIC SERIALIZATION FUNCTIONS -// ------------------------------------------------------------------- - -UCDRDLLAPI bool ucdr_serialize_char(ucdrBuffer* mb, const char value); -UCDRDLLAPI bool ucdr_serialize_bool(ucdrBuffer* mb, const bool value); -UCDRDLLAPI bool ucdr_serialize_uint8_t(ucdrBuffer* mb, const uint8_t value); -UCDRDLLAPI bool ucdr_serialize_uint16_t(ucdrBuffer* mb, const uint16_t value); -UCDRDLLAPI bool ucdr_serialize_uint32_t(ucdrBuffer* mb, const uint32_t value); -UCDRDLLAPI bool ucdr_serialize_uint64_t(ucdrBuffer* mb, const uint64_t value); -UCDRDLLAPI bool ucdr_serialize_int8_t(ucdrBuffer* mb, const int8_t value); -UCDRDLLAPI bool ucdr_serialize_int16_t(ucdrBuffer* mb, const int16_t value); -UCDRDLLAPI bool ucdr_serialize_int32_t(ucdrBuffer* mb, const int32_t value); -UCDRDLLAPI bool ucdr_serialize_int64_t(ucdrBuffer* mb, const int64_t value); -UCDRDLLAPI bool ucdr_serialize_float(ucdrBuffer* mb, const float value); -UCDRDLLAPI bool ucdr_serialize_double(ucdrBuffer* mb, const double value); - -UCDRDLLAPI bool ucdr_deserialize_char(ucdrBuffer* mb, char* value); -UCDRDLLAPI bool ucdr_deserialize_bool(ucdrBuffer* mb, bool* value); -UCDRDLLAPI bool ucdr_deserialize_uint8_t(ucdrBuffer* mb, uint8_t* value); -UCDRDLLAPI bool ucdr_deserialize_uint16_t(ucdrBuffer* mb, uint16_t* value); -UCDRDLLAPI bool ucdr_deserialize_uint32_t(ucdrBuffer* mb, uint32_t* value); -UCDRDLLAPI bool ucdr_deserialize_uint64_t(ucdrBuffer* mb, uint64_t* value); -UCDRDLLAPI bool ucdr_deserialize_int8_t(ucdrBuffer* mb, int8_t* value); -UCDRDLLAPI bool ucdr_deserialize_int16_t(ucdrBuffer* mb, int16_t* value); -UCDRDLLAPI bool ucdr_deserialize_int32_t(ucdrBuffer* mb, int32_t* value); -UCDRDLLAPI bool ucdr_deserialize_int64_t(ucdrBuffer* mb, int64_t* value); -UCDRDLLAPI bool ucdr_deserialize_float(ucdrBuffer* mb, float* value); -UCDRDLLAPI bool ucdr_deserialize_double(ucdrBuffer* mb, double* value); - -UCDRDLLAPI bool ucdr_serialize_endian_uint16_t(ucdrBuffer* mb, ucdrEndianness endianness, const uint16_t value); -UCDRDLLAPI bool ucdr_serialize_endian_uint32_t(ucdrBuffer* mb, ucdrEndianness endianness, const uint32_t value); -UCDRDLLAPI bool ucdr_serialize_endian_uint64_t(ucdrBuffer* mb, ucdrEndianness endianness, const uint64_t value); -UCDRDLLAPI bool ucdr_serialize_endian_int16_t(ucdrBuffer* mb, ucdrEndianness endianness, const int16_t value); -UCDRDLLAPI bool ucdr_serialize_endian_int32_t(ucdrBuffer* mb, ucdrEndianness endianness, const int32_t value); -UCDRDLLAPI bool ucdr_serialize_endian_int64_t(ucdrBuffer* mb, ucdrEndianness endianness, const int64_t value); -UCDRDLLAPI bool ucdr_serialize_endian_float(ucdrBuffer* mb, ucdrEndianness endianness, const float value); -UCDRDLLAPI bool ucdr_serialize_endian_double(ucdrBuffer* mb, ucdrEndianness endianness, const double value); - -UCDRDLLAPI bool ucdr_deserialize_endian_uint16_t(ucdrBuffer* mb, ucdrEndianness endianness, uint16_t* value); -UCDRDLLAPI bool ucdr_deserialize_endian_uint32_t(ucdrBuffer* mb, ucdrEndianness endianness, uint32_t *value); -UCDRDLLAPI bool ucdr_deserialize_endian_uint64_t(ucdrBuffer* mb, ucdrEndianness endianness, uint64_t* value); -UCDRDLLAPI bool ucdr_deserialize_endian_int16_t(ucdrBuffer* mb, ucdrEndianness endianness, int16_t* value); -UCDRDLLAPI bool ucdr_deserialize_endian_int32_t(ucdrBuffer* mb, ucdrEndianness endianness, int32_t* value); -UCDRDLLAPI bool ucdr_deserialize_endian_int64_t(ucdrBuffer* mb, ucdrEndianness endianness, int64_t* value); -UCDRDLLAPI bool ucdr_deserialize_endian_float(ucdrBuffer* mb, ucdrEndianness endianness, float* value); -UCDRDLLAPI bool ucdr_deserialize_endian_double(ucdrBuffer* mb, ucdrEndianness endianness, double* value); - -#ifdef __cplusplus -} -#endif - -#endif //_MICROCDR_TYPES_BASIC_H_ diff --git a/include/ucdr/types/sequence.h b/include/ucdr/types/sequence.h deleted file mode 100644 index 5c4b109..0000000 --- a/include/ucdr/types/sequence.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef _MICROCDR_TYPES_SEQUENCE_H_ -#define _MICROCDR_TYPES_SEQUENCE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -// ------------------------------------------------------------------- -// PUBLIC SERIALIZATION FUNCTIONS -// ------------------------------------------------------------------- - -UCDRDLLAPI bool ucdr_serialize_sequence_char(ucdrBuffer* mb, const char* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_sequence_bool(ucdrBuffer* mb, const bool* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_sequence_uint8_t(ucdrBuffer* mb, const uint8_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_sequence_uint16_t(ucdrBuffer* mb, const uint16_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_sequence_uint32_t(ucdrBuffer* mb, const uint32_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_sequence_uint64_t(ucdrBuffer* mb, const uint64_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_sequence_int8_t(ucdrBuffer* mb, const int8_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_sequence_int16_t(ucdrBuffer* mb, const int16_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_sequence_int32_t(ucdrBuffer* mb, const int32_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_sequence_int64_t(ucdrBuffer* mb, const int64_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_sequence_float(ucdrBuffer* mb, const float* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_sequence_double(ucdrBuffer* mb, const double* array, const uint32_t size); - -UCDRDLLAPI bool ucdr_deserialize_sequence_char(ucdrBuffer* mb, char* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_sequence_bool(ucdrBuffer* mb, bool* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_sequence_uint8_t(ucdrBuffer* mb, uint8_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_sequence_uint16_t(ucdrBuffer* mb, uint16_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_sequence_uint32_t(ucdrBuffer* mb, uint32_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_sequence_uint64_t(ucdrBuffer* mb, uint64_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_sequence_int8_t(ucdrBuffer* mb, int8_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_sequence_int16_t(ucdrBuffer* mb, int16_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_sequence_int32_t(ucdrBuffer* mb, int32_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_sequence_int64_t(ucdrBuffer* mb, int64_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_sequence_float(ucdrBuffer* mb, float* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_sequence_double(ucdrBuffer* mb, double* array, const uint32_t array_capacity, uint32_t* size); - -UCDRDLLAPI bool ucdr_serialize_endian_sequence_char(ucdrBuffer* mb, ucdrEndianness endianness, const char* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_sequence_bool(ucdrBuffer* mb, ucdrEndianness endianness, const bool* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_sequence_uint8_t(ucdrBuffer* mb, ucdrEndianness endianness, const uint8_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_sequence_uint16_t(ucdrBuffer* mb, ucdrEndianness endianness, const uint16_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_sequence_uint32_t(ucdrBuffer* mb, ucdrEndianness endianness, const uint32_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_sequence_uint64_t(ucdrBuffer* mb, ucdrEndianness endianness, const uint64_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_sequence_int8_t(ucdrBuffer* mb, ucdrEndianness endianness, const int8_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_sequence_int16_t(ucdrBuffer* mb, ucdrEndianness endianness, const int16_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_sequence_int32_t(ucdrBuffer* mb, ucdrEndianness endianness, const int32_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_sequence_int64_t(ucdrBuffer* mb, ucdrEndianness endianness, const int64_t* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_sequence_float(ucdrBuffer* mb, ucdrEndianness endianness, const float* array, const uint32_t size); -UCDRDLLAPI bool ucdr_serialize_endian_sequence_double(ucdrBuffer* mb, ucdrEndianness endianness, const double* array, const uint32_t size); - -UCDRDLLAPI bool ucdr_deserialize_endian_sequence_char(ucdrBuffer* mb, ucdrEndianness endianness, char* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_endian_sequence_bool(ucdrBuffer* mb, ucdrEndianness endianness, bool* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_endian_sequence_uint8_t(ucdrBuffer* mb, ucdrEndianness endianness, uint8_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_endian_sequence_uint16_t(ucdrBuffer* mb, ucdrEndianness endianness, uint16_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_endian_sequence_uint32_t(ucdrBuffer* mb, ucdrEndianness endianness, uint32_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_endian_sequence_uint64_t(ucdrBuffer* mb, ucdrEndianness endianness, uint64_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_endian_sequence_int8_t(ucdrBuffer* mb, ucdrEndianness endianness, int8_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_endian_sequence_int16_t(ucdrBuffer* mb, ucdrEndianness endianness, int16_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_endian_sequence_int32_t(ucdrBuffer* mb, ucdrEndianness endianness, int32_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_endian_sequence_int64_t(ucdrBuffer* mb, ucdrEndianness endianness, int64_t* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_endian_sequence_float(ucdrBuffer* mb, ucdrEndianness endianness, float* array, const uint32_t array_capacity, uint32_t* size); -UCDRDLLAPI bool ucdr_deserialize_endian_sequence_double(ucdrBuffer* mb, ucdrEndianness endianness, double* array, const uint32_t array_capacity, uint32_t* size); - -#ifdef __cplusplus -} -#endif - -#endif //_MICROCDR_TYPES_SEQUENCE_H_ diff --git a/include/ucdr/types/string.h b/include/ucdr/types/string.h deleted file mode 100644 index b8c714f..0000000 --- a/include/ucdr/types/string.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef _MICROCDR_TYPES_STRING_H_ -#define _MICROCDR_TYPES_STRING_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include - -// ------------------------------------------------------------------- -// PUBLIC SERIALIZATION FUNCTIONS -// ------------------------------------------------------------------- - -UCDRDLLAPI bool ucdr_serialize_string(ucdrBuffer* mb, const char* string); -UCDRDLLAPI bool ucdr_deserialize_string(ucdrBuffer* mb, char* string, const uint32_t string_capacity); - -UCDRDLLAPI bool ucdr_serialize_endian_string(ucdrBuffer* mb, ucdrEndianness endianness, const char* string); -UCDRDLLAPI bool ucdr_deserialize_endian_string(ucdrBuffer* mb, ucdrEndianness endianness, char* string, const uint32_t string_capacity); - -#ifdef __cplusplus -} -#endif - -#endif //_MICROCDR_TYPES_STRING_H_ diff --git a/include/ucdr/dll.h b/include/ucdr/visibility.h similarity index 90% rename from include/ucdr/dll.h rename to include/ucdr/visibility.h index ddcab17..fb5fa6e 100644 --- a/include/ucdr/dll.h +++ b/include/ucdr/visibility.h @@ -13,8 +13,8 @@ // limitations under the License. -#ifndef _MICROCDR_DLL_H_ -#define _MICROCDR_DLL_H_ +#ifndef _MICROCDR_VISIBILITY_H_ +#define _MICROCDR_VISIBILITY_H_ #if defined(_WIN32) #if defined(microcdr_SHARED) @@ -30,4 +30,4 @@ #define UCDRDLLAPI #endif // _WIN32 -#endif // _MICROCDR_DLL_H_ +#endif // _MICROCDR_VISIBILITY_H_ diff --git a/src/c/common.c b/src/c/common.c index 48f1ca1..294e901 100644 --- a/src/c/common.c +++ b/src/c/common.c @@ -12,116 +12,145 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include +#include "common_internal.h" #include +static size_t ucdr_next_remaining_size(ucdrBuffer* ub, size_t bytes, size_t data_size); + // ------------------------------------------------------------------- // INTERNAL UTIL IMPLEMENTATIONS // ------------------------------------------------------------------- -bool ucdr_check_buffer(ucdrBuffer* mb, const uint32_t bytes) + +bool ucdr_check_buffer_available_for(ucdrBuffer* ub, size_t bytes) +{ + return !ub->error && (ub->iterator + bytes <= ub->final); +} + +bool ucdr_check_final_buffer_behavior(ucdrBuffer* ub, size_t data_size) { - if(!mb->error) + if(!ub->error && ub->iterator + data_size > ub->final) { - bool fit = mb->iterator + bytes <= mb->final; - if(!fit) - { - mb->error = true; - } + ub->error = (NULL != ub->on_full_buffer) ? ub->on_full_buffer(ub, ub ->args) : true; } - return !mb->error; + return !ub->error; +} + +size_t ucdr_next_remaining_size(ucdrBuffer* ub, size_t bytes, size_t data_size) +{ + size_t remaining = ucdr_buffer_remaining(ub); + return (ub->iterator + bytes <= ub->final) + ? bytes + : remaining - (remaining % data_size); +} + +size_t ucdr_check_final_buffer_behavior_array(ucdrBuffer* ub, size_t bytes, size_t data_size) +{ + if(!ub->error && ub->iterator + data_size > ub->final && bytes > 0) + { + ub->error = (NULL != ub->on_full_buffer) ? ub->on_full_buffer(ub, ub->args) : true; + } + + return (!ub->error) ? ucdr_next_remaining_size(ub, bytes, data_size) : 0; +} + +void ucdr_set_on_full_buffer_callback(ucdrBuffer* ub, OnFullBuffer on_full_buffer, void* args) +{ + ub->on_full_buffer = on_full_buffer; + ub->args = args; } // ------------------------------------------------------------------- // PUBLIC IMPLEMENTATION // ------------------------------------------------------------------- -void ucdr_init_buffer(ucdrBuffer* mb, uint8_t* data, const uint32_t size) +void ucdr_init_buffer(ucdrBuffer* ub, uint8_t* data, size_t size) { - ucdr_init_buffer_offset(mb, data, size, 0U); + ucdr_init_buffer_offset(ub, data, size, 0u); } -void ucdr_init_buffer_offset(ucdrBuffer* mb, uint8_t* data, const uint32_t size, uint32_t offset) +void ucdr_init_buffer_offset(ucdrBuffer* ub, uint8_t* data, size_t size, size_t offset) { - ucdr_init_buffer_offset_endian(mb, data, size, offset, UCDR_MACHINE_ENDIANNESS); + ucdr_init_buffer_offset_endian(ub, data, size, offset, UCDR_MACHINE_ENDIANNESS); } -void ucdr_init_buffer_offset_endian(ucdrBuffer* mb, uint8_t* data, const uint32_t size, uint32_t offset, ucdrEndianness endianness) +void ucdr_init_buffer_offset_endian(ucdrBuffer* ub, uint8_t* data, size_t size, size_t offset, ucdrEndianness endianness) { - mb->init = data; - mb->final = mb->init + size; - mb->iterator = mb->init + offset; - mb->last_data_size = 0U; - mb->endianness = endianness; - mb->error = false; + ub->init = data; + ub->final = ub->init + size; + ub->iterator = ub->init + offset; + ub->last_data_size = 0u; + ub->endianness = endianness; + ub->error = false; + ub->on_full_buffer = NULL; + ub->args = NULL; } -void ucdr_copy_buffer(ucdrBuffer* mb_dest, const ucdrBuffer* mb_source) +void ucdr_copy_buffer(ucdrBuffer* ub_dest, const ucdrBuffer* ub_source) { - memcpy(mb_dest, mb_source, sizeof(ucdrBuffer)); + memcpy(ub_dest, ub_source, sizeof(ucdrBuffer)); } -void ucdr_reset_buffer(ucdrBuffer* mb) +void ucdr_reset_buffer(ucdrBuffer* ub) { - ucdr_reset_buffer_offset(mb, 0U); + ucdr_reset_buffer_offset(ub, 0u); } -void ucdr_reset_buffer_offset(ucdrBuffer* mb, const uint32_t offset) +void ucdr_reset_buffer_offset(ucdrBuffer* ub, size_t offset) { - mb->iterator = mb->init + offset; - mb->last_data_size = 0U; - mb->error = false; + ub->iterator = ub->init + offset; + ub->last_data_size = 0u; + ub->error = false; } -void ucdr_align_to(ucdrBuffer* mb, const uint32_t size) +void ucdr_align_to(ucdrBuffer* ub, size_t size) { - uint32_t offset = ucdr_buffer_alignment(mb, size); - mb->iterator += offset; - if(mb->iterator > mb->final) + ub->iterator += ucdr_buffer_alignment(ub, size); + if(ub->iterator > ub->final) { - mb->iterator = mb->final; + ub->iterator = ub->final; } - mb->last_data_size = size; + ub->last_data_size = (uint8_t)size; } -uint32_t ucdr_alignment(uint32_t current_alignment, const uint32_t data_size) +size_t ucdr_alignment(size_t current_alignment, size_t data_size) { return ((data_size - (current_alignment % data_size)) & (data_size - 1)); } -uint32_t ucdr_buffer_alignment(const ucdrBuffer* mb, const uint32_t data_size) +size_t ucdr_buffer_alignment(const ucdrBuffer* ub, size_t data_size) { - if(data_size > mb->last_data_size) + if(data_size > ub->last_data_size) { - return (data_size - ((uint32_t)(mb->iterator - mb->init) % data_size)) & (data_size - 1); + return (data_size - ((uint32_t)(ub->iterator - ub->init) % data_size)) & (data_size - 1); } return 0; } -size_t ucdr_buffer_size(const ucdrBuffer* mb) +size_t ucdr_buffer_size(const ucdrBuffer* ub) { - return (size_t)(mb->final - mb->init); + return (size_t)(ub->final - ub->init); } -size_t ucdr_buffer_length(const ucdrBuffer* mb) +size_t ucdr_buffer_length(const ucdrBuffer* ub) { - return (size_t)(mb->iterator - mb->init); + return (size_t)(ub->iterator - ub->init); } -size_t ucdr_buffer_remaining(const ucdrBuffer* mb) +size_t ucdr_buffer_remaining(const ucdrBuffer* ub) { - return (size_t)(mb->final - mb->iterator); + return (size_t)(ub->final - ub->iterator); } -ucdrEndianness ucdr_buffer_endianness(const ucdrBuffer* mb) +ucdrEndianness ucdr_buffer_endianness(const ucdrBuffer* ub) { - return mb->endianness; + return ub->endianness; } -bool ucdr_buffer_has_error(const ucdrBuffer* mb) +bool ucdr_buffer_has_error(const ucdrBuffer* ub) { - return mb->error; + return ub->error; } diff --git a/src/c/common_internals.h b/src/c/common_internal.h similarity index 70% rename from src/c/common_internals.h rename to src/c/common_internal.h index 70a6acc..bad7c0b 100644 --- a/src/c/common_internals.h +++ b/src/c/common_internal.h @@ -12,22 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef _SRC_COMMON_INTERNALS_H_ -#define _SRC_COMMON_INTERNALS_H_ +#ifndef _SRC_COMMON_INTERNAL_H_ +#define _SRC_COMMON_INTERNAL_H_ #ifdef __cplusplus extern "C" { #endif -#include +#include // ------------------------------------------------------------------- // INTERNAL UTIL FUNCTIONS // ------------------------------------------------------------------- -bool ucdr_check_buffer(ucdrBuffer* mb, const uint32_t bytes); +bool ucdr_check_buffer_available_for(ucdrBuffer* ub, size_t bytes); +bool ucdr_check_final_buffer_behavior(ucdrBuffer* ub, size_t bytes); +size_t ucdr_check_final_buffer_behavior_array(ucdrBuffer* ub, size_t bytes, size_t data_size); #ifdef __cplusplus } #endif -#endif //_SRC_COMMON_INTERNALS_H_ +#endif //_SRC_COMMON_INTERNAL_H_ diff --git a/src/c/types/array.c b/src/c/types/array.c index ea8dd43..5e5dde7 100644 --- a/src/c/types/array.c +++ b/src/c/types/array.c @@ -12,407 +12,148 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include - -#include "../common_internals.h" -#include "array_internals.h" -#include "basic_internals.h" +#include "../common_internal.h" #include +static void ucdr_array_to_buffer(ucdrBuffer* ub, const uint8_t* array, size_t size, size_t data_size); +static void ucdr_buffer_to_array(ucdrBuffer* ub, uint8_t* array, size_t size, size_t data_size); + // ------------------------------------------------------------------- -// INTERNAL SERIALIZATION IMPLEMENTATION +// SERIALIZE MACROS // ------------------------------------------------------------------- - -bool ucdr_serialize_array_byte_1(ucdrBuffer* mb, const uint8_t* array, const uint32_t size) +void ucdr_array_to_buffer(ucdrBuffer* ub, const uint8_t* array, size_t size, size_t data_size) { - uint32_t data_size = sizeof(uint8_t); - if(ucdr_check_buffer(mb, size)) + if(ucdr_check_buffer_available_for(ub, size)) { - memcpy(mb->iterator, array, size); - - mb->iterator += size; - mb->last_data_size = data_size; + memcpy(ub->iterator, array, size); + ub->iterator += size; } - return !mb->error; -} - -bool ucdr_serialize_array_byte_2(ucdrBuffer* mb, const ucdrEndianness endianness, const uint16_t* array, const uint32_t size) -{ - uint32_t data_size = sizeof(uint16_t); - uint32_t array_size = size * data_size; - uint32_t alignment = ucdr_buffer_alignment(mb, sizeof(uint16_t)); - - if(ucdr_check_buffer(mb, alignment + array_size)) + else { - mb->iterator += alignment; - if(UCDR_MACHINE_ENDIANNESS == endianness) - { - memcpy(mb->iterator, array, array_size); - - mb->iterator += array_size; - mb->last_data_size = data_size; - } - else + size_t remaining_size = size; + size_t serialization_size; + while(0 < (serialization_size = ucdr_check_final_buffer_behavior_array(ub, remaining_size, data_size))) { - for(uint32_t i = 0; i < size; i++) - { - ucdr_serialize_byte_2(mb, endianness, array + i); - } + memcpy(ub->iterator, array + (size - remaining_size), serialization_size); + remaining_size -= serialization_size; + ub->iterator += serialization_size; } } - return !mb->error; + ub->last_data_size = (uint8_t)data_size; } -bool ucdr_serialize_array_byte_4(ucdrBuffer* mb, const ucdrEndianness endianness, const uint32_t* array, const uint32_t size) +void ucdr_buffer_to_array(ucdrBuffer* ub, uint8_t* array, size_t size, size_t data_size) { - uint32_t data_size = sizeof(uint32_t); - uint32_t array_size = size * data_size; - uint32_t alignment = ucdr_buffer_alignment(mb, sizeof(uint32_t)); - - if(ucdr_check_buffer(mb, alignment + array_size)) + if(ucdr_check_buffer_available_for(ub, size)) { - mb->iterator += alignment; - - if(UCDR_MACHINE_ENDIANNESS == endianness) - { - memcpy(mb->iterator, array, array_size); - mb->iterator += array_size; - mb->last_data_size = data_size; - } - else - { - for(uint32_t i = 0; i < size; i++) - { - ucdr_serialize_byte_4(mb, endianness, array + i); - } - } + memcpy(array, ub->iterator, size); + ub->iterator += size; } - return !mb->error; -} - -bool ucdr_serialize_array_byte_8(ucdrBuffer* mb, const ucdrEndianness endianness, const uint64_t* array, const uint32_t size) -{ - uint32_t data_size = sizeof(uint64_t); - uint32_t array_size = size * data_size; - uint32_t alignment = ucdr_buffer_alignment(mb, sizeof(uint64_t)); - - if(ucdr_check_buffer(mb, alignment + array_size)) + else { - mb->iterator += alignment; - - if(UCDR_MACHINE_ENDIANNESS == endianness) - { - memcpy(mb->iterator, array, array_size); - mb->iterator += array_size; - mb->last_data_size = data_size; - } - else + size_t remaining_size = size; + size_t deserialization_size; + while(0 < (deserialization_size = ucdr_check_final_buffer_behavior_array(ub, remaining_size, data_size))) { - for(uint32_t i = 0; i < size; i++) - { - ucdr_serialize_byte_8(mb, endianness, array + i); - } + memcpy(array + (size - remaining_size), ub->iterator, deserialization_size); + remaining_size -= deserialization_size; + ub->iterator += deserialization_size; } } - return !mb->error; -} - -bool ucdr_deserialize_array_byte_1(ucdrBuffer* mb, uint8_t* array, const uint32_t size) -{ - uint32_t data_size = sizeof(uint8_t); - if(ucdr_check_buffer(mb, size)) - { - memcpy(array, mb->iterator, size); - - mb->iterator += size; - mb->last_data_size = data_size; - } - return !mb->error; -} - -bool ucdr_deserialize_array_byte_2(ucdrBuffer* mb, const ucdrEndianness endianness, uint16_t* array, const uint32_t size) -{ - uint32_t data_size = sizeof(uint16_t); - uint32_t array_size = size * data_size; - uint32_t alignment = ucdr_buffer_alignment(mb, sizeof(uint16_t)); + ub->last_data_size = (uint8_t)data_size; +} + +#define UCDR_SERIALIZE_ARRAY_BYTE_1(TYPE, ENDIAN) \ + (void)ENDIAN; \ + ucdr_array_to_buffer(ub, (uint8_t*)array, size, 1); \ + return !ub->error; + +#define UCDR_SERIALIZE_ARRAY_BYTE_N(TYPE, TYPE_SIZE, ENDIAN) \ + ub->iterator += ucdr_buffer_alignment(ub, TYPE_SIZE); \ + if(UCDR_MACHINE_ENDIANNESS == ENDIAN) \ + { \ + ucdr_array_to_buffer(ub, (uint8_t*)array, size * TYPE_SIZE, TYPE_SIZE); \ + } \ + else \ + { \ + for(uint32_t i = 0; i < size; ++i) \ + { \ + ucdr_serialize_endian_ ## TYPE(ub, ENDIAN, *(array + i)); \ + } \ + } \ + return !ub->error; + +#define UCDR_SERIALIZE_ARRAY_BYTE_2(TYPE, ENDIAN) UCDR_SERIALIZE_ARRAY_BYTE_N(TYPE, 2, ENDIAN) +#define UCDR_SERIALIZE_ARRAY_BYTE_4(TYPE, ENDIAN) UCDR_SERIALIZE_ARRAY_BYTE_N(TYPE, 4, ENDIAN) +#define UCDR_SERIALIZE_ARRAY_BYTE_8(TYPE, ENDIAN) UCDR_SERIALIZE_ARRAY_BYTE_N(TYPE, 8, ENDIAN) + +#define UCDR_SERIALIZE_ARRAY_DEFINITION(SUFFIX, TYPE, TYPE_SIZE) \ + bool ucdr_serialize_array ## SUFFIX(ucdrBuffer* ub, const TYPE* array, size_t size) \ + { \ + UCDR_SERIALIZE_ARRAY_BYTE_ ## TYPE_SIZE(TYPE, ub->endianness) \ + } \ + bool ucdr_serialize_endian_array ## SUFFIX(ucdrBuffer* ub, const ucdrEndianness endianness, const TYPE* array, size_t size) \ + { \ + UCDR_SERIALIZE_ARRAY_BYTE_ ## TYPE_SIZE(TYPE, endianness) \ + } \ - if(ucdr_check_buffer(mb, alignment + array_size)) - { - mb->iterator += alignment; - - if(UCDR_MACHINE_ENDIANNESS == endianness) - { - memcpy(array, mb->iterator, array_size); - mb->iterator += array_size; - mb->last_data_size = data_size; - } - else - { - for(uint32_t i = 0; i < size; i++) - { - ucdr_deserialize_byte_2(mb, endianness, array + i); - } - } - } - return !mb->error; -} - -bool ucdr_deserialize_array_byte_4(ucdrBuffer* mb, const ucdrEndianness endianness, uint32_t* array, const uint32_t size) -{ - uint32_t data_size = sizeof(uint32_t); - uint32_t array_size = size * data_size; - uint32_t alignment = ucdr_buffer_alignment(mb, sizeof(uint32_t)); - - if(ucdr_check_buffer(mb, alignment + array_size)) - { - mb->iterator += alignment; - - if(UCDR_MACHINE_ENDIANNESS == endianness) - { - memcpy(array, mb->iterator, array_size); - mb->iterator += array_size; - mb->last_data_size = data_size; - } - else - { - for(uint32_t i = 0; i < size; i++) - { - ucdr_deserialize_byte_4(mb, endianness, array + i); - } - } +// ------------------------------------------------------------------- +// DESERIALIZE MACROS +// ------------------------------------------------------------------- +#define UCDR_DESERIALIZE_ARRAY_BYTE_1(TYPE, ENDIAN) \ + (void)ENDIAN; \ + ucdr_buffer_to_array(ub, (uint8_t*)array, size, 1); \ + return !ub->error; + +#define UCDR_DESERIALIZE_ARRAY_BYTE_N(TYPE, TYPE_SIZE, ENDIAN) \ + ub->iterator += ucdr_buffer_alignment(ub, TYPE_SIZE); \ + if(UCDR_MACHINE_ENDIANNESS == ENDIAN) \ + { \ + ucdr_buffer_to_array(ub, (uint8_t*)array, size * TYPE_SIZE, TYPE_SIZE); \ + } \ + else \ + { \ + for(uint32_t i = 0; i < size; ++i) \ + { \ + ucdr_deserialize_endian_ ## TYPE(ub, ENDIAN, array + i); \ + } \ + } \ + return !ub->error; + +#define UCDR_DESERIALIZE_ARRAY_BYTE_2(TYPE, ENDIAN) UCDR_DESERIALIZE_ARRAY_BYTE_N(TYPE, 2, ENDIAN) +#define UCDR_DESERIALIZE_ARRAY_BYTE_4(TYPE, ENDIAN) UCDR_DESERIALIZE_ARRAY_BYTE_N(TYPE, 4, ENDIAN) +#define UCDR_DESERIALIZE_ARRAY_BYTE_8(TYPE, ENDIAN) UCDR_DESERIALIZE_ARRAY_BYTE_N(TYPE, 8, ENDIAN) + +#define UCDR_DESERIALIZE_ARRAY_DEFINITION(SUFFIX, TYPE, TYPE_SIZE) \ + bool ucdr_deserialize_array ## SUFFIX(ucdrBuffer* ub, TYPE* array, size_t size) \ + { \ + UCDR_DESERIALIZE_ARRAY_BYTE_ ## TYPE_SIZE(TYPE, ub->endianness) \ + } \ + bool ucdr_deserialize_endian_array ## SUFFIX(ucdrBuffer* ub, ucdrEndianness endianness, TYPE* array, size_t size) \ + { \ + UCDR_DESERIALIZE_ARRAY_BYTE_ ## TYPE_SIZE(TYPE, endianness) \ } - return !mb->error; -} -bool ucdr_deserialize_array_byte_8(ucdrBuffer* mb, const ucdrEndianness endianness, uint64_t* array, const uint32_t size) -{ - uint32_t data_size = sizeof(uint64_t); - uint32_t array_size = size * data_size; - uint32_t alignment = ucdr_buffer_alignment(mb, sizeof(uint64_t)); - - if(ucdr_check_buffer(mb, alignment + array_size)) - { - mb->iterator += alignment; - - if(UCDR_MACHINE_ENDIANNESS == endianness) - { - memcpy(array, mb->iterator, array_size); - mb->iterator += array_size; - mb->last_data_size = data_size; - } - else - { - for(uint32_t i = 0; i < size; i++) - { - ucdr_deserialize_byte_8(mb, endianness, array + i); - } - } - } - return !mb->error; -} +// ------------------------------------------------------------------- +// DEFINITION MACRO +// ------------------------------------------------------------------- +#define UCDR_ARRAY_DEFINITIONS(SUFFIX, TYPE, TYPE_SIZE) \ + UCDR_SERIALIZE_ARRAY_DEFINITION(SUFFIX, TYPE, TYPE_SIZE) \ + UCDR_DESERIALIZE_ARRAY_DEFINITION(SUFFIX, TYPE, TYPE_SIZE) \ // ------------------------------------------------------------------- // PUBLIC SERIALIZATION IMPLEMENTATIONS // ------------------------------------------------------------------- - -bool ucdr_serialize_array_char(ucdrBuffer* mb, const char* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_1(mb, (uint8_t*)array, size); -} - -bool ucdr_serialize_array_bool(ucdrBuffer* mb, const bool* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_1(mb, (uint8_t*)array, size); -} - -bool ucdr_serialize_array_uint8_t(ucdrBuffer* mb, const uint8_t* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_1(mb, array, size); -} - -bool ucdr_serialize_array_uint16_t(ucdrBuffer* mb, const uint16_t* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_2(mb, mb->endianness, array, size); -} - -bool ucdr_serialize_array_uint32_t(ucdrBuffer* mb, const uint32_t* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_4(mb, mb->endianness, array, size); -} - -bool ucdr_serialize_array_uint64_t(ucdrBuffer* mb, const uint64_t* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_8(mb, mb->endianness, array, size); -} - -bool ucdr_serialize_array_int8_t(ucdrBuffer* mb, const int8_t* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_1(mb, (uint8_t*)array, size); -} - -bool ucdr_serialize_array_int16_t(ucdrBuffer* mb, const int16_t* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_2(mb, mb->endianness, (uint16_t*)array, size); -} - -bool ucdr_serialize_array_int32_t(ucdrBuffer* mb, const int32_t* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_4(mb, mb->endianness, (uint32_t*)array, size); -} - -bool ucdr_serialize_array_int64_t(ucdrBuffer* mb, const int64_t* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_8(mb, mb->endianness, (uint64_t*)array, size); -} - -bool ucdr_serialize_array_float(ucdrBuffer* mb, const float* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_4(mb, mb->endianness, (uint32_t*)array, size); -} - -bool ucdr_serialize_array_double(ucdrBuffer* mb, const double* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_8(mb, mb->endianness, (uint64_t*)array, size); -} - -bool ucdr_deserialize_array_char(ucdrBuffer* mb, char* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_1(mb, (uint8_t*)array, size); -} - -bool ucdr_deserialize_array_bool(ucdrBuffer* mb, bool* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_1(mb, (uint8_t*)array, size); -} - -bool ucdr_deserialize_array_uint8_t(ucdrBuffer* mb, uint8_t* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_1(mb, array, size); -} - -bool ucdr_deserialize_array_uint16_t(ucdrBuffer* mb, uint16_t* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_2(mb, mb->endianness, array, size); -} - -bool ucdr_deserialize_array_uint32_t(ucdrBuffer* mb, uint32_t* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_4(mb, mb->endianness, array, size); -} - -bool ucdr_deserialize_array_uint64_t(ucdrBuffer* mb, uint64_t* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_8(mb, mb->endianness, array, size); -} - -bool ucdr_deserialize_array_int8_t(ucdrBuffer* mb, int8_t* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_1(mb, (uint8_t*)array, size); -} - -bool ucdr_deserialize_array_int16_t(ucdrBuffer* mb, int16_t* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_2(mb, mb->endianness, (uint16_t*)array, size); -} - -bool ucdr_deserialize_array_int32_t(ucdrBuffer* mb, int32_t* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_4(mb, mb->endianness, (uint32_t*)array, size); -} - -bool ucdr_deserialize_array_int64_t(ucdrBuffer* mb, int64_t* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_8(mb, mb->endianness, (uint64_t*)array, size); -} - -bool ucdr_deserialize_array_float(ucdrBuffer* mb, float* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_4(mb, mb->endianness, (uint32_t*)array, size); -} - -bool ucdr_deserialize_array_double(ucdrBuffer* mb, double* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_8(mb, mb->endianness, (uint64_t*)array, size); -} - -bool ucdr_serialize_endian_array_uint16_t(ucdrBuffer* mb, const ucdrEndianness endianness, const uint16_t* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_2(mb, endianness, array, size); -} - -bool ucdr_serialize_endian_array_uint32_t(ucdrBuffer* mb, const ucdrEndianness endianness, const uint32_t* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_4(mb, endianness, array, size); -} - -bool ucdr_serialize_endian_array_uint64_t(ucdrBuffer* mb, const ucdrEndianness endianness, const uint64_t* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_8(mb, endianness, array, size); -} - -bool ucdr_serialize_endian_array_int16_t(ucdrBuffer* mb, const ucdrEndianness endianness, const int16_t* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_2(mb, endianness, (uint16_t*)array, size); -} - -bool ucdr_serialize_endian_array_int32_t(ucdrBuffer* mb, const ucdrEndianness endianness, const int32_t* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_4(mb, endianness, (uint32_t*)array, size); -} - -bool ucdr_serialize_endian_array_int64_t(ucdrBuffer* mb, const ucdrEndianness endianness, const int64_t* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_8(mb, endianness, (uint64_t*)array, size); -} - -bool ucdr_serialize_endian_array_float(ucdrBuffer* mb, const ucdrEndianness endianness, const float* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_4(mb, endianness, (uint32_t*)array, size); -} - -bool ucdr_serialize_endian_array_double(ucdrBuffer* mb, const ucdrEndianness endianness, const double* array, const uint32_t size) -{ - return ucdr_serialize_array_byte_8(mb, endianness, (uint64_t*)array, size); -} - -bool ucdr_deserialize_endian_array_uint16_t(ucdrBuffer* mb, const ucdrEndianness endianness, uint16_t* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_2(mb, endianness, array, size); -} - -bool ucdr_deserialize_endian_array_uint32_t(ucdrBuffer* mb, const ucdrEndianness endianness, uint32_t* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_4(mb, endianness, array, size); -} - -bool ucdr_deserialize_endian_array_uint64_t(ucdrBuffer* mb, const ucdrEndianness endianness, uint64_t* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_8(mb, endianness, array, size); -} - -bool ucdr_deserialize_endian_array_int16_t(ucdrBuffer* mb, const ucdrEndianness endianness, int16_t* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_2(mb, endianness, (uint16_t*)array, size); -} - -bool ucdr_deserialize_endian_array_int32_t(ucdrBuffer* mb, const ucdrEndianness endianness, int32_t* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_4(mb, endianness, (uint32_t*)array, size); -} - -bool ucdr_deserialize_endian_array_int64_t(ucdrBuffer* mb, const ucdrEndianness endianness, int64_t* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_8(mb, endianness, (uint64_t*)array, size); -} - -bool ucdr_deserialize_endian_array_float(ucdrBuffer* mb, const ucdrEndianness endianness, float* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_4(mb, endianness, (uint32_t*)array, size); -} - -bool ucdr_deserialize_endian_array_double(ucdrBuffer* mb, const ucdrEndianness endianness, double* array, const uint32_t size) -{ - return ucdr_deserialize_array_byte_8(mb, endianness, (uint64_t*)array, size); -} - +UCDR_ARRAY_DEFINITIONS(_char, char, 1) +UCDR_ARRAY_DEFINITIONS(_bool, bool, 1) +UCDR_ARRAY_DEFINITIONS(_uint8_t, uint8_t, 1) +UCDR_ARRAY_DEFINITIONS(_uint16_t, uint16_t, 2) +UCDR_ARRAY_DEFINITIONS(_uint32_t, uint32_t, 4) +UCDR_ARRAY_DEFINITIONS(_uint64_t, uint64_t, 8) +UCDR_ARRAY_DEFINITIONS(_int8_t, int8_t, 1) +UCDR_ARRAY_DEFINITIONS(_int16_t, int16_t, 2) +UCDR_ARRAY_DEFINITIONS(_int32_t, int32_t, 4) +UCDR_ARRAY_DEFINITIONS(_int64_t, int64_t, 8) +UCDR_ARRAY_DEFINITIONS(_float, float, 4) +UCDR_ARRAY_DEFINITIONS(_double, double, 8) diff --git a/src/c/types/array_internals.h b/src/c/types/array_internals.h deleted file mode 100644 index b0b3fc7..0000000 --- a/src/c/types/array_internals.h +++ /dev/null @@ -1,42 +0,0 @@ - -// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef _SRC_TYPES_ARRAY_INTERNALS_H_ -#define _SRC_TYPES_ARRAY_INTERNALS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -// ------------------------------------------------------------------- -// INTERNAL SERIALIZATION FUNCTIONS -// ------------------------------------------------------------------- -bool ucdr_serialize_array_byte_1(ucdrBuffer* buffer, const uint8_t* array, const uint32_t size); -bool ucdr_serialize_array_byte_2(ucdrBuffer* buffer, ucdrEndianness endianness, const uint16_t* array, const uint32_t size); -bool ucdr_serialize_array_byte_4(ucdrBuffer* buffer, ucdrEndianness endianness, const uint32_t* array, const uint32_t size); -bool ucdr_serialize_array_byte_8(ucdrBuffer* buffer, ucdrEndianness endianness, const uint64_t* array, const uint32_t size); - -bool ucdr_deserialize_array_byte_1(ucdrBuffer* buffer, uint8_t* array, const uint32_t size); -bool ucdr_deserialize_array_byte_2(ucdrBuffer* buffer, ucdrEndianness endianness, uint16_t* array, const uint32_t size); -bool ucdr_deserialize_array_byte_4(ucdrBuffer* buffer, ucdrEndianness endianness, uint32_t* array, const uint32_t size); -bool ucdr_deserialize_array_byte_8(ucdrBuffer* buffer, ucdrEndianness endianness, uint64_t* array, const uint32_t size); - -#ifdef __cplusplus -} -#endif - -#endif //_SRC_TYPES_ARRAY_INTERNALS_H_ diff --git a/src/c/types/basic.c b/src/c/types/basic.c index 15db7b4..84db905 100644 --- a/src/c/types/basic.c +++ b/src/c/types/basic.c @@ -12,416 +12,163 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include -#include "../common_internals.h" -#include "basic_internals.h" +#include "../common_internal.h" #include - // ------------------------------------------------------------------- -// INTERNAL SERIALIZATION IMPLEMENTATION +// SERIALIZE MACROS // ------------------------------------------------------------------- - -bool ucdr_serialize_byte_1(ucdrBuffer* mb, const uint8_t* byte) -{ - uint32_t data_size = sizeof(uint8_t); - if(ucdr_check_buffer(mb, data_size)) - { - *mb->iterator = *byte; - - mb->iterator += data_size; - mb->last_data_size = data_size; - } - return !mb->error; -} - -bool ucdr_serialize_byte_2(ucdrBuffer* mb, const ucdrEndianness endianness, const uint16_t* bytes) -{ - uint32_t data_size = sizeof(uint16_t); - uint32_t alignment = ucdr_buffer_alignment(mb, data_size); - - if(ucdr_check_buffer(mb, alignment + data_size)) - { - mb->iterator += alignment; - - if(UCDR_MACHINE_ENDIANNESS == endianness) - { - memcpy(mb->iterator, bytes, data_size); - } - else - { - uint8_t* bytes_pointer = (uint8_t*)bytes; - *mb->iterator = *(bytes_pointer + 1); - *(mb->iterator + 1) = *bytes_pointer; - } - - mb->iterator += data_size; - mb->last_data_size = data_size; - } - return !mb->error; -} - -bool ucdr_serialize_byte_4(ucdrBuffer* mb, const ucdrEndianness endianness, const uint32_t* bytes) -{ - uint32_t data_size = sizeof(uint32_t); - uint32_t alignment = ucdr_buffer_alignment(mb, data_size); - - if(ucdr_check_buffer(mb, alignment + data_size)) - { - mb->iterator += alignment; - - if(UCDR_MACHINE_ENDIANNESS == endianness) - { - memcpy(mb->iterator, bytes, data_size); - } - else - { - uint8_t* bytes_pointer = (uint8_t*)bytes; - *mb->iterator = *(bytes_pointer + 3); - *(mb->iterator + 1) = *(bytes_pointer + 2); - *(mb->iterator + 2) = *(bytes_pointer + 1); - *(mb->iterator + 3) = *bytes_pointer; - } - - mb->iterator += data_size; - mb->last_data_size = data_size; - } - return !mb->error; -} - -bool ucdr_serialize_byte_8(ucdrBuffer* mb, const ucdrEndianness endianness, const uint64_t* bytes) -{ - uint32_t data_size = sizeof(uint64_t); - uint32_t alignment = ucdr_buffer_alignment(mb, data_size); - - if(ucdr_check_buffer(mb, alignment + data_size)) - { - mb->iterator += alignment; - - if(UCDR_MACHINE_ENDIANNESS == endianness) - { - memcpy(mb->iterator, bytes, data_size); - } - else - { - uint8_t* bytes_pointer = (uint8_t*)bytes; - *mb->iterator = *(bytes_pointer + 7); - *(mb->iterator + 1) = *(bytes_pointer + 6); - *(mb->iterator + 2) = *(bytes_pointer + 5); - *(mb->iterator + 3) = *(bytes_pointer + 4); - *(mb->iterator + 4) = *(bytes_pointer + 3); - *(mb->iterator + 5) = *(bytes_pointer + 2); - *(mb->iterator + 6) = *(bytes_pointer + 1); - *(mb->iterator + 7) = *bytes_pointer; - } - - mb->iterator += data_size; - mb->last_data_size = data_size; +#define UCDR_SERIALIZE_BYTE_1(TYPE, ENDIAN) \ + (void)ENDIAN; \ + if(ucdr_check_final_buffer_behavior(ub, 1)) \ + { \ + *ub->iterator = (uint8_t)value; \ + ub->iterator += 1; \ + ub->last_data_size = 1; \ + } \ + return !ub->error; + +#define UCDR_SERIALIZE_BYTE_2_CORE() \ + const uint8_t* bytes_pointer = (uint8_t*)&value; \ + *ub->iterator = *(bytes_pointer + 1); \ + *(ub->iterator + 1) = *bytes_pointer; + +#define UCDR_SERIALIZE_BYTE_4_CORE() \ + const uint8_t* bytes_pointer = (uint8_t*)&value; \ + *ub->iterator = *(bytes_pointer + 3); \ + *(ub->iterator + 1) = *(bytes_pointer + 2); \ + *(ub->iterator + 2) = *(bytes_pointer + 1); \ + *(ub->iterator + 3) = *bytes_pointer; + +#define UCDR_SERIALIZE_BYTE_8_CORE() \ + const uint8_t* bytes_pointer = (uint8_t*)&value; \ + *ub->iterator = *(bytes_pointer + 7); \ + *(ub->iterator + 1) = *(bytes_pointer + 6); \ + *(ub->iterator + 2) = *(bytes_pointer + 5); \ + *(ub->iterator + 3) = *(bytes_pointer + 4); \ + *(ub->iterator + 4) = *(bytes_pointer + 3); \ + *(ub->iterator + 5) = *(bytes_pointer + 2); \ + *(ub->iterator + 6) = *(bytes_pointer + 1); \ + *(ub->iterator + 7) = *bytes_pointer; + +#define UCDR_SERIALIZE_BYTE_N(TYPE, SIZE, ENDIAN) \ + ub->iterator += ucdr_buffer_alignment(ub, SIZE); \ + if(ucdr_check_final_buffer_behavior(ub, SIZE)) \ + { \ + if(UCDR_MACHINE_ENDIANNESS == ENDIAN) \ + { \ + memcpy(ub->iterator, (void*)&value, SIZE); \ + } \ + else \ + { \ + UCDR_SERIALIZE_BYTE_ ## SIZE ## _CORE() \ + } \ + ub->iterator += SIZE; \ + ub->last_data_size = SIZE; \ + } \ + return !ub->error; + +#define UCDR_SERIALIZE_BYTE_2(TYPE, ENDIAN) UCDR_SERIALIZE_BYTE_N(TYPE, 2, ENDIAN) +#define UCDR_SERIALIZE_BYTE_4(TYPE, ENDIAN) UCDR_SERIALIZE_BYTE_N(TYPE, 4, ENDIAN) +#define UCDR_SERIALIZE_BYTE_8(TYPE, ENDIAN) UCDR_SERIALIZE_BYTE_N(TYPE, 8, ENDIAN) + +#define UCDR_BASIC_TYPE_SERIALIZE_DEFINITION(SUFFIX, TYPE, SIZE) \ + bool ucdr_serialize ## SUFFIX(ucdrBuffer* ub, TYPE value) \ + { \ + UCDR_SERIALIZE_BYTE_ ## SIZE(TYPE, ub->endianness) \ + } \ + bool ucdr_serialize_endian ## SUFFIX(ucdrBuffer* ub, ucdrEndianness endianness, TYPE value) \ + { \ + UCDR_SERIALIZE_BYTE_ ## SIZE(TYPE, endianness) \ } - return !mb->error; -} -bool ucdr_deserialize_byte_1(ucdrBuffer* mb, uint8_t* byte) -{ - uint32_t data_size = sizeof(uint8_t); - if(ucdr_check_buffer(mb, data_size)) - { - *byte = *mb->iterator; - - mb->iterator += data_size; - mb->last_data_size = data_size; - } - return !mb->error; -} - -bool ucdr_deserialize_byte_2(ucdrBuffer* mb, const ucdrEndianness endianness, uint16_t* bytes) -{ - uint32_t data_size = sizeof(uint16_t); - uint32_t alignment = ucdr_buffer_alignment(mb, data_size); - - if(ucdr_check_buffer(mb, alignment + data_size)) - { - mb->iterator += alignment; - - if(UCDR_MACHINE_ENDIANNESS == endianness) - { - memcpy(bytes, mb->iterator, data_size); - } - else - { - uint8_t* bytes_pointer = (uint8_t*)bytes; - *bytes_pointer = *(mb->iterator + 1); - *(bytes_pointer + 1) = *mb->iterator ; - } - - mb->iterator += data_size; - mb->last_data_size = data_size; - } - return !mb->error; -} - -bool ucdr_deserialize_byte_4(ucdrBuffer* mb, const ucdrEndianness endianness, uint32_t* bytes) -{ - uint32_t data_size = sizeof(uint32_t); - uint32_t alignment = ucdr_buffer_alignment(mb, data_size); - - if(ucdr_check_buffer(mb, alignment + data_size)) - { - mb->iterator += alignment; - - if(UCDR_MACHINE_ENDIANNESS == endianness) - { - memcpy(bytes, mb->iterator, data_size); - } - else - { - uint8_t* bytes_pointer = (uint8_t*)bytes; - *bytes_pointer = *(mb->iterator + 3); - *(bytes_pointer + 1) = *(mb->iterator + 2); - *(bytes_pointer + 2) = *(mb->iterator + 1); - *(bytes_pointer + 3) = *mb->iterator; - } - - mb->iterator += data_size; - mb->last_data_size = data_size; - } - return !mb->error; -} - -bool ucdr_deserialize_byte_8(ucdrBuffer* mb, const ucdrEndianness endianness, uint64_t* bytes) -{ - uint32_t data_size = sizeof(uint64_t); - uint32_t alignment = ucdr_buffer_alignment(mb, data_size); - - if(ucdr_check_buffer(mb, alignment + data_size)) - { - mb->iterator += alignment; - - if(UCDR_MACHINE_ENDIANNESS == endianness) - { - memcpy(bytes, mb->iterator, data_size); - } - else - { - uint8_t* bytes_pointer = (uint8_t*)bytes; - *bytes_pointer = *(mb->iterator + 7); - *(bytes_pointer + 1) = *(mb->iterator + 6); - *(bytes_pointer + 2) = *(mb->iterator + 5); - *(bytes_pointer + 3) = *(mb->iterator + 4); - *(bytes_pointer + 4) = *(mb->iterator + 3); - *(bytes_pointer + 5) = *(mb->iterator + 2); - *(bytes_pointer + 6) = *(mb->iterator + 1); - *(bytes_pointer + 7) = *mb->iterator; - } - - mb->iterator += data_size; - mb->last_data_size = data_size; +// ------------------------------------------------------------------- +// DESERIALIZE MACROS +// ------------------------------------------------------------------- +#define UCDR_DESERIALIZE_BYTE_1(TYPE, ENDIAN) \ + (void)ENDIAN; \ + if(ucdr_check_final_buffer_behavior(ub, 1)) \ + { \ + *value = (TYPE)*ub->iterator; \ + ub->iterator += 1; \ + ub->last_data_size = 1; \ + } \ + return !ub->error; + +#define UCDR_DESERIALIZE_BYTE_2_CORE() \ + uint8_t* bytes_pointer = (uint8_t*)value; \ + *bytes_pointer = *(ub->iterator + 1); \ + *(bytes_pointer + 1) = *ub->iterator ; \ + +#define UCDR_DESERIALIZE_BYTE_4_CORE() \ + uint8_t* bytes_pointer = (uint8_t*)value; \ + *bytes_pointer = *(ub->iterator + 3); \ + *(bytes_pointer + 1) = *(ub->iterator + 2); \ + *(bytes_pointer + 2) = *(ub->iterator + 1); \ + *(bytes_pointer + 3) = *ub->iterator; + +#define UCDR_DESERIALIZE_BYTE_8_CORE() \ + uint8_t* bytes_pointer = (uint8_t*)value; \ + *bytes_pointer = *(ub->iterator + 7); \ + *(bytes_pointer + 1) = *(ub->iterator + 6); \ + *(bytes_pointer + 2) = *(ub->iterator + 5); \ + *(bytes_pointer + 3) = *(ub->iterator + 4); \ + *(bytes_pointer + 4) = *(ub->iterator + 3); \ + *(bytes_pointer + 5) = *(ub->iterator + 2); \ + *(bytes_pointer + 6) = *(ub->iterator + 1); \ + *(bytes_pointer + 7) = *ub->iterator; + +#define UCDR_DESERIALIZE_BYTE_N(TYPE, SIZE, ENDIAN) \ + ub->iterator += ucdr_buffer_alignment(ub, SIZE); \ + if(ucdr_check_final_buffer_behavior(ub, SIZE)) \ + { \ + if(UCDR_MACHINE_ENDIANNESS == ENDIAN) \ + { \ + memcpy((void*)value, ub->iterator, SIZE); \ + } \ + else \ + { \ + UCDR_DESERIALIZE_BYTE_ ## SIZE ## _CORE() \ + } \ + ub->iterator += SIZE; \ + ub->last_data_size = SIZE; \ + } \ + return !ub->error; + +#define UCDR_DESERIALIZE_BYTE_2(TYPE, ENDIAN) UCDR_DESERIALIZE_BYTE_N(TYPE, 2, ENDIAN) +#define UCDR_DESERIALIZE_BYTE_4(TYPE, ENDIAN) UCDR_DESERIALIZE_BYTE_N(TYPE, 4, ENDIAN) +#define UCDR_DESERIALIZE_BYTE_8(TYPE, ENDIAN) UCDR_DESERIALIZE_BYTE_N(TYPE, 8, ENDIAN) + +#define UCDR_BASIC_TYPE_DESERIALIZE_DEFINITION(SUFFIX, TYPE, SIZE) \ + bool ucdr_deserialize ## SUFFIX(ucdrBuffer* ub, TYPE* value) \ + { \ + UCDR_DESERIALIZE_BYTE_ ## SIZE(TYPE, ub->endianness) \ + } \ + bool ucdr_deserialize_endian ## SUFFIX(ucdrBuffer* ub, ucdrEndianness endianness, TYPE* value) \ + { \ + UCDR_DESERIALIZE_BYTE_ ## SIZE(TYPE, endianness) \ } - return !mb->error; -} // ------------------------------------------------------------------- -// PUBLIC SERIALIZATION IMPLEMENTATION +// DEFINITION MACRO // ------------------------------------------------------------------- +#define UCDR_BASIC_TYPE_DEFINITIONS(SUFFIX, TYPE, SIZE) \ + UCDR_BASIC_TYPE_SERIALIZE_DEFINITION(SUFFIX, TYPE, SIZE) \ + UCDR_BASIC_TYPE_DESERIALIZE_DEFINITION(SUFFIX, TYPE, SIZE) \ -bool ucdr_serialize_char(ucdrBuffer* mb, const char value) -{ - return ucdr_serialize_byte_1(mb, (uint8_t*)&value); -} - -bool ucdr_serialize_bool(ucdrBuffer* mb, const bool value) -{ - return ucdr_serialize_byte_1(mb, (uint8_t*)&value); -} - -bool ucdr_serialize_uint8_t(ucdrBuffer* mb, const uint8_t value) -{ - return ucdr_serialize_byte_1(mb, &value); -} - -bool ucdr_serialize_uint16_t(ucdrBuffer* mb, const uint16_t value) -{ - return ucdr_serialize_byte_2(mb, mb->endianness, &value); -} - -bool ucdr_serialize_uint32_t(ucdrBuffer* mb, const uint32_t value) -{ - return ucdr_serialize_byte_4(mb, mb->endianness, &value); -} - -bool ucdr_serialize_uint64_t(ucdrBuffer* mb, const uint64_t value) -{ - return ucdr_serialize_byte_8(mb, mb->endianness, &value); -} - -bool ucdr_serialize_int8_t(ucdrBuffer* mb, const int8_t value) -{ - return ucdr_serialize_byte_1(mb, (uint8_t*)&value); -} - -bool ucdr_serialize_int16_t(ucdrBuffer* mb, const int16_t value) -{ - return ucdr_serialize_byte_2(mb, mb->endianness, (uint16_t*)&value); -} - -bool ucdr_serialize_int32_t(ucdrBuffer* mb, const int32_t value) -{ - return ucdr_serialize_byte_4(mb, mb->endianness, (uint32_t*)&value); -} - -bool ucdr_serialize_int64_t(ucdrBuffer* mb, const int64_t value) -{ - return ucdr_serialize_byte_8(mb, mb->endianness, (uint64_t*)&value); -} - -bool ucdr_serialize_float(ucdrBuffer* mb, const float value) -{ - return ucdr_serialize_byte_4(mb, mb->endianness, (uint32_t*)&value); -} - -bool ucdr_serialize_double(ucdrBuffer* mb, const double value) -{ - return ucdr_serialize_byte_8(mb, mb->endianness, (uint64_t*)&value); -} - -bool ucdr_deserialize_char(ucdrBuffer* mb, char* value) -{ - return ucdr_deserialize_byte_1(mb, (uint8_t*)value); -} - -bool ucdr_deserialize_bool(ucdrBuffer* mb, bool* value) -{ - return ucdr_deserialize_byte_1(mb, (uint8_t*)value); -} - -bool ucdr_deserialize_uint8_t(ucdrBuffer* mb, uint8_t* value) -{ - return ucdr_deserialize_byte_1(mb, value); -} - -bool ucdr_deserialize_uint16_t(ucdrBuffer* mb, uint16_t* value) -{ - return ucdr_deserialize_byte_2(mb, mb->endianness, value); -} - -bool ucdr_deserialize_uint32_t(ucdrBuffer* mb, uint32_t* value) -{ - return ucdr_deserialize_byte_4(mb, mb->endianness, value); -} - -bool ucdr_deserialize_uint64_t(ucdrBuffer* mb, uint64_t* value) -{ - return ucdr_deserialize_byte_8(mb, mb->endianness, value); -} - -bool ucdr_deserialize_int8_t(ucdrBuffer* mb, int8_t* value) -{ - return ucdr_deserialize_byte_1(mb, (uint8_t*)value); -} - -bool ucdr_deserialize_int16_t(ucdrBuffer* mb, int16_t* value) -{ - return ucdr_deserialize_byte_2(mb, mb->endianness, (uint16_t*)value); -} - -bool ucdr_deserialize_int32_t(ucdrBuffer* mb, int32_t* value) -{ - return ucdr_deserialize_byte_4(mb, mb->endianness, (uint32_t*)value); -} - -bool ucdr_deserialize_int64_t(ucdrBuffer* mb, int64_t* value) -{ - return ucdr_deserialize_byte_8(mb, mb->endianness, (uint64_t*)value); -} - -bool ucdr_deserialize_float(ucdrBuffer* mb, float* value) -{ - return ucdr_deserialize_byte_4(mb, mb->endianness, (uint32_t*)value); -} - -bool ucdr_deserialize_double(ucdrBuffer* mb, double* value) -{ - return ucdr_deserialize_byte_8(mb, mb->endianness, (uint64_t*)value); -} - -bool ucdr_serialize_endian_uint16_t(ucdrBuffer* mb, const ucdrEndianness endianness, const uint16_t value) -{ - return ucdr_serialize_byte_2(mb, endianness, &value); -} - -bool ucdr_serialize_endian_uint32_t(ucdrBuffer* mb, const ucdrEndianness endianness, const uint32_t value) -{ - return ucdr_serialize_byte_4(mb, endianness, &value); -} - -bool ucdr_serialize_endian_uint64_t(ucdrBuffer* mb, const ucdrEndianness endianness, const uint64_t value) -{ - return ucdr_serialize_byte_8(mb, endianness, &value); -} - -bool ucdr_serialize_endian_int16_t(ucdrBuffer* mb, const ucdrEndianness endianness, const int16_t value) -{ - return ucdr_serialize_byte_2(mb, endianness, (uint16_t*)&value); -} - -bool ucdr_serialize_endian_int32_t(ucdrBuffer* mb, const ucdrEndianness endianness, const int32_t value) -{ - return ucdr_serialize_byte_4(mb, endianness, (uint32_t*)&value); -} - -bool ucdr_serialize_endian_int64_t(ucdrBuffer* mb, const ucdrEndianness endianness, const int64_t value) -{ - return ucdr_serialize_byte_8(mb, endianness, (uint64_t*)&value); -} - -bool ucdr_serialize_endian_float(ucdrBuffer* mb, const ucdrEndianness endianness, const float value) -{ - return ucdr_serialize_byte_4(mb, endianness, (uint32_t*)&value); -} - -bool ucdr_serialize_endian_double(ucdrBuffer* mb, const ucdrEndianness endianness, const double value) -{ - return ucdr_serialize_byte_8(mb, endianness, (uint64_t*)&value); -} - -bool ucdr_deserialize_endian_uint16_t(ucdrBuffer* mb, const ucdrEndianness endianness, uint16_t* value) -{ - return ucdr_deserialize_byte_2(mb, endianness, value); -} - -bool ucdr_deserialize_endian_uint32_t(ucdrBuffer* mb, const ucdrEndianness endianness, uint32_t* value) -{ - return ucdr_deserialize_byte_4(mb, endianness, value); -} - -bool ucdr_deserialize_endian_uint64_t(ucdrBuffer* mb, const ucdrEndianness endianness, uint64_t* value) -{ - return ucdr_deserialize_byte_8(mb, endianness, value); -} - -bool ucdr_deserialize_endian_int16_t(ucdrBuffer* mb, const ucdrEndianness endianness, int16_t* value) -{ - return ucdr_deserialize_byte_2(mb, endianness, (uint16_t*)value); -} - -bool ucdr_deserialize_endian_int32_t(ucdrBuffer* mb, const ucdrEndianness endianness, int32_t* value) -{ - return ucdr_deserialize_byte_4(mb, endianness, (uint32_t*)value); -} - -bool ucdr_deserialize_endian_int64_t(ucdrBuffer* mb, const ucdrEndianness endianness, int64_t* value) -{ - return ucdr_deserialize_byte_8(mb, endianness, (uint64_t*)value); -} - -bool ucdr_deserialize_endian_float(ucdrBuffer* mb, const ucdrEndianness endianness, float* value) -{ - return ucdr_deserialize_byte_4(mb, endianness, (uint32_t*)value); -} - -bool ucdr_deserialize_endian_double(ucdrBuffer* mb, const ucdrEndianness endianness, double* value) -{ - return ucdr_deserialize_byte_8(mb, endianness, (uint64_t*)value); -} - +// ------------------------------------------------------------------- +// PUBLIC DE-SERIALIZATION IMPLEMENTATIONS +// ------------------------------------------------------------------- +UCDR_BASIC_TYPE_DEFINITIONS(_char, char, 1) +UCDR_BASIC_TYPE_DEFINITIONS(_bool, bool, 1) +UCDR_BASIC_TYPE_DEFINITIONS(_uint8_t, uint8_t, 1) +UCDR_BASIC_TYPE_DEFINITIONS(_uint16_t, uint16_t, 2) +UCDR_BASIC_TYPE_DEFINITIONS(_uint32_t, uint32_t, 4) +UCDR_BASIC_TYPE_DEFINITIONS(_uint64_t, uint64_t, 8) +UCDR_BASIC_TYPE_DEFINITIONS(_int8_t, int8_t, 1) +UCDR_BASIC_TYPE_DEFINITIONS(_int16_t, int16_t, 2) +UCDR_BASIC_TYPE_DEFINITIONS(_int32_t, int32_t, 4) +UCDR_BASIC_TYPE_DEFINITIONS(_int64_t, int64_t, 8) +UCDR_BASIC_TYPE_DEFINITIONS(_float, float, 4) +UCDR_BASIC_TYPE_DEFINITIONS(_double, double, 8) diff --git a/src/c/types/basic_internals.h b/src/c/types/basic_internals.h deleted file mode 100644 index 85d29d8..0000000 --- a/src/c/types/basic_internals.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef _SRC_TYPES_BASIC_INTERNALS_H_ -#define _SRC_TYPES_BASIC_INTERNALS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -// ------------------------------------------------------------------- -// INTERNAL SERIALIZATION FUNCTIONS -// ------------------------------------------------------------------- -bool ucdr_serialize_byte_1(ucdrBuffer* buffer, const uint8_t* byte); -bool ucdr_serialize_byte_2(ucdrBuffer* buffer, ucdrEndianness endianness, const uint16_t* bytes); -bool ucdr_serialize_byte_4(ucdrBuffer* buffer, ucdrEndianness endianness, const uint32_t* bytes); -bool ucdr_serialize_byte_8(ucdrBuffer* buffer, ucdrEndianness endianness, const uint64_t* bytes); - -bool ucdr_deserialize_byte_1(ucdrBuffer* buffer, uint8_t* byte); -bool ucdr_deserialize_byte_2(ucdrBuffer* buffer, ucdrEndianness endianness, uint16_t* bytes); -bool ucdr_deserialize_byte_4(ucdrBuffer* buffer, ucdrEndianness endianness, uint32_t* bytes); -bool ucdr_deserialize_byte_8(ucdrBuffer* buffer, ucdrEndianness endianness, uint64_t* bytes); - -#ifdef __cplusplus -} -#endif - -#endif //_SRC_TYPES_BASIC_INTERNALS_H_ diff --git a/src/c/types/sequence.c b/src/c/types/sequence.c index 5accce0..1c43875 100644 --- a/src/c/types/sequence.c +++ b/src/c/types/sequence.c @@ -12,317 +12,71 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include -#include -#include +#include -#include "array_internals.h" -#include "sequence_internals.h" +static void ucdr_deserialize_sequence_header(ucdrBuffer* ub, ucdrEndianness endianness, size_t capacity, uint32_t* length); // ------------------------------------------------------------------- // INTERNAL UTIL IMPLEMENTATION // ------------------------------------------------------------------- -static inline void ucdr_deserialize_sequence_header(ucdrBuffer* mb, ucdrEndianness endianness, uint32_t capacity, uint32_t* size) +inline void ucdr_deserialize_sequence_header(ucdrBuffer* ub, ucdrEndianness endianness, size_t capacity, uint32_t* length) { - ucdr_deserialize_endian_uint32_t(mb, endianness, size); - if(*size > capacity) + ucdr_deserialize_endian_uint32_t(ub, endianness, length); + if(*length > capacity) { - mb->error = true; + ub->error = true; } } // ------------------------------------------------------------------- -// INTERNAL SERIALIZATION IMPLEMENTATION +// SERIALIZE MACROS // ------------------------------------------------------------------- -bool ucdr_serialize_sequence_byte_1(ucdrBuffer* mb, ucdrEndianness endianness, const uint8_t* array, const uint32_t size) -{ - ucdr_serialize_endian_uint32_t(mb, endianness, size); - return ucdr_serialize_array_byte_1(mb, array, size); -} - -bool ucdr_serialize_sequence_byte_2(ucdrBuffer* mb, ucdrEndianness endianness, const uint16_t* array, const uint32_t size) -{ - ucdr_serialize_endian_uint32_t(mb, endianness, size); - return ucdr_serialize_array_byte_2(mb, endianness, array, size); -} - -bool ucdr_serialize_sequence_byte_4(ucdrBuffer* mb, ucdrEndianness endianness, const uint32_t* array, const uint32_t size) -{ - ucdr_serialize_endian_uint32_t(mb, endianness, size); - return ucdr_serialize_array_byte_4(mb, endianness, array, size); -} - -bool ucdr_serialize_sequence_byte_8(ucdrBuffer* mb, ucdrEndianness endianness, const uint64_t* array, const uint32_t size) -{ - ucdr_serialize_endian_uint32_t(mb, endianness, size); - return ucdr_serialize_array_byte_8(mb, endianness, array, size); -} - -bool ucdr_deserialize_sequence_byte_1(ucdrBuffer* mb, ucdrEndianness endianness, uint8_t* array, const uint32_t array_capacity, uint32_t* size) -{ - ucdr_deserialize_sequence_header(mb, endianness, array_capacity, size); - return ucdr_deserialize_array_byte_1(mb, array, *size); -} - -bool ucdr_deserialize_sequence_byte_2(ucdrBuffer* mb, ucdrEndianness endianness, uint16_t* array, const uint32_t array_capacity, uint32_t* size) -{ - ucdr_deserialize_sequence_header(mb, endianness, array_capacity, size); - return ucdr_deserialize_array_byte_2(mb, endianness, array, *size); -} - -bool ucdr_deserialize_sequence_byte_4(ucdrBuffer* mb, ucdrEndianness endianness, uint32_t* array, const uint32_t array_capacity, uint32_t* size) -{ - ucdr_deserialize_sequence_header(mb, endianness, array_capacity, size); - return ucdr_deserialize_array_byte_4(mb, endianness, array, *size); -} - -bool ucdr_deserialize_sequence_byte_8(ucdrBuffer* mb, ucdrEndianness endianness, uint64_t* array, const uint32_t array_capacity, uint32_t* size) -{ - ucdr_deserialize_sequence_header(mb, endianness, array_capacity, size); - return ucdr_deserialize_array_byte_8(mb, endianness, array, *size); -} +#define UCDR_SEQUENCE_SERIALIZE_DEFINITION(SUFFIX, TYPE, SIZE) \ + bool ucdr_serialize_sequence ## SUFFIX(ucdrBuffer* ub, const TYPE* array, uint32_t length) \ + { \ + ucdr_serialize_endian_uint32_t(ub, ub->endianness, length); \ + return ucdr_serialize_endian_array ## SUFFIX(ub, ub->endianness, array, length); \ + } \ + bool ucdr_serialize_endian_sequence ## SUFFIX(ucdrBuffer* ub, ucdrEndianness endianness, const TYPE* array, uint32_t length) \ + { \ + ucdr_serialize_endian_uint32_t(ub, endianness, length); \ + return ucdr_serialize_endian_array ## SUFFIX(ub, endianness, array, length); \ + } \ // ------------------------------------------------------------------- -// PUBLIC SERIALIZATION IMPLEMENTATIONS +// DESERIALIZE MACROS // ------------------------------------------------------------------- +#define UCDR_SEQUENCE_DESERIALIZE_DEFINITION(SUFFIX, TYPE, SIZE) \ + bool ucdr_deserialize_sequence ## SUFFIX(ucdrBuffer* ub, TYPE* array, size_t array_capacity, uint32_t* length) \ + { \ + ucdr_deserialize_sequence_header(ub, ub->endianness, array_capacity, length); \ + return ucdr_deserialize_endian_array ## SUFFIX(ub, ub->endianness, array, *length); \ + } \ + bool ucdr_deserialize_endian_sequence ## SUFFIX(ucdrBuffer* ub, ucdrEndianness endianness, TYPE* array, size_t array_capacity, uint32_t* length) \ + { \ + ucdr_deserialize_sequence_header(ub, endianness, array_capacity, length); \ + return ucdr_deserialize_endian_array ## SUFFIX(ub, endianness, array, *length); \ + } \ -bool ucdr_serialize_sequence_char(ucdrBuffer* mb, const char* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_1(mb, mb->endianness, (uint8_t*)array, size); -} - -bool ucdr_serialize_sequence_bool(ucdrBuffer* mb, const bool* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_1(mb, mb->endianness, (uint8_t*)array, size); -} - -bool ucdr_serialize_sequence_uint8_t(ucdrBuffer* mb, const uint8_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_1(mb, mb->endianness, (uint8_t*)array, size); -} - -bool ucdr_serialize_sequence_uint16_t(ucdrBuffer* mb, const uint16_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_2(mb, mb->endianness, (uint16_t*)array, size); -} - -bool ucdr_serialize_sequence_uint32_t(ucdrBuffer* mb, const uint32_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_4(mb, mb->endianness, (uint32_t*)array, size); -} - -bool ucdr_serialize_sequence_uint64_t(ucdrBuffer* mb, const uint64_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_8(mb, mb->endianness, (uint64_t*)array, size); -} - -bool ucdr_serialize_sequence_int8_t(ucdrBuffer* mb, const int8_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_1(mb, mb->endianness, (uint8_t*)array, size); -} - -bool ucdr_serialize_sequence_int16_t(ucdrBuffer* mb, const int16_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_2(mb, mb->endianness, (uint16_t*)array, size); -} - -bool ucdr_serialize_sequence_int32_t(ucdrBuffer* mb, const int32_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_4(mb, mb->endianness, (uint32_t*)array, size); -} - -bool ucdr_serialize_sequence_int64_t(ucdrBuffer* mb, const int64_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_8(mb, mb->endianness, (uint64_t*)array, size); -} - -bool ucdr_serialize_sequence_float(ucdrBuffer* mb, const float* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_4(mb, mb->endianness, (uint32_t*)array, size); -} - -bool ucdr_serialize_sequence_double(ucdrBuffer* mb, const double* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_8(mb, mb->endianness, (uint64_t*)array, size); -} - -bool ucdr_deserialize_sequence_char(ucdrBuffer* mb, char* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_1(mb, mb->endianness, (uint8_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_sequence_bool(ucdrBuffer* mb, bool* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_1(mb, mb->endianness, (uint8_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_sequence_uint8_t(ucdrBuffer* mb, uint8_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_1(mb, mb->endianness, (uint8_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_sequence_uint16_t(ucdrBuffer* mb, uint16_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_2(mb, mb->endianness, (uint16_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_sequence_uint32_t(ucdrBuffer* mb, uint32_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_4(mb, mb->endianness, (uint32_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_sequence_uint64_t(ucdrBuffer* mb, uint64_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_8(mb, mb->endianness, (uint64_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_sequence_int8_t(ucdrBuffer* mb, int8_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_1(mb, mb->endianness, (uint8_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_sequence_int16_t(ucdrBuffer* mb, int16_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_2(mb, mb->endianness, (uint16_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_sequence_int32_t(ucdrBuffer* mb, int32_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_4(mb, mb->endianness, (uint32_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_sequence_int64_t(ucdrBuffer* mb, int64_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_8(mb, mb->endianness, (uint64_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_sequence_float(ucdrBuffer* mb, float* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_4(mb, mb->endianness, (uint32_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_sequence_double(ucdrBuffer* mb, double* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_8(mb, mb->endianness, (uint64_t*)array, array_capacity, size); -} - -bool ucdr_serialize_endian_sequence_char(ucdrBuffer* mb, const ucdrEndianness endianness, const char* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_1(mb, endianness, (uint8_t*)array, size); -} - -bool ucdr_serialize_endian_sequence_bool(ucdrBuffer* mb, const ucdrEndianness endianness, const bool* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_1(mb, endianness, (uint8_t*)array, size); -} - -bool ucdr_serialize_endian_sequence_uint8_t(ucdrBuffer* mb, const ucdrEndianness endianness, const uint8_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_1(mb, endianness, (uint8_t*)array, size); -} - -bool ucdr_serialize_endian_sequence_uint16_t(ucdrBuffer* mb, const ucdrEndianness endianness, const uint16_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_2(mb, endianness, (uint16_t*)array, size); -} - -bool ucdr_serialize_endian_sequence_uint32_t(ucdrBuffer* mb, const ucdrEndianness endianness, const uint32_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_4(mb, endianness, (uint32_t*)array, size); -} - -bool ucdr_serialize_endian_sequence_uint64_t(ucdrBuffer* mb, const ucdrEndianness endianness, const uint64_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_8(mb, endianness, (uint64_t*)array, size); -} - -bool ucdr_serialize_endian_sequence_int8_t(ucdrBuffer* mb, const ucdrEndianness endianness, const int8_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_1(mb, endianness, (uint8_t*)array, size); -} - -bool ucdr_serialize_endian_sequence_int16_t(ucdrBuffer* mb, const ucdrEndianness endianness, const int16_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_2(mb, endianness, (uint16_t*)array, size); -} - -bool ucdr_serialize_endian_sequence_int32_t(ucdrBuffer* mb, const ucdrEndianness endianness, const int32_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_4(mb, endianness, (uint32_t*)array, size); -} - -bool ucdr_serialize_endian_sequence_int64_t(ucdrBuffer* mb, const ucdrEndianness endianness, const int64_t* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_8(mb, endianness, (uint64_t*)array, size); -} - -bool ucdr_serialize_endian_sequence_float(ucdrBuffer* mb, const ucdrEndianness endianness, const float* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_4(mb, endianness, (uint32_t*)array, size); -} - -bool ucdr_serialize_endian_sequence_double(ucdrBuffer* mb, const ucdrEndianness endianness, const double* array, const uint32_t size) -{ - return ucdr_serialize_sequence_byte_8(mb, endianness, (uint64_t*)array, size); -} - -bool ucdr_deserialize_endian_sequence_char(ucdrBuffer* mb, const ucdrEndianness endianness, char* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_1(mb, endianness, (uint8_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_endian_sequence_bool(ucdrBuffer* mb, const ucdrEndianness endianness, bool* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_1(mb, endianness, (uint8_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_endian_sequence_uint8_t(ucdrBuffer* mb, const ucdrEndianness endianness, uint8_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_1(mb, endianness, (uint8_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_endian_sequence_uint16_t(ucdrBuffer* mb, const ucdrEndianness endianness, uint16_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_2(mb, endianness, (uint16_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_endian_sequence_uint32_t(ucdrBuffer* mb, const ucdrEndianness endianness, uint32_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_4(mb, endianness, (uint32_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_endian_sequence_uint64_t(ucdrBuffer* mb, const ucdrEndianness endianness, uint64_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_8(mb, endianness, (uint64_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_endian_sequence_int8_t(ucdrBuffer* mb, const ucdrEndianness endianness, int8_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_1(mb, endianness, (uint8_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_endian_sequence_int16_t(ucdrBuffer* mb, const ucdrEndianness endianness, int16_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_2(mb, endianness, (uint16_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_endian_sequence_int32_t(ucdrBuffer* mb, const ucdrEndianness endianness, int32_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_4(mb, endianness, (uint32_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_endian_sequence_int64_t(ucdrBuffer* mb, const ucdrEndianness endianness, int64_t* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_8(mb, endianness, (uint64_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_endian_sequence_float(ucdrBuffer* mb, const ucdrEndianness endianness, float* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_4(mb, endianness, (uint32_t*)array, array_capacity, size); -} - -bool ucdr_deserialize_endian_sequence_double(ucdrBuffer* mb, const ucdrEndianness endianness, double* array, const uint32_t array_capacity, uint32_t* size) -{ - return ucdr_deserialize_sequence_byte_8(mb, endianness, (uint64_t*)array, array_capacity, size); -} +// ------------------------------------------------------------------- +// DEFINITION MACRO +// ------------------------------------------------------------------- +#define UCDR_SEQUENCE_DEFINITIONS(SUFFIX, TYPE, SIZE) \ + UCDR_SEQUENCE_SERIALIZE_DEFINITION(SUFFIX, TYPE, SIZE) \ + UCDR_SEQUENCE_DESERIALIZE_DEFINITION(SUFFIX, TYPE, SIZE) \ +// ------------------------------------------------------------------- +// PUBLIC DE-SERIALIZATION IMPLEMENTATIONS +// ------------------------------------------------------------------- +UCDR_SEQUENCE_DEFINITIONS(_char, char, 1) +UCDR_SEQUENCE_DEFINITIONS(_bool, bool, 1) +UCDR_SEQUENCE_DEFINITIONS(_uint8_t, uint8_t, 1) +UCDR_SEQUENCE_DEFINITIONS(_uint16_t, uint16_t, 2) +UCDR_SEQUENCE_DEFINITIONS(_uint32_t, uint32_t, 4) +UCDR_SEQUENCE_DEFINITIONS(_uint64_t, uint64_t, 8) +UCDR_SEQUENCE_DEFINITIONS(_int8_t, int8_t, 1) +UCDR_SEQUENCE_DEFINITIONS(_int16_t, int16_t, 2) +UCDR_SEQUENCE_DEFINITIONS(_int32_t, int32_t, 4) +UCDR_SEQUENCE_DEFINITIONS(_int64_t, int64_t, 8) +UCDR_SEQUENCE_DEFINITIONS(_float, float, 4) +UCDR_SEQUENCE_DEFINITIONS(_double, double, 8) diff --git a/src/c/types/sequence_internals.h b/src/c/types/sequence_internals.h deleted file mode 100644 index f479517..0000000 --- a/src/c/types/sequence_internals.h +++ /dev/null @@ -1,43 +0,0 @@ - - -// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef _SRC_TYPES_SEQUENCE_INTERNALS_H_ -#define _SRC_TYPES_SEQUENCE_INTERNALS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -// ------------------------------------------------------------------- -// INTERNAL SERIALIZATION FUNCTIONS -// ------------------------------------------------------------------- -bool ucdr_serialize_sequence_byte_1(ucdrBuffer* buffer, ucdrEndianness endianness, const uint8_t* array, const uint32_t size); -bool ucdr_serialize_sequence_byte_2(ucdrBuffer* buffer, ucdrEndianness endianness, const uint16_t* array, const uint32_t size); -bool ucdr_serialize_sequence_byte_4(ucdrBuffer* buffer, ucdrEndianness endianness, const uint32_t* array, const uint32_t size); -bool ucdr_serialize_sequence_byte_8(ucdrBuffer* buffer, ucdrEndianness endianness, const uint64_t* array, const uint32_t size); - -bool ucdr_deserialize_sequence_byte_1(ucdrBuffer* buffer, ucdrEndianness endianness, uint8_t* array, const uint32_t array_capacity, uint32_t* size); -bool ucdr_deserialize_sequence_byte_2(ucdrBuffer* buffer, ucdrEndianness endianness, uint16_t* array, const uint32_t array_capacity, uint32_t* size); -bool ucdr_deserialize_sequence_byte_4(ucdrBuffer* buffer, ucdrEndianness endianness, uint32_t* array, const uint32_t array_capacity, uint32_t* size); -bool ucdr_deserialize_sequence_byte_8(ucdrBuffer* buffer, ucdrEndianness endianness, uint64_t* array, const uint32_t array_capacity, uint32_t* size); - -#ifdef __cplusplus -} -#endif - -#endif //_SRC_TYPES_SEQUENCE_INTERNALS_H_ diff --git a/src/c/types/string.c b/src/c/types/string.c index de0760f..49b63ff 100644 --- a/src/c/types/string.c +++ b/src/c/types/string.c @@ -13,8 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include -#include +#include #include @@ -22,24 +21,24 @@ // PUBLIC SERIALIZATION IMPLEMENTATIONS // ------------------------------------------------------------------- -bool ucdr_serialize_string(ucdrBuffer* mb, const char* string) +bool ucdr_serialize_string(ucdrBuffer* ub, const char* string) { - return ucdr_serialize_sequence_char(mb, string, (uint32_t)strlen(string) + 1); + return ucdr_serialize_sequence_char(ub, string, (uint32_t)strlen(string) + 1); } -bool ucdr_deserialize_string(ucdrBuffer* mb, char* string, const uint32_t string_capacity) +bool ucdr_serialize_endian_string(ucdrBuffer* ub, ucdrEndianness endianness, const char* string) { - uint32_t length; - return ucdr_deserialize_sequence_char(mb, string, string_capacity, &length); + return ucdr_serialize_endian_sequence_char(ub, endianness, string, (uint32_t)strlen(string) + 1); } -bool ucdr_serialize_endian_string(ucdrBuffer* mb, ucdrEndianness endianness, const char* string) +bool ucdr_deserialize_string(ucdrBuffer* ub, char* string, size_t string_capacity) { - return ucdr_serialize_endian_sequence_char(mb, endianness, string, (uint32_t)strlen(string) + 1); + uint32_t length; + return ucdr_deserialize_sequence_char(ub, string, string_capacity, &length); } -bool ucdr_deserialize_endian_string(ucdrBuffer* mb, ucdrEndianness endianness, char* string, const uint32_t string_capacity) +bool ucdr_deserialize_endian_string(ucdrBuffer* ub, ucdrEndianness endianness, char* string, size_t string_capacity) { uint32_t length; - return ucdr_deserialize_endian_sequence_char(mb, endianness, string, string_capacity, &length); + return ucdr_deserialize_endian_sequence_char(ub, endianness, string, string_capacity, &length); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f80f6d9..da32dc7 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -27,15 +27,18 @@ if(GTEST_FOUND) include(CTest) set(SRCS serialization/BasicSerialization.cpp - serialization/StringSerialization.cpp serialization/ArraySerialization.cpp serialization/SequenceSerialization.cpp + serialization/StringSerialization.cpp endianness/BasicEndianness.cpp endianness/ArrayEndianness.cpp endianness/SequenceEndianness.cpp + fragmentation/BasicFragmentation.cpp + fragmentation/ArrayFragmentation.cpp SequenceOverflow.cpp Alignment.cpp FullBuffer.cpp + FullBufferCallback.cpp ) add_executable(${PROJECT_NAME} ${SRCS}) set_common_compile_options(${PROJECT_NAME}) diff --git a/test/FullBuffer.cpp b/test/FullBuffer.cpp index 394e977..2c726e2 100644 --- a/test/FullBuffer.cpp +++ b/test/FullBuffer.cpp @@ -12,98 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "serialization/BasicSerialization.hpp" - -class FullBuffer : public BasicSerialization -{ -public: - FullBuffer() - { - } - - void fill_buffer_except(int gap) - { - for(int i = 0; i < BUFFER_LENGTH - gap; ++i) - { - uint8_t_serialization(); - } - - writer_it = writer.iterator; - reader_it = reader.iterator; - } - - void try_block_1() - { - uint8_t input = 0xAA; - uint8_t output = 0; - - EXPECT_FALSE(ucdr_serialize_uint8_t(&writer, input)); - EXPECT_FALSE(ucdr_deserialize_uint8_t(&reader, &output)); - } - - void try_block_2() - { - uint16_t input = 0xAABB; - uint16_t output = 0; - - EXPECT_FALSE(ucdr_serialize_uint16_t(&writer, input)); - EXPECT_FALSE(ucdr_deserialize_uint16_t(&reader, &output)); - } - - void try_block_4() - { - uint32_t input = 0xAABBCCDD; - uint32_t output = 0; - - EXPECT_FALSE(ucdr_serialize_uint32_t(&writer, input)); - EXPECT_FALSE(ucdr_deserialize_uint32_t(&reader, &output)); - } - - void try_block_8() - { - uint64_t input = 0x0123456789ABCDEF; - uint64_t output = 0; - - EXPECT_FALSE(ucdr_serialize_uint64_t(&writer, input)); - EXPECT_FALSE(ucdr_deserialize_uint64_t(&reader, &output)); - } - - ~FullBuffer() - { - EXPECT_EQ(writer_it, writer.iterator); - EXPECT_EQ(reader_it, reader.iterator); - EXPECT_TRUE(writer.error); - EXPECT_TRUE(reader.error); - - // To satisfy the base destructor - writer.error = false; - reader.error = false; - } - -private: - uint8_t* writer_it; - uint8_t* reader_it; -}; +#include "FullBuffer.hpp" TEST_F(FullBuffer, Block_8) { fill_buffer_except(7); try_block_8(); - try_block_1(); } TEST_F(FullBuffer, Block_4) { fill_buffer_except(3); try_block_4(); - try_block_1(); } TEST_F(FullBuffer, Block_2) { fill_buffer_except(1); try_block_2(); - try_block_1(); } TEST_F(FullBuffer, Block_1) @@ -111,3 +37,30 @@ TEST_F(FullBuffer, Block_1) fill_buffer_except(0); try_block_1(); } + +# define SUCCESSFUL_SERIALIZATION 3 +# define ARRAY_SERIALIZATION (SUCCESSFUL_SERIALIZATION + 1) +TEST_F(FullBuffer, ArrayBlock_8) +{ + fill_buffer_except(8 * SUCCESSFUL_SERIALIZATION + 7); + try_array_block_8(ARRAY_SERIALIZATION); +} + +TEST_F(FullBuffer, ArrayBlock_4) +{ + fill_buffer_except(4 * SUCCESSFUL_SERIALIZATION + 3); + try_array_block_4(ARRAY_SERIALIZATION); +} + +TEST_F(FullBuffer, ArrayBlock_2) +{ + fill_buffer_except(2 * SUCCESSFUL_SERIALIZATION + 1); + try_array_block_2(ARRAY_SERIALIZATION); +} + +TEST_F(FullBuffer, ArrayBlock_1) +{ + fill_buffer_except(SUCCESSFUL_SERIALIZATION); + try_array_block_1(ARRAY_SERIALIZATION); +} + diff --git a/test/FullBuffer.hpp b/test/FullBuffer.hpp new file mode 100644 index 0000000..fe76dd3 --- /dev/null +++ b/test/FullBuffer.hpp @@ -0,0 +1,125 @@ +// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "serialization/BasicSerialization.hpp" + +#define ARRAY_CAPACITY 128 + +class FullBuffer : public BasicSerialization +{ +public: + FullBuffer() + { + } + + void fill_buffer_except(int gap) + { + for(int i = 0; i < BUFFER_LENGTH - gap; ++i) + { + uint8_t_serialization(); + } + } + + void try_block_1() + { + uint8_t input = 0xAA; + uint8_t output = 0; + + EXPECT_FALSE(ucdr_serialize_uint8_t(&writer, input)); + EXPECT_FALSE(ucdr_deserialize_uint8_t(&reader, &output)); + } + + void try_block_2() + { + uint16_t input = 0xAABB; + uint16_t output = 0; + + EXPECT_FALSE(ucdr_serialize_uint16_t(&writer, input)); + EXPECT_FALSE(ucdr_deserialize_uint16_t(&reader, &output)); + } + + void try_block_4() + { + uint32_t input = 0xAABBCCDD; + uint32_t output = 0; + + EXPECT_FALSE(ucdr_serialize_uint32_t(&writer, input)); + EXPECT_FALSE(ucdr_deserialize_uint32_t(&reader, &output)); + } + + void try_block_8() + { + uint64_t input = 0x0123456789ABCDEF; + uint64_t output = 0; + + EXPECT_FALSE(ucdr_serialize_uint64_t(&writer, input)); + EXPECT_FALSE(ucdr_deserialize_uint64_t(&reader, &output)); + } + + void try_array_block_1(uint32_t size) + { + uint8_t input[ARRAY_CAPACITY]; + std::fill_n(input, size, uint8_t(0x09)); + uint8_t output[ARRAY_CAPACITY]; + + EXPECT_FALSE(ucdr_serialize_array_uint8_t(&writer, input, size)); + EXPECT_FALSE(ucdr_deserialize_array_uint8_t(&reader, output, size)); + } + + void try_array_block_2(uint32_t size) + { + uint16_t input[ARRAY_CAPACITY]; + std::fill_n(input, size, int16_t(0x0A0B)); + uint16_t output[ARRAY_CAPACITY]; + + EXPECT_FALSE(ucdr_serialize_array_uint16_t(&writer, input, size)); + EXPECT_FALSE(ucdr_deserialize_array_uint16_t(&reader, output, size)); + } + + void try_array_block_4(uint32_t size) + { + + uint32_t input[ARRAY_CAPACITY]; + std::fill_n(input, size, 0x0C0D0E0F); + uint32_t output[ARRAY_CAPACITY]; + + EXPECT_FALSE(ucdr_serialize_array_uint32_t(&writer, input, size)); + EXPECT_FALSE(ucdr_deserialize_array_uint32_t(&reader, output, size)); + } + + void try_array_block_8(uint32_t size) + { + uint64_t input[ARRAY_CAPACITY]; + std::fill_n(input, size, 0x0102030405060708L); + uint64_t output[ARRAY_CAPACITY]; + + EXPECT_FALSE(ucdr_serialize_array_uint64_t(&writer, input, size)); + EXPECT_FALSE(ucdr_deserialize_array_uint64_t(&reader, output, size)); + } + + ~FullBuffer() + { + EXPECT_TRUE(writer.error); + EXPECT_TRUE(reader.error); + + try_block_1(); //a serialization with an error, gives an error + + EXPECT_TRUE(writer.error); + EXPECT_TRUE(reader.error); + + // To satisfy the base destructor + writer.error = false; + reader.error = false; + } +}; diff --git a/test/FullBufferCallback.cpp b/test/FullBufferCallback.cpp new file mode 100644 index 0000000..98a7d0d --- /dev/null +++ b/test/FullBufferCallback.cpp @@ -0,0 +1,87 @@ +// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "FullBuffer.hpp" + +class FullBufferCallback : public FullBuffer +{ +public: + FullBufferCallback() + { + ucdr_set_on_full_buffer_callback(&writer, on_full_buffer, buffer); + ucdr_set_on_full_buffer_callback(&reader, on_full_buffer, buffer); + } + +protected: + static bool on_full_buffer(ucdrBuffer* ub, void* args) + { + uint8_t* buffer = static_cast(args); + + EXPECT_EQ(buffer, ub->init); + EXPECT_EQ(buffer + BUFFER_LENGTH, ub->final); //only satisfied if BUFFER_LENGTH is alignment to 8. + + return true; + } +}; + +TEST_F(FullBufferCallback, Block_8_callback) +{ + fill_buffer_except(7); + try_block_8(); +} + +TEST_F(FullBufferCallback, Block_4_callback) +{ + fill_buffer_except(3); + try_block_4(); +} + +TEST_F(FullBufferCallback, Block_2_callback) +{ + fill_buffer_except(1); + try_block_2(); +} + +TEST_F(FullBufferCallback, Block_1_callback) +{ + fill_buffer_except(0); + try_block_1(); +} + +# define SUCCESSFUL_SERIALIZATION 3 +# define ARRAY_SERIALIZATION (SUCCESSFUL_SERIALIZATION + 1) +TEST_F(FullBufferCallback, ArrayBlock_8_callback) +{ + fill_buffer_except(8 * SUCCESSFUL_SERIALIZATION + 7); + try_array_block_8(ARRAY_SERIALIZATION); +} + +TEST_F(FullBufferCallback, ArrayBlock_4_callback) +{ + fill_buffer_except(4 * SUCCESSFUL_SERIALIZATION + 3); + try_array_block_4(ARRAY_SERIALIZATION); +} + +TEST_F(FullBufferCallback, ArrayBlock_2_callback) +{ + fill_buffer_except(2 * SUCCESSFUL_SERIALIZATION + 1); + try_array_block_2(ARRAY_SERIALIZATION); +} + +TEST_F(FullBufferCallback, ArrayBlock_1_callback) +{ + fill_buffer_except(SUCCESSFUL_SERIALIZATION); + try_array_block_1(ARRAY_SERIALIZATION); +} + diff --git a/test/SequenceOverflow.cpp b/test/SequenceOverflow.cpp index ca35a14..573777e 100644 --- a/test/SequenceOverflow.cpp +++ b/test/SequenceOverflow.cpp @@ -26,8 +26,6 @@ class SequenceOverflow : public SequenceSerialization ~SequenceOverflow() { - //4 because of the sequence header (no necessary padding) - EXPECT_EQ(ucdr_buffer_length(&reader), 4u); EXPECT_TRUE(reader.error); // To satisfy the base destructor diff --git a/test/fragmentation/ArrayFragmentation.cpp b/test/fragmentation/ArrayFragmentation.cpp new file mode 100644 index 0000000..43471c0 --- /dev/null +++ b/test/fragmentation/ArrayFragmentation.cpp @@ -0,0 +1,106 @@ +// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "../serialization/ArraySerialization.hpp" + +#define OFFSET 16 + +class ArrayFragmentation : public ArraySerialization +{ +public: + ArrayFragmentation() + { + ucdr_set_on_full_buffer_callback(&writer, on_full_buffer, this); + ucdr_set_on_full_buffer_callback(&reader, on_full_buffer, this); + std::memset(buffer2, 0, BUFFER_LENGTH); + for(int i = 0; i < BUFFER_LENGTH - OFFSET; ++i) + { + uint8_t_serialization(); + } + } + +protected: + static bool on_full_buffer(ucdrBuffer* ub, void* args) + { + ArrayFragmentation* obj = static_cast(args); + + ub->init = obj->buffer2; + ub->iterator = ub->init; + ub->final = ub->init + BUFFER_LENGTH; + + return false; + } + + uint8_t buffer2[BUFFER_LENGTH]; +}; + +TEST_F(ArrayFragmentation, Bool) +{ + bool_array_serialization(); +} + +TEST_F(ArrayFragmentation, Char) +{ + char_array_serialization(); +} + +TEST_F(ArrayFragmentation, Int8) +{ + int8_t_array_serialization(); +} + +TEST_F(ArrayFragmentation, Uint8) +{ + uint8_t_array_serialization(); +} + +TEST_F(ArrayFragmentation, Int16) +{ + int16_t_array_serialization(); +} + +TEST_F(ArrayFragmentation, Uint16) +{ + uint16_t_array_serialization(); +} + +TEST_F(ArrayFragmentation, Int32) +{ + int32_t_array_serialization(); +} + +TEST_F(ArrayFragmentation, Uint32) +{ + uint32_t_array_serialization(); +} + +TEST_F(ArrayFragmentation, Int64) +{ + int64_t_array_serialization(); +} + +TEST_F(ArrayFragmentation, Uint64) +{ + uint64_t_array_serialization(); +} + +TEST_F(ArrayFragmentation, Float) +{ + float_array_serialization(); +} + +TEST_F(ArrayFragmentation, Double) +{ + double_array_serialization(); +} diff --git a/test/fragmentation/BasicFragmentation.cpp b/test/fragmentation/BasicFragmentation.cpp new file mode 100644 index 0000000..d2d1809 --- /dev/null +++ b/test/fragmentation/BasicFragmentation.cpp @@ -0,0 +1,105 @@ +// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "../serialization/BasicSerialization.hpp" + +class BasicFragmentation : public BasicSerialization +{ +public: + BasicFragmentation() + { + ucdr_set_on_full_buffer_callback(&writer, on_full_buffer, this); + ucdr_set_on_full_buffer_callback(&reader, on_full_buffer, this); + std::memset(buffer2, 0, BUFFER_LENGTH); + for(int i = 0; i < BUFFER_LENGTH; ++i) + { + uint8_t_serialization(); + } + } + +protected: + static bool on_full_buffer(ucdrBuffer* ub, void* args) + { + BasicFragmentation* obj = static_cast(args); + + ub->init = obj->buffer2; + ub->iterator = ub->init; + ub->final = ub->init + BUFFER_LENGTH; + + return false; + } + + uint8_t buffer2[BUFFER_LENGTH]; +}; + +TEST_F(BasicFragmentation, Bool) +{ + bool_serialization(); +} + +TEST_F(BasicFragmentation, Char) +{ + char_serialization(); +} + +TEST_F(BasicFragmentation, Int8) +{ + int8_t_serialization(); +} + +TEST_F(BasicFragmentation, Uint8) +{ + uint8_t_serialization(); +} + +TEST_F(BasicFragmentation, Int16) +{ + int16_t_serialization(); +} + +TEST_F(BasicFragmentation, Uint16) +{ + uint16_t_serialization(); +} + +TEST_F(BasicFragmentation, Int32) +{ + int32_t_serialization(); +} + +TEST_F(BasicFragmentation, Uint32) +{ + uint32_t_serialization(); +} + +TEST_F(BasicFragmentation, Int64) +{ + int64_t_serialization(); +} + +TEST_F(BasicFragmentation, Uint64) +{ + uint64_t_serialization(); +} + +TEST_F(BasicFragmentation, Float) +{ + float_serialization(); +} + +TEST_F(BasicFragmentation, Double) +{ + double_serialization(); +} +