Перейти к содержанию
Материалы раздела

TinyCBOR

Модуль для сериализации и десериализации данных в формате CBOR (Concise Binary Object Representation). CBOR - это компактный бинарный формат данных, стандартизированный в RFC 7049, широко используемый в IoT и встраиваемых системах.

tinycbor.encode(data)

Сериализует Lua-значение в бинарную строку формата CBOR.

Аргументы:

  • data: значение для сериализации (число, строка, булево, таблица или nil)

Возвращает: строку с бинарными данными CBOR

Поддерживаемые типы:

  • number - сериализуется как double
  • string - текстовая строка
  • boolean - булево значение
  • table - массив (если ключи последовательные числа от 1) или map (в остальных случаях)
  • nil - null

Глубина вложенности таблиц ограничена 16 уровнями. Циклические таблицы отклоняются с Lua-ошибкой; повторное использование одной и той же таблицы в разных независимых ветвях допустимо и кодируется повторно.

local cbor = require("tinycbor")

-- Кодирование простых значений
local encoded = cbor.encode(42)
local encoded = cbor.encode("hello")
local encoded = cbor.encode(true)
local encoded = cbor.encode(nil)

-- Кодирование массива
local encoded = cbor.encode({1, 2, 3, "four"})

-- Кодирование таблицы
local data = {
    name = "sensor",
    value = 25.5,
    active = true
}
local encoded = cbor.encode(data)

tinycbor.decode(data)

Десериализует бинарную строку CBOR в Lua-значение.

Аргументы:

  • data: строка с бинарными данными CBOR

Возвращает: десериализованное Lua-значение. Вложенность массивов и map ограничена 16 уровнями. Целые CBOR, которые помещаются в lua_Integer, возвращаются числами; более широкие положительные и отрицательные значения — точными десятичными строками без усечения.

local cbor = require("tinycbor")

-- Кодирование и декодирование
local original = {
    temperature = 25.5,
    humidity = 60,
    sensors = {"temp", "hum"}
}

local encoded = cbor.encode(original)
local decoded = cbor.decode(encoded)

print(decoded.temperature)  -- 25.5
print(decoded.sensors[1])   -- temp

Пример использования

local cbor = require("tinycbor")

-- Подготовка данных датчика
local sensor_data = {
    device_id = "esp32-001",
    timestamp = os.time(),
    readings = {
        temperature = 23.5,
        pressure = 1013.25,
        humidity = 45
    },
    battery = 85
}

-- Сериализация
local binary = cbor.encode(sensor_data)
print("CBOR size: " .. #binary .. " bytes")

-- Отправка данных...

-- Десериализация на приемной стороне
local received = cbor.decode(binary)
print("Device: " .. received.device_id)
print("Temperature: " .. received.readings.temperature)

Сравнение с JSON и MessagePack

CBOR имеет ряд преимуществ:

  • Более компактный, чем JSON
  • Поддержка бинарных данных
  • Самоописываемый формат
  • Стандартизирован (RFC 7049)
  • Широко используется в CoAP и других IoT протоколах
local cbor = require("tinycbor")
local json = require("cjson")

local data = {x = 1, y = 2, z = 3}

local cbor_data = cbor.encode(data)
local json_data = json.encode(data)

print("CBOR: " .. #cbor_data .. " bytes")
print("JSON: " .. #json_data .. " bytes")

Обработка ошибок

При ошибках кодирования или декодирования модуль генерирует Lua-ошибку:

local cbor = require("tinycbor")

-- Попытка декодировать некорректные данные
local ok, result = pcall(function()
    return cbor.decode("invalid data")
end)

if not ok then
    print("Error: " .. result)
end

Слишком глубокая структура и цикл при кодировании также являются ошибками.