copy from an old project
This commit is contained in:
75
include/json.hpp
Normal file
75
include/json.hpp
Normal 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
111
src/json.cpp
Normal 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
7
zephyr_module.cmake
Normal 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
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user