ESPHome 2026.2.1
Loading...
Searching...
No Matches
json_util.cpp
Go to the documentation of this file.
1#include "json_util.h"
2#include "esphome/core/log.h"
3
4// ArduinoJson::Allocator is included via ArduinoJson.h in json_util.h
5
6namespace esphome {
7namespace json {
8
9static const char *const TAG = "json";
10
11#ifdef USE_PSRAM
12// Global allocator that outlives all JsonDocuments returned by parse_json()
13// This prevents dangling pointer issues when JsonDocuments are returned from functions
14// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) - Must be mutable for ArduinoJson::Allocator
15static SpiRamAllocator global_json_allocator;
16#endif
17
18std::string build_json(const json_build_t &f) {
19 // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
20 JsonBuilder builder;
21 JsonObject root = builder.root();
22 f(root);
23 return builder.serialize();
24 // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
25}
26
27bool parse_json(const std::string &data, const json_parse_t &f) {
28 // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
29 return parse_json(reinterpret_cast<const uint8_t *>(data.c_str()), data.size(), f);
30}
31
32bool parse_json(const uint8_t *data, size_t len, const json_parse_t &f) {
33 // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
34 JsonDocument doc = parse_json(data, len);
35 if (doc.overflowed() || doc.isNull())
36 return false;
37 return f(doc.as<JsonObject>());
38 // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
39}
40
41JsonDocument parse_json(const uint8_t *data, size_t len) {
42 // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
43 if (data == nullptr || len == 0) {
44 ESP_LOGE(TAG, "No data to parse");
45 return JsonObject(); // return unbound object
46 }
47#ifdef USE_PSRAM
48 JsonDocument json_document(&global_json_allocator);
49#else
50 JsonDocument json_document;
51#endif
52 if (json_document.overflowed()) {
53 ESP_LOGE(TAG, "Could not allocate memory for JSON document!");
54 return JsonObject(); // return unbound object
55 }
56 DeserializationError err = deserializeJson(json_document, data, len);
57
58 if (err == DeserializationError::Ok) {
59 return json_document;
60 } else if (err == DeserializationError::NoMemory) {
61 ESP_LOGE(TAG, "Can not allocate more memory for deserialization. Consider making source string smaller");
62 return JsonObject(); // return unbound object
63 }
64 ESP_LOGE(TAG, "Parse error: %s", err.c_str());
65 return JsonObject(); // return unbound object
66 // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
67}
68
70 if (doc_.overflowed()) {
71 ESP_LOGE(TAG, "JSON document overflow");
72 return "{}";
73 }
74 std::string output;
75 serializeJson(doc_, output);
76 return output;
77}
78
79} // namespace json
80} // namespace esphome
Builder class for creating JSON documents without lambdas.
Definition json_util.h:64
std::function< void(JsonObject)> json_build_t
Callback function typedef for building JsonObjects.
Definition json_util.h:46
bool parse_json(const std::string &data, const json_parse_t &f)
Parse a JSON string and run the provided json parse function if it's valid.
Definition json_util.cpp:27
std::string build_json(const json_build_t &f)
Build a JSON string with the provided json build function.
Definition json_util.cpp:18
std::function< bool(JsonObject)> json_parse_t
Callback function typedef for parsing JsonObjects.
Definition json_util.h:43
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string size_t len
Definition helpers.h:692