Emboss C++ Generated Code Reference

structs

A struct will have a corresponding view class, and functions to create views.

MakeStructView free function

template <typename T>
auto MakeStructView(/* view parameters, */ T *data, size_t size);
template <typename T>
auto MakeStructView(/* view parameters, */ T *container);

Struct will be replaced by the name of the specific struct whose view will be constructed; for example, to make a view for struct Message, call the MakeMessageView function.

View parameters will be replaced by one argument for each parameter attached to the struct. E.g., for:

struct Foo(x: UInt:8):
   --

MakeFooView will be:

template <typename T>
auto MakeFooView(std::uint8_t x, T *data, size_t size);
template <typename T>
auto MakeFooView(std::uint8_t x, T *container);

And for:

struct Bar(x: UInt:8, y: Int:32):
  --

MakeBarView will be:

template <typename T>
auto MakeBarView(std::uint8_t x, std::int32_t y, T *data, size_t size);
template <typename T>
auto MakeBarView(std::uint8_t x, std::int32_t y, T *container);

The MakeStructView functions construct a view for Struct over the given bytes. For the data/size form, the type T must be a character type: char, const char, unsigned char, const unsigned char, signed char, or const signed char. For the container form, the container can be a std::vector, std::array, or std::basic_string of a character type, or any other type with a data() method that returns a possibly-const char *, signed char *, or unsigned char *, and a size() method that returns a size in bytes. Google's absl::string_view is one example of such a type.

If given a pointer to a const character type or a const reference to a container, MakeStructView will return a read-only view; otherwise it will return a read-write view.

The result of MakeStructView should be stored in an auto variable:

auto view = MakeFooView(byte_buffer, available_byte_count);

The specific type returned by MakeStructView is subject to change.

CopyFrom method

template <typename OtherStorage>
void CopyFrom(GenericStructView<OtherStorage> other) const;

The CopyFrom method copies data from the view other into the current view. When complete, the current view‘s backing storage will contain the same bytes as other. This works even if the view’s backing storage overlaps, in which case other's backing storage is modified by the operation.

UncheckedCopyFrom method

template <typename OtherStorage>
void UncheckedCopyFrom(GenericStructView<OtherStorage> other) const;

The UncheckedCopyFrom method performs the same operation as CopyFrom but without any checks on the integrity of or the compatibility of the two views.

TryToCopyFrom method

template <typename OtherStorage>
bool TryToCopyFrom(GenericStructView<OtherStorage> other) const;

TryToCopyFrom copies data from other into the current view, if other is Ok() and the current backing storage is large enough to hold other's data.

Equals method

template <typename OtherStorage>
bool Equals(GenericStructView<OtherStorage> other);

The Equals method returns true if and only if itself and other contain the same fields yielding equivalent values (as measured by the == operator). Equals() should only be called if Ok() is true on both views.

UncheckedEquals method

template <typename OtherStorage>
bool UncheckedEquals(GenericStructView<OtherStorage> other);

The UncheckedEquals method performs the same operation as Equals, but without any checks on the integrity of or the compatibility of the two views when reading values. UncheckedEquals() should only be called if Ok() is true on both views.

Ok method

bool Ok() const;

The Ok method returns true if and only if there are enough bytes in the backing store, and the Ok methods of all active fields return true.

IsComplete method

bool IsComplete() const;

The IsComplete method returns true if there are enough bytes in the backing store to fully contain the struct. If IsComplete() returns true but Ok() returns false, then the structure is broken in some way that cannot be fixed by adding more bytes.

IntrinsicSizeInBytes method

auto IntrinsicSizeInBytes() const;

or

static constexpr auto IntrinsicSizeInBytes() const;

The IntrinsicSizeInBytes method is the field method for $size_in_bytes. The Read method of the result returns the size of the struct, and the Ok method returns true if the struct's intrinsic size is known; i.e.:

if (view.IntrinsicSizeInBytes().Ok()) {
  // The exact return type of view.IntrinsicSizeInBytes().Read() may vary, but
  // it will always be implicitly convertible to std::uint64_t.
  std::uint64_t view_size = view.IntrinsicSizeInBytes().Read();
}

Alternately, if you are sure the size is known:

std::uint64_t view_size = view.IntrinsicSizeInBytes().UncheckedRead();

Or, if the size is a compile-time constant:

constexpr std::uint64_t view_size = StructView::IntrinsicSizeInBytes().Read();
constexpr std::uint64_t view_size2 = Struct::IntrinsicSizeInBytes();

MaxSizeInBytes method

auto MaxSizeInBytes() const;

or

static constexpr auto MaxSizeInBytes() const;

The MaxSizeInBytes method is the field method for $max_size_in_bytes. The Read method of the result returns the maximum size of the struct, and the Ok always method returns true.

assert(view.MaxSizeInBytes().Ok());
// The exact return type of view.MaxSizeInBytes().Read() may vary, but it will
// always be implicitly convertible to std::uint64_t.
std::uint64_t view_size = view.MaxSizeInBytes().Read();

Alternately:

std::uint64_t view_size = view.MaxSizeInBytes().UncheckedRead();

Or:

constexpr std::uint64_t view_size = StructView::MaxSizeInBytes().Read();
constexpr std::uint64_t view_size2 = Struct::MaxSizeInBytes();

MinSizeInBytes method

auto MinSizeInBytes() const;

or

static constexpr auto MinSizeInBytes() const;

The MinSizeInBytes method is the field method for $min_size_in_bytes. The Read method of the result returns the minimum size of the struct, and the Ok always method returns true.

assert(view.MinSizeInBytes().Ok());
// The exact return type of view.MinSizeInBytes().Read() may vary, but it will
// always be implicitly convertible to std::uint64_t.
std::uint64_t view_size = view.MinSizeInBytes().Read();

Alternately:

std::uint64_t view_size = view.MinSizeInBytes().UncheckedRead();

Or:

constexpr std::uint64_t view_size = StructView::MinSizeInBytes().Read();
constexpr std::uint64_t view_size2 = Struct::MinSizeInBytes();

SizeIsKnown method

bool SizeIsKnown() const;

or

static constexpr bool SizeIsKnown() const;

The SizeIsKnown method is an alias of IntrinsicSizeInBytes().Ok().

The SizeIsKnown method returns true if the size of the struct can be determined from the bytes that are available. For example, consider a struct like:

struct Message:
  0 [+4]   UInt        payload_length (pl)
  4 [+pl]  UInt:8[pl]  payload

The Message‘s view’s SizeIsKnown method will return true if at least four bytes are available in the backing store, because it can determine the actual size of the message if at least four bytes can be read. If the backing store contains three or fewer bytes, then SizeIsKnown will be false.

Note that if the struct contains no dynamically-sized or dynamically-located fields, then SizeIsKnown will be a static constexpr method that always return true.

SizeInBytes method

std::size_t SizeInBytes() const;

or

static constexpr std::size_t SizeInBytes() const;

The SizeInBytes method returns static_cast<std::size_t>(IntrinsicSizeInBytes().Read()).

The SizeInBytes method returns the size of the struct in bytes. SizeInBytes asserts that SizeIsKnown(), so applications should ensure that SizeIsKnown() before calling SizeInBytes.

If the struct contains no dynamically-sized or dynamically-located fields, then SizeInBytes will be a static constexpr method, and can always be called safely.

UpdateFromTextStream method

template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;

UpdateFromTextStream will read a text-format representation of the structure from the given stream and update fields. Generally, applications would not call this directly; instead, use the global UpdateFromText method, which handles setting up a stream from a std::string.

WriteToTextStream method

template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;

WriteToTextStream will write a text representation of the current value in a form that can be decoded by UpdateFromTextStream. Generally, applications would not call this directly; instead, use the global WriteToString method, which handles setting up the stream and returning the resulting string.

BackingStorage method

Storage BackingStorage() const;

Returns the backing storage for the view. The return type of BackingStorage() is a template parameter on the view.

Field methods

Each physical field and virtual field in the struct will have a corresponding method in the generated view for that struct, which returns a subview of that field. For example, take the struct definition:

struct Foo:
  0 [+4]  UInt  bar
  4 [+4]  Int   baz
  let qux = 2 * bar
  let bar_alias = bar

In this case, the generated code will have methods

auto bar() const;
auto baz() const;
auto qux() const;
auto bar_alias() const;

The bar method will return a UInt view, and baz() will return an Int view. The qux method will return a pseudo-UInt view which can only be read. The bar_alias method actually forwards to bar, and can be both read and written:

auto foo_view = MakeFooView(&vector_of_foo_bytes);
uint32_t bar_value = foo_view.bar().Read();
int32_t baz_value = foo_view.baz().Read();
int64_t qux_value = foo_view.qux().Read();
uint32_t bar_alias_value = foo_view.bar_alias().Read();
foo_view.bar_alias().Write(100);
assert(foo_view.bar().Read() == 100);

As with MakeStructView, the exact return type of field methods is subject to change; if a field's view must be stored, use an auto variable.

Fields in anonymous bits are treated as if they were fields of the enclosing struct in the generated code. Take this struct:

struct Foo:
  0 [+4]  bits:
    5 [+5]  UInt  bar

In C++, bar would be read like so:

auto foo_view = MakeFooView(&vector_of_foo_bytes);
uint8_t bar_value = foo_view.bar().Read();

For each field, there is a has_field() method, which returns an object. has_ methods are typically used for conditional fields. Suppose you have a struct like:

struct Foo:
  0 [+1]  enum  message_type:
    BAR = 1
  if message_type == MessageType.BAR:
    1 [+25]  Bar  bar

When you have a view of a Foo, you can call foo_view.has_bar().Known() to find out whether foo_view has enough information to determine if the field bar should exist. If it does .Known() returns true, you may call foo_view.has_bar().Value() to find out if bar should exist. You can also call foo_view.has_bar().ValueOr(false), which will return true if bar's status is known, and bar exists.

Every field will have a corresponding has_ method. In the example above, foo_view.has_message_type().Known() and foo_view.has_message_type().Value() are both supported calls; both will always return true.

Note that just because a field “exists,” that does not mean that it can be read from or written to the current message: the field's bytes might be missing, or present but contain a non-Ok() value. You can use view.field().Ok() to determine if the field can be read, and view.field().IsComplete() to determine if the field can be written.

Constant Virtual Fields

Virtual fields whose values are compile-time constants can be read without instantiating a view:

struct Foo:
  let register_number = 0xf8
  0 [+4]  UInt  foo
// Foo::register_number() is a constexpr function.
static_assert(Foo::register_number() == 0xf8);

field().Ok() vs field().IsComplete() vs has_field()

Emboss provides a number of methods to query different kinds of validity.

has_field() is used for checking the existence condition specified in the .emb file:

struct Foo:
  0 [+1]    UInt  x
  if x < 10:
    1 [+1]  UInt  y

In the .cc file:

::std::array<char, 2> bytes = { 5, 7 };
auto foo = MakeFooView(&bytes);
assert(foo.x().Read() == 5);

