Skip to content

Repository files navigation

ESPressio Serializable

Declarative serialization components for the Flowduino ESPressio Development Platform.

Latest Stable Version

0.10.2

0.10.2 warning-clean detailed deserialization

Version 0.10.2 makes the fallback branch in detailed deserialization unambiguous to compilers, eliminating GCC's -Wmisleading-indentation diagnostic when downstream consumers build ESPressio Serializable headers with warnings treated as errors.

There are no API, runtime-behaviour, or wire-format changes in this patch.

0.10.1 bounded BinaryArchive decoding

Version 0.10.1 hardens BinaryArchive when decoding untrusted or malformed ESPB v2 payloads. The default Load() overload now applies embedded-friendly limits for nesting depth, aggregate node count, object members, array elements, property-name length, and string length. Allocation or decoder exceptions are converted into a clean invalid-archive result rather than escaping into the application.

Applications with different requirements can supply explicit limits:

ESPressio::Serializable::BinaryArchive archive;
ESPressio::Serializable::BinaryArchiveDecodeLimits limits;

limits.MaximumDepth = 16;
limits.MaximumTotalNodes = 1024;
limits.MaximumObjectMembers = 256;
limits.MaximumArrayElements = 1024;
limits.MaximumNameLength = 256;
limits.MaximumStringLength = 16 * 1024;

if (!archive.Load(data, size, limits)) {
    // Malformed, truncated, unsupported, or outside the configured limits.
}

The no-options overload remains source-compatible and uses the library defaults. The ESPB v2 wire format is unchanged.

Allocation-free BinaryArchive validation and traversal

For diagnostics, protocol inspection, and other cases that do not require an owned SerializationNode tree, 0.10.1 also adds an allocation-free ESPB v2 traversal API:

ESPressio::Serializable::BinaryArchiveDecodeLimits limits;
limits.MaximumDepth = 12;
limits.MaximumTotalNodes = 1024;

if (ESPressio::Serializable::ValidateBinaryArchive(
        data,
        size,
        limits
    )) {
    // Structurally valid and within the configured limits.
}

TraverseBinaryArchive() accepts a BinaryArchiveVisitor and streams object, array, property, and scalar callbacks directly from the encoded bytes. The traversal uses std::string_view for borrowed names/string values and does not construct a second tree or copy payload strings merely to inspect them.

This is particularly useful on ESP32 for diagnostic paths where attempting to build another heap-backed tree during low-memory conditions would itself be undesirable.

0.10.0 direct Binary fast path

Version 0.10.0 adds a public direct Binary serialization/deserialization API for latency-sensitive integrations such as ESPressio Event Transport.

std::vector<uint8_t> bytes;

ESPressio::Serializable::SerializeDirectBinary(
    object,
    bytes
);

ESPressio::Serializable::DeserializeDirectBinary(
    bytes.data(),
    bytes.size(),
    object
);

AppendDirectBinary() is also available when a caller has already reserved or written a protocol/header prefix and wants the Serializable payload appended to the same final buffer.

The direct path preserves the existing BinaryArchive ESPB v2 wire format. It writes schema/property values directly to bytes and reads same-schema values directly from the input buffer, avoiding the full intermediate SerializationNode object tree. If a consumer requires structural schema migration it can continue to use the existing BinaryArchive/TreeArchive path; ESPressio Event Transport uses that path as a compatibility fallback.

ESPressio Development Platform

ESPressio is a collection of discrete, composable component libraries built around a common development ethos:

  • Light-weight --- minimise memory consumption and runtime overhead without sacrificing correctness.
  • Ease of use --- provide strongly typed, developer-friendly abstractions over lower-level facilities.
  • Object-oriented --- a type for everything, and everything in a type.
  • SOLID --- favour focused responsibilities, extensibility, substitutable abstractions, narrow interfaces, and dependency inversion wherever practical on embedded C++ platforms.

License

Licensed under the Apache License 2.0. See LICENSE.

ESPressio Library Dependencies

ESPressio is designed as a modular ecosystem of independently useful libraries, with required dependencies kept explicit and optional integrations introduced only when the corresponding functionality is selected.

For a complete overview of required dependencies, opt-in dependencies, and the overall hierarchy, see:

ESPressio Library Dependency Chart

  • Solid relationships represent required ESPressio dependencies.
  • Dashed relationships represent opt-in dependencies introduced only by the corresponding feature, integration, type, or header.

Required ESPressio dependencies

None.

Declarative schema model

Serializable types declare their schema alongside the type itself:

class Example :
    public ESPressio::Serializable::
        SerializableBase<Example> {

public:
    uint32_t Id = 0;
    String Name;

    ESPRESSIO_SERIALIZABLE_TYPE(Example)
    ESPRESSIO_SERIALIZABLE_SCHEMA_VERSION(1)

    ESPRESSIO_SERIALIZABLE_PROPERTIES(
        ESPRESSIO_PROPERTY("id", Id),
        ESPRESSIO_PROPERTY("name", Name)
    )
};

The same declaration can be consumed by multiple archive representations.

Representations

The framework supports JSON, CBOR and Binary representations, including direct CBOR/Binary paths rather than requiring JSON as an intermediate representation.

Streaming readers/writers are available where supported by the selected archive.

Value support

The framework supports common scalar and compound values including arithmetic types, nested Serializable objects, arrays/containers, Arduino String, std::optional, enum mapping, and supported map/set forms.

Validation

Properties and objects can participate in validation, including numeric constraints and application-defined validation callbacks.

Schema evolution

Serializable types declare schema versions. Migration helpers, aliases and defaults allow older persisted or transported representations to evolve deliberately.

Redaction

Schema metadata can identify fields that should be redacted in diagnostic/log-oriented representations.

Compile-time diagnostics

Where an invalid or unsupported schema declaration can be detected statically, the library is designed to fail at compile time rather than defer the problem to runtime.

ESPressio integrations

Serializable remains independent. Other libraries opt into it:

Units
    -> optional Serializable Unit variants

Event
    -> optional Serializable Events
    -> Event Transport payloads

Ordinary usage of those libraries remains serialization-free.

Design goals

  • One declarative schema per type.
  • Representation-neutral metadata.
  • Embedded-friendly archives.
  • Direct CBOR/Binary support.
  • Bounded and allocation-free BinaryArchive inspection where appropriate.
  • Validation and schema evolution.
  • Compile-time diagnostics where possible.
  • Optional rather than ecosystem-wide dependency.

About

Serializable Components of the ESPressio Development Platform

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages