Coverage Report

Created: 2026-07-16 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/arduinojson/src/ArduinoJson/Memory/StringNode.hpp
Line
Count
Source
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2026, Benoit BLANCHON
3
// MIT License
4
5
#pragma once
6
7
#include <ArduinoJson/Memory/Allocator.hpp>
8
#include <ArduinoJson/Namespace.hpp>
9
#include <ArduinoJson/Polyfills/assert.hpp>
10
#include <ArduinoJson/Polyfills/integer.hpp>
11
#include <ArduinoJson/Polyfills/limits.hpp>
12
13
#include <stddef.h>  // offsetof
14
15
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
16
17
struct StringNode {
18
  // Use the same type as SlotId to store the reference count
19
  // (there can never be more references than slots)
20
  using references_type = uint_t<ARDUINOJSON_SLOT_ID_SIZE * 8>;
21
22
  using length_type = uint_t<ARDUINOJSON_STRING_LENGTH_SIZE * 8>;
23
24
  struct StringNode* next;
25
  references_type references;
26
  length_type length;
27
  char data[1];
28
29
  static constexpr size_t maxLength = numeric_limits<length_type>::highest();
30
31
9.03k
  static constexpr size_t sizeForLength(size_t n) {
32
9.03k
    return n + 1 + offsetof(StringNode, data);
33
9.03k
  }
34
35
6.34k
  static StringNode* create(size_t length, Allocator* allocator) {
36
6.34k
    if (length > maxLength)
37
113
      return nullptr;
38
6.23k
    auto size = sizeForLength(length);
39
6.23k
    if (size < length)  // integer overflow
40
0
      return nullptr;   // (not testable on 64-bit)
41
6.23k
    auto node = reinterpret_cast<StringNode*>(allocator->allocate(size));
42
6.23k
    if (node) {
43
6.23k
      node->length = length_type(length);
44
6.23k
      node->references = 1;
45
6.23k
    }
46
6.23k
    return node;
47
6.23k
  }
48
49
  static StringNode* resize(StringNode* node, size_t length,
50
2.79k
                            Allocator* allocator) {
51
2.79k
    ARDUINOJSON_ASSERT(node != nullptr);
52
2.79k
    StringNode* newNode;
53
2.79k
    if (length <= maxLength)
54
2.79k
      newNode = reinterpret_cast<StringNode*>(
55
2.79k
          allocator->reallocate(node, sizeForLength(length)));
56
0
    else
57
0
      newNode = nullptr;
58
2.79k
    if (newNode)
59
2.79k
      newNode->length = length_type(length);
60
0
    else
61
0
      allocator->deallocate(node);
62
2.79k
    return newNode;
63
2.79k
  }
64
65
6.23k
  static void destroy(StringNode* node, Allocator* allocator) {
66
6.23k
    allocator->deallocate(node);
67
6.23k
  }
68
};
69
70
// Returns the size (in bytes) of an string with n characters.
71
0
constexpr size_t sizeofString(size_t n) {
72
0
  return StringNode::sizeForLength(n);
73
0
}
74
75
ARDUINOJSON_END_PRIVATE_NAMESPACE