// foo.x() is readable, so the existence condition on y is known.
assert(foo.has_y().Known());

// foo.x().Read() < 10, so y exists in foo.
assert(foo.has_y().Value());

foo.x().Write(15);

// foo.x().Read() >= 10, so y no longer exists in foo.
assert(foo.has_y().Known());
assert(!foo.has_y().Value());

// foo.has_x() is always true, since x's existence condition is just "true".
assert(foo.has_x().Known());
assert(foo.has_x().Value());

// incomplete_foo has 0 bytes of backing storage, so x is unreadable.
auto incomplete_foo = MakeFooView(&bytes[0], 0);

// incomplete_foo.has_x() is known, since it does not depend on anything.
assert(incomplete_foo.has_x().Known());
assert(incomplete_foo.has_x().Value());

// incomplete_foo.x().Ok() is false, since x cannot be read.
assert(!incomplete_foo.x().Ok());

// Since x cannot be read, incomplete_foo.has_y().Known() is false.
assert(!incomplete_foo.has_y().Known());

// Since has_y() is not Known(), calling has_y().Value() will crash if Emboss
// assertions are enabled.
// incomplete_foo.has_y().Value()  // Would crash

// It is safe to call has_y().ValueOr(false).
assert(!incomplete_foo.has_y().ValueOr(false));

has_field() is notional: it queries whether field should be present in the view. Even if has_field().Value() is true, field().IsComplete() and field().Ok() might return false.

field().IsComplete() tests if there are enough bytes in the backing storage to hold field. If field().IsComplete(), it is safe to call Write() on the field with a valid value for that field. field().Ok() tests if there are enough bytes in the backing storage to hold field, and that those bytes contain a valid value for field:

struct Bar:
  0 [+1]  Bcd  x
  1 [+1]  Bcd  y
::std::array<char, 1> bytes = { 0xbb };  // Not a valid BCD number.
auto bar = MakeBarView(&bytes);

// There are enough bytes to read and write x.
assert(bar.x().IsComplete());

// The value in x is not correct.
assert(!bar.x().Ok());

// Read() would crash if assertions are enabled.
// bar.x().Read();

// Writing a valid value is safe.
bar.x().Write(99);
assert(bar.x().Ok());

// Notionally, bar should have y, even though y's byte is not available:
assert(bar.has_y().Value());

// Since there is no byte to read y from, y is not complete:
assert(!bar.y().IsComplete());

Note that all views have Ok() and IsComplete() methods. A view of a structure is Ok() if all of its fields are either Ok() or not present, and has_field().Known() is true for all fields.

A structure view IsComplete() if its SizeIsKnown() and its backing storage contains at least SizeInBits() or SizeInBytes() bits or bytes. In other words: IsComplete() is true if Emboss can determine that (just) adding more bytes to the view‘s backing storage won’t help. Note that just because IsComplete() is false, that does not mean that adding more bytes will help. It is possible to define incoherent structures that will confuse Emboss, such as:

struct SizeNeverKnown:
  if false:
    0   [+1]  UInt  x_loc
  x_loc [+1]  UInt  x

bits Views

The code generated for a bits construct is very similar to the code generated for a struct. The primary differences are that there is no MakeBitsView function and that SizeInBytes is replaced by SizeInBits.

Ok method

bool Ok() const;

The Ok method returns true if and only if there are enough bytes in the backing store, and the Ok methods of all active fields return true.

IsComplete method

bool IsComplete() const;

The IsComplete method returns true if there are enough bytes in the backing store to fully contain the bits. If IsComplete() returns true but Ok() returns false, then the structure is broken in some way that cannot be fixed by adding more bytes.

IntrinsicSizeInBits method

auto IntrinsicSizeInBits() const;

or

static constexpr auto IntrinsicSizeInBits() const;

The IntrinsicSizeInBits method is the field method for $size_in_bits. The Read method of the result returns the size of the struct, and the Ok method returns true if the struct's intrinsic size is known; i.e.:

if (view.IntrinsicSizeInBits().Ok()) {
  std::uint64_t view_size = view.IntrinsicSizeInBits().Read();
}

Since the intrinsic size of a bits is always a compile-time constant:

constexpr std::uint64_t view_size = BitsView::IntrinsicSizeInBits().Read();
constexpr std::uint64_t view_size2 = Bits::IntrinsicSizeInBits();

MaxSizeInBits method

auto MaxSizeInBits() const;

or

static constexpr auto MaxSizeInBits() const;

The MaxSizeInBits method is the field method for $max_size_in_bits. The Read method of the result returns the maximum size of the bits, and the Ok always method returns true.

assert(view.MaxSizeInBits().Ok());
// The exact return type of view.MaxSizeInBits().Read() may vary, but it will
// always be implicitly convertible to std::uint64_t.
std::uint64_t view_size = view.MaxSizeInBits().Read();

Alternately:

std::uint64_t view_size = view.MaxSizeInBits().UncheckedRead();

Or:

constexpr std::uint64_t view_size = StructView::MaxSizeInBits().Read();
constexpr std::uint64_t view_size2 = Struct::MaxSizeInBits();

MinSizeInBits method

auto MinSizeInBits() const;

or

static constexpr auto MinSizeInBits() const;

The MinSizeInBits method is the field method for $min_size_in_bits. The Read method of the result returns the minimum size of the bits, and the Ok always method returns true.

assert(view.MinSizeInBits().Ok());
// The exact return type of view.MinSizeInBits().Read() may vary, but it will
// always be implicitly convertible to std::uint64_t.
std::uint64_t view_size = view.MinSizeInBits().Read();

