LCOV - code coverage report
Current view: top level - libs/bsw/cpp2someip/src - EtlString.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 97 97
Test Date: 2026-09-11 12:05:06 Functions: 100.0 % 8 8

            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              : /**
      12              :  * Contains
      13              :  */
      14              : 
      15              : #include "someip/EtlString.h"
      16              : 
      17              : namespace someip
      18              : {
      19              : // protected
      20              : // static
      21           18 : bool StringParser::parseBom(SomeIpParser& parser, char const* const bom, uint32_t const bomLength)
      22              : {
      23           18 :     char ch = '\0';
      24              : 
      25           53 :     for (uint32_t i = 0U; i < bomLength; ++i)
      26              :     {
      27           37 :         parser >> ch;
      28           37 :         if ((bom != nullptr) && (ch != bom[i]))
      29              :         {
      30            2 :             parser.setFailure();
      31            2 :             return false;
      32              :         }
      33              :     }
      34              : 
      35           16 :     return true;
      36              : }
      37              : 
      38              : // protected
      39              : // static
      40           15 : void StringParser::readAndSkipNulls(SomeIpParser& parser, ::etl::istring& str, uint32_t const nulls)
      41              : {
      42           15 :     char ch = '\0';
      43              : 
      44              :     // read in nulls
      45           33 :     for (uint32_t i = 0U; i < nulls; ++i)
      46              :     {
      47           20 :         parser >> ch;
      48           20 :         if (ch != '\0')
      49              :         {
      50            2 :             parser.setFailure();
      51            2 :             str.clear();
      52            2 :             break;
      53              :         }
      54              :     }
      55           15 : }
      56              : 
      57              : // protected
      58              : // static
      59           12 : void StringSerializer::writeStringBytes(
      60              :     SomeIpSerializer& serializer,
      61              :     ::etl::istring const& str,
      62              :     Encoding const encoding,
      63              :     uint32_t const nulls)
      64              : {
      65              :     // write out the BOM
      66           12 :     char const* const bom = ::someip::internal::EncodingHelper::bom(encoding);
      67           12 :     if (bom != nullptr)
      68              :     {
      69           11 :         uint32_t const bomLength = ::someip::internal::EncodingHelper::encodingLength(encoding);
      70              : 
      71           34 :         for (uint32_t i = 0U; i < bomLength; ++i)
      72              :         {
      73           23 :             serializer << bom[i];
      74              :         }
      75              : 
      76           11 :         uint32_t const length = static_cast<uint32_t>(str.size());
      77              : 
      78              :         // write out each element
      79           68 :         for (uint32_t i = 0U; i < length; ++i)
      80              :         {
      81           57 :             serializer << str[i];
      82              :         }
      83              : 
      84              :         // pad with null terminators
      85           34 :         for (uint32_t i = 0U; i < nulls; ++i)
      86              :         {
      87           23 :             serializer << '\0';
      88              :         }
      89              :     }
      90           12 : }
      91              : 
      92              : /*
      93              :  * StaticStringParser
      94              :  */
      95              : // private
      96              : // static
      97            2 : void StaticStringParser::readUtf8Bytes(
      98              :     SomeIpParser& parser, ::etl::istring& str, uint32_t const terminationLength)
      99              : {
     100            2 :     char ch = '\0';
     101              : 
     102            2 :     size_t const strMaxSize = str.max_size();
     103           13 :     for (size_t i = 0U; i < (strMaxSize - 1U); ++i)
     104              :     {
     105           12 :         parser >> ch;
     106           12 :         if (ch == '\0')
     107              :         {
     108            1 :             break;
     109              :         }
     110           11 :         str += ch;
     111              :     }
     112              : 
     113            2 :     if ((strMaxSize - 1U) == str.size())
     114              :     {
     115            1 :         readAndSkipNulls(parser, str, terminationLength);
     116              :     }
     117              :     else
     118              :     {
     119            1 :         readAndSkipNulls(
     120            1 :             parser, str, static_cast<uint32_t>(strMaxSize - str.size()) + (terminationLength - 2U));
     121              :     }
     122            2 : }
     123              : 
     124              : // private
     125              : // static
     126            8 : void StaticStringParser::readUtf16Bytes(
     127              :     SomeIpParser& parser, ::etl::istring& str, uint32_t const terminationLength)
     128              : {
     129              :     // for UTF16 we look for 2 null terminators
     130            8 :     char ch  = '\0';
     131            8 :     char ch2 = '\0';
     132              : 
     133            8 :     size_t const strMaxSize = str.max_size();
     134           54 :     for (size_t i = 0U; i < (strMaxSize - 1U); ++i)
     135              :     {
     136           48 :         parser >> ch;
     137           48 :         if (ch == '\0')
     138              :         {
     139            3 :             parser >> ch2;
     140            3 :             if (ch2 == '\0')
     141              :             {
     142            2 :                 break;
     143              :             }
     144              : 
     145            1 :             ++i;
     146              : 
     147            1 :             str += ch;
     148            1 :             str += ch2;
     149              :         }
     150              :         else
     151              :         {
     152           45 :             str += ch;
     153              :         }
     154              :     }
     155              : 
     156            8 :     if ((strMaxSize - 1U) == str.size())
     157              :     {
     158            6 :         readAndSkipNulls(parser, str, terminationLength);
     159              :     }
     160              :     else
     161              :     {
     162            2 :         readAndSkipNulls(
     163            2 :             parser, str, static_cast<uint32_t>(strMaxSize - str.size()) + (terminationLength - 3U));
     164              :     }
     165            8 : }
     166              : 
     167              : // static
     168           14 : void StaticStringParser::readString(
     169              :     SomeIpParser& parser, ::etl::istring& str, Encoding const encoding)
     170              : {
     171           14 :     if (!parser.isGood())
     172              :     {
     173            1 :         return;
     174              :     }
     175              : 
     176           13 :     str.clear();
     177              : 
     178           13 :     char const* const bom    = ::someip::internal::EncodingHelper::bom(encoding);
     179           13 :     uint32_t const bomLength = ::someip::internal::EncodingHelper::encodingLength(encoding);
     180              :     uint32_t const terminationLength
     181           13 :         = ::someip::internal::EncodingHelper::terminationLength(encoding);
     182              : 
     183              :     // make sure we have enough bytes!
     184           13 :     if (parser.bytesAvailable() < (((bomLength + str.max_size()) - 1U) + terminationLength))
     185              :     {
     186            2 :         parser.setFailure();
     187            2 :         return;
     188              :     }
     189              : 
     190              :     // read in the BOM
     191           11 :     if (!parseBom(parser, bom, bomLength))
     192              :     {
     193            1 :         return;
     194              :     }
     195              : 
     196           10 :     if (encoding == Encoding::SOMEIP_ENCODING_UTF8)
     197              :     {
     198            2 :         readUtf8Bytes(parser, str, terminationLength);
     199              :     }
     200              :     else
     201              :     {
     202            8 :         readUtf16Bytes(parser, str, terminationLength);
     203              :     }
     204              : }
     205              : 
     206              : /*
     207              :  * StaticStringSerializer
     208              :  */
     209              : // static
     210           11 : void StaticStringSerializer::writeString(
     211              :     SomeIpSerializer& serializer, ::etl::istring const& str, Encoding const encoding)
     212              : {
     213           11 :     if (!serializer.isGood())
     214              :     {
     215            1 :         return;
     216              :     }
     217              : 
     218              :     uint32_t const terminationLength
     219           10 :         = ::someip::internal::EncodingHelper::terminationLength(encoding);
     220              :     uint32_t const nulls
     221           10 :         = static_cast<uint32_t>((str.max_size() - str.size()) - 1U) + terminationLength;
     222              : 
     223           10 :     writeStringBytes(serializer, str, encoding, nulls);
     224              : }
     225              : 
     226              : /*
     227              :  * DynamicStringParserBase
     228              :  */
     229            7 : void DynamicStringParserBase::parseStringBytes(
     230              :     SomeIpParser& parser, ::etl::istring& str, Encoding const encoding, uint32_t const numBytes)
     231              : {
     232            7 :     char const* const bom    = ::someip::internal::EncodingHelper::bom(encoding);
     233            7 :     uint32_t const bomLength = ::someip::internal::EncodingHelper::encodingLength(encoding);
     234              :     uint32_t const terminationLength
     235            7 :         = ::someip::internal::EncodingHelper::terminationLength(encoding);
     236              : 
     237              :     // verify we have the correct BOM
     238            7 :     if (!parseBom(parser, bom, bomLength))
     239              :     {
     240            2 :         return;
     241              :     }
     242              : 
     243            6 :     uint32_t const usefulBytes = numBytes - bomLength - terminationLength;
     244              : 
     245            6 :     if (usefulBytes >= str.max_size())
     246              :     {
     247            1 :         parser.setFailure();
     248            1 :         return;
     249              :     }
     250              : 
     251            5 :     char ch = '\0';
     252              : 
     253           34 :     for (size_t i = 0U; i < usefulBytes; ++i)
     254              :     {
     255           29 :         parser >> ch;
     256           29 :         str += ch;
     257              :     }
     258              : 
     259            5 :     readAndSkipNulls(parser, str, terminationLength);
     260              : }
     261              : 
     262              : } // namespace someip
        

Generated by: LCOV version 2.0-1