FastLED 3.10.9
Loading...
Searching...
No Matches
serial.cpp.hpp
Go to the documentation of this file.
1// src/fl/remote/transport/serial.cpp.hpp
2// Implementation of JSON-RPC serial transport layer
3
4#pragma once
5
7#include "fl/stl/cstring.h"
8#include "fl/stl/noexcept.h"
9
10namespace fl {
11
12namespace {
13// Small error reply used when the response cannot be serialized or framed.
14fl::string outOfMemoryResponse(const char* prefix, fl::size prefixLength) FL_NO_EXCEPT {
15 static const char error[] =
16 "{\"error\":{\"code\":-32603,\"message\":\"Out of memory\"},"
17 "\"id\":null,\"jsonrpc\":\"2.0\"}";
18 fl::string failure;
19 failure.write(prefix, prefixLength);
20 failure.write(error, sizeof(error) - 1);
21 if (failure.size() == prefixLength + sizeof(error) - 1) {
22 return failure;
23 }
24 return error;
25}
26} // namespace
27
28fl::string formatJsonResponse(const fl::json& response, const char* prefix) FL_NO_EXCEPT {
29 // Reuse the serialized body. A second growing stream kept two full copies
30 // of large discovery responses alive and could exhaust ESP32's heap.
31 fl::string jsonStr = response.to_string();
32 const fl::size bodyLength = jsonStr.size();
33 const fl::size prefixLength = prefix ? fl::strlen(prefix) : 0;
34 if (bodyLength == 0) {
35 // to_string() returns empty only when its buffer could not be
36 // allocated; never publish a bare prefix (FastLED #4899).
37 return outOfMemoryResponse(prefix, prefixLength);
38 }
39 if (prefixLength != 0) {
40 const fl::size totalLength = bodyLength + prefixLength;
41 if (totalLength >= bodyLength && totalLength != fl::string::npos) {
42 jsonStr.reserve(totalLength);
43 jsonStr.write(prefix, prefixLength);
44 }
45 if (jsonStr.size() != totalLength || totalLength < bodyLength) {
46 // Release the large body before allocating the small error reply.
47 // A failed extension must not publish partially formed JSON.
48 jsonStr.clear(true);
49 return outOfMemoryResponse(prefix, prefixLength);
50 }
51 char *bytes = &jsonStr[0]; // fl-lint: container-data-ptr-ok - contiguous mutable string for memmove/memcpy interop
52 fl::memmove(bytes + prefixLength, bytes, bodyLength);
53 fl::memcpy(bytes, prefix, prefixLength);
54 }
55
56 // Preserve prefix bytes; normalize only the serialized body in place.
57 for (fl::size i = prefixLength; i < jsonStr.size(); ++i) {
58 char &byte = jsonStr[i];
59 if (byte == '\n' || byte == '\r') {
60 byte = ' ';
61 }
62 }
63 return jsonStr;
64}
65
66} // namespace fl
void clear(bool freeMemory=false) FL_NO_EXCEPT
void reserve(fl::size newCapacity) FL_NO_EXCEPT
fl::size write(const fl::u8 *data, fl::size n) FL_NO_EXCEPT
fl::size size() const FL_NO_EXCEPT
static constexpr fl::size npos
Definition string.h:204
fl::string outOfMemoryResponse(const char *prefix, fl::size prefixLength) FL_NO_EXCEPT
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
FASTLED_FORCE_INLINE void * memmove(void *dest, const void *src, size_t n) FL_NO_EXCEPT
Definition cstring.h:144
FASTLED_FORCE_INLINE void * memcpy(void *dest, const void *src, size_t n) FL_NO_EXCEPT
Definition cstring.h:136
fl::string formatJsonResponse(const fl::json &response, const char *prefix) FL_NO_EXCEPT
Serialize JSON response to a string.
FASTLED_FORCE_INLINE size_t strlen(const char *s) FL_NO_EXCEPT
Definition cstring.h:56
Base definition for an LED controller.