• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bblanchon / ArduinoJson / 4403824802

pending completion
4403824802

push

github

Benoit Blanchon
Fix Clang3.8

3334 of 3348 relevant lines covered (99.58%)

6130.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.84
/src/ArduinoJson/Document/BasicJsonDocument.hpp
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2023, Benoit BLANCHON
3
// MIT License
4

5
#pragma once
6

7
#include <ArduinoJson/Document/JsonDocument.hpp>
8

9
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
10

11
// Helper to implement the "base-from-member" idiom
12
// (we need to store the allocator before constructing JsonDocument)
13
template <typename TAllocator>
14
class AllocatorOwner {
15
 public:
16
  AllocatorOwner() {}
4✔
17
  AllocatorOwner(TAllocator a) : _allocator(a) {}
1,423✔
18

19
  void* allocate(size_t size) {
1,436✔
20
    return _allocator.allocate(size);
1,436✔
21
  }
22

23
  void deallocate(void* ptr) {
1,451✔
24
    if (ptr)
1,451✔
25
      _allocator.deallocate(ptr);
1,435✔
26
  }
1,451✔
27

28
  void* reallocate(void* ptr, size_t new_size) {
15✔
29
    return _allocator.reallocate(ptr, new_size);
15✔
30
  }
31

32
  TAllocator& allocator() {
1✔
33
    return _allocator;
1✔
34
  }
35

36
 private:
37
  TAllocator _allocator;
38
};
39

40
// A JsonDocument that uses the provided allocator to allocate its memory pool.
41
// https://arduinojson.org/v6/api/basicjsondocument/
42
template <typename TAllocator>
43
class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
44
 public:
45
  explicit BasicJsonDocument(size_t capa, TAllocator alloc = TAllocator())
1,423✔
46
      : AllocatorOwner<TAllocator>(alloc), JsonDocument(allocPool(capa)) {}
1,423✔
47

48
  // Copy-constructor
49
  BasicJsonDocument(const BasicJsonDocument& src)
5✔
50
      : AllocatorOwner<TAllocator>(src), JsonDocument() {
5✔
51
    copyAssignFrom(src);
5✔
52
  }
5✔
53

54
  // Move-constructor
55
  BasicJsonDocument(BasicJsonDocument&& src) : AllocatorOwner<TAllocator>(src) {
2✔
56
    moveAssignFrom(src);
2✔
57
  }
2✔
58

59
  BasicJsonDocument(const JsonDocument& src) {
1✔
60
    copyAssignFrom(src);
1✔
61
  }
1✔
62

63
  // Construct from variant, array, or object
64
  template <typename T>
65
  BasicJsonDocument(const T& src,
2✔
66
                    typename detail::enable_if<
67
                        detail::is_same<T, JsonVariant>::value ||
68
                        detail::is_same<T, JsonVariantConst>::value ||
69
                        detail::is_same<T, JsonArray>::value ||
70
                        detail::is_same<T, JsonArrayConst>::value ||
71
                        detail::is_same<T, JsonObject>::value ||
72
                        detail::is_same<T, JsonObjectConst>::value>::type* = 0)
73
      : JsonDocument(allocPool(src.memoryUsage())) {
4✔
74
    set(src);
2✔
75
  }
2✔
76

77
  // disambiguate
78
  BasicJsonDocument(JsonVariant src)
1✔
79
      : JsonDocument(allocPool(src.memoryUsage())) {
2✔
80
    set(src);
1✔
81
  }
1✔
82

83
  ~BasicJsonDocument() {
1,434✔
84
    freePool();
1,434✔
85
  }
1,434✔
86

87
  BasicJsonDocument& operator=(const BasicJsonDocument& src) {
5✔
88
    copyAssignFrom(src);
5✔
89
    return *this;
5✔
90
  }
91

92
  BasicJsonDocument& operator=(BasicJsonDocument&& src) {
3✔
93
    moveAssignFrom(src);
3✔
94
    return *this;
3✔
95
  }
96

97
  template <typename T>
98
  BasicJsonDocument& operator=(const T& src) {
11✔
99
    size_t requiredSize = src.memoryUsage();
11✔
100
    if (requiredSize > capacity())
11✔
101
      reallocPool(requiredSize);
×
102
    set(src);
11✔
103
    return *this;
11✔
104
  }
105

106
  // Reduces the capacity of the memory pool to match the current usage.
107
  // https://arduinojson.org/v6/api/basicjsondocument/shrinktofit/
108
  void shrinkToFit() {
30✔
109
    ptrdiff_t bytes_reclaimed = _pool.squash();
30✔
110
    if (bytes_reclaimed == 0)
30✔
111
      return;
15✔
112

113
    void* old_ptr = _pool.buffer();
15✔
114
    void* new_ptr = this->reallocate(old_ptr, _pool.capacity());
15✔
115

116
    ptrdiff_t ptr_offset =
15✔
117
        static_cast<char*>(new_ptr) - static_cast<char*>(old_ptr);
118

119
    _pool.movePointers(ptr_offset);
15✔
120
    _data.movePointers(ptr_offset, ptr_offset - bytes_reclaimed);
15✔
121
  }
122

123
  // Reclaims the memory leaked when removing and replacing values.
124
  // https://arduinojson.org/v6/api/jsondocument/garbagecollect/
125
  bool garbageCollect() {
3✔
126
    // make a temporary clone and move assign
127
    BasicJsonDocument tmp(*this);
6✔
128
    if (!tmp.capacity())
3✔
129
      return false;
1✔
130
    tmp.set(*this);
2✔
131
    moveAssignFrom(tmp);
2✔
132
    return true;
2✔
133
  }
134

135
  using AllocatorOwner<TAllocator>::allocator;
136

137
 private:
138
  detail::MemoryPool allocPool(size_t requiredSize) {
1,436✔
139
    size_t capa = detail::addPadding(requiredSize);
1,436✔
140
    return {reinterpret_cast<char*>(this->allocate(capa)), capa};
1,436✔
141
  }
142

143
  void reallocPool(size_t requiredSize) {
11✔
144
    size_t capa = detail::addPadding(requiredSize);
11✔
145
    if (capa == _pool.capacity())
11✔
146
      return;
1✔
147
    freePool();
10✔
148
    replacePool(allocPool(detail::addPadding(requiredSize)));
10✔
149
  }
150

151
  void freePool() {
1,451✔
152
    this->deallocate(getPool()->buffer());
1,451✔
153
  }
1,451✔
154

155
  void copyAssignFrom(const JsonDocument& src) {
11✔
156
    reallocPool(src.capacity());
11✔
157
    set(src);
11✔
158
  }
11✔
159

160
  void moveAssignFrom(BasicJsonDocument& src) {
7✔
161
    freePool();
7✔
162
    _data = src._data;
7✔
163
    _pool = src._pool;
7✔
164
    src._data.setNull();
7✔
165
    src._pool = {0, 0};
7✔
166
  }
7✔
167
};
168

169
ARDUINOJSON_END_PUBLIC_NAMESPACE
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc