Parser Infrastructure

StructureRegistry

class aws.osml.io.StructureRegistry

Bases: object

Manages loading, caching, and lookup of structure definitions.

The registry discovers .ksy structure definition files from one or more search paths and makes them available by name. Built-in definitions for NITF headers, image subheaders, and common TREs are loaded automatically. You can extend the registry by adding custom search paths or registering definitions at runtime. Use get() to obtain a StructureDefinition for use with StructureAccessor or StructureWriter.

Example:

```python from aws.osml.io import StructureRegistry

registry = StructureRegistry() registry.add_search_path(“/path/to/my/structures”) definition = registry.get(“TRE_GEOLOB”) for name in registry.list():

print(name)

```

add_search_path(path)

Add a search path with higher priority than existing paths.

Parameters:

path (str) – Directory path to add to the search paths.

get(name)

Retrieve a structure definition by name.

Parameters:

name (str) – The structure name (e.g., "NITF_02.10_FileHeader", "TRE_GEOLOB").

Returns:

The StructureDefinition, or None if not found.

Return type:

StructureDefinition or None

list()

List all available structure definition names.

Returns:

Names that can be passed to get().

Return type:

list[str]

register(name, definition)

Register a definition at runtime with highest priority.

Runtime-registered definitions take priority over file-based definitions with the same name.

Parameters:
reload()

Reload all definitions from disk.

Clears the file cache and re-scans search paths. Definitions registered at runtime via register() are preserved.

Raises:

RuntimeError – If a search path cannot be read.

search_paths()

Return the current search paths.

Returns:

Directory paths being searched for .ksy files.

Return type:

list[str]

StructureDefinition

A StructureDefinition is the entire public interface for reading and writing a named binary structure. Its decode method parses raw bytes into a nested dict (lists for repeated fields, dicts for nested types), and its encode method serializes such a dict back to bytes — a symmetric, dict-based round trip.

class aws.osml.io.StructureDefinition

Bases: object

A read-only structure definition parsed from a .ksy file.

Contains field names and layout information used by StructureAccessor and StructureWriter to read and write binary data. Obtain instances from StructureRegistry via StructureRegistry.get().

Example:

`python definition = registry.get("TRE_GEOLOB") print(definition.id, definition.field_names) `

decode(data)

Parse bytes into a nested dict.

Repeated fields are returned as lists and nested types as dicts, using the same recursion as the NITF metadata read path. bytes-typed fields are returned as a lowercase hex string (which encode() accepts back).

Parameters:

data (bytes-like) – The binary data to parse. Accepts bytes, bytearray, memoryview, or any object supporting the buffer protocol.

Returns:

A dict of field names to parsed values.

Return type:

dict

Example:

`python fields = definition.decode(raw) `

describe()

Describe this structure’s fields as the parser actually loaded them.

Returns a dict with two keys:

  • "fields": a list of per-field dicts for the top-level sequence, in definition order.

  • "types": a dict mapping each nested type name to its list of per-field dicts.

Each per-field dict carries the parser’s authoritative classification — not a re-parse of the source YAML — so callers (e.g. the property-test generator) can decide how to treat a field without maintaining their own copy of the type table, which is prone to drifting out of sync with the parser. Keys:

  • "id" (str): field identifier.

  • "kind" (str): one of "string", "bytes", "uint", "sint", "float", "typeref".

  • "width" (int or None): byte width for uint/sint/float.

  • "type_name" (str or None): referenced type name for typeref.

  • "type_resolved" (bool or None): for typeref, whether the name resolves to a definition in this structure’s local types map.

  • "conditional" (bool): whether the field has an if: condition.

  • "repeated" (bool): whether the field repeats.

Returns:

A description of the loaded structure.

Return type:

dict

encode(values, strict=None)

Serialize a nested dict of field values to bytes.

Walks the definition’s fields in order, drawing matching values from values (matched case-insensitively). Scalars become field values, list values become repeated fields, and dict values become single nested (TypeRef) fields. Fields absent from values and not required are skipped; conditional fields are governed by the values present, exactly as in the NITF metadata write path. bytes-typed fields accept a lowercase hex string (the same representation decode() produces).

Parameters:
  • values (Mapping) – Mapping of field name to value (str/int/float/list/dict).

  • strict (bool) – When True, numeric encodings are validated exactly; when False (default), numeric fields are relaxed to BCS-A — matching the metadata write default.

Returns:

The encoded bytes.

Return type:

bytes

Raises:

ValueError – On a missing required field, an over-large value, or an out-of-spec value under strict.

Example:

`python raw = definition.encode({"ARV": "000360000", "BRV": "000360000"}) `

field_names

Ordered list of field names defined in this structure.

id

The unique identifier for this structure (e.g., "TRE_GEOLOB").

title

Human-readable title from the definition, or None if not set.