Alternately:

std::uint64_t view_size = view.MinSizeInBits().UncheckedRead();

Or:

constexpr std::uint64_t view_size = StructView::MinSizeInBits().Read();
constexpr std::uint64_t view_size2 = Struct::MinSizeInBits();

SizeIsKnown method

static constexpr bool SizeIsKnown() const;

For a bits construct, SizeIsKnown() always returns true, because the size of a bits construct is always statically known at compilation time.

SizeInBits method

static constexpr std::size_t SizeInBits() const;

The SizeInBits method returns the size of the bits in bits. It is equivalent to static_cast<std::size_t>(IntrinsicSizeInBits().Read()).

UpdateFromTextStream method

template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;

UpdateFromTextStream will read a text-format representation of the structure from the given stream and update fields. Generally, applications would not call this directly; instead, use the global UpdateFromText method, which handles setting up a stream from a std::string.

WriteToTextStream method

template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;

WriteToTextStream will write a text representation of the current value in a form that can be decoded by UpdateFromTextStream. Generally, applications would not call this directly; instead, use the global WriteToString method, which handles setting up the stream and returning the resulting string.

Field methods

As with struct, each field in a bits will have a corresponding method of the same name generated, and each such method will return a view of the given field. Take the module:

bits Bar:
  0 [+12]  UInt  baz
  31 [+1]  Flag  qux
  let two_baz = baz * 2

struct Foo:
  0 [+4]  Bar  bar

In this case, the generated code in the Bar view will have methods

auto baz() const;
auto qux() const;
auto two_baz() const;

The baz method will return a UInt view, and qux() will return a Flag view:

auto foo_view = MakeFooView(&vector_of_foo_bytes);
uint16_t baz_value = foo_view.bar().baz().Read();
bool qux_value = foo_view.bar().qux().Read();
uint32_t two_baz_value = foo_view.bar().two_baz().Read();

The exact return type of field methods is subject to change; if a field's view must be stored, use an auto variable.

enums

For each enum in an .emb, the Emboss compiler will generate a corresponding C++11-style enum class. Take the following Emboss enum:

enum Foo:
  BAR = 1
  BAZ = 1000

Emboss will generate something equivalent to the following C++:

enum class Foo : uint64_t {
  BAR = 1,
  BAZ = 1000,
};

Additionally, like other Emboss entities, enums have corresponding view classes.

TryToGetEnumFromName free function

static inline bool TryToGetEnumFromName(const char *name, EnumType *result);

The TryToGetEnumFromName function will try to match name against the names in the Emboss enum definition. If it finds an exact match, it will return true and update result with the corresponding enum value. If it does not find a match, it will return false and leave result unchanged.

Note that TryToGetNameFromEnum will not match the text of the numeric value of an enum; given the Foo enum above, TryToGetEnumFromName("1000", &my_foo) would return false.

TryToGetNameFromEnum free function

static inline const char *TryToGetNameFromEnum(EnumType value);

TryToGetNameFromEnum will attempt to find the textual name for the corresponding enum value. If a name is found, it will be returned; otherwise TryToGetEnumFromName will return nullptr. (Note that C++ enums are allowed to contain numeric values that are not explicitly listed in the enum definition, as long as they are in range for the underlying integral type.) If the given value has more than one name, the first name that appears in the Emboss definition will be returned.

Read method

EnumType Read() const;

The Read method reads the enum from the underlying bytes and returns its value as a C++ enum. Read will assert that there are enough bytes to read. If the application cannot tolerate a failed assertion, it should first call Ok() to ensure that it can safely read the enum. If performance is critical and the application can assure that there will always be enough bytes to read the enum, it can call UncheckedRead instead.

UncheckedRead method

EnumType UncheckedRead() const;

Like Read, UncheckedRead reads the enum from the underlying bytes and returns it value as a C++ enum. Unlike Read, UncheckedRead does not attempt to validate that there are enough bytes in the backing store to actually perform the read. In performance-critical situations, if the application is otherwise able to ensure that there are sufficient bytes in the backing store to read the enum, UncheckedRead may be used.

Write method

void Write(EnumType value) const;

Write writes the value into the backing store. Like Read, Write asserts that there are enough bytes in the backing store to safely write the enum. If the application cannot tolerate an assertion failure, it can use TryToWrite or the combination of IsComplete and CouldWriteValue.

TryToWrite method

bool TryToWrite(EnumType value) const;

TryToWrite attempts to write the value into the backing store. If the backing store does not have enough bytes to hold the enum field, or value is too large for the specific enum field, then TryToWrite will return false and not update anything.

CouldWriteValue method

static constexpr bool CouldWriteValue(EnumType value);

CouldWriteValue returns true if the given value could be written into the enum field, assuming that there were enough bytes in the backing store to cover the field.

Although CouldWriteValue is static constexpr, it is tricky to call statically; client code that wishes to call it statically must use decltype and declval to get the specific type for the specific enum field in question.

UncheckedWrite method

void UncheckedWrite(EnumType value) const;

Like Write, UncheckedWrite writes the given value to the backing store. Unlike Write, UncheckedWrite does not check that there are actually enough bytes in the backing store to safely write; it should only be used if the application has ensured that there are sufficient bytes in the backing store in some other way, and performance is a concern.

Ok method

bool Ok() const;

Ok returns true if there are enough bytes in the backing store for the enum field to be read or written.

In the future, Emboss may add a “known values only” annotation to enum fields, in which case Ok would also check that the given field contains a known value.

