Skip to content
GyverLibsPublic

About

Обёртка для передачи чисел, строк и бинарных данных с преобразованием совместимых типов

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

latest PIO Foo Foo Foo

Foo

Any

Обёртка для передачи чисел, строк и бинарных данных с преобразованием совместимых типов

Содержание

API

AType

enum class AType : uint8_t { None, Bool, Int, Uint, Float, Str, CStr, String, FStr, Bin };

Any

// ПОДКЛЮЧЕНИЕ ДАННЫХ
// указанный тип
Any(AType type, void* p, uint16_t size = 0);

// бинарные
static Any bin(T* p);
static Any bin(void* p, uint16_t size);

// строки
Any(String* p);
Any(String& s);
Any(char* p);
Any(__FlashStringHelper* p);
Any(char* p, uint16_t len);             // len не считая \0
Any(PGM_P p, uint16_t len, bool pgm);   // len не считая \0
Any(char* p, size_t cap, uint16_t len); // len не считая \0

template <size_t N>
Any(char (&arr)[N]);

// числа
Any(bool* p);
Any(signed char* p);
Any(unsigned char* p);
Any(short* p);
Any(unsigned short* p);
Any(int* p);
Any(unsigned int* p);
Any(long* p);
Any(unsigned long* p);
Any(long long* p);
Any(unsigned long long* p);
Any(float* p);

// ПРОСТО ЗНАЧЕНИЕ
Any(bool v);
Any(char v);
Any(signed char v);
Any(unsigned char v);
Any(short v);
Any(unsigned short v);
Any(int v);
Any(unsigned int v);
Any(long v);
Any(unsigned long v);
Any(float v);
Any(double v);

// МЕТОДЫ
// валидность
explicit operator bool();

// длина строк, размер int и bin
uint16_t size();

// тип
AType type();

// ram-строка
bool isStr();

// число
bool isInt();

// указатель на данные
void* data();

// записать в
bool writeTo(Any& dst);

// записать только в совместимый базовый тип:
// Str/CStr -> Str/String, Int/Uint -> Int/Uint, остальные без преобразования
bool writeToSame(Any& dst);

// прочитать из Any
bool readFrom(Any& src);

// прочитать из строки (в Str/String/Int/Uint/Float)
bool readFromStr(const char* s);

// напечатать в (целые до 32 бит)
void printTo(Print& p);

// в String-строку (целые до 32 бит)
String toString();

// получить нуль-терминированную RAM-строку
char* c_str();

// получить как int (для числовых типов)
int32_t toInt();

// получить как int64 (для числовых типов)
int64_t toInt64();

// получить как uint (для числовых типов)
uint32_t toUint();

// получить как uint64 (для числовых типов)
uint64_t toUint64();

// получить как float (для числовых типов)
float toFloat();

Особенности и сценарии работы

Передача в функцию

Основная идея Any - передавать в функцию данные любого типа, т.е. перегрузка на уровне конструктора Any, а не на уровне функции:

void foo(Any v1, Any v2);

foo(123, "str");
foo(F("fstr"), 3.14);

Any позволяет печататься и конвертироваться между базовыми типами, а также копировать в любой неконстантный тип данные из строки.

Значение и ссылка

Any передаёт значения разных типов через единый интерфейс. Числа до 32 бит и float, переданные по значению, хранятся внутри объекта. double приводится к float. Указатели на числа, строки и бинарные данные не передают владение памятью: источник должен существовать до завершения работы с Any. Для 64-битных целых используйте указатель на переменную и toInt64() или toUint64().

Копирование и присваивание Any запрещены, доступен конструктор перемещения. operator bool() проверяет наличие данных, а не логическое значение числа. Any(char) представляет строку из одного символа - для числового байта используйте signed char или unsigned char.

#include <Any.h>

int value = 10;
Any ref(&value);
ref.readFrom(42);
Any snapshot(value);
value = 7;
Serial.println(ref.toInt());       // 7
Serial.println(snapshot.toInt());  // 42

Преобразование типов

  • Целые числа преобразуются в целые, bool и float
  • Значение bool записывается в bool и целые числа
  • Значение float записывается в float и целые числа, дробная часть отбрасывается
  • Строки записываются в изменяемый массив char или String
  • Бинарные блоки копируются только в бинарные блоки того же размера

writeTo() и readFrom() возвращают false для неподдерживаемого преобразования. Числа не парсятся из строк. toInt(), toUint(), toFloat(), printTo() и toString() не обеспечивают полноценную обработку 64-битных целых. Сужение целых не проверяет переполнение.

writeToSame() допускает Int/Uint → Int/Uint, Str/CStr → Str/String, а также одинаковые Bool, Float и Bin. Источники String и FStr этим методом не поддерживаются. Для них используйте writeTo().

Строки и размер буфера

char text[16] = "";
String dynamic;
Any("hello").writeTo(text);
Any(F("world")).writeTo(&dynamic);

Any(String*) ссылается на изменяемый объект String, а Any(const String&) сохраняет указатель на его текущий буфер. Не сохраняйте Any от временного String и не меняйте адрес буфера источника до чтения.

Длина строки не включает нулевой терминатор, вместимость массива включает его. При нехватке места writeTo() обрезает строку, добавляет \0 и возвращает false. writeToSame() для изменяемой строки обновляет сохранённую длину и возвращает true даже при обрезании. Обычный writeTo() сохранённую длину приёмника не обновляет. Для c_str(), toString() и записи в String исходная строка должна быть нуль-терминированной даже при явно заданной длине.

Бинарные данные

struct Config { uint16_t period; uint8_t mode; };
Config source{1000, 1};
Config target{};
bool ok = Any::bin(&source).writeTo(Any::bin(&target));

Размер строк и бинарных блоков хранится в uint16_t. Бинарное копирование переносит представление объекта в памяти, включая возможные байты выравнивания.

Установка

  • Библиотеку можно найти по названию Any и установить через менеджер библиотек в:
    • 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

Обёртка для передачи чисел, строк и бинарных данных с преобразованием совместимых типов

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages