LCOV - code coverage report
Current view: top level - libs/bsw/cpp2someip/include/someip - SomeIpSerializer.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 97.2 % 36 35
Test Date: 2026-09-11 12:05:06 Functions: 100.0 % 25 25

            Line data    Source code
       1              : /********************************************************************************
       2              :  * Copyright (c) 2026 Accenture
       3              :  *
       4              :  * This program and the accompanying materials are made available under the
       5              :  * terms of the Apache License Version 2.0 which is available at
       6              :  * https://www.apache.org/licenses/LICENSE-2.0
       7              :  *
       8              :  * SPDX-License-Identifier: Apache-2.0
       9              :  ********************************************************************************/
      10              : 
      11              : #pragma once
      12              : 
      13              : #include "someip/ISomeIpSerializable.h"
      14              : #include "someip/SomeIpStreamer.h"
      15              : 
      16              : #include <etl/span.h>
      17              : #include <etl/unaligned_type.h>
      18              : #include <cmath>
      19              : 
      20              : namespace someip
      21              : {
      22              : /**
      23              :  * The SomeIpSerializer class provides an easy way to serialize Some/IP
      24              :  * types into raw bytes. This class also provides a helper function for
      25              :  * writing out a length field. The class is created with a buffer to
      26              :  * ensure that buffer overwrites do not happen. If a serializer object
      27              :  * enters an error state all subsequent writes will be empty operations;
      28              :  * they will not cause other problems.
      29              :  *
      30              :  * \section SomeIpSerializer_example Usage example
      31              :  * \code{.cpp}
      32              :  * void serialize(::etl::span<uint8_t> target, const ISomeIpSerializable& obj)
      33              :  * {
      34              :  *     SomeIpSerializer serializer(target);
      35              :  *
      36              :  *     // create a promise so we can write the length when we are done
      37              :  *     {
      38              :  *         LengthHelper<uint8_t> promise(serializer);
      39              :  *
      40              :  *         size_t position = serializer.getCurrentPosition();
      41              :  *
      42              :  *         // write out the object
      43              :  *         serializer << obj;
      44              :  *
      45              :  *         // The length will be written when the LengthHelper goes out of scope.
      46              :  *     }
      47              :  *     // write more data
      48              :  *     serializer << uint32_t(42);
      49              :  * }
      50              :  * \endcode
      51              :  */
      52              : class SomeIpSerializer : public SomeIpStreamer
      53              : {
      54              : public:
      55              :     /**
      56              :      * Create a new SomeIpSerializer that uses the specified buffer.
      57              :      *
      58              :      * \param buffer The buffer the serializer will use to write bytes.
      59              :      */
      60              :     explicit SomeIpSerializer(::etl::span<uint8_t> buffer);
      61              : 
      62              :     /**
      63              :      * Returns the underlying payload as a const buffer.
      64              :      */
      65           11 :     ::etl::span<uint8_t const> getPayload() const { return _buffer.first(_currentPos); }
      66              : 
      67          140 :     size_t getCurrentPosition() const { return _currentPos; }
      68              : 
      69              :     /**
      70              :      * Returns how much more data can be written.
      71              :      */
      72           21 :     size_t bytesAvailable() const { return _buffer.size() - _currentPos; }
      73              : 
      74              :     /**
      75              :      * Writes out a bool value. The value is converted to a uint8_t and
      76              :      * then written to the byte buffer.
      77              :      *
      78              :      * \param item The boolean value to write.
      79              :      *
      80              :      * \note If the serializer is in an error state then no value will be written
      81              :      * to the buffer. If there is no space for the value then the serializer will
      82              :      * set to an error state.
      83              :      */
      84            2 :     void operator<<(bool const item) { write_byte(item); }
      85              : 
      86              :     /**
      87              :      * Writes out a char value. The value is converted to a uint8_t and
      88              :      * then written to the byte buffer.
      89              :      *
      90              :      * \param item The char value to write.
      91              :      *
      92              :      * \note If the serializer is in an error state then no value will be written
      93              :      * to the buffer. If there is no space for the value then the serializer will
      94              :      * set to an error state.
      95              :      */
      96          103 :     void operator<<(char const item) { write_byte(item); }
      97              : 
      98              :     /**
      99              :      * Writes out a uint8_t value.
     100              :      *
     101              :      * \param item The uint8_t value to write.
     102              :      *
     103              :      * \note If the serializer is in an error state then no value will be written
     104              :      * to the buffer. If there is no space for the value then the serializer will
     105              :      * set to an error state.
     106              :      */
     107         1497 :     void operator<<(uint8_t const item) { write_byte(item); }
     108              : 
     109              :     /**
     110              :      * Writes out an int8_t value.
     111              :      *
     112              :      * \param item The int8_t value to write.
     113              :      *
     114              :      * \note If the serializer is in an error state then no value will be written
     115              :      * to the buffer. If there is no space for the value then the serializer will
     116              :      * set to an error state.
     117              :      */
     118            3 :     void operator<<(int8_t const item) { write_byte(item); }
     119              : 
     120              :     /**
     121              :      * Writes out a uint16_t value in the currently selected endianness.
     122              :      *
     123              :      * \param item The uint16_t value to write.
     124              :      *
     125              :      * \note If the serializer is in an error state then no value will be written
     126              :      * to the buffer. If there is no space for the value then the serializer will
     127              :      * set to an error state.
     128              :      */
     129           13 :     void operator<<(uint16_t const item) { write(item); }
     130              : 
     131              :     /**
     132              :      * Writes out an int16_t value in the currently selected endianness.
     133              :      *
     134              :      * \param item The int16_t value to write.
     135              :      *
     136              :      * \note If the serializer is in an error state then no value will be written
     137              :      * to the buffer. If there is no space for the value then the serializer will
     138              :      * set to an error state.
     139              :      */
     140            3 :     void operator<<(int16_t const item) { write(item); }
     141              : 
     142              :     /**
     143              :      * Writes out a uint32_t value in the currently selected endianness.
     144              :      *
     145              :      * \param item The uint32_t value to write.
     146              :      *
     147              :      * \note If the serializer is in an error state then no value will be written
     148              :      * to the buffer. If there is no space for the value then the serializer will
     149              :      * set to an error state.
     150              :      */
     151            5 :     void operator<<(uint32_t const item) { write(item); }
     152              : 
     153              :     /**
     154              :      * Writes out an int32_t value in the currently selected endianness.
     155              :      *
     156              :      * \param item The int32_t value to write.
     157              :      *
     158              :      * \note If the serializer is in an error state then no value will be written
     159              :      * to the buffer. If there is no space for the value then the serializer will
     160              :      * set to an error state.
     161              :      */
     162            3 :     void operator<<(int32_t const item) { write(item); }
     163              : 
     164              :     /**
     165              :      * Writes out a uint64_t value in the currently selected endianness.
     166              :      *
     167              :      * \param item The uint64_t value to write.
     168              :      *
     169              :      * \note If the serializer is in an error state then no value will be written
     170              :      * to the buffer. If there is no space for the value then the serializer will
     171              :      * set to an error state.
     172              :      */
     173            4 :     void operator<<(uint64_t const item) { write(item); }
     174              : 
     175              :     /**
     176              :      * Writes out an int64_t value in the currently selected endianness.
     177              :      *
     178              :      * \param item The int64_t value to write.
     179              :      *
     180              :      * \note If the serializer is in an error state then no value will be written
     181              :      * to the buffer. If there is no space for the value then the serializer will
     182              :      * set to an error state.
     183              :      */
     184            3 :     void operator<<(int64_t const item) { write(item); }
     185              : 
     186              :     /**
     187              :      * Writes out a float value according to the IEEE-754 standard.
     188              :      *
     189              :      * \param item The float value to write.
     190              :      *
     191              :      * \note If the serializer is in an error state then no value will be written
     192              :      * to the buffer. If there is no space for the value then the serializer will
     193              :      * set to an error state.
     194              :      */
     195              :     void operator<<(float_t item);
     196              : 
     197              :     /**
     198              :      * Writes out a double value according to the IEEE-754 standard.
     199              :      *
     200              :      * \param item The double value to write.
     201              :      *
     202              :      * \note If the serializer is in an error state then no value will be written
     203              :      * to the buffer. If there is no space for the value then the serializer will
     204              :      * set to an error state.
     205              :      */
     206              :     void operator<<(double_t item);
     207              : 
     208              :     /**
     209              :      * Writes out the ISomeIpSerializable object. This calls the
     210              :      * ISomeIpSerializable::serializeToArray method.
     211              :      *
     212              :      * \param item The serializable object to write.
     213              :      *
     214              :      * \note If the serializer is in an error state then no value will be written
     215              :      * to the buffer. If an error happens during the call to serializeToArray then
     216              :      * the serializer will be set to an error state. The data in the underlying buffer may
     217              :      * be corrupted and incomplete and should not be used.
     218              :      */
     219              :     void operator<<(ISomeIpSerializable const& item);
     220              : 
     221              :     void operator<<(::etl::span<uint8_t const> data);
     222              : 
     223              :     /**
     224              :      * Returns a buffer of a specified length at the current serializer position, where something
     225              :      * can be written later. This is used for writing sizes of dynamically sized types.
     226              :      *
     227              :      * In case the requested number of bytes is not available, an error is be set and empty slice is
     228              :      * returned.
     229              :      *
     230              :      * \param length The number of bytes that are requested.
     231              :      * \return Byte buffer at the current position.
     232              :      */
     233           12 :     ::etl::span<uint8_t> skipBytes(size_t const length)
     234              :     {
     235           12 :         size_t const start = _currentPos;
     236              : 
     237           12 :         if (!hasSpace(length))
     238              :         {
     239            0 :             return ::etl::span<uint8_t>();
     240              :         }
     241              : 
     242           12 :         _currentPos += length;
     243           12 :         return _buffer.subspan(start, length);
     244              :     }
     245              : 
     246              :     void writeTypeFieldSize(uint32_t fieldType);
     247              : 
     248              : private:
     249              :     template<typename T>
     250           31 :     void write(T const item)
     251              :     {
     252           31 :         if (hasSpace(sizeof(T)) && isGood())
     253              :         {
     254           19 :             if (_bigEndian)
     255              :             {
     256           12 :                 ::etl::unaligned_type_ext<T, ::etl::endian::big>{&_buffer[_currentPos]} = item;
     257              :             }
     258              :             else
     259              :             {
     260            7 :                 ::etl::unaligned_type_ext<T, ::etl::endian::little>{&_buffer[_currentPos]} = item;
     261              :             }
     262           19 :             _currentPos += sizeof(T);
     263              :         }
     264           31 :     }
     265              : 
     266              :     template<typename T>
     267         1605 :     void write_byte(T const item)
     268              :     {
     269         1605 :         if (hasSpace(1) && isGood())
     270              :         {
     271         1601 :             _buffer[_currentPos] = static_cast<uint8_t>(item);
     272         1601 :             _currentPos++;
     273              :         }
     274         1605 :     }
     275              : 
     276         1669 :     bool hasSpace(size_t const length)
     277              :     {
     278         1669 :         if (_currentPos + length > _buffer.size())
     279              :         {
     280           19 :             _errorCode = ErrorCode::SOMEIP_ERROR;
     281           19 :             return false;
     282              :         }
     283              : 
     284         1650 :         return true;
     285              :     }
     286              : 
     287              :     ::etl::span<uint8_t> _buffer;
     288              :     size_t _currentPos;
     289              : };
     290              : 
     291              : } // namespace someip
        

Generated by: LCOV version 2.0-1