This is the lisp-binary Reference Manual, version 1, generated automatically by Declt version 4.0 beta 2 "William Riker" on Sun Sep 15 05:41:42 2024 GMT+0.
The main system appears first, followed by any subsystem dependency.
lisp-binary
Declare binary formats as structs and then read and write them.
Jeremy Phelps
GPLv3
1
closer-mop
(system).
moptilities
(system).
flexi-streams
(system).
quasiquote-2.0
(system).
alexandria
(system).
cffi
(system).
binary-1.lisp
(file).
binary-2.lisp
(file).
types.lisp
(file).
simple-bit-stream.lisp
(file).
reverse-stream.lisp
(file).
integer.lisp
(file).
float.lisp
(file).
utils.lisp
(file).
Files are sorted by type and then listed depth-first from the systems components trees.
lisp-binary/lisp-binary.asd
lisp-binary/binary-1.lisp
lisp-binary/binary-2.lisp
lisp-binary/types.lisp
lisp-binary/simple-bit-stream.lisp
lisp-binary/reverse-stream.lisp
lisp-binary/integer.lisp
lisp-binary/float.lisp
lisp-binary/utils.lisp
lisp-binary/binary-1.lisp
utils.lisp
(file).
float.lisp
(file).
integer.lisp
(file).
simple-bit-stream.lisp
(file).
reverse-stream.lisp
(file).
lisp-binary
(system).
*byte-order*
(special variable).
bad-enum-value
(condition).
bad-magic-value
(condition).
buffer
(function).
decode-ip-addr
(function).
define-enum
(macro).
input-string-too-long
(condition).
open-binary
(function).
pointer
(special variable).
pointer
(class).
read-binary
(generic function).
read-binary-type
(function).
read-bytes
(method).
read-counted-string
(function).
read-enum
(function).
read-file
(function).
read-terminated-string
(function).
with-buffered-output
(macro).
with-local-pointer-resolving-context
(macro).
with-open-binary-file
(macro).
write-binary
(generic function).
write-binary-type
(function).
write-bytes
(method).
write-counted-string
(function).
write-enum
(function).
write-terminated-string
(function).
*always-produce-byte-count*
(special variable).
*base-pointer-tags*
(special variable).
*debug*
(special variable).
*enum-definitions*
(special variable).
*ignore-eval-type-bitstream-issue*
(special variable).
*ignore-on-write*
(special variable).
*known-defbinary-types*
(special variable).
*outer-stream-file-position*
(special variable).
*queued-pointers*
(special variable).
*type-expanders*
(special variable).
*type-info-objects*
(special variable).
*virtual-types*
(special variable).
add-base-pointer-tag
(function).
align-to-boundary
(function).
array-pop
(function).
binary-field
(structure).
binary-field-bit-stream-id
(reader).
(setf binary-field-bit-stream-id)
(writer).
binary-field-defstruct-field
(reader).
(setf binary-field-defstruct-field)
(writer).
binary-field-name
(reader).
(setf binary-field-name)
(writer).
binary-field-p
(function).
binary-field-read-form
(reader).
(setf binary-field-read-form)
(writer).
binary-field-type
(reader).
(setf binary-field-type)
(writer).
binary-field-write-form
(reader).
(setf binary-field-write-form)
(writer).
build-virtual-type-reader/writer-expander
(function).
clear-tag
(function).
copy-binary-field
(function).
copy-enum-definition
(function).
copy-out-pointer
(function).
copy-virtual-type
(function).
debug-data
(special variable).
defbinary-type
(special variable).
defbinary-type
(class).
defbinary-type-align
(reader method).
(setf defbinary-type-align)
(writer method).
defbinary-type-bind-index-to
(reader method).
(setf defbinary-type-bind-index-to)
(writer method).
defbinary-type-byte-count-name
(reader method).
(setf defbinary-type-byte-count-name)
(writer method).
defbinary-type-byte-order
(reader method).
(setf defbinary-type-byte-order)
(writer method).
defbinary-type-element-align
(reader method).
(setf defbinary-type-element-align)
(writer method).
defbinary-type-name
(reader method).
(setf defbinary-type-name)
(writer method).
defbinary-type-previous-defs-symbol
(reader method).
(setf defbinary-type-previous-defs-symbol)
(writer method).
defbinary-type-reader
(reader method).
(setf defbinary-type-reader)
(writer method).
defbinary-type-stream-symbol
(reader method).
(setf defbinary-type-stream-symbol)
(writer method).
defbinary-type-type
(reader method).
(setf defbinary-type-type)
(writer method).
defbinary-type-writer
(reader method).
(setf defbinary-type-writer)
(writer method).
define-lisp-binary-type
(macro).
define-virtual-type
(macro).
dump-tag
(function).
enum-definition
(structure).
enum-definition-byte-order
(reader).
(setf enum-definition-byte-order)
(writer).
enum-definition-name
(reader).
(setf enum-definition-name)
(writer).
enum-definition-p
(function).
enum-definition-reader
(reader).
(setf enum-definition-reader)
(writer).
enum-definition-signed
(reader).
(setf enum-definition-signed)
(writer).
enum-definition-signed-representation
(reader).
(setf enum-definition-signed-representation)
(writer).
enum-definition-size
(reader).
(setf enum-definition-size)
(writer).
enum-definition-variables
(reader).
(setf enum-definition-variables)
(writer).
enum-definition-writer
(reader).
(setf enum-definition-writer)
(writer).
enump
(function).
expand-previous-defs
(function).
expand-read/write-binary-type-body
(function).
get-base-pointer-tag
(function).
get-enum-definition
(function).
get-enum-name
(function).
get-enum-value
(function).
get-tag
(function).
get-type-fields
(function).
load-offset
(function).
make-binary-field
(function).
make-enum-definition
(function).
make-fixed-length-string
(function).
make-out-pointer
(function).
make-simple-array
(function).
make-truncated-fixed-length-string
(function).
make-virtual-type
(function).
out-pointer
(structure).
out-pointer-closure
(reader).
(setf out-pointer-closure)
(writer).
out-pointer-data-to-store
(reader).
(setf out-pointer-data-to-store)
(writer).
out-pointer-offset-byte-order
(reader).
(setf out-pointer-offset-byte-order)
(writer).
out-pointer-offset-position
(reader).
(setf out-pointer-offset-position)
(writer).
out-pointer-offset-signedness
(reader).
(setf out-pointer-offset-signedness)
(writer).
out-pointer-offset-size/bytes
(reader).
(setf out-pointer-offset-size/bytes)
(writer).
out-pointer-p
(function).
pointer-base-pointer
(reader method).
(setf pointer-base-pointer)
(writer method).
pointer-offset
(reader method).
(setf pointer-offset)
(writer method).
pointer-stream
(reader method).
(setf pointer-stream)
(writer method).
pointer-type
(reader method).
(setf pointer-type)
(writer method).
push-to-tag
(function).
queue-write-pointer
(function).
read-octets-to-string
(macro).
read/write-binary-type
(macro).
remove-all-restart-case
(function).
remove-double-multiple-value-bind
(function).
remove-impossible-error-checks
(function).
right-pad
(function).
runtime-reader/writer-form
(function).
simple-array-p
(function).
type-size
(function).
unknown-type-size
(condition).
unspecified-type-error
(condition).
virtual-type
(structure).
virtual-type-can-be-in-bit-field
(reader).
(setf virtual-type-can-be-in-bit-field)
(writer).
virtual-type-estimated-total-bits
(reader).
(setf virtual-type-estimated-total-bits)
(writer).
virtual-type-lambda-list
(reader).
(setf virtual-type-lambda-list)
(writer).
virtual-type-lisp-type
(reader).
(setf virtual-type-lisp-type)
(writer).
virtual-type-name
(reader).
(setf virtual-type-name)
(writer).
virtual-type-p
(function).
virtual-type-reader
(reader).
(setf virtual-type-reader)
(writer).
virtual-type-stream-required
(reader).
(setf virtual-type-stream-required)
(writer).
virtual-type-writer
(reader).
(setf virtual-type-writer)
(writer).
lisp-binary/binary-2.lisp
utils.lisp
(file).
float.lisp
(file).
integer.lisp
(file).
simple-bit-stream.lisp
(file).
reverse-stream.lisp
(file).
binary-1.lisp
(file).
lisp-binary
(system).
defbinary
(macro).
%make-reader-let-def
(function).
*last-f*
(special variable).
add-bit-stream-id
(function).
add-bit-stream-vars
(function).
add-stream-definitions
(function).
bit-field-type-p
(function).
bitfield-spec->defstruct-specs
(function).
combine-field-descriptions
(function).
convert-to-bit-fields
(function).
defbinary-constructor-name
(function).
expand-byte-shorthand
(function).
expand-defbinary-field
(function).
expand-defbinary-type-field
(function).
externally-byte-aligned-p
(function).
field-description-plist
(function).
field-description-type
(function).
field-option
(function).
find-bit-field-groups
(function).
group-write-forms
(function).
list-of-fields-p
(function).
make-bit-field
(function).
make-reader-let-def
(macro).
recursive-field-list
(function).
reverse-bit-stream-groups
(function).
var-bit-stream
(function).
lisp-binary/types.lisp
utils.lisp
(file).
binary-1.lisp
(file).
binary-2.lisp
(file).
lisp-binary
(system).
lisp-binary/simple-bit-stream.lisp
integer.lisp
(file).
lisp-binary
(system).
bit-stream
(class).
byte-aligned-p
(function).
close
(method).
read-bits
(function).
read-bytes-with-partial
(function).
stream-element-type
(method).
stream-file-position
(method).
stream-finish-output
(method).
stream-force-output
(method).
stream-read-byte
(method).
stream-read-sequence
(method).
stream-write-byte
(method).
stream-write-sequence
(method).
with-wrapped-in-bit-stream
(macro).
wrap-in-bit-stream
(generic function).
write-bits
(function).
%stream-read-sequence
(function).
%stream-write-sequence
(function).
init-read
(function).
init-write
(function).
read-bits/big-endian
(function).
read-bits/little-endian
(function).
read-bytes-with-partial/macro
(macro).
read-partial-byte/big-endian
(function).
read-partial-byte/little-endian
(function).
reset-op
(function).
lisp-binary/reverse-stream.lisp
integer.lisp
(file).
lisp-binary
(system).
close
(method).
reverse-stream
(class).
stream-file-position
(method).
stream-finish-output
(method).
stream-force-output
(method).
stream-read-byte
(method).
stream-read-sequence
(method).
stream-write-byte
(method).
stream-write-sequence
(method).
with-wrapped-in-reverse-stream
(macro).
wrap-in-reverse-stream
(generic function).
%stream-read-sequence
(function).
%stream-write-sequence
(function).
*8-bit-lookup-table*
(special variable).
compute-reversed-byte
(function).
make-lookup-table
(function).
reverse-byte
(function).
lisp-binary/integer.lisp
utils.lisp
(file).
lisp-binary
(system).
decode-lsb
(function).
decode-msb
(function).
encode-lsb
(function).
encode-msb
(function).
get-lsb-byte
(function).
join-field-bits
(function).
pop-bits
(macro).
pop-bits/le
(macro).
push-bits
(macro).
push-bits/le
(macro).
read-bytes
(generic function).
read-integer
(function).
signed->unsigned
(function).
signed->unsigned/bits
(function).
split-bit-field
(function).
unsigned->signed
(function).
unsigned->signed/bits
(function).
write-bytes
(generic function).
write-integer
(function).
ash*
(function).
logior*
(function).
ones-complement->twos-complement
(function).
tif
(macro).
tlabels
(macro).
twos-complement->ones-complement
(function).
lisp-binary/float.lisp
integer.lisp
(file).
lisp-binary
(system).
+inf
(special variable).
-inf
(special variable).
decode-float-bits
(macro).
encode-float-bits
(macro).
infinityp
(function).
nanp
(function).
quiet-nan
(special variable).
read-float
(macro).
signalling-nan
(special variable).
write-float
(macro).
%infinityp
(function).
%make-infinity
(function).
%make-quiet-nan
(function).
%make-signalling-nan
(function).
%qnanp
(function).
%read-float
(function).
%snanp
(function).
%write-float
(function).
*denormals*
(special variable).
*format-table*
(special variable).
calculate-exponent
(function).
calculate-significand
(function).
decode-float-bits/arithmetic
(function).
decode-float-bits/arithmetic-macro
(macro).
decode-float-bits/cffi
(function).
decode-significand
(function).
denormalp
(function).
denormalp/arithmetic
(function).
encode-float-bits/arithmetic
(function).
encode-float-bits/arithmetic-macro
(macro).
encode-float-bits/cffi
(function).
encode-float-bits/runtime-format
(function).
encode-significand
(function).
exponent-all-ones-p
(function).
exponent-zero-p
(function).
float-coerce
(function).
float-value
(function).
format-size
(function).
get-exponent
(function).
get-format
(function).
get-significand
(function).
make-infinity
(function).
make-largest-denormal
(function).
make-quiet-nan
(function).
make-signalling-nan
(function).
make-smallest-denormal
(function).
popbit
(macro).
lisp-binary/utils.lisp
lisp-binary
(system).
aif
(macro).
assoc-cdr
(function).
awhen
(macro).
bind-class-slots
(macro).
destructuring-case
(macro).
destructuring-lambda
(macro).
divisiblep
(function).
find-sublist
(function).
group
(function).
insert-before
(function).
let-values
(macro).
let-values*
(macro).
letf
(macro).
mapseq
(function).
named-let
(macro).
no-destructuring-match
(condition).
plist-replace
(function).
pushover
(macro).
recursive-find
(function).
recursive-find-if
(function).
recursive-find-sublist
(function).
recursive-find/collect
(function).
recursive-map
(function).
recursive-mapcar
(function).
relative-file-position
(function).
remove-binding
(function).
remove-plist-keys
(function).
simple-define-condition
(macro).
struct-like-defclass
(macro).
subst*
(function).
with-file-position
(macro).
acond
(macro).
add-default-value-if-needed
(function).
expand-struct-like-defclass-slot
(function).
let-values/stupid*
(macro).
list-begins-with-p
(function).
optimize-let-values
(function).
take-while
(function).
with-letf-bindings
(macro).
Packages are listed by definition order.
lisp-binary/float
reverse-stream
simple-bit-stream
lisp-binary/integer
lisp-binary-utils
lisp-binary
lisp-binary/float
common-lisp
.
lisp-binary/integer
.
+inf
(special variable).
-inf
(special variable).
decode-float-bits
(macro).
encode-float-bits
(macro).
infinityp
(function).
nanp
(function).
quiet-nan
(special variable).
read-float
(macro).
signalling-nan
(special variable).
write-float
(macro).
%infinityp
(function).
%make-infinity
(function).
%make-quiet-nan
(function).
%make-signalling-nan
(function).
%qnanp
(function).
%read-float
(function).
%snanp
(function).
%write-float
(function).
*denormals*
(special variable).
*format-table*
(special variable).
calculate-exponent
(function).
calculate-significand
(function).
decode-float-bits/arithmetic
(function).
decode-float-bits/arithmetic-macro
(macro).
decode-float-bits/cffi
(function).
decode-significand
(function).
denormalp
(function).
denormalp/arithmetic
(function).
encode-float-bits/arithmetic
(function).
encode-float-bits/arithmetic-macro
(macro).
encode-float-bits/cffi
(function).
encode-float-bits/runtime-format
(function).
encode-significand
(function).
exponent-all-ones-p
(function).
exponent-zero-p
(function).
float-coerce
(function).
float-value
(function).
format-size
(function).
get-exponent
(function).
get-format
(function).
get-significand
(function).
make-infinity
(function).
make-largest-denormal
(function).
make-quiet-nan
(function).
make-signalling-nan
(function).
make-smallest-denormal
(function).
popbit
(macro).
reverse-stream
A stream that reads from another stream and reverses the bit order
of each byte so that the low-order bit becomes the high-order bit and vice versa.
This functionality is called for by the TIFF file format, because "It is easy and
inexpensive for writers to reverse bit order by using a 256-byte lookup table." It
is devillishly tricky to include this functionality directly in the DEFBINARY macro,
however, when the macro was written without gratuitous bit-reversal in mind.
The REVERSE-STREAM does not keep track of any file positioning information. That means
it can coexist with its client stream, and you can mix reads and/or writes between
the two.
REVERSE-STREAM is not limited to 8-bit bytes. It can handle any byte size that the underlying Lisp implementation supports. On PC hardware, some Lisps can read byte sizes that are multiples of 8 bits, such as (UNSIGNED-BYTE 24).
common-lisp
.
lisp-binary-utils
.
lisp-binary/integer
.
trivial-gray-streams
.
reverse-stream
(class).
with-wrapped-in-reverse-stream
(macro).
wrap-in-reverse-stream
(generic function).
%stream-read-sequence
(function).
%stream-write-sequence
(function).
*8-bit-lookup-table*
(special variable).
compute-reversed-byte
(function).
make-lookup-table
(function).
reverse-byte
(function).
simple-bit-stream
common-lisp
.
lisp-binary/integer
.
trivial-gray-streams
.
byte-aligned-p
(function).
read-bits
(function).
read-bytes-with-partial
(function).
with-wrapped-in-bit-stream
(macro).
wrap-in-bit-stream
(generic function).
write-bits
(function).
%stream-read-sequence
(function).
%stream-write-sequence
(function).
bits-left
(slot).
byte-order
(slot).
element-bits
(slot).
init-read
(function).
init-write
(function).
last-byte
(slot).
last-op
(slot).
read-bits/big-endian
(function).
read-bits/little-endian
(function).
read-bytes-with-partial/macro
(macro).
read-partial-byte/big-endian
(function).
read-partial-byte/little-endian
(function).
real-stream
(slot).
reset-op
(function).
lisp-binary/integer
common-lisp
.
lisp-binary-utils
.
bit-stream
(class).
decode-lsb
(function).
decode-msb
(function).
encode-lsb
(function).
encode-msb
(function).
get-lsb-byte
(function).
join-field-bits
(function).
pop-bits
(macro).
pop-bits/le
(macro).
push-bits
(macro).
push-bits/le
(macro).
read-bytes
(generic function).
read-integer
(function).
signed->unsigned
(function).
signed->unsigned/bits
(function).
split-bit-field
(function).
unsigned->signed
(function).
unsigned->signed/bits
(function).
write-bytes
(generic function).
write-integer
(function).
ash*
(function).
logior*
(function).
ones-complement->twos-complement
(function).
tif
(macro).
tlabels
(macro).
twos-complement->ones-complement
(function).
lisp-binary-utils
common-lisp
.
metabang.moptilities
.
aif
(macro).
assoc-cdr
(function).
awhen
(macro).
bind-class-slots
(macro).
destructuring-case
(macro).
destructuring-lambda
(macro).
divisiblep
(function).
find-sublist
(function).
group
(function).
insert-before
(function).
let-values
(macro).
let-values*
(macro).
letf
(macro).
mapseq
(function).
named-let
(macro).
no-destructuring-match
(condition).
plist-replace
(function).
pushover
(macro).
recursive-find
(function).
recursive-find-if
(function).
recursive-find-sublist
(function).
recursive-find/collect
(function).
recursive-map
(function).
recursive-mapcar
(function).
relative-file-position
(function).
remove-binding
(function).
remove-plist-keys
(function).
simple-define-condition
(macro).
struct-like-defclass
(macro).
subst*
(function).
with-file-position
(macro).
acond
(macro).
add-default-value-if-needed
(function).
expand-struct-like-defclass-slot
(function).
let-values/stupid*
(macro).
list-begins-with-p
(function).
optimize-let-values
(function).
take-while
(function).
with-letf-bindings
(macro).
lisp-binary
Read binary data directly into structs, and write it back out again. Also provides a lower-level API for reading and writing integers and floating-point numbers. Also provides a bit-stream API.
closer-common-lisp
.
flexi-streams
.
lisp-binary-utils
.
lisp-binary/float
.
lisp-binary/integer
.
quasiquote-2.0
.
simple-bit-stream
.
*byte-order*
(special variable).
bad-enum-value
(condition).
bad-magic-value
(condition).
buffer
(function).
decode-ip-addr
(function).
defbinary
(macro).
define-enum
(macro).
input-string-too-long
(condition).
open-binary
(function).
pointer
(special variable).
pointer
(class).
read-binary
(generic function).
read-binary-type
(function).
read-counted-string
(function).
read-enum
(function).
read-file
(function).
read-terminated-string
(function).
with-buffered-output
(macro).
with-local-pointer-resolving-context
(macro).
with-open-binary-file
(macro).
write-binary
(generic function).
write-binary-type
(function).
write-counted-string
(function).
write-enum
(function).
write-terminated-string
(function).
%make-reader-let-def
(function).
*always-produce-byte-count*
(special variable).
*base-pointer-tags*
(special variable).
*debug*
(special variable).
*enum-definitions*
(special variable).
*ignore-eval-type-bitstream-issue*
(special variable).
*ignore-on-write*
(special variable).
*known-defbinary-types*
(special variable).
*last-f*
(special variable).
*outer-stream-file-position*
(special variable).
*queued-pointers*
(special variable).
*type-expanders*
(special variable).
*type-info-objects*
(special variable).
*virtual-types*
(special variable).
add-base-pointer-tag
(function).
add-bit-stream-id
(function).
add-bit-stream-vars
(function).
add-stream-definitions
(function).
align-to-boundary
(function).
array-pop
(function).
binary-field
(structure).
binary-field-bit-stream-id
(reader).
(setf binary-field-bit-stream-id)
(writer).
binary-field-defstruct-field
(reader).
(setf binary-field-defstruct-field)
(writer).
binary-field-name
(reader).
(setf binary-field-name)
(writer).
binary-field-p
(function).
binary-field-read-form
(reader).
(setf binary-field-read-form)
(writer).
binary-field-type
(reader).
(setf binary-field-type)
(writer).
binary-field-write-form
(reader).
(setf binary-field-write-form)
(writer).
bit-field-type-p
(function).
bitfield-spec->defstruct-specs
(function).
build-virtual-type-reader/writer-expander
(function).
clear-tag
(function).
combine-field-descriptions
(function).
convert-to-bit-fields
(function).
copy-binary-field
(function).
copy-enum-definition
(function).
copy-out-pointer
(function).
copy-virtual-type
(function).
debug-data
(special variable).
defbinary-constructor-name
(function).
defbinary-type
(special variable).
defbinary-type
(class).
defbinary-type-align
(generic reader).
(setf defbinary-type-align)
(generic writer).
defbinary-type-bind-index-to
(generic reader).
(setf defbinary-type-bind-index-to)
(generic writer).
defbinary-type-byte-count-name
(generic reader).
(setf defbinary-type-byte-count-name)
(generic writer).
defbinary-type-byte-order
(generic reader).
(setf defbinary-type-byte-order)
(generic writer).
defbinary-type-element-align
(generic reader).
(setf defbinary-type-element-align)
(generic writer).
defbinary-type-name
(generic reader).
(setf defbinary-type-name)
(generic writer).
defbinary-type-previous-defs-symbol
(generic reader).
(setf defbinary-type-previous-defs-symbol)
(generic writer).
defbinary-type-reader
(generic reader).
(setf defbinary-type-reader)
(generic writer).
defbinary-type-stream-symbol
(generic reader).
(setf defbinary-type-stream-symbol)
(generic writer).
defbinary-type-type
(generic reader).
(setf defbinary-type-type)
(generic writer).
defbinary-type-writer
(generic reader).
(setf defbinary-type-writer)
(generic writer).
define-lisp-binary-type
(macro).
define-virtual-type
(macro).
dump-tag
(function).
enum-definition
(structure).
enum-definition-byte-order
(reader).
(setf enum-definition-byte-order)
(writer).
enum-definition-name
(reader).
(setf enum-definition-name)
(writer).
enum-definition-p
(function).
enum-definition-reader
(reader).
(setf enum-definition-reader)
(writer).
enum-definition-signed
(reader).
(setf enum-definition-signed)
(writer).
enum-definition-signed-representation
(reader).
(setf enum-definition-signed-representation)
(writer).
enum-definition-size
(reader).
(setf enum-definition-size)
(writer).
enum-definition-variables
(reader).
(setf enum-definition-variables)
(writer).
enum-definition-writer
(reader).
(setf enum-definition-writer)
(writer).
enump
(function).
expand-byte-shorthand
(function).
expand-defbinary-field
(function).
expand-defbinary-type-field
(function).
expand-previous-defs
(function).
expand-read/write-binary-type-body
(function).
externally-byte-aligned-p
(function).
field-description-plist
(function).
field-description-type
(function).
field-option
(function).
find-bit-field-groups
(function).
get-base-pointer-tag
(function).
get-enum-definition
(function).
get-enum-name
(function).
get-enum-value
(function).
get-tag
(function).
get-type-fields
(function).
group-write-forms
(function).
list-of-fields-p
(function).
load-offset
(function).
make-binary-field
(function).
make-bit-field
(function).
make-enum-definition
(function).
make-fixed-length-string
(function).
make-out-pointer
(function).
make-reader-let-def
(macro).
make-simple-array
(function).
make-truncated-fixed-length-string
(function).
make-virtual-type
(function).
out-pointer
(structure).
out-pointer-closure
(reader).
(setf out-pointer-closure)
(writer).
out-pointer-data-to-store
(reader).
(setf out-pointer-data-to-store)
(writer).
out-pointer-offset-byte-order
(reader).
(setf out-pointer-offset-byte-order)
(writer).
out-pointer-offset-position
(reader).
(setf out-pointer-offset-position)
(writer).
out-pointer-offset-signedness
(reader).
(setf out-pointer-offset-signedness)
(writer).
out-pointer-offset-size/bytes
(reader).
(setf out-pointer-offset-size/bytes)
(writer).
out-pointer-p
(function).
pointer-base-pointer
(generic reader).
(setf pointer-base-pointer)
(generic writer).
pointer-offset
(generic reader).
(setf pointer-offset)
(generic writer).
pointer-stream
(generic reader).
(setf pointer-stream)
(generic writer).
pointer-type
(generic reader).
(setf pointer-type)
(generic writer).
push-to-tag
(function).
queue-write-pointer
(function).
read-octets-to-string
(macro).
read/write-binary-type
(macro).
recursive-field-list
(function).
remove-all-restart-case
(function).
remove-double-multiple-value-bind
(function).
remove-impossible-error-checks
(function).
reverse-bit-stream-groups
(function).
right-pad
(function).
runtime-reader/writer-form
(function).
simple-array-p
(function).
type-size
(function).
unknown-type-size
(condition).
unspecified-type-error
(condition).
var-bit-stream
(function).
virtual-type
(structure).
virtual-type-can-be-in-bit-field
(reader).
(setf virtual-type-can-be-in-bit-field)
(writer).
virtual-type-estimated-total-bits
(reader).
(setf virtual-type-estimated-total-bits)
(writer).
virtual-type-lambda-list
(reader).
(setf virtual-type-lambda-list)
(writer).
virtual-type-lisp-type
(reader).
(setf virtual-type-lisp-type)
(writer).
virtual-type-name
(reader).
(setf virtual-type-name)
(writer).
virtual-type-p
(function).
virtual-type-reader
(reader).
(setf virtual-type-reader)
(writer).
virtual-type-stream-required
(reader).
(setf virtual-type-stream-required)
(writer).
virtual-type-writer
(reader).
(setf virtual-type-writer)
(writer).
Definitions are sorted by export status, category, package, and then by lexicographic order.
Evaluates BODY with the slots from the CLASS bound to the values taken from INSTANCE. The CLASS must be a class object at compile-time, so the macro can extract the needed variable names for binding.
Decodes the bits from an IEEE floating point number. Supported formats are
listed in the variable LISP-BINARY/FLOAT::*FORMAT-TABLE*.
If the FORMAT is either :SINGLE or :DOUBLE, then the decoding is
done by storing the bits in memory and having the CPU reinterpret that buffer
as a float. Otherwise, arithmetic methods are used to arrive at the correct value.
To prevent precision loss if you are decoding a larger type such as :QUADRUPLE
or :OCTUPLE precision, use ’RATIONAL for the RESULT-TYPE to avoid a conversion to
a smaller 32- or 64-bit float.
Defines a struct that represents binary data. Also generates two methods for this struct, named
READ-BINARY and WRITE-BINARY, which (de)serialize the struct to or from a stream. The serialization is
a direct binary representation of the fields of the struct. For instance, if there’s a field with a :TYPE of
(UNSIGNED-BYTE 32), 4 bytes will be written in the specified :BYTE-ORDER. The fields are written (or read) in
the order in which they are specified in the body of the DEFBINARY form.
ARGUMENTS
NAME - Used as the name in the generated DEFSTRUCT form.
:BYTE-ORDER - The byte-order to use when reading or writing multi-byte
data. Accepted values are :BIG-ENDIAN, :LITTLE-ENDIAN,
and :DYNAMIC. If :DYNAMIC is specified, then the
READ- and WRITE-BINARY methods will consult the special
variable LISP-BINARY:*BYTE-ORDER* at runtime to decide
which byte order to use. That variable is expected to
be either :LITTLE-ENDIAN or :BIG-ENDIAN.
:PRESERVE-*BYTE-ORDER* - Don’t revert changes that get made to
LISP-BINARY:*BYTE-ORDER* during the call
to either READ- or WRITE-BINARY.
:ALIGN - Align to the specified byte boundary before reading or writing
the struct.
:EXPORT - Export all symbols associated with the generated struct,
including the name of the struct, the name of the constructor,
and all the slot names.
:BYTE-COUNT-NAME - In all value and type forms, bind to this name
the number of bytes in the struct written so far.
&ALLOW-OTHER-KEYS - All other keyword arguments will be passed through
to the generated CL:DEFSTRUCT form as part of the
NAME-AND-OPTIONS argument.
FIELD-DESCRIPTIONS - A list of slot specifications, having the following structure:
(FIELD-NAME DEFAULT-VALUE &KEY TYPE BYTE-ORDER ALIGN ELEMENT-ALIGN
READER WRITER BIND-INDEX-TO)
The parameters have the following meanings:
FIELD-NAME - The name of the slot.
DEFAULT-VALUE - The default value.
TYPE - The type of the field. Some Common Lisp types such as
(UNSIGNED-BYTE 32) are supported. Any type defined
with DEFBINARY is also supported. For more info, see
’TYPES’ below.
BYTE-ORDER - The byte order to use when reading or writing this
field. Defaults to the BYTE-ORDER given for the whole
struct.
ALIGN - If specified, reads and writes will be aligned on this
boundary. When reading, bytes will be thrown away until
alignment is achieved. When writing, NUL bytes will be
written.
UNTYPED-STRUCT - Don’t declare the :TYPEs of the fields in the generated
DEFSTRUCT form.
ELEMENT-ALIGN - If the TYPE is an array, each element of the array will
be aligned to this boundary.
READER - If speficied, this function will be used to read the field.
It must accept one argument (a stream), and return two
values - The object read, and the the number of bytes read.
The number of bytes read is used for alignment purposes.
WRITER - If specified, this function will be used to write the field.
It must accept two arguments (the object to write, and the
stream), and return the number of bytes written, which is
used for alignment purposes.
BIND-INDEX-TO - If the EVAL type specifier is used as an array’s element type
(see below), BIND-INDEX-TO will be bound to the current index
into the array, in case that matters for determining the type
of the next element.
Example:
(defbinary simple-binary (:export t
:byte-order :little-endian)
(magic 38284 :type (magic :actual-type (unsigned-byte 16)
:value 38284))
(size 0 :type (unsigned-byte 32))
(oddball-value 0 :type (unsigned-byte 32)
:byte-order :big-endian)
((b g r) 0 :type (bit-field :raw-type (unsigned-byte 8)
:member-types
((unsigned-byte 2)
(unsigned-byte 3)
(unsigned-byte 3))))
(name "" :type (counted-string 1 :external-format :utf8))
(alias #() :type (counted-buffer 4)
:byte-order :big-endian)
(floating-point 0.0d0 :type double-float)
(big-float 0 :type octuple-float)
(odd-float 0 :type (double-float :byte-order :big-endian))
(c-string "" :type (terminated-buffer 1 :terminator 0))
(nothing nil :type null) ;; Reads and writes nothing.
(other-struct nil :type other-binary
:reader #’read-other-binary
:writer #’write-other-binary)
(struct-array #() :type (counted-array 1 simple-binary))
(blah-type 0 :type (unsigned-byte 32))
(blah nil :type (eval (case oddball-value
((1) ’(unsigned-byte 32))
((2) ’(counted-string 2)))))
(an-array #() :type (simple-array (unsigned-byte 32) ((length c-string))))
(body #() :type (simple-array (unsigned-byte 8) (size))))
The above generates a DEFSTRUCT definition for SIMPLE-BINARY, along with
a definition for a READ-BINARY method and a WRITE-BINARY method.
‘
The READ-BINARY method is EQL-specialized, and will construct the needed
object for you. It can be invoked like this:
(read-binary ’simple-binary stream)
The WRITE-BINARY method is called like this:
(write-binary object stream)
TYPES
DEFBINARY supports two kinds of types: Ordinary Common Lisp types, and Virtual Types.
Out of the Common Lisp types, DEFBINARY knows how to read:
(UNSIGNED-BYTE n) and (SIGNED-BYTE n &key (signed-representation :twos-complement),
where N is the number of bits. Since these types are used so frequently in DEFBINARY
structs, there is a shorthand for them: You can simply use the number of bits as the
type. Positive for unsigned, and negative for signed (two’s complement only). Example:
(defbinary foobar ()
(x 0 :type 16) ;; 16-bit unsigned
(y 1 :type -16)) ;; 16-bit signed
If you need to read one’s complement, it must be written out:
(defbinary foobar ()
(x 0 :type (signed-byte 16 :signed-representation :ones-complement)))
float, short-float, half-float, single-float, double-float, quadruple-float,
and octuple-float.
FLOAT and SINGLE-FLOAT are treated as IEEE Single Precision,
DOUBLE-FLOAT is treated as IEEE Double Precision, while the others are read
in as IEEE Half Precision, Quadruple Precision, etc.
HALF-FLOAT is stored in memory as a single-float, while floats larger than
Double Precision are decoded into RATIONAL numbers to preserve their
precision (they are encoded in their proper format on writing).
(SIMPLE-ARRAY element-type (size))
Example:
(defbinary foobar ()
(size 0 :type (unsigned-byte 16))
(arr #() :type (simple-array (unsigned-byte 8) (size))))
For the element type, any real or virtual type supported by DEFBINARY is allowed.
The SIZE is a Lisp expression that will be evaluated in an environment where all
previous members of the struct are bound to their names.
DEFBINARY will read and write all other CL objects using their READ-BINARY and
WRITE-BINARY methods, if defined.
The virtual types are:
(COUNTED-ARRAY count-size-in-bytes element-type &key bind-index-to)
This is a SIMPLE-ARRAY preceded by an integer specifying how many
elements are in it. The SIMPLE-ARRAY example above could be rewritten to use
a COUNTED-ARRAY instead, like this:
(defbinary foobar ()
(arr #() :type (counted-array 2 (unsigned-byte 8))))
Obscure fact: The COUNT-SIZE-IN-BYTES does not have to be an integer. It can also be a
fraction, which will trigger non-byte-aligned I/O. (example, if the size is 1/2, then the count
is 4 bits wide, and the first element begins halfway into the same byte as the count) The
ELEMENT-TYPE can also be non-byte-aligned. Doing this can result in needing to use a BIT-STREAM
to do I/O with the struct.
The same obscure fact applies anywhere the library accepts a size in bytes.
(COUNTED-STRING count-size-in-bytes &key (EXTERNAL-FORMAT :latin1))
(COUNTED-BUFFER count-size-in-bytes)
These are like COUNTED-ARRAYS, but their elements are one byte long. Furthermore, a
COUNTED-STRING will be encoded or decoded into a Lisp string according to its EXTERNAL-FORMAT.
The encoding/decoding is done using the FLEXI-STREAMS library, and valid EXTERNAL-FORMATs are those
that are accepted by FLEXI-STREAMS:OCTETS-TO-STRING.
Example:
(defbinary foobar ()
(str "" :type (counted-string 2 :external-format :utf8)))
(TERMINATED-STRING termination-length &key (terminator 0) (extenal-format :latin1))
(TERMINATED-BUFFER termination-length &key (terminator 0))
Specifies a C-style terminated string. The TERMINATOR is an integer that will be en/decoded
according to the field’s BYTE-ORDER. As such, it is capable of being more than one byte long,
so it can be used to specify multi-character terminators such as CRLF.
(FIXED-LENGTH-STRING length &key (external-format :latin1) (padding-character #Nul))
Specifies a string of fixed length. When writing, any excess space
in the string will be padded with the PADDING-CHARACTER. The LENGTH is the
number of bytes desired after encoding.
If the input string is longer than the provided LENGTH, a condition of type
LISP-BINARY:INPUT-STRING-TOO-LONG will be raised. Invoke the restart CL:TRUNCATE
to trim enough excess characters from the string to make it equal to the LENGTH.
(MAGIC &key actual-type value)
Specifies that a magic value will be read and written. The value will be
read as type ACTUAL-TYPE.
If the value read is not CL:EQUAL to the VALUE given, then a condition of type
BAD-MAGIC-VALUE will be raised.
A BAD-MAGIC-VALUE object contains the slots BAD-VALUE and REQUIRED-VALUE.
The error can be ignored by invoking the CL:CONTINUE restart.
BASE-POINTER
Instead of reading or writing this field, CL:FILE-POSITION will be called
on the current stream, and the address returned will be stored under a tag
with the same name as this slot. The tag can then be used to calculate
file positions and offsets. See the POINTER type for an example.
FILE-POSITION
Like BASE-POINTER, but no global tag is stored. The slot will contain the
address in the file of the next thing to be read. No actual reading or
writing is triggered by a slot of this type.
(REGION-TAG &key base-pointer-name)
Instead of writing the value of this slot, all POINTERs that have the same
REGION-TAG name as this slot will be written out here, and the corresponding
offsets will be updated. The file being written must be opened with
:DIRECTION :IO. The POINTERs themselves will be written as offsets from
whatever object has the BASE-POINTER named BASE-POINTER-NAME.
(POINTER &key pointer-type data-type base-pointer-name region-tag)
Specifies that the value is really a pointer to another value somewhere else
in the file. When reading, if a BASE-POINTER-NAME is supplied and a base-pointer
tag has been created, then the pointer will be treated as an offset from that
base-pointer. If no BASE-POINTER-NAME is provided, then the pointer is treated
as being an absolute file-position.
The :POINTER-TYPE key specifies the type of the pointer itself, and must be some kind
of integer.
The :DATA-TYPE specifies the data that is being pointed to.
The :REGION-TAG is used when writing. When WRITE-BINARY writes this field, what
it really does is just write a zero pointer (since the object being pointed to
proably occurs later in the file, so we don’t know what the address is going to
be yet). Then WRITE-BINARY stores the address OF THE POINTER, along with a
serialized representation of the data to be written.
When any WRITE-BINARY method gets to a REGION-TAG field, it writes out all the data
that has been stored under that tag’s name, and goes back to update the pointers.
POINTERs cannot be automatically written if they point to an earlier part of the file
than they themselves occur (no backwards-pointing pointers).
Because it must go back and change what it has previously written, the stream must
be opened with :DIRECTION :IO.
All I/O involving POINTERs, REGION-TAGs, or BASE-POINTERs should be performed
within a WITH-LOCAL-POINTER-RESOLVING-CONTEXT block.
Example:
(defbinary bar ()
(pointer-1 nil :type (pointer :pointer-type (unsigned-byte 16)
:data-type (terminated-string 1)
:base-pointer-name foo-base
:region-tag foo-region))
(pointer-2 0 :type (pointer :pointer-type (unsigned-byte 16)
:data-type quadruple-float
:base-pointer-name foo-base
:region-tag foo-region)))
(defbinary foo ()
(foo-base 0 :type base-pointer)
(bar nil :type bar)
;; POINTER-1 and POINTER-2 will point to this:
(foo-region nil :type (region-tag :base-pointer-name foo-base)))
(with-local-pointer-resolving-context
(let ((input (with-open-binary-file (in "foo.bin")
(read-binary ’foo in))))
(with-open-binary-file (out "bar.bin"
:direction :io)
(write-binary input stream))))
(BIT-FIELD &key raw-type member-types)
Specifies that multiple values are to be OR’d into a single integer for serialization
purposes. The name of a slot of this type must be specified as a list of names,
one for each value in the bit field. :RAW-TYPE specifies the type of the single integer
into which everything is being stored, and must meet the following requirements:
1. Be of the form (UNSIGNED-BYTE n)
2. Where N is divisible by 8.
The :MEMBER-TYPES is an unevaluated list of types that must consist entirely of
(UNSIGNED-BYTE b) or (SIGNED-BYTE b) types. The Bs must add up to N above.
READ-BINARY will automatically separate the values in the bit field into their
slots, and WRITE-BINARY will automatically OR them back together.
The default value you specify for this field should be given as a list
of default values for each of the subfields.
(CUSTOM &key reader writer (lisp-type t))
Specifies a slot of type LISP-TYPE that will be read by the provided
READER function and written with the provided WRITER function
The READER function must accept the lambda-list (STREAM), and its
argument will be the stream currently being read.
The WRITER function must accept the lambda-list (OBJECT STREAM), and
it is generally expected to write the OBJECT to the STREAM.
If these functions are specified as LAMBDA forms, then they will
be closures. The READER can expect every field that has been read
so far to be bound to their names, while the WRITER can expect
to be able to see all the slots in the struct being written.
Both functions are optional.
NULL
Reading and writing will be a no-op. The value of a field of type NULL will always read
as NIL and be ignored when writing.
RUNTIME TYPE DETERMINATION
(EVAL unquoted-type-expression)
The EVAL type specifier causes the type to be computed at runtime. The UNQUOTED-TYPE-EXPRESSION will be
evaluated just before attempting to read the field of this type in an environment where all the
previously-defined fields are bound to their names.
Example:
(defbinary foobar ()
(type-tag 0 :type (unsigned-byte 32))
(data nil :type (eval (case type-tag
(1 ’(unsigned-byte 16))
(2 ’(counted-string 1 :external-format :utf-8))))))
In the above example, READ-BINARY will first read the TYPE-TAG as an (UNSIGNED-BYTE 32),
then it will evaluate the CASE expression in order to get the type of the DATA. Then it
will generate a reader and a writer the same way DEFBINARY normally does, except at runtime
instead of compile time.
The CASE expression is not actually evaluated with a runtime call to EVAL. Instead, it is
embedded directly in the source code of the generated READ-BINARY and WRITE-BINARY methods.
The reader/writer code derived from the resulting type expression, however, *is* evaluated with
a runtime call to EVAL, and the part of the macroexpander that handles type fields gets called
at runtime as well.
If the UNQUOTED-TYPE-EXPRESSION evaluates to another EVAL type specifier, then that specifier
will be expanded once again.
DEFINING STRINGS
:EXTERNAL-FORMAT is any value accepted by flexi-streams:octets-to-string, such as :latin1 or :utf8.
String count and terminated-buffer terminator lengths are given in BYTES, unlike the
Common Lisp type ’(unsigned-byte n)’ in which the length is given in bits.
The types COUNTED-STRING and COUNTED-BUFFER are virtual types. When encountered, DEFBINARY will
generate code that deals with counted strings and buffers, which are blocks of data that begin
with a size. The number passed with this type is the size of the count. The difference between the
two is that one of them is converted to and from a STRING while the other retains its raw binary
representation and will be a SIMPLE-ARRAY of (UNSIGNED-BYTE 8).
(TERMINATED-STRING terminator-size) and (TERMINATED-BUFFER terminator-size) are for blocks of data that end with a
terminator of some kind. The terminator is not produced as part of the buffer. The terminator-size defaults to 1.
All generated buffers and strings are guaranteed to have the type SIMPLE-ARRAY.
ARRAYS OF COMPLEX TYPES
In the (SIMPLE-ARRAY element-type length) type specifier, the LENGTH is evaluated when the array is being read.
Previously defined fields will be bound. The ELEMENT-TYPE can be any type supported by DEFBINARY, including
the EVAL type specifier and the COUNTED-STRING, COUNTED-BUFFER, TERMINATED-STRING, and TERMINATED-BUFFER virtual
types. Notably, ELEMENT-TYPE can be other types that were previously defined with DEFBINARY.
There is also the type (COUNTED-ARRAY count-size element-type), which functions like COUNTED-STRING or COUNTED-BUFFER,
except that each element of the array can be a complex type.
NON-BYTE-ALIGNED I/O: AN ALTERNATIVE TO BIT FIELDS
DEFBINARY supports non-byte-aligned reads. For example, if you want to read a 4-bit
unsigned integer and a 12-bit signed integer:
(defbinary non-conforming (:byte-order :big-endian)
(x 0 :type 4)
(y 0 :type 12)) ;; Total: 16 bits.
The above will compile to a single 16-bit read, and the two values will be automatically
extracted into their respective fields. The reverse operation is generated for writing.
In fact, the above is converted into a BIT-FIELD declaration, so it is exactly equivalent
to the following:
(defbinary non-conforming-bit-field-version (:byte-order :big-endian)
((x y) 0 :type (bit-field :raw-type (unsigned-byte 16)
:member-types ((unsigned-byte 4)
(unsigned-byte 12)))))
The macro will group sets signed or unsigned bytes to achieve a read that consists of
whole bytes. This grouping mechanism only works for SIGNED-BYTE and UNSIGNED-BYTE integers.
For other types, DEFBINARY will generate a temporary BIT-STREAM for the non-byte-aligned parts:
(defbinary non-byte-aligned-string (:byte-order :big-endian)
(x 0 :type 4)
(string "" :type (counted-string 1))
(y 0 :type 4))
;; End of non-byte-aligned part
(z "" :type (counted-string 1)))
As long as the sum of the bits adds up to a whole number of bytes, no
special handling is required on the part of the programmer. Internally,
the above generates a temporary bit-stream and reads from it, and it discards
the bit-stream before reading Z, because Z doesn’t require non-byte-aligned I/O.
This is slower than doing whole-byte reads.
Finally, you can specify bytes that throw off the byte-alignment of the
stream:
(defbinary stays-non-byte-aligned ()
(x 0 :type 3))
If the macro cannot group the fields in the struct into byte-aligned reads,
then the struct can only be read from a BIT-STREAM and not a normal
stream (see WRAP-IN-BIT-STREAM and WITH-WRAPPED-IN-BIT-STREAM). In this
case, the macro will generate READ-BINARY and WRITE-BINARY methods that
are specialized to a second argument of type BIT-STREAM.
BIT-STREAMs can wrap any type of stream, including other BIT-STREAMs. This
means that you can nest one struct that does BIT-STREAM I/O inside another:
(defbinary stays-non-byte-aligned ()
(x 0 :type 3)
(y nil :type non-byte-aligned-string)) ;; See above
NON-BYTE-ALIGNED FIELDS and LITTLE ENDIANNESS
Bit fields are inherently confusing when they are applied to little-endian data (unlike
big-endian data, where they make perfect sense). This is because programmers who write
specifications for little-endian formats sometimes still describe the bit fields by
starting with the most significant bit.
Also, code that handles bit fields from little endian data may also handle that data
starting with the most significant bit (including some byte-order-independent code in
this library).
The BIT-FIELD type in DEFBINARY adds to this confusion, since the fields must always
be given starting with the most significant bit, regardless of the format’s byte order.
However, when specifying non-byte-aligned fields without using BIT-FIELDs, they must be
specified starting with the LEAST significant bit in a LITTLE-ENDIAN format, but they
must be specified starting with the MOST significant bit in a BIG-ENDIAN format. For
example, consider the following toy format:
(defbinary toy-format (:byte-order :little-endian)
(a 0 :type 4)
(b 0 :type 16)
(c 0 :type 4))
Write it to disk with the following code:
(with-open-binary-file (out #P"/tmp/test-1.bin" :direction :output
:if-exists :supersede
:if-does-not-exist :create)
(write-binary (make-toy-format :a #x1 :b #x2345 :c #x6) out))
The resulting file would produce the following confusing hex dump:
51 34 62
What is that 5 from the middle doing at the very beginning?!?! Since 0x5 is
the second-least-significant nibble in the structure, it appears in the
most significant nibble of the least significant byte.
Reading the above as a little-endian, 24-bit unsigned integer gives the
integer #x623451, which is what you should have been expecting, since
C is the most significant field, and its value is 6.
You can also specify the above format using the BIT-FIELD type. But then you
have to account for the fact that in a BIT-FIELD type description, you always
describe the most significant bits first, no matter what. So the variables
and their corresponding types have to be reversed:
(defbinary toy-format/bit-field (:byte-order :little-endian)
((c b a) nil :type (bit-field :raw-type (unsigned-byte 24)
:member-types ((unsigned-byte 4)
(unsigned-byte 16)
(unsigned-byte 4)))))
ALIGNMENT
DEFBINARY can generate aligned structures. Alignment is calculated as an offset from the beginning of the structure
being defined. If a SIMPLE-ARRAY is defined with :ALIGN-ELEMENT {boundary}, then each element will be aligned to that
boundary. On writes, the alignment is achieved by writing NUL (0) bytes. On reads, the alignment is performed by
reading bytes from the stream one at a time. Alignment is always performed before reading and writing, never after.
MANUAL ALIGNMENT
If the &KEY argument :BYTE-COUNT-NAME is specified, then the name given will be bound as a variable whose value is the number of bytes read or
written so far. This binding is visible in forms that are evaluated at runtime, such as array-length specifiers and EVAL type
specifiers.
FLOATING-POINT NUMBERS
DEFBINARY can read IEEE floats ranging from half-precision up to octuple precision. Double-precision and below are
represented in memory by hardware floats, while larger-precision floats are decoded into RATIONALs.
Furthermore, single and double-precision floats are decoded from their byte representation by using CFFI, which
lets the hardware do the work on those systems that have FPUs (such as x86/AMD machines).
All other types of floating-point number are encoded and decoded using arithmetic.
Define an enum type. What this does is allow LISP-BINARY to automatically map between keywords and integer values that are expected to be found in a binary file. The SIZE is in bytes.
Example:
(define-enum speeds 2 ()
slow ;; Implicitly 0
light-speed ;; Implicitly 1
(ridiculous-speed 5) ;; Explicit value
ludicrous-speed) ;; Implicitly 6
The READER and WRITER functions must accept the same lambda-lists
as READ-INTEGER and WRITE-INTEGER, and have the same return
values (ie, the READER returns (VALUES object bytes-read) and the
WRITER returns bytes-written).
Matches the EXPRESSION against one of the CASES. Each CASE is of
the form (lambda-list &key where &body body) and can have a guard clause.
The first pattern that successfully DESTRUCTURING-BINDs against the EXPRESSION
without an error *and* satisfies the optional :WHERE expression is the one
that will be selected. OTHERWISE is supported and works just as in the CL:CASE
form.
Example:
(destructuring-case ’(1 2 3)
((a b c) :where (symbolp a)
(declare (ignore b c))
(list :symbol a))
((a b &optional c) :where (number b)
(declare (ignore a c)))
(list :number b))
((a &rest b)
(declare (ignore b))
(list :whatever a))
(otherwise
:nothing-matched))
The DECLARE form is processed before the :WHERE clause even though it appears after it.
Optimized implementation of LET-VALUES*. You can bind a multiple-value expression to
a list of variables, or you can bind a single value. Generates as few nested MULTIPLE-VALUE-BIND
and LET* forms as possible.
Temporarily rebind places like you would special variables. Before control enters the BODY,
the PLACE-BINDINGS are altered using SETF, and after exiting the BODY, their values are restored
to their original values with SETF.
Similar to CL-LETF in Emacs.
Pops the N most significant bits off the front of the INTEGER-PLACE and returns it. INTEGER-SIZE is the number of unpopped bits in the integer.
Pops the N LEAST significant bits off the front of the INTEGER-PLACE and returns it. INTEGER-SIZE is the number of bits in the integer.
Pushes N onto the front of INTEGER-PLACE,
the ’front’ being defined as the MOST significant bits. The
INTEGER-SIZE specifies how many bits are already in the
INTEGER-PLACE.
Pushes N-BITS bits from N onto the front of INTEGER-PLACE, the ’front’ being defined as the LEAST significant bits. The INTEGER-SIZE specifies how many bits are already in the INTEGER-PLACE.
Pushes the OBJ* into the PLACE. If an "identical" object is already there, it is overwritten. Whether something in the PLACE is considered "identical" can be controlled with the :TEST and :KEY keywords.
An extremely simplified version of DEFCLASS. Written because I needed to be able to list the slots of a certain struct.
Creates buffered output stream VAR. Data written to VAR will be written to STREAM after the BODY returns. This makes it possible to write binaries that require streams opened in :DIRECTION :IO to streams that are open in :DIRECTION :OUT
Deal with POINTERs in a thread-safe manner. Generated READ-BINARY and WRITE-BINARY methods rely on special variables to store information to make sure that offsets are calculated correctly. This macro creates local bindings of all the relevant special variables.
Like WITH-OPEN-FILE, but always opens the file as a binary file.
Finds any part of LIST is equal to SUBLIST and returns it, otherwise returns NIL
Returns two values:
T if the DECODED-VALUE represents a floating-point infinity
T if the DECODED-VALUE represents positive infinity, or NIL if it’s negative infinity.
Some Lisp implementations support real floating-point infinities, but the ANSI standard does
not require it, and some Lisp implementations don’t bother to support them. On those implementations,
infinities are represented by the keywords :+INF and :-INF. To detect positive/negative infinity portably,
use this function.
Like OPEN, but always opens a binary stream suitable for use with the DEFBINARY library.
Read a value of type TYPE from the STREAM. TYPE is any type supported by the DEFBINARY macro.
Reads BITS bits from STREAM. If the STREAM is big-endian, the most significant BITS bits will be read, otherwise, the least significant BITS bits will be. The result is an integer of BITS bits.
Reads BITS bits from the STREAM, where BITS is expected to be more than a byte’s worth
of bits. Returns three values:
1. A buffer containing as many whole bytes as possible. This buffer
is always read first, regardless of whether the bitstream is byte-aligned.
2. The partial byte.
3. The number of bits that were read for the partial byte.
The byte order is determined from the STREAM object, which must be a SIMPLE-BIT-STREAM:BIT-STREAM.
Reads an unsigned integer of SIZE-LEN bytes in the specified BYTE-ORDER,
then reads a byte vector of SIZE-LEN bytes. Returns two values:
1. The byte vector
2. The total number of bytes that were read.
Reads an integer of LENGTH bytes from the STREAM in the specified BYTE-ORDER.
If SIGNED is non-NIL, the number is interpreted as being in two’s complement format.
If the STREAM is a BIT-STREAM, then the LENGTH doesn’t have to be an integer.
Reads a string ending in the byte sequence specified by TERMINATOR. The TERMINATOR is not included in the resulting buffer. The default is to read C-style strings, terminated by a zero.
Maps the FUNCTION onto every node in the TREE. Works correctly with
improper lists.
If TRAVERSE-RESULTS is non-NIL, then RECURSIVE-MAPCAR will traverse the result of the FUNCTION even if it is not EQ to the original value.
Removes any binding for VAR from all LET, LET*, LET-VALUES, or LET-VALUES* forms found in the FORM.
Given the INTEGER, split it up as a bit field. The sizes and number of elements are given
by the FIELD-BITS parameter. If FIELD-SIGNEDNESS is specified, then it must be a list
that contains NIL for each element that will be interpreted as an unsigned integer,
and non-NIL for signed integers.
Example:
CL-USER> (split-bit-field #xffaaff ’(8 8 8))
255
170
255
CL-USER>
Better performance could be acheived if INTEGER could be a FIXNUM, but it can’t.
Write the VALUE, interpreting it as type TYPE, to the STREAM. The TYPE is any type supported by the DEFBINARY macro.
Writes the length of the BUFFER on the STREAM as an unsigned integer of SIZE-LEN bytes in the specified BYTE-ORDER, then writes out the BUFFER.
(eql lisp-binary:terminated-string)
) stream) ¶Read N bytes of type ELEMENT-TYPE from STREAM and return them in a newly-allocated array.
Returns two values: The array containing the bytes, and the number of bytes read.
For some types of stream, it is legal to use a fractional number for N. In that case,
the whole bytes are read first, and then the leftover bits. The leftover bits are given
their own byte at the end of the returned array. The second return value (# of bytes read)
will also be fractional in this case. The fractional part can be used to calculate
how many bits the partial byte represents.
If you’re using 8-bit bytes and want to read 11 bits (a whole byte plus three bits), give
11/8 as the value of N.
NOTE: If you’re using this with a bit-stream created with WRAP-IN-BIT-STREAM, the :BYTE-ORDER given to that function should match the one given to this function.
bit-stream
) &key element-type) ¶Creates a BIT-STREAM that can read one bit at a time from the OBJECT. The BIT-STREAM can be discarded if BYTE-ALIGNED-P returns T.
stream
) &key byte-order) ¶Creates a REVERSE-STREAM that can read one bit at a time from the OBJECT. The REVERSE-STREAM can be discarded if BYTE-ALIGNED-P returns T.
stream
)) ¶Write BYTES bytes of the BUFFER into the STREAM. If
BYTES is not provided, then the whole BUFFER is written.
For some types of stream, it is legal to use a fractional number for BYTES. In that case,
the whole bytes are written first, and then the leftover bits. The leftover bits must be given
their own byte at the end of the BUFFER. WRITE-BYTES assumes that all bytes are 8 bits long,
so to write 4 bits, you would give 1/2 as the value of BYTES.
NOTE: If you’re using this with a bit-stream created with WRAP-IN-BIT-STREAM, the :BYTE-ORDER given to that function should match the one given to this function.
bit-stream
) &optional bytes) ¶reverse-stream
) &key abort) ¶bit-stream
) &key abort) ¶bit-stream
)) ¶reverse-stream
) &optional position-spec) ¶sb-gray
.
bit-stream
) &optional position-spec) ¶sb-gray
.
reverse-stream
)) ¶sb-gray
.
bit-stream
)) ¶sb-gray
.
reverse-stream
)) ¶sb-gray
.
bit-stream
)) ¶sb-gray
.
reverse-stream
)) ¶sb-gray
.
bit-stream
)) ¶sb-gray
.
reverse-stream
) (sequence array
) &optional start end) ¶sb-gray
.
bit-stream
) (sequence array
) &optional start end) ¶sb-gray
.
reverse-stream
) integer) ¶sb-gray
.
bit-stream
) integer) ¶sb-gray
.
reverse-stream
) seq &optional start end) ¶sb-gray
.
bit-stream
) seq &optional start end) ¶sb-gray
.
simple-error
.
:input-string
warning
.
fundamental-binary-stream
.
fundamental-input-stream
.
fundamental-output-stream
.
fixnum
8
:element-bits
stream
:real-stream
(or unsigned-byte null)
0
symbol
integer
0
keyword
:little-endian
:byte-order
integer
0
:offset
common-lisp
.
symbol
:type
keyword
:beginning
:base-pointer
common-lisp
.
stream
*standard-input*
:stream
These functions are known to always produce a byte count, so DEFBINARY doesn’t have to generate code to verify that they did.
If a DEFBINARY struct contains a field of type (EVAL ...),
then the macro cannot statically determine whether the struct can
be read without using a BIT-STREAM. If this is set to NIL, then
a condition is raised every time an (EVAL ...) type is encountered,
with restarts available to tell the macro whether a bitstream is
required for that particular field.
Typically, the error would reach EMACS, and the programmer can then
pick a restart from the menu.
However, this doesn’t work if you’re using COMPILE-FILE, because COMPILE-FILE
catches exceptions, so you don’t see the error until it has already been
caught, so you will not be presented with the restarts that I have set up.
For most programs, just ignoring the issue is good enough. Setting this to T (the default) causes the expander to ignore this problem and not raise a condition.
An alist whose keys are the names of DEFBINARY structs and whose values are the field-descriptions of those structs. Needed by TYPE-SIZE
Defines a LISP-BINARY type. The TYPE-INFO-VAR will be bound to a DEFBINARY-TYPE
object that describes the field. The LAMBDA-LIST will be structurally matched against
the :TYPE parameter specified in the DEFBINARY form. The BODY may begin with the keyword
:WHERE followed by a form. If present, this form acts as a further condition for considering
the LAMBDA-LIST to match the :TYPE parameter.
The BODY is expected to return 3 values:
1. The Lisp type that should be used to represent the instance of this LISP-BINARY type described
by the LAMBDA-LIST.
2. A form that reads an instance of the data described by the LAMBDA-LIST from a stream whose name
will be bound to STREAM-SYMBOL.
3. A form that writes an instance of the data from a variable whose name will be bound to NAME, into
a stream whose name is bound to STREAM-SYMBOL.
The slots of the DEFBINARY-TYPE object provide extra information, and will be bound in the BODY using
WITH-SLOTS. These slots are described below:
NAME - The name of the variable to be defined. The WRITER-FORM will be evaluated in a context
where the NAME is bound to the object being written.
TYPE - The type specifier. It’s the same value that will have been matched against the LAMBDA-LIST.
BYTE-ORDER - :LITTLE-ENDIAN or :BIG-ENDIAN.
TERMINATOR - A SIMPLE-ARRAY that will be matched against the input to determine the end of a string.
If the TYPE is itself a SIMPLE-ARRAY, TERMINATOR can be a function, which will be passed
each element read. (TODO: Actually implement that function part)
READER - A user-specified function that overrides the reader that this function would otherwise
generate.
WRITER - A user-specified writer function that overrides the default writer.
STREAM-SYMBOL - The name that will be given to the input and output stream.
PREVIOUS-DEFS-SYMBOL - A symbol that will be bound to a list of LET bindings at runtime. In the event of
an EVAL type, code is generated that will splice the LET bindings found here
into a runtime-constructed LET form that will then be EVAL’d.
BYTE-COUNT-NAME - The name of the variable that will be bound to the number of bytes read or written so far.
ALIGN - The alignment boundary
ELEMENT-ALIGN - The alignment boundary for individual elements in an array.
BIND-INDEX-TO - In array reads and writes, may specify a variable to bind the loop index to.
Or it can be NIL.
Define a new Virtual Type.
A Virtual Type is a rule that tells the LISP-BINARY how to read a particular kind of
value from a stream, and how to write it back. The result of reading a Virtually-Typed object
can be an object of any Lisp type. Which Lisp type the Virtual Type corresponds to must
be specified in the LISP-TYPE argument.
The same LISP-TYPE can be produced by many different Virtual Types. As a result, the LISP-BINARY
library must always be told which type it is reading or writing. This is usually done at compile-time
through the DEFBINARY macro.
The READER and WRITER must be functions.
The READER accepts a STREAM argument and returns two values:
1. The fully-processed value that was read.
2. The number of bytes that were read from the STREAM. If the STREAM is a BIT-STREAM,
then the number of bytes can be fractional, to indicate how much was read down to
the bit. 1/8 of a byte = 1 bit.
The WRITER accepts the lambda list (OBJ STREAM), where OBJ is the value to be written. It
returns the number of bytes that were written.
A naive implementation of LET-VALUES*. Each binding must bind a multiple-value expression to a list of variables, and will expand to a nested MULTIPLE-VALUE-BIND expression.
Creates a single variable definition to go in the let-def form within READ-BINARY. F is a BINARY-FIELD object that describes the field.
If the LET-DEFS contain fields that must be read from a bit-stream, this function
adds the necessary BIT-STREAM type variables to them. BIT-STREAM-GROUPS is a hash table
that maps each bit-stream variable name to the BINARY-FIELD objects of the variables that
must be read from that bit-stream. The STREAM-SYMBOL is the name of the default stream,
and BYTE-ORDER is the :BYTE-ORDER option passed to the DEFBINARY macro (only :BIG-ENDIAN
and :LITTLE-ENDIAN are supported. Handling for :DYNAMIC byte order must happen elsewhere).
name
.
type
.
Given a FRACTION and number of SIGNIFICAND-BITS, calculates the integer significand. The significand returned includes the implicit bit, which must be removed in the final floating-point encoding.
Group the FIELD-DESCRIPTIONS according to how they should be grouped into bit-fields.
Returns two values:
1. A list of fields very similar to the FIELD-DESCRIPTIONS, except that some elements of the
list will be replaced by lists of fields that should be grouped together. Since a single
field description is itself a list, use LIST-OF-FIELDS-P to tell the difference between
one field and a list of fields.
2. Either :BIT-STREAM-REQUIRED if the whole struct can only be read with a bit-stream, or no second value otherwise.
Converts groups of non-byte-aligning field descriptions into bitfields where possible. If they can’t be read as bitfields, then a :BIT-STREAM-ID option is added to the field.
Decodes IEEE floating-point from an integer bit-pattern.
Decodes the bits from a read-in floating-point number using the hardware. Assumes that only :SINGLE and :DOUBLE work.
Given an encoded SIGNIFICAND of length SIGNIFICAND-BITS, calculate the
number it represents. RAW-EXPONENT is only used to determine whether to use
the denormalized interpretation of the SIGNIFICAND. The value of SIGNIFICAND-BITS
includes the ’implicit bit’ which is not actually encoded in the significand. So,
if the SIGNIFICAND is physically 23 bits, plus one implicit bit, then SIGNIFICAND-BITS
is 24.
Calculate the bits of a floating-point number using plain arithmetic, given the FRACTION and the format information SIGNIFICAND-BITS, EXPONENT-BITS, and EXPONENT-BIAS. The returned value is an integer.
name
.
size
.
Expands the field into three values: A slot-descriptor suitable for CL:DEFSTRUCT, a form that reads this slot from a stream, and a form that writes it to a stream. The reader and writer must be evaluated in a context where the NAME is bound to the slot’s value.
Expands the :TYPE field of a DEFBINARY form. Returns three values:
1. A :TYPE specifier that can be spliced into a slot definition in a DEFSTRUCT form.
2. A READER-FORM that can be spliced into another function to read a datum of the specified
type. The READER-FORM will assume that it will be spliced into a scope where there’s
a readable stream. The name of this stream must be stored in (SLOT-VALUE TYPE-INFO ’STREAM-SYMBOL).
3. A WRITER-FORM to write such a datum. It can be spliced into a scope similar to that of the READER-FORM.
Identifies those fields in the LIST of fields that must be
read/written either as a BIT-FIELD or through a BIT-STREAM wrapper.
A list of the original fields is returned, with those groups
that will be read/written in a non-byte-aligned mode grouped
in sublists.
See also: TYPE-SIZE
Coerce the VALUE to the RESULT-TYPE, taking into account the fact that values
generated by this library are not always actually numbers. So on Lisp systems that
don’t support infinity, (FLOAT-COERCE :+INF ’DOUBLE-FLOAT) will actually leave it
alone.
Also takes into account the fact that even on Lisps that do support infinities and NaNs,
you can’t coerce them to non-floating-point numbers, so it passes infinities and NaNs
through untouched if the RESULT-TYPE isn’t floating-point.
There should never be an error as a result of trying to decode a floating-point bit pattern to a number.
Given the decoded parameters of a floating-point number, calculate its numerical value.
Returns the size in bytes of a given floating-point format.
Returns the name that corresponds to the VALUE in the given ENUM.
Given an INTEGER that represents the bit-pattern of a floating point number, extract the bits that represent the significand. SIGNIFICAND-BITS specifies the number of bits in the significand. Does not add the implicit bit.
Groups a list of WRITE-FORMS according to which stream they write to. The streams are identified by matching them to their names, which must be given in STREAM-NAMES.
Creates a FIXED-LENGTH-STRING and encodes it for writing. The REQUIRED-LENGTH is the length in bytes of the string
after encoding. The EXTERNAL-FORMAT is any value accepted by the FLEXI-STREAMS library as an external-format.
If the NORMAL-STRING is longer than the REQUIRED-LENGTH after encoding without any padding, then a condition of type
INPUT-STRING-TOO-LONG is raised. The restart CL:TRUNCATE tells this function to truncate the string to the required
length.
FIXME:
There is still a potential problem here. Suppose that getting to the REQUIRED-LENGTH requires adding an odd number
of bytes, but the PADDING-CHARACTER is encoded as an even number of bytes. Then this function would loop forever.
Alternately, suppose that the input is too long, and the TRUNCATE restart is chosen. If the input is one byte longer
than the REQUIRED-LENGTH, but the last character in the string is encoded as two bytes, then MAKE-TRUNCATED-FIXED-LENGTH-STRING
will never find the right number of characters to trim (the answer is to trim the two-byte character and then pad with a one-byte
character). I need to find concrete examples of this. These examples are likely to be found in the UTF-8 encoding.
Creates a floating-point infinity. Returns the integer bit pattern.
Given a number that has been decoded as one’s complement, correct it to what its value should be if the original bits were a two’s complement representation. This function doesn’t need the number of bits because all ones in one’s complement represents ’negative zero’, a value that can’t be represented in Common Lisp integers.
Add the OBJ to the queue for TAG.
This is the shittiest implementation ever. It functionally rebuilds the entire
tag list each time it runs, sometimes discarding this rebuild and going with
the original version.
There are several reasons for this. First, the tag system can tolerate a
direct SETF of *QUEUED-POINTERS*, but it cannot tolerate mutation of the
underlying data structure. That is because I’m attempting to rely on the
way special variables work in multithreaded Lisps as a source of thread
safety. Mutating *QUEUED-POINTERS* with RPLACA or RPLACD could be seen
in another thread, but rebuilding the list and SETFing it will not affect
other threads.
FIXME: This approach doesn’t provide thread safety unless every
thread binds *QUEUED-POINTERS* with a LET or LAMBDA form. The
WRITE-BINARY method can’t do this because it must be able to
push items onto the tag that can be seen by other implementations
of WRITE-BINARY that might have the corresponding DUMP-TAG call.
Queue some data along with a closure to write it at a later time, and arrange for its address to be written to the OFFSET-POSITION at that time.
Build a list of fields; grandparents are included as their field lists are inclusive.
Strips out all RESTART-CASE forms from the FORM, replacing them with their value form. Improves performance at the cost of easy error recovery.
Pads the STRING with PAD-LENGTH copies of the PADDING-CHARACTER. If PAD-LENGTH is negative, removes characters from the right end of the string instead.
Wraps READER-OR-WRITER in the lexical context required for it to work. READER-OR-WRITER is a reader or writer form generated by EXPAND-DEFBINARY-TYPE-FIELD at runtime as a result of an EVAL type specifier being used. This form assumes that it will be spliced into the body of a READ-BINARY or WRITE-BINARY method, where certain variables are bound. Since the EVAL type specifier produces code that will use this form in an EVAL, the values that would normally be bound must be added with a LET form.
Given a number that has been decoded as two’s complement, correct it to what its value should be if the original bits were a one’s complement representation.
Determines the size in bits of a DEFBINARY type, for the purposes
of determining whether reading the field requires doing non-byte-aligned I/O.
The types accepted are those handled by EXPAND-DEFBINARY-TYPE-FIELD.
It relies on a few simplifications when it comes to arrays and strings, which allow
it to not need to know the exact size of the array, only the count size and the size
of the element-type.
Returns three values:
- The (approximate) number of bits that the field will take up.
- T if the field could be treated as part of a BIT-FIELD, or
NIL if it can only be read using a BIT-STREAM. BIT-FIELD support
is limited to UNSIGNED-BYTEs and SIGNED-BYTEs.
- :BIT-STREAM-ONLY if the field generates so much alignment uncertainty that
the whole structure and everything thereafter must be read
from a BIT-STREAM, and :NORMAL-STREAM if it’s okay to read
byte-aligned parts of the struct from a regular stream.
name
.
defbinary-type
)) ¶automatically generated reader method
defbinary-type
)) ¶automatically generated writer method
defbinary-type
)) ¶automatically generated reader method
defbinary-type
)) ¶automatically generated writer method
defbinary-type
)) ¶automatically generated reader method
defbinary-type
)) ¶automatically generated writer method
defbinary-type
)) ¶automatically generated reader method
defbinary-type
)) ¶automatically generated writer method
defbinary-type
)) ¶automatically generated reader method
defbinary-type
)) ¶automatically generated writer method
defbinary-type
)) ¶automatically generated reader method
name
.
defbinary-type
)) ¶automatically generated writer method
name
.
defbinary-type
)) ¶automatically generated reader method
defbinary-type
)) ¶automatically generated writer method
defbinary-type
)) ¶automatically generated reader method
defbinary-type
)) ¶automatically generated writer method
defbinary-type
)) ¶automatically generated reader method
defbinary-type
)) ¶automatically generated writer method
defbinary-type
)) ¶automatically generated reader method
type
.
defbinary-type
)) ¶automatically generated writer method
type
.
defbinary-type
)) ¶automatically generated reader method
defbinary-type
)) ¶automatically generated writer method
simple-error
.
simple-condition
.
structure-object
.
symbol
number
0
boolean
keyword
:little-endian
list
keyword
:twos-complement
structure-object
.
number
0
number
0
keyword
:little-endian
boolean
function
(function identity)
structure-object
.
8
:normal-stream
(setf defbinary-type-align)
.
defbinary-type-align
.
(setf defbinary-type-bind-index-to)
.
defbinary-type-bind-index-to
.
(setf defbinary-type-byte-count-name)
.
defbinary-type-byte-count-name
.
(setf defbinary-type-byte-order)
.
defbinary-type-byte-order
.
(setf defbinary-type-element-align)
.
defbinary-type-element-align
.
(setf defbinary-type-name)
.
defbinary-type-name
.
(setf defbinary-type-previous-defs-symbol)
.
defbinary-type-previous-defs-symbol
.
(setf defbinary-type-reader)
.
defbinary-type-reader
.
(setf defbinary-type-stream-symbol)
.
defbinary-type-stream-symbol
.
(setf defbinary-type-type)
.
defbinary-type-type
.
(setf defbinary-type-writer)
.
defbinary-type-writer
.
:name
common-lisp
.
:type
symbol
:little-endian
:byte-order
:reader
:writer
:stream-symbol
:previous-defs-symbol
:byte-count-name
:align
:element-align
:bind-index-to
Jump to: | %
(
A B C D E F G I J L M N O P Q R S T U V W |
---|
Jump to: | %
(
A B C D E F G I J L M N O P Q R S T U V W |
---|
Jump to: | *
+
-
A B C D E I L N O P Q R S T V W |
---|
Jump to: | *
+
-
A B C D E I L N O P Q R S T V W |
---|
Jump to: | B C D E F I L N O P R S T U V |
---|
Jump to: | B C D E F I L N O P R S T U V |
---|