2.2 Light Detail Member Format

This section describes the format of “light” detail .bin members. These members have a binary format which we describe here in terms of a context-free grammar using the following conventions:

NonTerminal ⇒ …

Nonterminals have CamelCaps names, and ⇒ indicates a production. The right-hand side of a production is often broken across multiple lines. Break points are chosen for aesthetics only and have no semantic significance.

00, 01, …, ff.

A bytes with a fixed value, written as a pair of hexadecimal digits.

i0, i1, …, i9, i10, i11, …
ib0, ib1, …, ib9, ib10, ib11, …

A 32-bit integer in little-endian or big-endian byte order, respectively, with a fixed value, written in decimal. Prefixed by ‘i’ for little-endian or ‘ib’ for big-endian.

byte

A byte.

bool

A byte with value 0 or 1.

int16
be16

A 16-bit unsigned integer in little-endian or big-endian byte order, respectively.

int32
be32

A 32-bit unsigned integer in little-endian or big-endian byte order, respectively.

int64
be64

A 64-bit unsigned integer in little-endian or big-endian byte order, respectively.

double

A 64-bit IEEE floating-point number.

float

A 32-bit IEEE floating-point number.

string
bestring

A 32-bit unsigned integer, in little-endian or big-endian byte order, respectively, followed by the specified number of bytes of character data. (The encoding is indicated by the Formats nonterminal.)

x?

x is optional, e.g. 00? is an optional zero byte.

x*n

x is repeated n times, e.g. byte*10 for ten arbitrary bytes.

x[name]

Gives x the specified name. Names are used in textual explanations. They are also used, also bracketed, to indicate counts, e.g. int32[n] byte*[n] for a 32-bit integer followed by the specified number of arbitrary bytes.

a | b

Either a or b.

(x)

Parentheses are used for grouping to make precedence clear, especially in the presence of |, e.g. in 00 (01 | 02 | 03) 00.

count(x)
becount(x)

A 32-bit unsigned integer, in little-endian or big-endian byte order, respectively, that indicates the number of bytes in x, followed by x itself.

v1(x)

In a version 1 .bin member, x; in version 3, nothing. (The .bin header indicates the version.)

v3(x)

In a version 3 .bin member, x; in version 1, nothing.

PSPP uses this grammar to parse light detail members. See src/output/spv/light-binary.grammar in the PSPP source tree for the full grammar.

Little-endian byte order is far more common in this format, but a few pieces of the format use big-endian byte order.

Light detail members express linear units in two ways: points (pt), at 72/inch, and “device-independent pixels” (px), at 96/inch. To convert from pt to px, multiply by 1.33 and round up. To convert from px to pt, divide by 1.33 and round down.

A “light” detail member .bin consists of a number of sections concatenated together, terminated by an optional byte 01:

Table =>
    Header Titles Footnotes
    Areas Borders PrintSettings TableSettings Formats
    Dimensions Axes Cells
    01?

The following sections go into more detail.