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

bblanchon / ArduinoJson / 3619649488

pending completion
3619649488

push

github

Benoit Blanchon
CI: use `ubuntu-20.04` for GCC

3373 of 3389 relevant lines covered (99.53%)

5926.06 hits per line

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

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

5
#pragma once
6

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

9
namespace ARDUINOJSON_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,384✔
18

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

23
  void deallocate(void* ptr) {
1,409✔
24
    if (ptr)
1,409✔
25
      _allocator.deallocate(ptr);
1,399✔
26
  }
1,409✔
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
template <typename TAllocator>
41
class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
42
 public:
43
  explicit BasicJsonDocument(size_t capa, TAllocator alloc = TAllocator())
1,384✔
44
      : AllocatorOwner<TAllocator>(alloc), JsonDocument(allocPool(capa)) {}
1,384✔
45

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

52
  // Move-constructor
53
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
54
  BasicJsonDocument(BasicJsonDocument&& src) : AllocatorOwner<TAllocator>(src) {
55
    moveAssignFrom(src);
56
  }
57
#endif
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(
2✔
66
      const T& src,
67
      typename enable_if<
68
          is_same<T, VariantRef>::value || is_same<T, VariantConstRef>::value ||
69
          is_same<T, ArrayRef>::value || is_same<T, ArrayConstRef>::value ||
70
          is_same<T, ObjectRef>::value ||
71
          is_same<T, ObjectConstRef>::value>::type* = 0)
72
      : JsonDocument(allocPool(src.memoryUsage())) {
4✔
73
    set(src);
2✔
74
  }
2✔
75

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

82
  ~BasicJsonDocument() {
1,394✔
83
    freePool();
1,394✔
84
  }
1,394✔
85

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

91
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
92
  BasicJsonDocument& operator=(BasicJsonDocument&& src) {
93
    moveAssignFrom(src);
94
    return *this;
95
  }
96
#endif
97

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

107
  void shrinkToFit() {
30✔
108
    ptrdiff_t bytes_reclaimed = _pool.squash();
30✔
109
    if (bytes_reclaimed == 0)
30✔
110
      return;
15✔
111

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

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

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

122
  bool garbageCollect() {
3✔
123
    // make a temporary clone and move assign
124
    BasicJsonDocument tmp(*this);
6✔
125
    if (!tmp.capacity())
3✔
126
      return false;
1✔
127
    tmp.set(*this);
2✔
128
    moveAssignFrom(tmp);
2✔
129
    return true;
2✔
130
  }
131

132
  using AllocatorOwner<TAllocator>::allocator;
133

134
 private:
135
  MemoryPool allocPool(size_t requiredSize) {
1,400✔
136
    size_t capa = addPadding(requiredSize);
1,400✔
137
    return MemoryPool(reinterpret_cast<char*>(this->allocate(capa)), capa);
1,400✔
138
  }
139

140
  void reallocPool(size_t requiredSize) {
14✔
141
    size_t capa = addPadding(requiredSize);
14✔
142
    if (capa == _pool.capacity())
14✔
143
      return;
1✔
144
    freePool();
13✔
145
    replacePool(allocPool(addPadding(requiredSize)));
13✔
146
  }
147

148
  void freePool() {
1,409✔
149
    this->deallocate(getPool()->buffer());
1,409✔
150
  }
1,409✔
151

152
  void copyAssignFrom(const JsonDocument& src) {
14✔
153
    reallocPool(src.capacity());
14✔
154
    set(src);
14✔
155
  }
14✔
156

157
  void moveAssignFrom(BasicJsonDocument& src) {
2✔
158
    freePool();
2✔
159
    _data = src._data;
2✔
160
    _pool = src._pool;
2✔
161
    src._data.setNull();
2✔
162
    src._pool = MemoryPool(0, 0);
2✔
163
  }
2✔
164
};
165

166
}  // namespace ARDUINOJSON_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