IsComplete method

bool IsComplete() const;

IsComplete returns true if there are enough bytes in the backing store for the enum field to be read or written.

UpdateFromTextStream method

template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;

UpdateFromTextStream will read a text-format representation of the enum from the given stream and write it into the backing store. Generally, applications would not call this directly; instead, use the global UpdateFromText method, which handles setting up a stream from a std::string.

WriteToTextStream method

template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;

WriteToTextStream will write a text representation of the current value in a form that can be decoded by UpdateFromTextStream. Generally, applications would not call this directly; instead, use the global WriteToString method, which handles setting up the stream and returning the resulting string.

Arrays

operator[] method

ElementView operator[](size_t index) const;

The operator[] method of an array view returns a view of the array element at index.

begin()/rbegin() and end()/rend() methods

ElementViewIterator<> begin();
ElementViewIterator<> end();
ElementViewIterator<> rbegin();
ElementViewIterator<> rend();

The begin() and end() methods of an array view returns view iterators to the beginning and past-the-end of the array, respectively. They may be used with arrays in range-based for loops, for example:

  auto view = MakeArrayView(...);
  for(auto element : view){
    int a = view.member().Read();
    ...
  }

The rbegin() and rend() methods of an array view returns reverse view iterators to the end and element preceding the first, respectively.

SizeInBytes or SizeInBits method

size_t SizeInBytes() const;

or

size_t SizeInBits() const;

Arrays in structs have the SizeInBytes method; arrays in bits have the SizeInBits method. SizeInBytes returns the size of the array in bytes; SizeInBits returns the size of the array in bits.

ElementCount method

size_t ElementCount() const;

ElementCount returns the number of elements in the array.

Ok method

bool Ok() const;

Ok returns true if there are enough bytes in the backing store to hold the entire array, and every element's Ok method returns true.

IsComplete method

bool IsComplete() const;

IsComplete returns true if there are sufficient bytes in the backing store to hold the entire array.

ToString method

template <class String>
String ToString() const;

Intended usage:

// Makes a copy of view's backing storage.
auto str = view.ToString<std::string>();

// Points to view's backing storage.
auto str_view = view.ToString<std::string_view>();

ToString() returns a string type constructed from the backing storage of the array. Note that ToString() is only enabled for arrays of 1-byte values, such as UInt:8[], and only when the array view's underlying storage is contiguous.

Although it is intended for use with std::string and std::string_view, ToString() can work with any C++ type that:

  1. Has a data() method that returns a pointer to the string's underlying data as a char type.
  2. Has a constructor that accepts a const declval(data()) pointer and a size_t length.

UpdateFromTextStream method

template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;

UpdateFromTextStream will read a text-format representation of the structure from the given stream and update array elements. Generally, applications would not call this directly; instead, use the global UpdateFromText method, which handles setting up a stream from a std::string.

WriteToTextStream method

template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;

WriteToTextStream will write a text representation of the current value in a form that can be decoded by UpdateFromTextStream. Generally, applications would not call this directly; instead, use the global WriteToString method, which handles setting up the stream and returning the resulting string.

BackingStorage method

Storage BackingStorage() const;

Returns the backing storage for the view. The return type of BackingStorage() is a template parameter on the view.

UInt

Type ValueType

using ValueType = ...;

The ValueType type alias maps to the least-width C++ unsigned integer type that contains enough bits to hold any value of the given UInt. For example:

  • a UInt:32's ValueType would be uint32_t
  • a UInt:64's ValueType would be uint64_t
  • a UInt:12's ValueType would be uint16_t
  • a UInt:2's ValueType would be uint8_t

The Read and Write families of methods use ValueType to return or accept values, respectively.

Read method

ValueType Read() const;

The Read method reads the UInt from the underlying bytes and returns its value as a C++ unsigned integer type. Read will assert that there are enough bytes to read. If the application cannot tolerate a failed assertion, it should first call Ok() to ensure that it can safely read the UInt. If performance is critical and the application can assure that there will always be enough bytes to read the UInt, it can call UncheckedRead instead.

UncheckedRead method

ValueType UncheckedRead();

Like Read, UncheckedRead reads the UInt from the underlying bytes and returns it value as a C++ unsigned integer type. Unlike Read, UncheckedRead does not attempt to validate that there are enough bytes in the backing store to actually perform the read. In performance-critical situations, if the application is otherwise able to ensure that there are sufficient bytes in the backing store to read the UInt, UncheckedRead may be used.

Write method

void Write(ValueType value);

Write writes the value into the backing store. Like Read, Write asserts that there are enough bytes in the backing store to safely write the UInt. If the application cannot tolerate an assertion failure, it can use TryToWrite or the combination of IsComplete and CouldWriteValue.

TryToWrite method

bool TryToWrite(ValueType value);

TryToWrite attempts to write the value into the backing store. If the backing store does not have enough bytes to hold the UInt field, or value is too large for the UInt field, then TryToWrite will return false and not update anything.

CouldWriteValue method

static constexpr bool CouldWriteValue(ValueType value);

CouldWriteValue returns true if the given value could be written into the UInt field, assuming that there were enough bytes in the backing store to cover the field.

Although CouldWriteValue is static constexpr, it is tricky to call statically; client code that wishes to call it statically must use decltype and declval to get the specific type for the specific UInt field in question.

UncheckedWrite method

void UncheckedWrite(ValueType value);

