Skip to content

Introduction#

The data types in AES70 are:

  • Basic data types (e.g. OcaFloat32, OcaString, OcaList<T>)
  • Enums (e.g. OcaStatus) and bitsets
  • Structure types that are compositions of other types

For each data type defined in the AES70 standard, this library defines a corresponding C++ type using standard library types. For example:

  • OcaFloat32 is a typedef for float
  • OcaString is a typedef for std::string
  • OcaList<T> is a typedef for std::vector<T>

The full list of data types can be found in the files included from include/aes70/types.hpp.

OCP.1 Encoding#

AES70 uses a binary encoding called OCP.1. OCP.1 defines how data types in return values and arguments are encoded for transfer over the network.

The implementation of OCP.1 is defined in the aes70::OCP1 namespace. For instance, the implementation of the encoding of OcaString is defined as aes70::OCP1::OcaString.

One important detail about these encoder classes is that they can decode to and encode more than just the standard types. This means, for instance, that the encoder for OcaString supports not only std::string, but also several other string-like types such as std::string_view.

Encoding happens in the following situations:

  • Return value of control methods in devices (see here)
  • Arguments of controller classes (see here)
  • When sending property changed events

Decoding happens in the following situations:

  • Argument of control methods in devices (see here)
  • Return values of controller classes (see here)
  • When receiving property changed events in controllers

As a consequence, return values and arguments of AES70 methods are flexible.

The following sections describe the encoding and decoding possibilities in detail.

To understand in detail which data types are supported, look at the encoder implementations in include/aes70/OCP1/encoders.hpp and especially the signatures of the methods

    uint8_t *encode_to(uint8_t *dst, const T &x);
    const uint8_t *decode_from(const uint8_t *src, T &x);

There are some special types which any encoder supports:

  • aes70::OCP1::ignore. When encoding, this results in the trivial encoding of the corresponding type (e.g. 0 for integers, the empty list for OcaList<T>, the empty string, etc.). When used during decoding, the encoder decodes and discards the result. This is useful for unused arguments in OCA method implementations.
  • aes70::buffer_view. This class is similar to std::string_view; it represents a pointer and a length. When used as an argument during decoding, it will contain the part of the network buffer that contains the encoding of the corresponding parameter. This can be useful in situations where custom decoding logic needs to be implemented.

Integer types#

All integer types (OcaInt8, OcaUint16, etc.) can decode into and encode any integer type.

Note

Keep in mind that when decoding into a smaller integer type, the value may not fit. For example, when an AES70 method is defined to receive a value of type OcaInt64, using an int16_t could result in a different value. It is therefore recommended to use the integer of the correct size, e.g. int64_t.

OcaFloat32, OcaFloat64#

These encode and decode into the corresponding floating point types float and double. When decoding values, they are validated using the macro AES70_IS_VALID_FLOAT(x), which by default will not allow NaN.

OcaString#

Supported types when encoding:

  • const char * (the string is expected to be null-terminated)
  • std::string
  • std::string_view

Supported types when decoding:

  • std::string
  • std::string_view: Does not copy the data

OcaString is defined to contain a UTF-8 encoded string. When decoding, the content will be validated to contain only codepoints in the "Unicode Assignables" set defined in section 4.2 of RFC 9893. This behavior can be customized by defining the macro AES70_IS_VALID_UTF8(start, end, codepoints). See the source file include/aes70/utf8/code_codepoints.hpp for more details.

OcaBlob and OcaLongBlob#

Supported types when encoding:

  • const char * (the string is expected to be null-terminated)
  • Any container type that can be iterated over, e.g. std::string, std::string_view, std::span<uint8_t>, std::vector<uint8_t>

Supported types when decoding:

  • std::string
  • std::string_view: This does not copy the data. The resulting std::string_view points into the data stored in the network buffer

OcaList#

Supported types when encoding:

  • Any container type that can be iterated over. For example, it supports all standard container types such as std::list, std::vector, etc.

Supported types when decoding:

  • Any container that implements clear() and push_back methods. If available, reserve will be called with the length of the resulting list before decoding elements.
  • std::array<T, N> and T[N]. If the destination array length is too small, the additional elements will be discarded. If the destination array is too large, the additional elements will be overwritten with T().
  • std::span<T, Extent> with static extent. If the span is too small, the additional elements will be discarded.

OcaMap#

Supported types when encoding:

  • Supports standard map types such as std::map or std::unordered_map.
  • Supports vector-like containers such as std::vector<std::pair<A, B>>.

Supported types when decoding:

  • Any container that supports clear() and emplace(key, value).

OcaBitstring#

Supported types when encoding:

  • Any linear container that can be iterated. Interprets individual elements as the resulting bits. If an entry is true-ish, the resulting bit is 1.
  • std::bitset<N>
  • Unsigned integral types such as uint16_t. The first bit of the resulting bitset is 1. The length of the resulting bitstring is the length of the integral type.

Supported types when decoding:

  • Any linear container that stores bool and implements clear() and push_back, e.g. std::vector<bool>.
  • std::bitset<N> and unsigned integral types as above.

OcaVariant#

Supports only std::variant.

Enums#

Enums are decoded and encoded using the corresponding integer type, i.e. OcaUint8 or OcaUint16. When decoding into any of the built-in OCA enums (e.g. OcaClassicalFilterShape), the decoder will check that the enum value is valid. This is done by using the special enum entries min_value and max_value, which are present in all standard AES70 enums. If it does not, the decoded result will be the entry unknown_value.

When implementing OCA methods and this behavior is not wanted, use the underlying integer type.

Struct types#

Decoding and encoding support the following types:

  • Classes that implement the methods std::tuple<TN...> oca_properties() and const std::tuple<TN...> oca_properties() const. See the default implementations in include/aes70/types_complex.hpp for examples.

  • std::tuple<TN...>

  • std::array<T, N> for struct types that contain only one type