Class Union

Class Documentation

class Union

The Union class is intended to allow examining arbitrary blocks of memory in a structured way, in an API-independent manner.

The Union class describes the layout of a C/C++ union in a generic fashion, which allows the user to interpret an arbitrary block of memory independent of the original declaration. The methods of a Union instance can be used to determine the sizes, basic types, declared types and names of the fields within the union, and given a pointer containing the base location of the start of the union's memory, this can be used to examine and/or change the contents of the union, without having access to the union's original definition in the source language.

This is useful in cases where there is a need to be able to access both the union's data and metadata independent of the context in which the union instance was created.

Examples

Examine a memory block as a Union. In this example we define a function that takes a pointer to memory, and a pointer to a Union instance, and accesses the memory using the layout definition provided by the Union instance.

#include "reflection/field.h"
#include <cstdint>
#include <iostream>

union Foo {
 uint32_t x;
 char const* str;
};

// validation and error-checking left out for brevity
void Bar(void const* memory, Union const* unionDef) {
    // for simple pointer arithmetic, cast the pointer to uint8_t*
    uint8_t const* data = (uint8_t const*)memory;

    Field const* xField = unionDef->GetField(0);
    Field const* strField = unionDef->GetField(1);

    // Fields for unions should have an offset of 0 since they overlap in memory.
    uint32_t const* xValuePtr = (uint32_t const*)(data);
    char const** strValuePtr = (char const**)(data);

    std::cout << "x: " << *xValuePtr << std::endl;
    std::cout << "str: " << *strValuePtr << std::endl;
}

Public Functions

Union()

Default constructor.

Note

All members are initialized to their type-specific "zero" values.

Union(char const *name, Field const *fields, uint64_t fieldCount, size_t size)

Full constructor &#8212; all members initialized to provided parameter values.

Note

fields refers only to the members directly declared for this union; any nested fields are referred to by the fields themselves

Note

Since size may be compiler-dependent, and may depend on compiler-specific packing algorithms, it is important to know that the compiler used to parse the original API headers when the GPA Framework was built, is clang.

Parameters
  • name -- Name of the union as declared in the original API header.

  • fields -- Pointer to one or more Field instances that define the top-level union members

  • fieldCount -- Number of fields pointed to by the fields argument

  • size -- Size, in bytes, of the union as determined by the compiler used to parse the original API headers

~Union()
char const *Name() const

Access the name of the union as declared in the original API header.

Returns

The union name as declared in original code.

uint64_t FieldCount() const

Access the number of fields declared in the union.

Note

This value can be zero if the union does not have any declared fields.

Returns

Number of fields declared in the union, or zero if no fields declared.

Field const *GetField(uint64_t index) const

Access metadata for a union member.

See also

FieldCount().

Note

Field ordering is defined by the ordering of the union layout as declared in the original API headers. The offset for each field is expected to be 0 since union members overlap on the same memory region.

Parameters

index -- Zero-based index of the member in the union.

Returns

A Field instance describing one of the union members, or nullptr if index is out of range (greater than or equal to the number of members in the union).

Field const *GetFieldByName(char const *name) const
size_t Size() const

Obtain union size, in bytes.

This value can be used to allocate space for an instance of this union, which can then be filled in using the field member definitions.

Returns

The number of bytes required to store an instance of this union.