Like Write, UncheckedWrite writes the given value to the backing store. Unlike Write, UncheckedWrite does not check that there are actually enough bytes in the backing store to safely write; it should only be used if the application has ensured that there are sufficient bytes in the backing store in some other way, and performance is a concern.

Ok method

bool Ok() const;

The Ok method returns true if there are enough bytes in the backing store to hold the given UInt field.

IsComplete method

bool IsComplete();

The IsComplete method returns true if there are enough bytes in the backing store to hold the given UInt field.

UpdateFromTextStream method

template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;

UpdateFromTextStream will read a text-format representation of the UInt from the given stream and update fields. Generally, applications would not call this directly; instead, use the global UpdateFromText method, which handles setting up a stream from a std::string.

WriteToTextStream method

template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;

WriteToTextStream will write a text representation of the current value in a form that can be decoded by UpdateFromTextStream. Generally, applications would not call this directly; instead, use the global WriteToString method, which handles setting up the stream and returning the resulting string.

SizeInBits method

static constexpr int SizeInBits();

The SizeInBits method returns the size of this specific UInt field, in bits.

Int

Type ValueType

using ValueType = ...;

The ValueType type alias maps to the least-width C++ signed integer type that contains enough bits to hold any value of the given Int. For example:

  • a Int:32's ValueType would be int32_t
  • a Int:64's ValueType would be int64_t
  • a Int:12's ValueType would be int16_t
  • a Int:2's ValueType would be int8_t

The Read and Write families of methods use ValueType to return or accept values, respectively.

Read method

ValueType Read() const;

The Read method reads the Int from the underlying bytes and returns its value as a C++ signed integer type. Read will assert that there are enough bytes to read. If the application cannot tolerate a failed assertion, it should first call Ok() to ensure that it can safely read the Int. If performance is critical and the application can assure that there will always be enough bytes to read the Int, it can call UncheckedRead instead.

UncheckedRead method

ValueType UncheckedRead();

Like Read, UncheckedRead reads the Int from the underlying bytes and returns it value as a C++ signed integer type. Unlike Read, UncheckedRead does not attempt to validate that there are enough bytes in the backing store to actually perform the read. In performance-critical situations, if the application is otherwise able to ensure that there are sufficient bytes in the backing store to read the Int, UncheckedRead may be used.

Write method

void Write(ValueType value);

Write writes the value into the backing store. Like Read, Write asserts that there are enough bytes in the backing store to safely write the Int. If the application cannot tolerate an assertion failure, it can use TryToWrite or the combination of IsComplete and CouldWriteValue.

TryToWrite method

bool TryToWrite(ValueType value);

TryToWrite attempts to write the value into the backing store. If the backing store does not have enough bytes to hold the Int field, or value is too large for the Int field, then TryToWrite will return false and not update anything.

CouldWriteValue method

static constexpr bool CouldWriteValue(ValueType value);

CouldWriteValue returns true if the given value could be written into the Int field, assuming that there were enough bytes in the backing store to cover the field.

Although CouldWriteValue is static constexpr, it is tricky to call statically; client code that wishes to call it statically must use decltype and declval to get the specific type for the specific Int field in question.

UncheckedWrite method

void UncheckedWrite(ValueType value);

Like Write, UncheckedWrite writes the given value to the backing store. Unlike Write, UncheckedWrite does not check that there are actually enough bytes in the backing store to safely write; it should only be used if the application has ensured that there are sufficient bytes in the backing store in some other way, and performance is a concern.

Ok method

bool Ok() const;

The Ok method returns true if there are enough bytes in the backing store to hold the given Int field.

IsComplete method

bool IsComplete();

The IsComplete method returns true if there are enough bytes in the backing store to hold the given Int field.

UpdateFromTextStream method

template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;

UpdateFromTextStream will read a text-format representation of the Int from the given stream and update fields. Generally, applications would not call this directly; instead, use the global UpdateFromText method, which handles setting up a stream from a std::string.

WriteToTextStream method

template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;

WriteToTextStream will write a text representation of the current value in a form that can be decoded by UpdateFromTextStream. Generally, applications would not call this directly; instead, use the global WriteToString method, which handles setting up the stream and returning the resulting string.

SizeInBits method

static constexpr int SizeInBits();

The SizeInBits method returns the size of this specific Int field, in bits.

Bcd

Type ValueType

using ValueType = ...;

The ValueType type alias maps to a C++ unsigned integer type that contains at least enough bits to hold any value of the given Bcd. For example:

  • a Bcd:32's ValueType would be uint32_t
  • a Bcd:64's ValueType would be uint64_t
  • a Bcd:12's ValueType would be uint16_t
  • a Bcd:2's ValueType would be uint8_t

The Read and Write families of methods use ValueType to return or accept values, respectively.

Read method

ValueType Read() const;

The Read method reads the Bcd from the underlying bytes and returns its value as a C++ unsigned integer type. Read will assert that there are enough bytes to read, and that the binary representation is a valid BCD integer. If the application cannot tolerate a failed assertion, it should first call Ok() to ensure that it can safely read the Bcd. If performance is critical and the application can assure that there will always be enough bytes to read the Bcd, and that the bytes will be a valid BCD value, it can call UncheckedRead instead.

UncheckedRead method

ValueType UncheckedRead();

Like Read, UncheckedRead reads the Bcd from the underlying bytes and returns it value as a C++ unsigned integer type. Unlike Read, UncheckedRead does not attempt to validate that there are enough bytes in the backing store to actually perform the read, nor that the bytes contain an actual BCD number. In performance-critical situations, if the application is otherwise able to ensure that there are sufficient bytes in the backing store to read the Bcd, UncheckedRead may be used.

