Skip to content

GyverLibs/BSON

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

latest PIO Foo Foo Foo

Foo

BSON

Простой "бинарный" вариант JSON пакета, собирается линейно:

  • В среднем в 2-3 раза легче обычного JSON, собирается сильно быстрее
  • В ~4 раза быстрее String строки в сборке
  • Поддерживает "коды": число, которое может быть ключом или значением, а при распаковке заменится на строку из списка по индексу
  • Строки не нужно экранировать
  • Поддержка целых чисел 0..8 байт
  • Поддержка float с указанием количества знаков точности
  • Поддержка JSON массивов и объектов ключ:значение
  • Поддержка упаковки произвольных бинарных данных
  • Не содержит запятых, они добавляются при распаковке
  • Лимит длины 8192 байт для всего: значение кодов, длина строк, длина бинарных данных
  • Статическая и динамическая сборка
  • Встроенный парсер

Совместимость

Совместима со всеми Arduino платформами (используются Arduino-функции)

Зависимости

Содержание

Использование

Структура пакета

bson

Настройки

#define BSON_NO_TEXT    // отключить поддержку Text (библиотка StringUtils)
#define BSON_USE_VECTOR // использовать std::vector вместо библиотеки GTL

// #include <BSON.h>

Динамическая сборка, BSON

// прибавить данные любого типа
BSON& add(T data);
void operator=(T data);
void operator+=(T data);

// float
BSON& add(float data, int dec);
BSON& add(double data, int dec);

// ключ
BSON& operator[](T key);

// контейнер, всегда вернёт true. type: '{', '[', '}', ']'
bool operator()(char type);

// бинарные данные
bool beginBin(uint16_t size);   // затем вручную write(data, size, pgm)
BSON& addBin(const void* data, size_t size, bool pgm = false);
BSON& addBin(const T& data);

// строки
BSON& beginStr(size_t len); // затем вручную write(str, len, pgm)
BSON& addStr(const char* str, size_t len, bool pgm = false);

// зарезервировать размер
bool reserve(size_t size);

// зарезервировать, элементов (добавить к текущему размеру буфера)
bool addCapacity(size_t size);

// установить увеличение размера для уменьшения количества мелких реаллокаций. Умолч. 8
void setOversize(uint16_t oversize);

// размер в байтах
size_t length();

// доступ к буферу
uint8_t* buf();

// очистить
void clear();

// переместить в другой объект
void move(BSON& bson);

// STATIC

// максимальная длина строк и бинарных данных
static size_t maxDataLength();

// вывести в Print как JSON
static void stringify(BSON& bson, Print& p, bool pretty = false);

// вывести в Print как JSON
static void stringify(const uint8_t* bson, size_t len, Print& p, bool pretty = false);

Статическая сборка

BSON_CONT(char t)   // контейнер '{', '}', '[', ']'
BSON_CODE(code)     // код
BSON_FLOAT(val)     // float
BSON_INT8(val)      // int8
BSON_INT16(val)     // int16
BSON_INT24(val)     // int24
BSON_INT32(val)     // int32
BSON_INT64(val)     // int64
BSON_BOOL(val)      // bool
BSON_STR(str, len)  // "string" + длина
BSON_CHARS(...)     // 's', 't', 'r', 'i', 'n', 'g'

Линейный парсер BSON::Parser

enum class BSType {
    String,
    Boolean,
    Integer,
    Float,
    Code,
    Binary,
    ObjectOpen,
    ObjectClose,
    ArrayOpen,
    ArrayClose,
};
Parser(uint8_t* bson, uint16_t len);

// вывести в Print как JSON
void stringify(Print& p, bool pretty = false);

// начать заново
void reset();

// парсить следующий блок и проверить тип. Вернёт true при успехе
bool next(BSType type);

// парсить следующий блок и проверить контейнер [ ] { }. Вернёт true при успехе
bool next(char cont);

// парсить следующий блок. Вернёт true при успехе
bool next();

// true - парсинг окончен корректно
bool isDone();

// получить тип блока
BSType getType();

// контейнер - объект [Container]
bool isObject();

// контейнер - массив [Container]
bool isArray();

// контейнер открыт [Container]
bool isOpen();

// контейнер закрыт [Container]
bool isClose();

// длина в байтах [String, Binary, Integer]
uint16_t length();

// число отрицательное [Integer]
bool isNegative();

// в указатель на строку [String], длина length()
const char* toStr();

