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 which 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 datatype can be found in the files included from include/aes70/types.hpp.

OCP.1 Encoding#

AES70 used 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. That 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, looking at the encoder implementations in include/aes70/OCP1/encodrs.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, 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 when 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 when decoding it will contain the part of the network buffer which contains the encoding of the corresponding parameter. This can be useful in situations where some 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 result. It is therefore recommended to use the integer of correct size, e.g. int64_t.

OcaFloat32, OcaFloat64#

Encodes and decoded 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 an 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)
  • Generically any container type which 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 case 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 which 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 which 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 big, 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 which 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 stored 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 encoding 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 supports the following types:

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

  • std::tuple<TN...>

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