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 BytevectorsCowan version 4

author

cowan

comment


    

ipnr

127.11.51.1

name

BytevectorsCowan

readonly

0

text

This is a proposal for a bytevector API whose procedures allow a bytevector to be viewed as one of several kinds of numeric vectors.  It differs from related designs such as [http://srfi.schemers.org/srfi-63/srfi-63.html SRFI 63], [http://srfi.schemers.org/srfi-66/srfi-66.html SRFI 66], and [http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-3.html R6RS] in that each procedure listed below actually represents many procedures, one for each defined representation type.  This makes for a ''lot'' of procedures, but many of them can be easily inlined by even a very dumb compiler, providing high efficiency.   The procedures provided in the present proposal are the analogues of the R7RS-small vector API with a few additions.

== Representation types ==

A [type] consists of a [principal type] followed by an [endianism].

The [principal type] values are:

 `u8`::
  unsigned 8-bit integer
 `s8`::
  signed 8-bit integer
 `u16`::
  unsigned 16-bit integer
 `s16`::
  signed 16-bit integer
 `u32`::
  unsigned 32-bit integer
 `s32`::
  signed 32-bit integer
 `u64`::
  unsigned 64-bit integer
 `s64`::
  signed 64-bit integer
 `f32`::
  32-bit float
 `f64`::
  64-bit float
 `c64`::
  64-bit complex number (two 32-bit floats, real followed by imaginary)
 `c128`::
  128-bit complex number (two 64-bit floats, real followed by imaginary)

The [endianism] values are:

 (empty)::
  Native representations (system-dependent)
 `le`::
  Little-endian (for float and complex, IEEE format)
 `be`::
  Big-endian (for float and complex, IEEE format)

Endianism is not applicable to the `u8` and `s8` types.  Thus there are 3 * 12 - 4, or 32, representation types altogether.

The `s` and `u` types correspond to limited ranges of exact integers, the `f` types to limited ranges of inexact real numbers, and the `c` types to limited ranges of inexact complex numbers.

The number of bytes occupied by a representation type is the number of bits expressed in its name divided by 8.  This value is designated by ''b'' in the descriptions of procedures.

== Constructors ==

`(make-[type]-bytevector `''k'' [ ''fill'' ]`)`

Returns a newly allocated bytevector of length ''k * b''.''Fill'' is converted to a binary value according to `[type] and used to fill the bytevector; if ''fill'' is not specified, the values of the elements are unspecified.  It is an error if ''fill'' cannot be converted to [type].

`([type]-bytevector ` ''v'' ... `)`

Returns a newly allocated bytevector of length ''k * b'', where ''k'' is the number of arguments to the procedure.  It is filled with the binary values resulting from encoding the ''v'' arguments according to [type].  It is an error if an argument cannot be converted to [type].

== Selectors ==

`([type]-bytevector-ref` ''bytevector k''`)`

Returns a Scheme number corresponding to the binary value encoded according to [type] beginning at offset ''k * b'' in ''bytevector''.  This procedure treats ''bytevector'' as a uniformly typed vector.

`(bytevector-[type]-ref` ''bytevector k''`)`

Returns a Scheme number corresponding to the binary value encoded according to [type] beginning at offset ''k'' in ''bytevector''.  This procedure treats ''bytevector'' as potentially containing more than one type.

Note that `bytevector-u8-ref` is defined in the small language.

== Mutators ==

`([type]-bytevector-set!` ''bytevector k v''`)`

Converts ''v'' to a binary value encoded according to [type] and places it into ''bytevector'' beginning at offset ''k * b''.  This procedure treats ''bytevector'' as a uniformly typed vector.  It is an error if ''v'' cannot be converted to [type].

`(bytevector-[type]-set!` ''bytevector k v''`)`

Converts ''v'' to a binary value encoded according to [type] and places it into ''bytevector'' beginning at offset ''k''.  This procedure treats ''bytevector'' as potentially containing more than one type.  It is an error if ''v'' cannot be converted to [type].

Note that `bytevector-u8-set!` is defined in the small language.

== Conversions to bytevectors ==

It is an error if a value being used to fill an element of a [type]vector cannot be converted to [type], or if ''start'' (inclusive), ''end'' (inclusive), or ''at'' are out of range, or if an existing bytevector is being overflowed.

`(vector->[type]-bytevector `''vector'' [''start'' [ ''end'' ] ]`)`

Returns a newly allocated bytevector of length ''end * b - start * b'', filled with the corresponding elements of ''vector''.

`(list->[type]-bytevector `''list''`)`

Returns a newly allocated bytevector whose length is the length of ''list'' times ''b'', filled with the elements of ''list''.

`(vector->[type]-bytevector! `''bytevector at vector'' [''start'' [ ''end'' ] ]`)`

Writes the elements of ''vector'' from ''start'' to ''end'' into ''bytevector'' starting at ''at''.

`(list->[type]-bytevector! `''list bytevector at''`)`

Writes the elements of ''list'' into ''bytevector'' starting at ''at''.

== Conversions from bytevectors ==

It is an error if ''start'' (inclusive), ''end'' (inclusive), or ''at'' are out of range, or if an existing vector is being overflowed.

`([type]-bytevector->vector `''bytevector'' [ ''start'' [ ''end'' ] ]`)`

`([type]-bytevector->list `''bytevector'' [ ''start'' [ ''end'' ] ]`)`

Returns a newly allocated vector or list of length ''end - start'' with the elements of ''bytevector'' from ''start * b'' to ''end * b''.

`([type]-bytevector->vector! `''vector at bytevector'' [''start'' [ ''end'' ] ]`)`

Writes the elements of ''bytevector'' from ''start * b'' to ''end * b'' into ''vector'' starting at ''at''.

== The whole bytevector ==

`([type]-bytevector-length ` ''bytevector''`)`

Returns the length of ''bytevector / b'', rounded toward zero.

`([type]-bytevector-fill! `''bytevector fill'' [ [ ''start'' ] ''end'' ] `)`

Stores ''fill'' in the elements of ''bytevector'' viewed as a [type]vector from ''start * b'' to ''end * b''. An error is signaled if ''fill'' cannot be converted to [type].

== Mapping ==

`([type]-bytevector-map `''proc bytevector'' ...`)`

Returns a newly allocated bytevector which contains the results of applying ''proc'' to the elements of the ''bytevectors'', considered as typed vectors, in an unspecified order.

`([type]-bytevector-map! `''proc output-bytevector bytevector'' ...`)`

Writes the results of applying ''proc'' to the elements of the ''bytevectors'', considered as typed vectors, into the corresponding elements of ''output-bytevector'' in an unspecified order.  It is not an error for ''output-bytevector'' to be the same as one of the ''bytevectors''.  Returns an unspecified value.

`([type]-bytevector-for-each `''proc bytevector'' ...`)`

Applies ''proc'' to the elements of the ''bytevectors'', considered as typed vectors, in order from first to last and discards the results.  Returns an unspecified value.

== Extended bytevector API ==

See the procedures of VectorsCowan, with the exceptions of the ones defined here.

== Structured representation types ==

For mapping C structs onto bytevectors, see StructuresCowan or [https://gitorious.org/taylan-guile/bytestructures/source/0a5426d6b5a6bea66f0f6eea02690c22e11e251a: StructuresTaylan].

== Packaging ==

Since there are a great many procedures, it makes sense to factor this into separate libraries.  Most programs won't require all the representation types, so factoring horizontally into 38 libraries based on that is a simple approach.  If the result is still too large, then we can factor vertically based on expected uses for the function.

== Implementation ==

[https://gist.github.com/ijp/1e0e67ff93c486f66fc8 This syntax-rules macro by Ian Price] will be helpful in implementing lots of similar but not identical procedures for the 38 types.

time

2014-09-27 03:31:19

version

4