Class Struct

Class Documentation

class Struct

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

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

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

Examples

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

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

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

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

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

    uint32_t const* xValuePtr = (uint32_t const*)(data + xField->Offset());
    char const** strValuePtr = (char const**)(data + strField->Offset());

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

Public Functions

Struct()

Default constructor.

Note

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

Struct(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 struct; 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 struct as declared in the original API header.

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

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

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

~Struct()
char const *Name() const

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

Returns

The struct name as declared in original code.

uint64_t FieldCount() const

Access the number of fields declared in the struct.

Note

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

Returns

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

Field const *GetField(uint64_t index) const

Access metadata for a struct member.

See also

FieldCount().

Note

Field ordering is defined by the ordering of the struct layout as declared in the original API headers.

Warning

Bitfield members are not supported.

Parameters

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

Returns

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

Field const *GetFieldByName(char const *name) const

Access metadata for a struct member by the name of the field.

See also

Field::Name().

Parameters

name -- Name of the struct field.

Returns

A Field instance describing one of the struct members, or nullptr if name is not a name for any field in the struct.

void AddUnionFieldSelectorValue(uint64_t selectorValue, char const *unionFieldName, uint64_t unionIndex)

Add a mapping from a field value to a union field name. If the selector field is equal to this value then @GetValidField() will return the a field with a name equal to @unionFieldName from a union within this struct.

Parameters
  • selectorValue -- The value used to select the union field name equal to @unionFieldName.

  • unionFieldName -- the name of the field that should be selected from this struct's union.

  • unionIndex -- The index of the union field inside this struct that this mapping applies to.

void SetUnionFieldSelector(uint64_t index, uint64_t unionIndex)

Set witch field will be used as the selector for the valid field in this struct's union.

Parameters
  • index -- The index of the field.

  • unionIndex -- The index of the union field inside this struct that this selector applies to.

Field const *GetValidField(void const *structBase, uint64_t unionIndex) const

Finds the field within this struct's union field that is valid based on the value of the selector field.

Parameters
  • structBase -- A pointer to the beginning of this struct's data.

  • unionIndex -- The index of the union field inside this struct that a valid field is requested from.

Returns

The Field object within the desired union that has a valid value.

UnionBinding const *GetUnionBinding(uint64_t unionIndex) const

Access one of this struct's valid field bindings.

Parameters

unionIndex -- The index of the union field inside this struct

Returns

The UnionBinding Object that contains information about what field selects the valid field of this union and what values make which union field valid.

size_t Size() const

Obtain struct size, in bytes.

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

Returns

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