LCOV - code coverage report
Current view: top level - core/data - SPDataDecodeCbor.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 208 232 89.7 %
Date: 2024-05-12 00:16:13 Functions: 32 40 80.0 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2017-2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : #ifndef STAPPLER_DATA_SPDATADECODECBOR_H_
      25             : #define STAPPLER_DATA_SPDATADECODECBOR_H_
      26             : 
      27             : #include "SPDataCbor.h"
      28             : #include "SPDataValue.h"
      29             : 
      30             : namespace STAPPLER_VERSIONIZED stappler::data::cbor {
      31             : 
      32             : template <typename Interface>
      33             : struct Decoder : public Interface::AllocBaseType {
      34             :         using InterfaceType = Interface;
      35             :         using ValueType = ValueTemplate<Interface>;
      36             :         using StringType = typename InterfaceType::StringType;
      37             :         using BytesType = typename InterfaceType::BytesType;
      38             :         using ArrayType = typename ValueType::ArrayType;
      39             :         using DictionaryType = typename ValueType::DictionaryType;
      40             : 
      41       20700 :         Decoder(BytesViewTemplate<Endian::Network> &r) : r(r), back(nullptr) {
      42       20700 :                 stack.reserve(10);
      43       20700 :         }
      44             : 
      45      323350 :         void decodePositiveInt(uint8_t type, ValueType &v) {
      46      323350 :                 auto value = _readIntValue(r, type);
      47      323350 :                 v._type = ValueType::Type::INTEGER;
      48      323350 :                 v.intVal = (int64_t)value;
      49      323350 :         }
      50        4625 :         void decodeNegativeInt(uint8_t type, ValueType &v) {
      51        4625 :                 auto value = _readIntValue(r, type);
      52        4625 :                 v._type = ValueType::Type::INTEGER;
      53        4625 :                 v.intVal = (int64_t)(-1 - value);
      54        4625 :         }
      55             :         void decodeByteString(uint8_t type, ValueType &);
      56             :         void decodeCharString(uint8_t type, ValueType &);
      57             :         void decodeArray(uint8_t type, ValueType &);
      58             :         void decodeMap(uint8_t type, ValueType &);
      59             :         void decodeTaggedValue(uint8_t type, ValueType &);
      60             :         void decodeSimpleValue(uint8_t type, ValueType &);
      61             :         void decode(MajorTypeEncoded majorType, uint8_t type, ValueType &);
      62             :         void decode(ValueType &);
      63             : 
      64             :         template <typename Container>
      65             :         void decodeUndefinedLength(Container &, MajorTypeEncoded rootType);
      66             : 
      67             :         BytesViewTemplate<Endian::Network> r;
      68             :         StringType buf;
      69             :         ValueType *back;
      70             :         typename InterfaceType::template ArrayType<ValueType *> stack;
      71             : };
      72             : 
      73             : template <typename Interface>
      74             : template <typename Container>
      75         100 : void Decoder<Interface>::decodeUndefinedLength(Container &buf, MajorTypeEncoded rootType) {
      76         100 :         uint8_t type = 0;
      77         100 :         size_t size = 0, tmpSize = 0;
      78             :         do {
      79         300 :                 type = r.readUnsigned();
      80         300 :                 auto majorType = (MajorTypeEncoded)(type & toInt(Flags::MajorTypeMaskEncoded));
      81         300 :                 type = type & toInt(Flags::AdditionalInfoMask);
      82             : 
      83         300 :                 if (majorType != rootType && (majorType != MajorTypeEncoded::Simple || type != toInt(Flags::UndefinedLength))) {
      84             :                         //logTag("CBOR Coder", "malformed CBOR block: invalid ByteString sequence with MajorType: %d and Info: %d", toInt(majorType), type);
      85           0 :                         return;
      86             :                 }
      87             : 
      88         300 :                 size = size_t(_readIntValue(r, type));
      89         300 :                 tmpSize = buf.size();
      90         300 :                 size = min(r.size(), size);
      91         300 :                 buf.resize(tmpSize + size);
      92         300 :                 memcpy((void *)(buf.data() + tmpSize), r.data(), size);
      93         300 :                 r.offset(size);
      94         300 :         } while (type != toInt(Flags::UndefinedLength));
      95             : }
      96             : 
      97             : template <typename Interface>
      98      426462 : void Decoder<Interface>::decodeByteString(uint8_t type, ValueType &v) {
      99      426462 :         if (type != toInt(Flags::UndefinedLength)) {
     100      426412 :                 auto size = size_t(_readIntValue(r, type));
     101      426412 :                 size = min(r.size(), (size_t)size);
     102      426412 :                 v._type = ValueType::Type::BYTESTRING;
     103      426412 :                 v.bytesVal = new BytesType(r.data(), r.data() + size);
     104      426412 :                 r.offset(size);
     105             :         } else {
     106             :                 // variable-length string
     107          50 :                 BytesType ret;
     108          50 :                 decodeUndefinedLength(ret, MajorTypeEncoded::ByteString);
     109          50 :                 v._type = ValueType::Type::BYTESTRING;
     110          50 :                 v.bytesVal = new BytesType(std::move(ret));
     111          50 :         }
     112      426462 : }
     113             : 
     114             : template <typename Interface>
     115     2894606 : void Decoder<Interface>::decodeCharString(uint8_t type, ValueType &v) {
     116     2894606 :         if (type != toInt(Flags::UndefinedLength)) {
     117     2894556 :                 auto size = size_t(_readIntValue(r, type));
     118     2894556 :                 size = min(r.size(), (size_t)size);
     119     2894556 :                 v._type = ValueType::Type::CHARSTRING;
     120     2894556 :                 v.strVal = new StringType((char *)r.data(), size);
     121     2894556 :                 r.offset(size);
     122             :         } else {
     123             :                 // variable-length string
     124          50 :                 StringType ret;
     125          50 :                 decodeUndefinedLength(ret, MajorTypeEncoded::CharString);
     126          50 :                 ret[ret.length()] = 0;
     127          50 :                 v._type = ValueType::Type::CHARSTRING;
     128          50 :                 v.strVal = new StringType(std::move(ret));
     129          50 :         }
     130     2894606 : }
     131             : 
     132             : template <typename Interface>
     133      251400 : void Decoder<Interface>::decodeArray(uint8_t type, ValueType &ret) {
     134      251400 :         size_t size = maxOf<size_t>();
     135      251400 :         if (type != toInt(Flags::UndefinedLength)) {
     136      251000 :                 size = size_t(_readIntValue(r, type));
     137             :         } else {
     138         400 :                 type = 0;
     139             :         }
     140             : 
     141      251400 :         MajorTypeEncoded majorType = MajorTypeEncoded::Simple;
     142      251400 :         if (size > 0) {
     143      248200 :                 type = r.readUnsigned();
     144      248200 :                 majorType = MajorTypeEncoded(type & toInt(Flags::MajorTypeMaskEncoded));
     145      248200 :                 type = type & toInt(Flags::AdditionalInfoMask);
     146             :         } else {
     147        3200 :                 majorType = MajorTypeEncoded::Simple;
     148        3200 :                 type = toInt(Flags::UndefinedLength);
     149             :         }
     150             : 
     151      251400 :         ret._type = ValueType::Type::ARRAY;
     152      423900 :         ret.arrayVal = new ArrayType();
     153      251400 :         if (size != maxOf<size_t>()) {
     154      251000 :                 ret.arrayVal->reserve(size);
     155             :         }
     156             : 
     157      251400 :         while (
     158     1331956 :                         (!r.empty() || (
     159       14100 :                                         (majorType == MajorTypeEncoded::Unsigned || majorType == MajorTypeEncoded::Negative || majorType == MajorTypeEncoded::Simple)
     160       15150 :                                         && type < toInt(Flags::MaxAdditionalNumber)
     161             :                                 )
     162             :                         )
     163     1302706 :                         && size > 0
     164     2633612 :                         && !(majorType == MajorTypeEncoded::Simple && type == toInt(Flags::UndefinedLength))) {
     165     1065406 :                 ret.arrayVal->emplace_back(ValueType::Type::EMPTY);
     166     1065406 :                 decode(majorType, type, ret.arrayVal->back());
     167             : 
     168     1065406 :                 size --;
     169             : 
     170     1065406 :                 if (size > 0) {
     171      817606 :                         type = r.readUnsigned();
     172      817606 :                         majorType = (MajorTypeEncoded)(type & toInt(Flags::MajorTypeMaskEncoded));
     173      817606 :                         type = type & toInt(Flags::AdditionalInfoMask);
     174             :                 } else {
     175      247800 :                         majorType = MajorTypeEncoded::Simple;
     176      247800 :                         type = toInt(Flags::UndefinedLength);
     177             :                 }
     178             :         }
     179      251400 : }
     180             : 
     181             : template <typename Interface>
     182      782231 : void Decoder<Interface>::decodeMap(uint8_t type, ValueType &ret) {
     183      782231 :         size_t size = maxOf<size_t>();
     184      782231 :         if (type != toInt(Flags::UndefinedLength)) {
     185      782081 :                 size = size_t(_readIntValue(r, type));
     186             :         } else {
     187         150 :                 type = 0;
     188             :         }
     189             : 
     190      782231 :         MajorTypeEncoded majorType = MajorTypeEncoded::Simple;
     191      782231 :         if (size > 0) {
     192      782106 :                 type = r.readUnsigned();
     193      782106 :                 majorType = (MajorTypeEncoded)(type & toInt(Flags::MajorTypeMaskEncoded));
     194      782106 :                 type = type & toInt(Flags::AdditionalInfoMask);
     195             :         } else {
     196         125 :                 majorType = MajorTypeEncoded::Simple;
     197         125 :                 type = toInt(Flags::UndefinedLength);
     198             :         }
     199             : 
     200      782231 :         ret._type = ValueType::Type::DICTIONARY;
     201     1161656 :         ret.dictVal = new DictionaryType();
     202             : 
     203             :         if constexpr (Interface::usesMemoryPool()) {
     204      379425 :                 if (size != maxOf<size_t>()) {
     205      379425 :                         ret.dictVal->reserve(size);
     206             :                 }
     207             :         }
     208             : 
     209     9736241 :         while (!r.empty() && size > 0 && !(majorType == MajorTypeEncoded::Simple && type == toInt(Flags::UndefinedLength))) {
     210     4477005 :                 bool skip = false;
     211     4477005 :                 StringType parsedKey;
     212     4477005 :                 StringView key;
     213             : 
     214     4477005 :                 switch(majorType) {
     215         100 :                 case MajorTypeEncoded::Unsigned:
     216         100 :                         parsedKey = string::toString<Interface>(_readIntValue(r, type));
     217         100 :                         key = StringView(parsedKey);
     218         100 :                         break;
     219           0 :                 case MajorTypeEncoded::Negative:
     220           0 :                         parsedKey = string::toString<Interface>(int64_t(-1 - _readIntValue(r, type)));
     221           0 :                         key = StringView(parsedKey);
     222           0 :                         break;
     223           0 :                 case MajorTypeEncoded::ByteString:
     224           0 :                         if (type == toInt(Flags::UndefinedLength)) {
     225           0 :                                 decodeUndefinedLength(parsedKey, MajorTypeEncoded::ByteString);
     226           0 :                                 key = StringView(parsedKey);
     227             :                         } else {
     228           0 :                                 auto size = size_t(_readIntValue(r, type));
     229           0 :                                 key = StringView((char *)r.data(), size);
     230           0 :                                 r += size;
     231             :                         }
     232           0 :                         break;
     233     4476905 :                 case MajorTypeEncoded::CharString:
     234     4476905 :                         if (type == toInt(Flags::UndefinedLength)) {
     235           0 :                                 decodeUndefinedLength(parsedKey, MajorTypeEncoded::CharString);
     236           0 :                                 key = StringView(parsedKey);
     237             :                         } else {
     238     4476905 :                                 auto size = size_t(_readIntValue(r, type));
     239     4476905 :                                 key = StringView((char *)r.data(), size);
     240     4476905 :                                 r += size;
     241             :                         }
     242     4476905 :                         break;
     243           0 :                 case MajorTypeEncoded::Array:
     244             :                 case MajorTypeEncoded::Map:
     245             :                 case MajorTypeEncoded::Tag:
     246             :                 case MajorTypeEncoded::Simple:
     247           0 :                         decode(majorType, type, ret);
     248           0 :                         break;
     249             :                 }
     250             : 
     251             : 
     252     4477005 :                 if (key.empty()) {
     253             :                         //logTag("CBOR Coder", "Key can not be converted to string, skip pair");
     254           0 :                         skip = true;
     255             :                 }
     256             : 
     257     4477005 :                 if (!r.empty()) {
     258     4477005 :                         type = r.readUnsigned();
     259     4477005 :                         majorType = (MajorTypeEncoded)(type & toInt(Flags::MajorTypeMaskEncoded));
     260     4477005 :                         type = type & toInt(Flags::AdditionalInfoMask);
     261             : 
     262     4477005 :                         if (majorType == MajorTypeEncoded::Simple && type == toInt(Flags::UndefinedLength)) {
     263           0 :                                 break;
     264             :                         }
     265             : 
     266     4477005 :                         if (!skip) {
     267     4477005 :                                 decode(majorType, type, ret.dictVal->emplace(key.str<Interface>(), ValueType::Type::EMPTY).first->second);
     268             :                         } else {
     269           0 :                                 ValueType val;
     270           0 :                                 decode(majorType, type, val);
     271           0 :                         }
     272             : 
     273     4477005 :                         size --;
     274             : 
     275     4477005 :                         if (size > 0) {
     276     3695049 :                                 type = r.readUnsigned();
     277     3695049 :                                 majorType = (MajorTypeEncoded)(type & toInt(Flags::MajorTypeMaskEncoded));
     278     3695049 :                                 type = type & toInt(Flags::AdditionalInfoMask);
     279             :                         } else {
     280      781956 :                                 majorType = MajorTypeEncoded::Simple;
     281      781956 :                                 type = toInt(Flags::UndefinedLength);
     282             :                         }
     283             :                 }
     284             :         }
     285      782231 : }
     286             : 
     287             : template <typename Interface>
     288         300 : void Decoder<Interface>::decodeTaggedValue(uint8_t type, ValueType &ret) {
     289         300 :         /* auto tagValue = */ _readIntValue(r, type);
     290         300 :         decode(ret);
     291         300 : }
     292             : 
     293             : template <typename Interface>
     294      880437 : void Decoder<Interface>::decodeSimpleValue(uint8_t type, ValueType &ret) {
     295      880437 :         if (type == toInt(Flags::Simple8Bit)) {
     296         100 :                 ret._type = ValueType::Type::INTEGER;
     297         100 :                 ret.intVal = r.readUnsigned();
     298      880337 :         } else if (type == toInt(Flags::AdditionalFloat16Bit)) {
     299      428862 :                 ret._type = ValueType::Type::DOUBLE;
     300      428862 :                 ret.doubleVal = (double)r.readFloat16();
     301      451475 :         } else if (type == toInt(Flags::AdditionalFloat32Bit)) {
     302         400 :                 ret._type = ValueType::Type::DOUBLE;
     303         400 :                 ret.doubleVal = (double)r.readFloat32();
     304      451075 :         } else if (type == toInt(Flags::AdditionalFloat64Bit)) {
     305         575 :                 ret._type = ValueType::Type::DOUBLE;
     306         575 :                 ret.doubleVal = (double)r.readFloat64();
     307      450500 :         } else if (type == toInt(SimpleValue::Null) || type == toInt(SimpleValue::Undefined)) {
     308        2025 :                 ret._type = ValueType::Type::EMPTY;
     309      448475 :         } else if (type == toInt(SimpleValue::True)) {
     310      135325 :                 ret._type = ValueType::Type::BOOLEAN;
     311      135325 :                 ret.boolVal = true;
     312      313150 :         } else if (type == toInt(SimpleValue::False)) {
     313      313100 :                 ret._type = ValueType::Type::BOOLEAN;
     314      313100 :                 ret.boolVal = false;
     315             :         } else {
     316          50 :                 ret._type = ValueType::Type::INTEGER;
     317          50 :                 ret.intVal = type;
     318             :         }
     319      880437 : }
     320             : 
     321             : template <typename Interface>
     322     5563411 : void Decoder<Interface>::decode(MajorTypeEncoded majorType, uint8_t type, ValueType &ret) {
     323     5563411 :         switch(majorType) {
     324      323350 :         case MajorTypeEncoded::Unsigned:
     325      323350 :                 decodePositiveInt(type, ret);
     326      323350 :                 break;
     327        4625 :         case MajorTypeEncoded::Negative:
     328        4625 :                 decodeNegativeInt(type, ret);
     329        4625 :                 break;
     330      426462 :         case MajorTypeEncoded::ByteString:
     331      426462 :                 decodeByteString(type, ret);
     332      426462 :                 break;
     333     2894606 :         case MajorTypeEncoded::CharString:
     334     2894606 :                 decodeCharString(type, ret);
     335     2894606 :                 break;
     336      251400 :         case MajorTypeEncoded::Array:
     337      251400 :                 decodeArray(type, ret);
     338      251400 :                 break;
     339      782231 :         case MajorTypeEncoded::Map:
     340      782231 :                 decodeMap(type, ret);
     341      782231 :                 break;
     342         300 :         case MajorTypeEncoded::Tag:
     343         300 :                 decodeTaggedValue(type, ret);
     344         300 :                 break;
     345      880437 :         case MajorTypeEncoded::Simple:
     346      880437 :                 decodeSimpleValue(type, ret);
     347      880437 :                 break;
     348             :         }
     349     5563411 : }
     350             : 
     351             : template <typename Interface>
     352       21000 : void Decoder<Interface>::decode(ValueType &ret) {
     353             :         uint8_t type;
     354             :         MajorTypeEncoded majorType;
     355             : 
     356       21000 :         if (!r.empty()) {
     357       21000 :                 type = r.readUnsigned();
     358       21000 :                 majorType = (MajorTypeEncoded)(type & toInt(Flags::MajorTypeMaskEncoded));
     359       21000 :                 type = type & toInt(Flags::AdditionalInfoMask);
     360       21000 :                 decode(majorType, type, ret);
     361             :         }
     362       21000 : }
     363             : 
     364             : template <typename Interface>
     365       20700 : auto read(BytesViewTemplate<Endian::Network> &data) -> ValueTemplate<Interface> {
     366             :         // read CBOR id ( 0xd9d9f7 )
     367       20700 :         if (data.size() <= 3 || data[0] != 0xd9 || data[1] != 0xd9 || data[2] != 0xf7) {
     368           0 :                 return ValueTemplate<Interface>();
     369             :         }
     370             : 
     371       20700 :         BytesViewTemplate<Endian::Network> reader(data);
     372       20700 :         reader.offset(3);
     373             : 
     374       20700 :         ValueTemplate<Interface> ret;
     375       20700 :         Decoder<Interface> dec(reader);
     376       20700 :         dec.decode(ret);
     377       20700 :         data = dec.r;
     378       20700 :         return ret;
     379       20700 : }
     380             : 
     381             : template <typename Interface>
     382             : auto read(BytesViewTemplate<Endian::Little> &data) -> ValueTemplate<Interface> {
     383             :         // read CBOR id ( 0xd9d9f7 )
     384             :         if (data.size() <= 3 || data[0] != 0xd9 || data[1] != 0xd9 || data[2] != 0xf7) {
     385             :                 return ValueTemplate<Interface>();
     386             :         }
     387             : 
     388             :         BytesViewTemplate<Endian::Network> reader(data);
     389             :         reader.offset(3);
     390             : 
     391             :         ValueTemplate<Interface> ret;
     392             :         Decoder<Interface> dec(reader);
     393             :         dec.decode(ret);
     394             :         data = dec.r;
     395             :         return ret;
     396             : }
     397             : 
     398             : template <typename Interface, typename Container>
     399       20700 : auto read(const Container &data) -> ValueTemplate<Interface> {
     400       20700 :         BytesViewTemplate<Endian::Network> reader((const uint8_t*)data.data(), data.size());
     401       41400 :         return read<Interface>(reader);
     402             : }
     403             : 
     404             : }
     405             : 
     406             : #endif /* STAPPLER_DATA_SPDATADECODECBOR_H_ */

Generated by: LCOV version 1.14