// в текст [String]
Text toText();

// в свой тип [Binary]
template <typename T>
T toBin();

// в код [Code]
template <typename T>
T toCode();

// в bool [Boolean]
bool toBool();

// в int [Integer]
int32_t toInt();

// в uint [Integer]
uint32_t toUint();

// в int [Integer]
int64_t toInt64();

// в uint [Integer]
uint64_t toUint64();

// в float [Float]
float toFloat();

// парсинг
bool readStr(Text* t);
bool readStr(char* s, uint16_t size, bool terminate = true);
bool readBool(bool* b);
bool readInt(T* i);
bool readInt64(T* i);
bool readFloat(float* f);
bool readCode(T* c);
bool readBin(T* b);
bool readBin(T* b, uint16_t size);

Примеры

Динамическая сборка

// коды
enum class Const {
    some,
    string,
    constants,
};

BSON b;
b('{');

if (b["str"]('{')) {
    b["cstring"] = "text";
    b["fstring"] = F("text");
    b["String"] = String("text");
    b('}');
}

if (b[Const::constants]('{')) {
    b[Const::some] = Const::string;
    b[Const::string] = "cstring";
    b[Const::constants] = 123;
    b('}');
}

if (b["num"]('{')) {
    b["int8"] = 123;
    b["int16"] = 12345;
    b["int32"] = -123456789;
    b('}');
}

if (b["arr"]('[')) {
    b += "str";
    b += 123;
    b += 3.14;
    b += Const::string;
    b(']');
}

b('}');

Статическая сборка

uint8_t bson[] = {
    BSON_CONT('{'),
    BSON_KEY("str", 3),
    BSON_STR("hello", 5),

    BSON_KEY("int", 3),
    BSON_INT16(12345),

    BSON_KEY("arr", 3),
    BSON_CONT('['),
    BSON_STR("string", 6),
    BSON_CODE(12),
    BSON_INT8(123),
    BSON_INT8(-123),
    BSON_INT16(12345),
    BSON_INT16(-12345),
    BSON_INT32(12345678),
    BSON_INT32(-12345678),
    BSON_FLOAT(3.1415),
    BSON_BOOL(true),
    BSON_CONT(']'),

    BSON_CONT('}'),
};

Парсинг

// сборка

struct Str {
    int v;
    float f;
};

BSON bs;
bs += 1234;
bs += "keks";
bs += true;
bs += 3.14;
bs.addBin(Str{321, 33.44});

// парсинг

BSON::Parser p(&bs);

int v;
char s[5];
bool b;
float f;
Str str;

if (p.readInt(&v) &&
    p.readStr(s, sizeof(s)) &&
    p.readBool(&b) &&
    p.readFloat(&f) &&
    p.readBin(&str)) {
    //
    Serial.println("done");
    Serial.println(v);
    Serial.println(s);
    Serial.println(b);
    Serial.println(f);
    Serial.println(str.v);
    Serial.println(str.f);
} else {
    Serial.println("error");
}

Другие платформы

Есть готовая библиотека для JavaScript

npm i @alexgyver/bson

Версии

  • v2.0.0

Установка

  • Библиотеку можно найти по названию BSON и установить через менеджер библиотек в:
    • Arduino IDE
    • Arduino IDE v2
    • PlatformIO
  • Скачать библиотеку .zip архивом для ручной установки:
    • Распаковать и положить в C:\Program Files (x86)\Arduino\libraries (Windows x64)
    • Распаковать и положить в C:\Program Files\Arduino\libraries (Windows x32)
    • Распаковать и положить в Документы/Arduino/libraries/
    • (Arduino IDE) автоматическая установка из .zip: Скетч/Подключить библиотеку/Добавить .ZIP библиотеку… и указать скачанный архив
  • Читай более подробную инструкцию по установке библиотек здесь

Обновление

  • Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
  • Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
  • Вручную: удалить папку со старой версией, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!

Баги и обратная связь

При нахождении багов создавайте Issue, а лучше сразу пишите на почту alex@alexgyver.ru
Библиотека открыта для доработки и ваших Pull Request'ов!

При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:

  • Версия библиотеки
  • Какой используется МК
  • Версия SDK (для ESP)
  • Версия Arduino IDE
  • Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
  • Какой код загружался, какая работа от него ожидалась и как он работает в реальности
  • В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код

About

Сборщик линейных бинарных JSON пакетов

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors