copy from an old project

This commit is contained in:
Mickael Bosch
2026-04-01 10:30:52 +02:00
commit 2813645669
3 changed files with 193 additions and 0 deletions

75
include/json.hpp Normal file
View File

@@ -0,0 +1,75 @@
#ifndef JSON_HPP
#define JSON_HPP
#include <cstddef>
#include <cstdint>
#include <zephyr/data/json.h>
#include <log.hpp>
namespace JsonParser
{
void init();
void add_text(uint8_t* buf, size_t size);
int json_printer(const char* bytes, size_t len, void* data);
class HandlerBase
{
public:
/* private but accessible from static functions */
HandlerBase* _next;
HandlerBase();
virtual bool handle(const char* buf, size_t size) = 0;
};
template <typename Struct, size_t DESC_SIZE, typename Fct>
class Handler: public HandlerBase
{
const Struct& _s;
const json_obj_descr* _da;
Fct _fct;
bool _allow_partial;
const int64_t _all_fields;
public:
Handler(Struct default_s, const json_obj_descr (&da)[DESC_SIZE], Fct fct, bool allow_partial=false):
_s {default_s},
_da {da},
_fct {fct},
_allow_partial{allow_partial},
_all_fields {(1 << DESC_SIZE) - 1}
{
}
void print( const Struct& s) { json_obj_encode(_da, DESC_SIZE, &s, json_printer, NULL); }
bool handle(const char* buf, size_t size) override
{
Struct s{_s};
int64_t ret = json_obj_parse((char*)buf, size, _da, DESC_SIZE, &s);
if (ret <= 0)
{
return false;
}
if(ret != _all_fields && !_allow_partial)
{
return false;
}
if (!_fct(s, ret, _all_fields))
{
return false;
}
// info("received a valid json\n");
// print(s);
// info("\n");
return true;
}
};
} // namespace JsonParser
#endif /* JSON_HPP */

111
src/json.cpp Normal file
View File

@@ -0,0 +1,111 @@
#include <json.hpp>
static constexpr size_t BUF_SIZE = 64 + 1;
char _buf[BUF_SIZE];
size_t _idx;
size_t _indent;
JsonParser::HandlerBase* _handlers;
JsonParser::HandlerBase::HandlerBase()
{
_next = _handlers;
_handlers = this;
}
int JsonParser::json_printer(const char* bytes, size_t len, void* data)
{
// info("[[%d]]\n", len);
// for (size_t i = 0; i < len; i++)
// {
// info("%c", bytes[i]);
// }
// return 0;
for (size_t i = 0; i < len; i++)
{
bool nl = true;
if (bytes[i] == '}' || bytes[i] == ']')
{
nl = false;
_indent--;
info("\n");
for (size_t i = 0; i < _indent; i++)
{
info(" ");
}
}
info("%c", bytes[i]);
if (bytes[i] == '{' || bytes[i] == '[')
{
_indent++;
}
if (nl
&& (bytes[i] == ',' || bytes[i] == '{' || bytes[i] == '}'
|| bytes[i] == '[' || bytes[i] == ']'))
{
info("\n");
for (size_t i = 0; i < _indent; i++)
{
info(" ");
}
}
}
return 0;
}
void commit()
{
_buf[_idx] = '\0';
bool ok = false;
JsonParser::HandlerBase* h = _handlers;
while (h)
{
if (h->handle(_buf, _idx))
{
ok = true;
break;
}
h = h->_next;
};
_idx = 0;
if (!ok)
{
info("parse end error\n");
}
}
void flush_error()
{
_idx = 0;
error("input buffer overflow, flushing\n");
}
void JsonParser::init()
{
/* nothing to do */
}
void JsonParser::add_text(uint8_t* buf, size_t size)
{
for (size_t i = 0; i < size; i++)
{
if (buf[i] == ' ' || buf[i] == '\r' || buf[i] == '\n')
{
continue;
}
if (buf[i] == '}')
{
_buf[_idx] = buf[i];
_idx++;
commit();
continue;
}
_buf[_idx] = buf[i];
_idx++;
if (_idx >= BUF_SIZE)
{
flush_error();
}
}
}

7
zephyr_module.cmake Normal file
View File

@@ -0,0 +1,7 @@
target_include_directories(app PRIVATE
${CMAKE_CURRENT_LIST_DIR}/include
)
target_sources(app PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/json.cpp
)