Write method

void Write(ValueType value);

Write writes the value into the backing store. Like Read, Write asserts that there are enough bytes in the backing store to safely write the Bcd. If the application cannot tolerate an assertion failure, it can use TryToWrite or the combination of IsComplete and CouldWriteValue.

TryToWrite method

bool TryToWrite(ValueType value);

TryToWrite attempts to write the value into the backing store. If the backing store does not have enough bytes to hold the Bcd field, or value is too large for the Bcd field, then TryToWrite will return false and not update anything.

CouldWriteValue method

static constexpr bool CouldWriteValue(ValueType value);

CouldWriteValue returns true if the given value could be written into the Bcd field, assuming that there were enough bytes in the backing store to cover the field.

Although CouldWriteValue is static constexpr, it is tricky to call statically; client code that wishes to call it statically must use decltype and declval to get the specific type for the specific Bcd field in question.

UncheckedWrite method

void UncheckedWrite(ValueType value);

Like Write, UncheckedWrite writes the given value to the backing store. Unlike Write, UncheckedWrite does not check that there are actually enough bytes in the backing store to safely write; it should only be used if the application has ensured that there are sufficient bytes in the backing store in some other way, and performance is a concern.

Ok method

bool Ok() const;

The Ok method returns true if there are enough bytes in the backing store to hold the given Bcd field, and the bytes contain a valid BCD number: that is, that every nibble in the backing store contains a value between 0 and 9, inclusive.

IsComplete method

bool IsComplete();

The IsComplete method returns true if there are enough bytes in the backing store to hold the given Bcd field.

UpdateFromTextStream method

template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;

UpdateFromTextStream will read a text-format representation of the Bcd from the given stream and update fields. Generally, applications would not call this directly; instead, use the global UpdateFromText method, which handles setting up a stream from a std::string.

WriteToTextStream method

template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;

WriteToTextStream will write a text representation of the current value in a form that can be decoded by UpdateFromTextStream. Generally, applications would not call this directly; instead, use the global WriteToString method, which handles setting up the stream and returning the resulting string.

SizeInBits method

static constexpr int SizeInBits();

The SizeInBits method returns the size of this specific Bcd field, in bits.

Flag

Read method

bool Read() const;

The Read method reads the Flag from the underlying bit and returns its value as a C++ bool. Read will assert that the underlying bit is in the backing store. If the application cannot tolerate a failed assertion, it should first call Ok() to ensure that it can safely read the Flag. If performance is critical and the application can assure that there will always be enough bytes to read the Flag, it can call UncheckedRead instead.

UncheckedRead method

bool UncheckedRead();

Like Read, UncheckedRead reads the Flag from the underlying bit and returns it value as a C++ bool. Unlike Read, UncheckedRead does not attempt to validate that the backing bit is actually in the backing store. In performance-critical situations, if the application is otherwise able to ensure that there are sufficient bytes in the backing store to read the Flag, UncheckedRead may be used.

Write method

void Write(bool value);

Write writes the value into the backing store. Like Read, Write asserts that there are enough bytes in the backing store to safely write the Flag. If the application cannot tolerate an assertion failure, it can use TryToWrite or the combination of IsComplete and CouldWriteValue.

TryToWrite method

bool TryToWrite(bool value);

TryToWrite attempts to write the value into the backing store. If the backing store does not contain the Flag's bit, then TryToWrite will return false and not update anything.

CouldWriteValue method

static constexpr bool CouldWriteValue(bool value);

CouldWriteValue returns true, as both C++ bool values can be written to any Flag.

UncheckedWrite method

void UncheckedWrite(ValueType value);

Like Write, UncheckedWrite writes the given value to the backing store. Unlike Write, UncheckedWrite does not check that there are actually enough bytes in the backing store to safely write; it should only be used if the application has ensured that there are sufficient bytes in the backing store in some other way, and performance is a concern.

Ok method

bool Ok() const;

The Ok method returns true if the backing store contains the Flag's bit.

IsComplete method

bool IsComplete();

The IsComplete method returns true if the backing store contains the Flag's bit.

UpdateFromTextStream method

template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;

UpdateFromTextStream will read a text-format representation of the Flag from the given stream and update fields. Generally, applications would not call this directly; instead, use the global UpdateFromText method, which handles setting up a stream from a std::string.

WriteToTextStream method

template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;

WriteToTextStream will write a text representation of the current value in a form that can be decoded by UpdateFromTextStream. Generally, applications would not call this directly; instead, use the global WriteToString method, which handles setting up the stream and returning the resulting string.

Float

Type ValueType

using ValueType = ...;

The ValueType type alias maps to the C++ floating-point type that matches the Float field's type; generally float for 32-bit Floats and double for 64-bit Floats.

The Read and Write families of methods use ValueType to return or accept values, respectively.

Read method

ValueType Read() const;

The Read method reads the Float from the underlying bytes and returns its value as a C++ floating point type. Read will assert that there are enough bytes to read. If the application cannot tolerate a failed assertion, it should first call Ok() to ensure that it can safely read the Float. If performance is critical and the application can assure that there will always be enough bytes to read the Float, it can call UncheckedRead instead.

UncheckedRead method

ValueType UncheckedRead();

Like Read, UncheckedRead reads the Float from the underlying bytes and returns it value as a C++ floating point type. Unlike Read, UncheckedRead does not attempt to validate that there are enough bytes in the backing store to actually perform the read. In performance-critical situations, if the application is otherwise able to ensure that there are sufficient bytes in the backing store to read the Float, UncheckedRead may be used.

Write method

void Write(ValueType value);

Write writes the value into the backing store. Like Read, Write asserts that there are enough bytes in the backing store to safely write the Float. If the application cannot tolerate an assertion failure, it can use TryToWrite or the combination of IsComplete and CouldWriteValue.

TryToWrite method

bool TryToWrite(ValueType value);

TryToWrite attempts to write the value into the backing store. If the backing store does not have enough bytes to hold the Float field, then TryToWrite will return false and not update anything.

CouldWriteValue method

static constexpr bool CouldWriteValue(ValueType value);

CouldWriteValue returns true.

UncheckedWrite method

void UncheckedWrite(ValueType value);

Like Write, UncheckedWrite writes the given value to the backing store. Unlike Write, UncheckedWrite does not check that there are actually enough bytes in the backing store to safely write; it should only be used if the application has ensured that there are sufficient bytes in the backing store in some other way, and performance is a concern.

Ok method

bool Ok() const;

The Ok method returns true if there are enough bytes in the backing store to hold the given Float field.

IsComplete method

bool IsComplete();

The IsComplete method returns true if there are enough bytes in the backing store to hold the given Float field.

UpdateFromTextStream method

template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;

UpdateFromTextStream will read a text-format representation of the Float from the given stream and update fields. Generally, applications would not call this directly; instead, use the global UpdateFromText method, which handles setting up a stream from a std::string.

Note: this method is not yet implemented.

WriteToTextStream method

template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;

WriteToTextStream will write a text representation of the current value in a form that can be decoded by UpdateFromTextStream. Generally, applications would not call this directly; instead, use the global WriteToString method, which handles setting up the stream and returning the resulting string.

Note: this method is not yet implemented.

::emboss::UpdateFromText function

template <typename EmbossViewType>
bool UpdateFromText(EmbossViewType view, const ::std::string &text) const;

The ::emboss::UpdateFromText function constructs an appropriate text strem object from the given text and calls view's UpdateFromTextStream method. This is the preferred way to read Emboss text format in C++.

::emboss::WriteToString function

template <typename EmbossViewType>
::std::string WriteToString(EmbossViewType view);
template <typename EmbossViewType>
::std::string WriteToString(EmbossViewType view, TextOutputOptions options);

The ::emboss::WriteToString function constructs a string stream, passes it into the view's WriteToTextStream method, and finally returns the text format of the view.

The single-argument form WriteToString(view) will return a single line of text. For more readable output, WriteToString(view, ::emboss::MultilineText()) should help.

::emboss::TextOutputOptions class

The TextOutputOptions is used to set options for text output, such as numeric base, whether or not to use multiple lines, etc.

PlusOneIndent method

TextOutputOptions PlusOneIndent() const;

PlusOneIndent returns a new TextOutputOptions with one more level of indentation than the current TextOutputOptions. This is primarily intended for use inside of WriteToTextStream methods, as a way to get an indented TextOutputOptions to pass to the WriteToTextStream methods of child objects. However, application callers may use PlusOneIndent(), possibly multiple times, to indent the entire output.

Multiline method

TextOutputOptions Multiline(bool new_value) const;

Returns a new TextOutputOptions with the same options as the current TextOutputOptions, except for a new value for multiline().

WithIndent method

TextOutputOptions WithIndent(::std::string new_value) const;

Returns a new TextOutputOptions with the same options as the current TextOutputOptions, except for a new value for indent().

WithComments method

TextOutputOptions WithComments(bool new_value) const;

Returns a new TextOutputOptions with the same options as the current TextOutputOptions, except for a new value for comments().

WithDigitGrouping method

TextOutputOptions WithDigitGrouping(bool new_value) const;

Returns a new TextOutputOptions with the same options as the current TextOutputOptions, except for a new value for digit_grouping().

WithNumericBase method

TextOutputOptions WithNumericBase(int new_value) const;

Returns a new TextOutputOptions with the same options as the current TextOutputOptions, except for a new value for digit_grouping(). The new numeric base should be 2, 10, or 16.

WithAllowPartialOutput method

TextOutputOptions WithAllowPartialOutput(bool new_value) const;

Returns a new TextOutputOptions with the same options as the current TextOutputOptions, except for a new value for allow_partial_output().

current_indent method

::std::string current_indent() const;  // Default "".

Returns the current indent string.

indent method

::std::string indent() const;  // Default "  ".

Returns the indent string. The indent string is the string used for a single level of indentation.

multiline method

bool multiline() const;  // Default false.

Returns true if text output should use multiple lines, or false if text output should be single-line only.

digit_grouping method

bool digit_grouping() const;  // Default false.

Returns true if text output should include digit separators on numbers; i.e. 1_000_000 instead of 1000000.

comments method

bool comments() const;  // Default false.

Returns true if text output should include comments, e.g., to show numbers in multiple bases.

numeric_base method

uint8_t numeric_base() const;  // Default 10.

Returns the numeric base that should be used for formatting numbers. This should always be 2, 10, or 16.

allow_partial_output method

bool allow_partial_output() const;  // Default false.

Returns true if text output should attempt to extract fields from a view that is not Ok(). If so:

  • WriteToString() or WriteToTextStream() should never CHECK-fail.
  • Atomic fields (e.g., Int, UInt, enum, Flag, etc. types) will not be written to the text stream if they cannot be read.
  • If comments() is also true, unreadable atomic fields will be commented in the text stream.
  • Aggregate fields (struct, bits, or arrays) will be written, but may be missing fields or entirely empty if they have non-Ok() members.