Coverage Report

Created: 2026-09-03 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/arduinojson/src/ArduinoJson/MsgPack/MsgPackExtension.hpp
Line
Count
Source
1
#pragma once
2
3
#include <ArduinoJson/Variant/Converter.hpp>
4
5
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
6
7
class MsgPackExtension {
8
 public:
9
0
  MsgPackExtension() : data_(nullptr), size_(0), type_(0) {}
10
  explicit MsgPackExtension(int8_t type, const void* data, size_t size)
11
0
      : data_(data), size_(size), type_(type) {}
12
13
0
  int8_t type() const {
14
0
    return type_;
15
0
  }
16
17
0
  const void* data() const {
18
0
    return data_;
19
0
  }
20
21
0
  size_t size() const {
22
0
    return size_;
23
0
  }
24
25
 private:
26
  const void* data_;
27
  size_t size_;
28
  int8_t type_;
29
};
30
31
template <>
32
struct Converter<MsgPackExtension> : private detail::VariantAttorney {
33
0
  static bool toJson(MsgPackExtension src, JsonVariant dst) {
34
0
    auto data = getData(dst);
35
0
    if (!data)
36
0
      return false;
37
0
38
0
    auto resources = getResourceManager(dst);
39
0
    detail::VariantImpl::clear(data, resources);
40
0
41
0
    if (!src.data())
42
0
      return true;
43
0
44
0
    uint8_t format, sizeBytes;
45
0
    if (src.size() >= 0x10000) {
46
0
      format = 0xc9;  // ext 32
47
0
      sizeBytes = 4;
48
0
    } else if (src.size() >= 0x100) {
49
0
      format = 0xc8;  // ext 16
50
0
      sizeBytes = 2;
51
0
    } else if (src.size() == 16) {
52
0
      format = 0xd8;  // fixext 16
53
0
      sizeBytes = 0;
54
0
    } else if (src.size() == 8) {
55
0
      format = 0xd7;  // fixext 8
56
0
      sizeBytes = 0;
57
0
    } else if (src.size() == 4) {
58
0
      format = 0xd6;  // fixext 4
59
0
      sizeBytes = 0;
60
0
    } else if (src.size() == 2) {
61
0
      format = 0xd5;  // fixext 2
62
0
      sizeBytes = 0;
63
0
    } else if (src.size() == 1) {
64
0
      format = 0xd4;  // fixext 1
65
0
      sizeBytes = 0;
66
0
    } else {
67
0
      format = 0xc7;  // ext 8
68
0
      sizeBytes = 1;
69
0
    }
70
0
71
0
    auto str = resources->createString(src.size() + 2 + sizeBytes);
72
0
    if (!str)
73
0
      return false;
74
0
75
0
    resources->saveString(str);
76
0
    auto ptr = reinterpret_cast<uint8_t*>(str->data);
77
0
    *ptr++ = uint8_t(format);
78
0
    for (uint8_t i = 0; i < sizeBytes; i++)
79
0
      *ptr++ = uint8_t(src.size() >> (sizeBytes - i - 1) * 8 & 0xff);
80
0
    *ptr++ = uint8_t(src.type());
81
0
    memcpy(ptr, src.data(), src.size());
82
0
    data->setRawString(str);
83
0
    return true;
84
0
  }
85
86
0
  static MsgPackExtension fromJson(JsonVariantConst src) {
87
0
    auto data = getData(src);
88
0
    if (!data)
89
0
      return {};
90
0
    auto rawstr = data->asRawString();
91
0
    if (rawstr.size() == 0)
92
0
      return {};
93
0
    auto p = reinterpret_cast<const uint8_t*>(rawstr.c_str());
94
0
95
0
    size_t payloadSize = 0;
96
0
    uint8_t headerSize = 0;
97
0
98
0
    const uint8_t& code = p[0];
99
0
100
0
    if (code >= 0xd4 && code <= 0xd8) {  // fixext 1
101
0
      headerSize = 2;
102
0
      payloadSize = size_t(1) << (code - 0xd4);
103
0
    }
104
0
105
0
    if (code >= 0xc7 && code <= 0xc9) {
106
0
      uint8_t sizeBytes = uint8_t(1 << (code - 0xc7));
107
0
      for (uint8_t i = 0; i < sizeBytes; i++)
108
0
        payloadSize = (payloadSize << 8) | p[1 + i];
109
0
      headerSize = uint8_t(2 + sizeBytes);
110
0
    }
111
0
112
0
    if (rawstr.size() == headerSize + payloadSize)
113
0
      return MsgPackExtension(int8_t(p[headerSize - 1]), p + headerSize,
114
0
                              payloadSize);
115
0
116
0
    return {};
117
0
  }
118
119
0
  static bool checkJson(JsonVariantConst src) {
120
0
    return fromJson(src).data() != nullptr;
121
0
  }
122
};
123
124
ARDUINOJSON_END_PUBLIC_NAMESPACE