Package ghidra.program.model.data

# Interface Structure

All Superinterfaces:
  `Composite`, `DataType`

All Known Subinterfaces:
  `StructureInternal`

All Known Implementing Classes:
  `StructureDataType`

public interface Structure extends Composite
The structure interface.

NOTE: A zero-length Structure will report a length of 1 which will result in improper code unit sizing since we are unable to support a defined data of length 0.

NOTE: The use of zero-length bitfields within non-packed structures is discouraged since they have no real affect and are easily misplaced. Their use should be reserved for packed structures.

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Interface
  Description
  `static class`
  `Structure.BitOffsetComparator`
  `BitOffsetComparator` provides ability to compare an normalized bit offset (see `Structure.BitOffsetComparator.getNormalizedBitfieldOffset(int, int, int, int, boolean)`) with a `DataTypeComponent` object.

- ## Field Summary

  ### Fields inherited from interface ghidra.program.model.data.DataType

  `CONFLICT_SUFFIX, DEFAULT, NO_LAST_CHANGE_TIME, NO_SOURCE_SYNC_TIME, TYPEDEF_ATTRIBUTE_PREFIX, TYPEDEF_ATTRIBUTE_SUFFIX, VOID`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `clearAtOffset(int offset)`
  Clears all defined components containing the specified offset in this structure.
  `void`
  `clearComponent(int ordinal)`
  Clears the defined component at the specified component ordinal.
  `Structure`
  `clone(DataTypeManager dtm)`
  Returns an instance of this DataType using the specified `DataTypeManager` to allow its use of the corresponding `DataOrganization` while retaining its unique identity (see `DataType.getUniversalID()` and archive association (see `DataType.getSourceArchive()`) if applicable.
  `void`
  `deleteAll()`
  Remove all components from this structure, effectively setting the length to zero.
  `void`
  `deleteAtOffset(int offset)`
  Deletes all defined components containing the specified offset in this structure.
  `DataTypeComponent`
  `getComponent(int ordinal)`
  Returns the component of this structure with the indicated ordinal.
  `default DataTypeComponent`
  `getComponentAt(int offset)`
  Gets the first non-zero-length component that starts at the specified offset.
  `DataTypeComponent`
  `getComponentContaining(int offset)`
  Gets the first non-zero-length component that contains the byte at the specified offset.
  `List<DataTypeComponent>`
  `getComponentsContaining(int offset)`
  Get an ordered list of components that contain the byte at the specified offset.
  `DataTypeComponent`
  `getDataTypeAt(int offset)`
  Returns the lowest-level component that contains the specified offset.
  `DataTypeComponent`
  `getDefinedComponentAtOrAfterOffset(int offset)`
  Gets the first defined component located at or after the specified offset.
  `void`
  `growStructure(int amount)`
  Increases the size of the structure by the specified amount by adding undefined filler at the end of the structure.
  `DataTypeComponent`
  `insertAtOffset(int offset, DataType dataType, int length)`
  Inserts a new datatype at the specified offset into this structure.
  `DataTypeComponent`
  `insertAtOffset(int offset, DataType dataType, int length, String name, String comment)`
  Inserts a new datatype at the specified offset into this structure.
  `DataTypeComponent`
  `insertBitField(int ordinal, int byteWidth, int bitOffset, DataType baseDataType, int bitSize, String componentName, String comment)`
  Inserts a new bitfield at the specified ordinal position in this structure.
  `DataTypeComponent`
  `insertBitFieldAt(int byteOffset, int byteWidth, int bitOffset, DataType baseDataType, int bitSize, String componentName, String comment)`
  Inserts a new bitfield at the specified location in this composite.
  `DataTypeComponent`
  `replace(int ordinal, DataType dataType, int length)`
  Replaces the component at the specified ordinal with a new component using the specified datatype, length, name and comment.
  `DataTypeComponent`
  `replace(int ordinal, DataType dataType, int length, String name, String comment)`
  Replaces the component at the specified ordinal with a new component using the specified datatype, length, name and comment.
  `DataTypeComponent`
  `replaceAtOffset(int offset, DataType dataType, int length, String name, String comment)`
  Replaces all components containing the specified byte offset with a new component using the specified datatype, length, name and comment.

  ### Methods inherited from interface ghidra.program.model.data.Composite

  `add, add, add, add, addBitField, align, dataTypeAlignmentChanged, delete, delete, getAlignment, getAlignmentType, getComponents, getDefinedComponents, getExplicitMinimumAlignment, getExplicitPackingValue, getNumComponents, getNumDefinedComponents, getPackingType, hasDefaultPacking, hasExplicitMinimumAlignment, hasExplicitPackingValue, insert, insert, insert, isDefaultAligned, isMachineAligned, isPackingEnabled, isPartOf, pack, repack, setDescription, setExplicitMinimumAlignment, setExplicitPackingValue, setPackingEnabled, setToDefaultAligned, setToDefaultPacking, setToMachineAligned`

  ### Methods inherited from interface ghidra.program.model.data.DataType

  `addParent, copy, dataTypeDeleted, dataTypeNameChanged, dataTypeReplaced, dataTypeSizeChanged, dependsOn, encodeRepresentation, encodeValue, getAlignedLength, getCategoryPath, getDataOrganization, getDataTypeManager, getDataTypePath, getDefaultAbbreviatedLabelPrefix, getDefaultLabelPrefix, getDefaultLabelPrefix, getDefaultOffcutLabelPrefix, getDefaultSettings, getDescription, getDisplayName, getDocs, getLastChangeTime, getLastChangeTimeInSourceArchive, getLength, getMnemonic, getName, getParents, getPathName, getRepresentation, getSettingsDefinitions, getSourceArchive, getTypeDefSettingsDefinitions, getUniversalID, getValue, getValueClass, hasLanguageDependantLength, isDeleted, isEncodable, isEquivalent, isNotYetDefined, isZeroLength, removeParent, replaceWith, setCategoryPath, setLastChangeTime, setLastChangeTimeInSourceArchive, setName, setNameAndCategory, setSourceArchive`

- ## Method Details

  - ### clone

    Structure clone(DataTypeManager dtm)
    Description copied from interface: `DataType`
    Returns an instance of this DataType using the specified `DataTypeManager` to allow its use of the corresponding `DataOrganization` while retaining its unique identity (see `DataType.getUniversalID()` and archive association (see `DataType.getSourceArchive()`) if applicable.

    This instance will be returned if this datatype's DataTypeManager matches the specified dtm. The recursion depth of a clone will stop on any datatype whose `DataTypeManager` matches the specified dtm and simply use the existing datatype instance.

    NOTE: In general, this method should not be used to obtain an instance to be modified. In most cases changes may be made directly to this instance if supported or to a `DataType.copy(DataTypeManager)` of this type.

    Specified by:
      `clone` in interface `DataType`
    Parameters:
      `dtm` - the data-type manager instance whose data-organization should apply.
    Returns:
      cloned instance which may be the same as this instance

  - ### getComponent

    DataTypeComponent getComponent(int ordinal) throws IndexOutOfBoundsException
    Returns the component of this structure with the indicated ordinal.
    Specified by:
      `getComponent` in interface `Composite`
    Parameters:
      `ordinal` - the ordinal of the component requested.
    Returns:
      the data type component.
    Throws:
      `IndexOutOfBoundsException` - if the ordinal is out of bounds

  - ### getDefinedComponentAtOrAfterOffset

    DataTypeComponent getDefinedComponentAtOrAfterOffset(int offset)
    Gets the first defined component located at or after the specified offset. Note: The returned component may be a zero-length component.
    Parameters:
      `offset` - the byte offset into this structure
    Returns:
      the first defined component located at or after the specified offset or null if not found.

  - ### getComponentContaining

    DataTypeComponent getComponentContaining(int offset)
    Gets the first non-zero-length component that contains the byte at the specified offset. Note that one or more components may share the same offset when a bit-field or zero-length component is present since these may share an offset. A null may be returned under one of the following conditions:
    - offset only corresponds to a zero-length component within a packed structure
    - offset corresponds to a padding byte within a packed structure
    - offset is >= structure length.
    If a bitfield is returned, and the caller supports bitfields, it is recommended that `getComponentsContaining(int)` be invoked to gather all bitfields which contain the specified offset.
    Parameters:
      `offset` - the byte offset into this structure
    Returns:
      the first non-zero-length component that contains the byte at the specified offset or null if not found.

  - ### getComponentAt

    default DataTypeComponent getComponentAt(int offset)
    Gets the first non-zero-length component that starts at the specified offset. Note that one or more components may share the same offset when a bit-field or zero-length component is present since these may share an offset. A null may be returned under one of the following conditions:
    - offset only corresponds to a zero-length component within a packed structure
    - offset corresponds to a padding byte within a packed structure
    - offset is contained within a component but is not the starting offset of that component
    - offset is >= structure length
    If a bitfield is returned, and the caller supports bitfields, it is recommended that `getComponentsContaining(int)` be invoked to gather all bitfields which contain the specified offset.
    Parameters:
      `offset` - the byte offset into this structure
    Returns:
      the first component that starts at specified offset or null if not found.

  - ### getComponentsContaining

    List<DataTypeComponent> getComponentsContaining(int offset)
    Get an ordered list of components that contain the byte at the specified offset. Unlike `getComponentAt(int)` and `getComponentContaining(int)` this method will include zero-length components if they exist at the specified offset. For this reason the specified offset may equal the structure length to obtain and trailing zero-length components. Note that this method will only return more than one component when a bit-fields and/or zero-length components are present since these may share an offset. An empty list may be returned under the following conditions:
    - offset only corresponds to a padding byte within a packed structure
    - offset is equal structure length and no trailing zero-length components exist
    - offset is > structure length
    Parameters:
      `offset` - the byte offset into this structure
    Returns:
      a list of zero or more components containing the specified offset

  - ### getDataTypeAt

    DataTypeComponent getDataTypeAt(int offset)
    Returns the lowest-level component that contains the specified offset. This is useful for structures that have sub-structures. This method is best used when working with known structures which do not contain bitfields or zero-length components since in those situations multiple components may correspond to the specified offset. A similar ambiguous condition occurs if offset corresponds to a union component.
    Parameters:
      `offset` - the byte offset into this data type.
    Returns:
      a primitive component data type which contains the specified offset.

  - ### insertBitField

    DataTypeComponent insertBitField(int ordinal, int byteWidth, int bitOffset, DataType baseDataType, int bitSize, String componentName, String comment) throws InvalidDataTypeException, IndexOutOfBoundsException
    Inserts a new bitfield at the specified ordinal position in this structure. Within packed structures the specified byteWidth and bitOffset will be ignored since packing will occur at the specified ordinal position. The resulting component length and bitfield details will reflect the use of minimal storage sizing.

    For structures with packing disabled, a component shift will only occur if the bitfield placement conflicts with another component. If no conflict occurs, the bitfield will be placed at the specified location consuming any DEFAULT components as needed. When a conflict does occur a shift will be performed at the ordinal position based upon the specified byteWidth. When located onto existing bitfields they will be packed together provided they do not conflict, otherwise the conflict rule above applies.

    Supported packing starts with bit-0 (lsb) of the first byte for little-endian, and with bit-7 (msb) of the first byte for big-endian. This is the default behavior for most compilers. Insertion behavior may not work as expected if packing rules differ from this.

    Parameters:
      `ordinal` - the ordinal of the component to be inserted.
      `byteWidth` - the storage allocation unit width which contains the bitfield. Must be large enough to contain the "effective bit size" and corresponding bitOffset. The actual component size used will be recomputed during insertion.
      `bitOffset` - corresponds to the bitfield left-shift amount with the storage unit when viewed as big-endian. The final offset may be reduced based upon the minimal storage size determined during insertion.
      `baseDataType` - the bitfield base datatype (certain restrictions apply).
      `bitSize` - the declared bitfield size in bits. The effective bit size may be adjusted based upon the specified baseDataType.
      `componentName` - the field name to associate with this component.
      `comment` - the comment to associate with this component.
    Returns:
      the bitfield component created whose associated data type will be BitFieldDataType.
    Throws:
      `InvalidDataTypeException` - if the specified baseDataType is not a valid base type for bitfields.
      `IndexOutOfBoundsException` - if ordinal is less than 0 or greater than the current number of components.

  - ### insertBitFieldAt

    DataTypeComponent insertBitFieldAt(int byteOffset, int byteWidth, int bitOffset, DataType baseDataType, int bitSize, String componentName, String comment) throws InvalidDataTypeException
    Inserts a new bitfield at the specified location in this composite. This method is intended to be used with structures with packing disabled where the bitfield will be precisely placed. Within an packed structure the specified byteOffset, byteWidth and bitOffset will be used to identify the appropriate ordinal but may not be preserved. The component length will be computed based upon the specified parameters and will be reduced from byteWidth to its minimal size for the new component.

    When packing disabled, a component shift will only occur if the bitfield placement conflicts with another component. If no conflict occurs, the bitfield will be placed at the specified location consuming any DEFAULT components as needed. When a conflict does occur a shift will be performed at the point of conflict based upon the specified byteWidth. When located onto existing bitfields they will be packed together provided they do not conflict, otherwise the conflict rule above applies.

    Supported packing for little-endian fills lsb first, whereas big-endian fills msb first. Insertion behavior may not work as expected if packing rules differ from this.

    Zero length bitfields may be inserted although they have no real affect when packing disabled. Only the resulting byte offset within the structure is of significance in determining its ordinal placement.

    Parameters:
      `byteOffset` - the first byte offset within this structure which corresponds to the first byte of the specified storage unit identified by its byteWidth.
      `byteWidth` - the storage unit width which contains the bitfield. Must be large enough to contain the specified bitSize and corresponding bitOffset. The actual component size used will be recomputed during insertion.
      `bitOffset` - corresponds to the bitfield left-shift amount with the storage unit when viewed as big-endian. The final offset may be reduced based upon the minimal storage size determined during insertion.
      `baseDataType` - the bitfield base datatype (certain restrictions apply).
      `componentName` - the field name to associate with this component.
      `bitSize` - the bitfield size in bits. A bitSize of 0 may be specified although its name will be ignored.
      `comment` - the comment to associate with this component.
    Returns:
      the componentDataType created whose associated data type will be BitFieldDataType.
    Throws:
      `InvalidDataTypeException` - if the specified data type is not a valid base type for bitfields.

  - ### insertAtOffset

    DataTypeComponent insertAtOffset(int offset, DataType dataType, int length) throws IllegalArgumentException
    Inserts a new datatype at the specified offset into this structure. Inserting a component will cause any conflicting components to shift down to the extent necessary to avoid a conflict.
    Parameters:
      `offset` - the byte offset into the structure where the new datatype is to be inserted.
      `dataType` - the datatype to insert. If `DataType.DEFAULT` is specified for a packed structure an `Undefined1DataType` will be used in its place.
      `length` - the length to associate with the dataType. For fixed length types a length <= 0 will use the length of the resolved dataType.
    Returns:
      the componentDataType created.
    Throws:
      `IllegalArgumentException` - if the specified data type is not allowed to be inserted into this composite data type or an invalid length is specified. For example, suppose dt1 contains dt2. Therefore it is not valid to insert dt1 to dt2 since this would cause a cyclic dependency.

  - ### insertAtOffset

    DataTypeComponent insertAtOffset(int offset, DataType dataType, int length, String name, String comment) throws IllegalArgumentException
    Inserts a new datatype at the specified offset into this structure. Inserting a component will cause any conflicting components to shift down to the extent necessary to avoid a conflict.

    This method does not support bit-field insertions which must use the method `insertBitFieldAt(int, int, int, DataType, int, String, String)`.

    Parameters:
      `offset` - the byte offset into the structure where the new datatype is to be inserted.
      `dataType` - the datatype to insert. If `DataType.DEFAULT` is specified for a packed structure an `Undefined1DataType` will be used in its place.
      `length` - the length to associate with the dataType. For fixed length types a length <= 0 will use the length of the resolved dataType.
      `name` - the field name to associate with this component.
      `comment` - the comment to associate with this component.
    Returns:
      the componentDataType created.
    Throws:
      `IllegalArgumentException` - if the specified data type is not allowed to be inserted into this composite data type or an invalid length is specified. For example, suppose dt1 contains dt2. Therefore it is not valid to insert dt1 to dt2 since this would cause a cyclic dependency.

  - ### deleteAtOffset

    void deleteAtOffset(int offset) throws IllegalArgumentException
    Deletes all defined components containing the specified offset in this structure. If the offset corresponds to a bit-field or zero-length component (e.g., 0-element array) multiple components may be deleted. Bit-fields are only cleared and may leave residual undefined components in their place. This method will generally reduce the length of the structure. The `clearAtOffset(int)` method should be used for non-packed structures to preserve the structure length and placement of other components.
    Parameters:
      `offset` - the byte offset into the structure where the component(s) are to be deleted. An offset equal to the structure length may be specified to delete any trailing zero-length components.
    Throws:
      `IllegalArgumentException` - if a negative offset is specified

  - ### deleteAll

    void deleteAll()
    Remove all components from this structure, effectively setting the length to zero. Packing and minimum alignment settings are unaffected.

  - ### clearAtOffset

    void clearAtOffset(int offset)
    Clears all defined components containing the specified offset in this structure. If the offset corresponds to a bit-field or zero-length component (e.g., 0-element array) multiple components may be cleared. This method will preserve the structure length and placement of other components since freed space will appear as undefined components.

    To avoid clearing zero-length components at a specified offset within a non-packed structure, the `replaceAtOffset(int, DataType, int, String, String)` may be used with to clear only the sized component at the offset by specified `DataType.DEFAULT` as the replacement datatype.

    Parameters:
      `offset` - the byte offset into the structure where the component(s) are to be deleted.

  - ### clearComponent

    void clearComponent(int ordinal) throws IndexOutOfBoundsException
    Clears the defined component at the specified component ordinal. Clearing a component within a non-packed structure causes a defined component to be replaced with a number of undefined components. This may not the case when clearing a zero-length component or bit-field which may not result in such undefined components. In the case of a packed structure clearing is always completed without backfill.
    Parameters:
      `ordinal` - the ordinal of the component to clear.
    Throws:
      `IndexOutOfBoundsException` - if component ordinal is out of bounds

  - ### replace

    DataTypeComponent replace(int ordinal, DataType dataType, int length) throws IndexOutOfBoundsException, IllegalArgumentException
    Replaces the component at the specified ordinal with a new component using the specified datatype, length, name and comment. In the case of a packed structure a 1-for-1 replacement will occur. In the case of a non-packed structure certain restrictions apply:
    - A zero-length component may only be replaced with another zero-length component.
    - If ordinal corresponds to a bit-field, all bit-fields which overlap the specified bit-field will be replaced.
    There must be sufficient space to complete the replacement factoring in the space freed by the consumed component(s). If there are no remaining defined components beyond the consumed components the structure will expand its length as needed. For a packed structure, this method behaves the same as a ordinal-based delete followed by an insert.

    Datatypes not permitted include `FactoryDataType` types, non-sizable `Dynamic` types, and those which result in a circular direct dependency.

    NOTE: In general, it is not recommended that this method be used with non-packed structures where the replaced component is a bit-field.

    Parameters:
      `ordinal` - the ordinal of the component to be replaced.
      `dataType` - the datatype to insert. If `DataType.DEFAULT` is specified for a packed structure an `Undefined1DataType` will be used in its place. If `DataType.DEFAULT` is specified for a non-packed structure this is equivelant to `clearComponent(int)`, ignoring the length, name and comment arguments.
      `length` - component length for containing the specified dataType. A positive length is required for sizable `Dynamic` datatypes and should be specified as -1 for fixed-length datatypes to rely on their resolved size.
    Returns:
      the new component.
    Throws:
      `IllegalArgumentException` - may be caused by: 1) invalid offset specified, 2) invalid datatype or associated length specified, or 3) insufficient space for replacement.
      `IndexOutOfBoundsException` - if component ordinal is out of bounds

  - ### replace

    DataTypeComponent replace(int ordinal, DataType dataType, int length, String name, String comment) throws IndexOutOfBoundsException, IllegalArgumentException
    Replaces the component at the specified ordinal with a new component using the specified datatype, length, name and comment. In the case of a packed structure a 1-for-1 replacement will occur. In the case of a non-packed structure certain restrictions apply:
    - A zero-length component may only be replaced with another zero-length component.
    - If ordinal corresponds to a bit-field, all bit-fields which overlap the specified bit-field will be replaced.
    There must be sufficient space to complete the replacement factoring in the space freed by the consumed component(s). If there are no remaining defined components beyond the consumed components the structure will expand its length as needed. For a packed structure, this method behaves the same as a ordinal-based delete followed by an insert.

    Datatypes not permitted include `FactoryDataType` types, non-sizable `Dynamic` types, and those which result in a circular direct dependency.

    NOTE: In general, it is not recommended that this method be used with non-packed structures where the replaced component is a bit-field.

    Parameters:
      `ordinal` - the ordinal of the component to be replaced.
      `dataType` - the datatype to insert. If `DataType.DEFAULT` is specified for a packed structure an `Undefined1DataType` will be used in its place. If `DataType.DEFAULT` is specified for a non-packed structure this is equivelant to `clearComponent(int)`, ignoring the length, name and comment arguments.
      `length` - component length for containing the specified dataType. A positive length is required for sizable `Dynamic` datatypes and should be specified as -1 for fixed-length datatypes to rely on their resolved size.
      `name` - the field name to associate with this component or null.
      `comment` - the comment to associate with this component or null.
    Returns:
      the new component.
    Throws:
      `IllegalArgumentException` - may be caused by: 1) invalid offset specified, 2) invalid datatype or associated length specified, or 3) insufficient space for replacement.
      `IndexOutOfBoundsException` - if component ordinal is out of bounds

  - ### replaceAtOffset

    DataTypeComponent replaceAtOffset(int offset, DataType dataType, int length, String name, String comment) throws IllegalArgumentException
    Replaces all components containing the specified byte offset with a new component using the specified datatype, length, name and comment. If the offset corresponds to a bit-field more than one component may be consumed by this replacement.

    This method may not be used to replace a zero-length component since there may be any number of zero-length components at the same offset. If the only defined component(s) at the specified offset are zero-length the subsequent undefined will be replaced in the case of a non-packed structure. For a packed structure such a case would be treated as an insert as would an offset which is not contained within a component.

    For a non-packed structure a replacement will attempt to consume sufficient space within moving other defined components. There must be sufficient space to complete the replacement factoring in the space freed by the consumed component(s). When replacing the last defined component the structure size will be expanded as needed to fit the new component. For a packed If there are no remaining defined components beyond the consumed components, or an offset equals to the structure length is specified, the structure will expand its length as needed.

    For a non-packed structure the new component will use the specified offset. In the case of packed structure, the actual offset will be determined during a repack.

    Datatypes not permitted include `FactoryDataType` types, non-sizable `Dynamic` types, and those which result in a circular direct dependency.

    Parameters:
      `offset` - the byte offset into the structure where the datatype is to be placed. The specified offset must be less than the length of the structure.
      `dataType` - the datatype to insert. If `DataType.DEFAULT` is specified for a packed structure an `Undefined1DataType` will be used in its place. If `DataType.DEFAULT` is specified for a non-packed structure this is equivelant to clearing all components, which contain the specified offset, ignoring the length, name and comment arguments.
      `length` - component length for containing the specified dataType. A positive length is required for sizable `Dynamic` datatypes and should be specified as -1 for fixed-length datatypes to rely on their resolved size.
      `name` - the field name to associate with this component or null.
      `comment` - the comment to associate with this component or null.
    Returns:
      the new component.
    Throws:
      `IllegalArgumentException` - may be caused by: 1) invalid offset specified, 2) invalid datatype or associated length specified, or 3) insufficient space for replacement.

  - ### growStructure

    void growStructure(int amount)
    Increases the size of the structure by the specified amount by adding undefined filler at the end of the structure. NOTE: This method only has an affect on non-packed structures.
    Parameters:
      `amount` - the amount by which to grow the structure.
    Throws:
      `IllegalArgumentException` - if amount < 1