This site is a static rendering of the Trac instance that was used by R7RS-WG1 for its work on R7RS-small (PDF), which was ratified in 2013. For more information, see Home.

Source for wiki StructuresCowan version 2

author

cowan

comment


    

ipnr

69.195.55.172

name

StructuresCowan

readonly

0

text

Structures are an extension of the representation types of NumericVectorsCowan.  A structure is created by specifying a named sequence of representation types, each with a name and a repetition count, in the manner of a C struct; the repetition count corresponds to the size of an array within the structure.  This representation type can then be mapped onto a bytevector, allowing the bytevector to be manipulated as if it were a Scheme record or a vector of such records.

== Structure descriptors ==

`(make-structure-descriptor `''name fieldspecs''`)`

''Name'' is a symbol used for documentation purposes only.  ''Fieldspecs'' is a vector each of whose elements is a list of three elements, a symbol denoting a name (again, for documentation purposes only), another symbol denoting a representation type and an exact non-negative integer denoting a repetition count.  The valid symbols are: `u8`, `s8`, `u16`, `s16`, `u32`, `s32`, `f32`, `f64`, `c64`, `c128`, which have the same meaning as in NumericVectorsCowan; `char8`, `char16`, `char32`, which are equivalent to `u8`, `u16`, `u32` but are interpreted as characters when converting to and from Scheme; and `bool8`, `bool16`, `bool32`, which are also equivalent to `u8`, `u16`, `u32`, but are interpreted as booleans when converting to and from Scheme.  Implementations may extend this list.

The result is a newly allocated immutable object of a disjoint type from which ''name'' can be retrieved, called a structure descriptor.  It is also possible to retrieve fields, which are objects representing the name, type, repetition count, and the computed byte offset from the beginning of a struct to each field.  Fields may or may not be a disjoint type.  Implementations should pad offsets as necessary in order to achieve the same layout as the dominant C implementation on the same platform.

`(structure-descriptor? `''obj''`)`

Returns `#t` if ''obj'' is a structure descriptor and `#f` otherwise.

`(structure-descriptor-name `''structure-type''`)`

Returns the name of ''structure-type''.

`(structure-descriptor-field `''structure-type obj''`)`

If ''obj'' is an exact integer, returns the ''obj''th field from ''structure-type''.  If ''obj'' is a symbol, returns the field whose name is ''obj''.

`(structure-length `''structure-type''`)`

Returns the length of all the fields in bytes including any intermediate or trailing padding.

== Structure fields ==

`(structure-field-name `''field''`)`

Returns the name associated with ''field''.

`(structure-field-type `''field''`)`

Returns the symbol representing the representation type of ''field''.

`(structure-field-count `''field''`)`

Returns the non-negative exact integer representing the repetition count of ''field''.

`(structure-field-offset `''field''`)`

Returns the non-negative exact integer representing the byte offset of ''field''.

`(structure-field-structure-descriptor `''field''`)`

Returns the structure descriptor to which ''field'' belongs.

== Constructors ==

`(make-structure ` ''structure-descriptor'' [ ''k'' ] `)`

Returns a newly allocated bytevector whose length is equal to the length of ''structure-descriptor'' times ''k'' (default 1).  The initial values of the fields are implementation-dependent.

`(structure ` ''structure-descriptor'' ''value'' ... `)`

Returns a newly allocated bytevector whose length is equal to the length of ''structure-descriptor''.  The bytes are initialized based on converting the values sequentially, based on the representation types in ''structure-descriptor''.  A field with a repetition count other than 1 is initialized from a vector of numbers, a string, or a vector of booleans of appropriate length depending on the field's representation type.  If the fields have been exhausted and more values are available, the fields begin again, thus making it possible to return a vector of structures.

== Accessors ==

`(structure-ref `''bytevector field'' [ ''index'' ] `)`

Fetches the ''index''th repetition (0 by default) of ''field'' found by mapping the structure descriptor of ''field'' onto the bytes of ''bytevector''.  The result is a Scheme number, character, or boolean.

`(bytevector-structure-ref `''bytevector k field'' [ ''index'' ] `)`

The same as `structure-ref`, but rather than mapping the structure to the beginning of ''bytevector'', it is mapped starting at the ''k''th byte of ''bytevector''.  This is appropriate when the structure is embedded at an arbitrary point in the bytevector.

`(structure-vector-ref `''bytevector k field'' [ ''index'' ] `)`

The same as `bytevector-structure-ref`, except that ''k'' is multiplied by the length of the structure definition to which ''field'' belongs.  This is appropriate when the bytevector is being viewed as a homogeneous array of structures.

== Mutators ==

`(structure-set! `''bytevector field'' [ ''index'' ] ''obj'' `)`

Sets the ''index''th repetition (0 by default) of ''field'' found by mapping the structure descriptor of ''field'' onto the bytes of ''bytevector'' to the Scheme number, character, or boolean ''obj''.  In the case of a boolean field, any object other than `#f` is treated as `#t`.

`(bytevector-structure-set! `''bytevector k field'' [ ''index'' ] ''obj'' `)`

The same as `structure-set!`, but rather than mapping the structure to the beginning of ''bytevector'', it is mapped starting at the ''k''th byte of ''bytevector''.  This is appropriate when the structure is embedded at an arbitrary point in the bytevector.

`(structure-vector-set! `''bytevector k field'' [ ''index'' ] ''obj'' `)`

The same as `bytevector-structure-set!`, except that ''k'' is multiplied by the length of the structure definition to which ''field'' belongs.  This is appropriate when the bytevector is being viewed as a homogeneous array of structures.

== Conversion ==

`(vector->structure `''structure-descriptor bytevector''`)`

`(list->structure `''structure-descriptor bytevector''`)`

Returns a newly allocated bytevector which, when viewed as one or more structures specified by ''structure-descriptor'', has the same elements as ''vector'' or ''list''.  The conversion is done as specified in the description of the `structure` procedure.  An error is signaled if an element of ''vector'' or ''list'' cannot be accurately converted to the appropriate type.

`(structure->vector `''structure-descriptor bytevector''`)`

`(structure->list `''structure-descriptor bytevector''`)`

Returns a vector or list with the same elements as ''bytevector'' viewed as one or more structures as specified by ''structure-descriptor''.

== Structure definition macro ==

`(define-structure `''name'' `(`''fieldname type'' [ ''count'' ] [ ''accessor'' [ ''mutator'' ] ] `)` ... `)`

Invokes `make-structure` on ''name'' and a vector of fieldspecs constructed from the quoted name, representation type and repetition count specifiers.  The default repetition count is 1.  The variable ''name'' is then bound to the resulting structure type and the ''fieldname'' variables to the fields as if by `define`.  Any ''accessor'' variables present are bound to procedures which accept a bytevector and an optional index, and behave like `structure-ref`.  Any ''mutator'' variables present are bound to procedures which accept a bytevector, an optional index, and a value, and behave like `structure-set!`.

== Issues ==

The ''fieldspecs'' argument of `make-structure-descriptor` is a vector for the sake of compatibility with SRFI 99.  If we decide to change that, we ought to change this too.

time

2012-11-24 04:18:43

version

2