This document lays out the required (and optional) functions of the code generated by codegen.py, and their signatures. The code is generated based on the format described on the nif.xml wiki, with some additional flexibility for the names of tags and attributes. The generated classes fall into one of 4 cases:
- Basic. This corresponds to the
basic
tag in the xml. These classes are not generated, merely copied from the source for that format. They do not have a shared class unless they had one in the source. - Enum. This corresponds to the
enum
tag in the xml. These classes all inherit from theBaseEnum
class defined inbase_enum.py
. - Bitfield. This corresponds to the
bitfield
,bitflags
andbitstruct
tags in the xml. These classes all inherit from theBasicBitfield
class defined inbitfield.py
. - Struct. This corresponds to the
struct
,compound
andniobject
tags in the xml. These classes all inherit from theBaseStruct
class defined inbase_struct.py
.
This also means that, in the generated python objects, every field in a struct falls into one of those four categories (the associated type, not necessarily the value). There is one exception:
- Array. Any field which has the
arr1
(orlength
) field specified will have theArray
class , defined inarray.py
, as its type. The actual type of the field is passed via an extra argument.- There is also the
RaggedArray
class. This class is used for arrays where shape[1] is not an integer, but instead an iterable of integers. However, this is an implementation detail, as access to theRaggedArray
class can be handled solely through the Array class, which will defer functions to theRaggedArray
class if necessary.
- There is also the
There are a number of shared functions across every class. Strict adherence to this is necessary/desirable for the following reasons:
- Implementation of
type="#T#"
. Standardized functions means that functions can be called onself.template
without knowing beforehand what class it is. - Code simplification. By standardizing the functions and introducing iteration over the fields, the generated code for structs is much less, and Array code is simplified.
It should be noted that most shared functions are class or static methods instead of instance methods. This is because any class is not guaranteed to return an instance of itself when reading or instancing. A typical example of this would be basic classes which are ints or floats, or SizedString, which in an xml may be described as a struct with an integer for the length and an array of characters, but may return a python str
.
Every class must have three basic functions. These functions are necessary for reading and writing files for the generated format, as well as instantiation of the defined objects without a file to read from:
- Instantiation of the class object (either through
__new__
or__init__
function). This does not necessarily have to return an actual instance of the class.- Function signature:
class(context, arg, template)
- context: object which stores file-specific variables.
- arg: corresponds to the
arg
attribute specified in a field. - template: corresponds to the
template
attribute specified in a field.
- Function signature:
- Class- or static method
from_stream
which reads from the stream and returns an instance of the same type as instantiation does.- Function signature:
class.from_stream(stream, context, arg, template)
- stream: binary stream from which to read the object.
- context: object which stores file-specific variables.
- arg: corresponds to the
arg
attribute specified in a field. - template: corresponds to the
template
attribute specified in a field.
- Function signature:
- Class- or static method
to_stream
which writes an instance to the stream.- Function signature:
class.to_stream(instance, stream, context, arg, template)
- instance: object that quacks like the object returned by instantiation/reading of this class.
- stream: binary stream to which to write the object.
- context: object which stores file-specific variables.
- arg: corresponds to the
arg
attribute specified in a field. - template: corresponds to the
template
attribute specified in a field.
- Function signature:
The following functions are implemented on the 4 classes included by default in source (BaseEnum
, BasicBitfield
, BaseStruct
and Array
). They are not integral to essential functionality (reading, writing and instantation) but may prove useful in various cases. If you make use of these, they must be implemented on all basics.
- Class- or static method
format_indented
, which takes in an object and returns a string. Useful for printing.- Function signature:
class.format_indented(member, indent)
- member: object that quacks like the object returned by instantiation/reading of this class.
- indent: used for pretty-printing, mostly to allow for a tree-like representation of structs within structs.
- Function signature:
- Class- or static method
get_size
, used for getting the size (in bytes) of the associated instance.- Function signature:
class.get_size(instance, context, arg, template)
- context: object which stores file-specific variables.
- instance: object that quacks like the object returned by instantiation/reading of this class.
- arg: corresponds to the
arg
attribute specified in a field. - template: corresponds to the
template
attribute specified in a field.
- Function signature:
- Class- or static method
from_xml
, used for conversion from xml file to python objects in much the same way asfrom_stream
does from binary.- Function signature:
class.from_xml(target, elem, prop, arg, template)
- target: parent object.
- elem: xml element associated with the parent object.
- prop: name of the field of the parent where the instance should be.
- arg: corresponds to the
arg
attribute specified in a field. - template: corresponds to the
template
attribute specified in a field.
- Function signature:
- Class- or static method
to_xml
, used for conversion from python objects to xml file in much the same way asto_stream
does to binary.- Function signature:
class.to_xml(elem, prop, instance, arg, template, debug)
- elem: xml element associated with the parent object.
- prop: name of the field of the parent where the instance should be.
- instance: object that quacks like the object returned by instantiation/reading of this class.
- arg: corresponds to the
arg
attribute specified in a field. - template: corresponds to the
template
attribute specified in a field. - debug: whether to write in debugging mode.
- Function signature:
- Class- or static method
validate_instance
, used to check whether the instance matches the given arguments. Can be used before file writing to find incorrect fields.- Function signature:
class.validate_instance(instance, context, arg, template)
- instance: object that quacks like the object returned by instantiation/reading of this class.
- context: object which stores file-specific variables.
- arg: corresponds to the
arg
attribute specified in a field. - template: corresponds to the
template
attribute specified in a field.
- Function signature:
The following functions don't have to be implemented on any classes, but may be implemented on some.
- Class- or static method
from_value
. Used to convert a value (typically an int, float or tuple, but isn't limited to that) to an instance of the same type as returned by instantiation/reading of this class. Bitfields and enums already have this implemented, any other classes will need to have it manually defined in source.- Function signature:
class.from_value(value)
- value: any object which the class can use to instance itself.
- Function signature:
- Class- or static method
create_array
. If present, is used instead to instantiate arrays for this class, instead of an Array with this class as its dtype.- Function signature:
class.create_array(shape, default, context, arg, template)
- shape: shape of the array.
- default: the value with which to fill every point of the array (as if filling the array with
from_value(default)
. - context: object which stores file-specific variables.
- arg: corresponds to the
arg
attribute specified in a field. - template: corresponds to the
template
attribute specified in a field.
- Function signature:
- Class- or static method
read_array
. If present, is used to read arrays from the stream instead of the Array class.- Function signature:
class.read_array(stream, shape, context, arg, template)
- stream: binary stream from which to read the array.
- shape: shape of the array.
- context: object which stores file-specific variables.
- Function signature:
- Class- or static method
write_array
. If present, is used to write arrays to the stream instead of the Array class.- Function signature:
class.write_array(stream, instance)
- stream: binary stream to which to write the array.
- instance: array that quacks like the array returned by instantiation/reading of this dtype's array.
- Function signature:
- Class- or static method
validate_array
. If present, is used to validate arrays instead of the Array class.- Function signature:
class.validate_array(instance, context, arg, template, shape)
- instance: array
- context: array that quacks like the array returned by instantiation/reading of this dtype's array.
- arg: corresponds to the
arg
attribute specified in a field. - template: corresponds to the
template
attribute specified in a field. - shape: corresponds to the arr1/length and arr2/width attribute specified in a field.
- Function signature:
Structs and Arrays share some similarity because they both can contain the other classes and themselves. To iterate over these fields and access them, the following functions are used. Note that these functions do not have to exist on, for example, a struct class, it merely indicates that the fields do not exist or are not accessible on the object resulting from instantiation/reading.
- Class- or static method
_get_filtered_attribute_list
, which returns an iterator over the fields whose conditions currently evaluate to false. These field definitions do not return the fields value.- Function signature:
_get_filtered_attribute_list(instance, include_abstract)
.- instance: object that quacks like the object returned by instantiation/reading of this class.
- include_abstract: whether to include fields with the
abstract="true"
attribute. These fields are not found in the file, but are found on the resulting objects.
- Returns: for every field,
field_name, field_type, arguments, (optional, default)
. If the field has noarr1
orlength
attribute defined in the xml,field_type
corresponds to thetype
attribute andarguments
is (arg
,template
) corresponding to the attributes. If the field does havearr1
orlength
attribute defined in the xml, thenfield_type
is Array, andarguments
is (arg
,template
,shape
,dtype
), with shape being the shape tuple of the array anddtype
corresponding to thetype
attribute of the field.
- Function signature:
- Class- or static method
get_field
, which is used to access the fields returned by_get_filtered_attribute_list
through their name.