dreamworkAPI
Ctrl K
GitHub
classDocs / BinaryWriter

BinaryWriter

classsharedmenusource
Object → BinaryWriter

A growable binary buffer, writes values one after another at any bit position.

The exact inverse of BinaryReader: the same bit layout (LSB-first, as pack and Source's bf_write), the same cursor counted in bits from 0, and big endian by default:

lua
local writer = BinaryWriter()
writer:writeBit( 1 )
writer:writeUInt( 2, 7, true )
writer:writeUInt( 300, 16, true )
writer:compile() --> "\5\44\1"

Lua strings can't be changed in place, so bytes are kept in a buffer (bytes) until compile (or tostring) joins them: a string.buffer written in place when FFI and string.buffer are available (appends and compile are memcpy), a growable FFI uint8_t array when only FFI is, or a table otherwise, where large aligned appends at the end are kept as string chunks and writing before them joins everything back into bytes.

Writing overwrites the data under the cursor, bits next to a field in the same byte are kept. The size grows to the furthest position written or moved to (seek, skip, align), bytes that were never written are 0 in the result.

Integers are written as their lowest bit_count bits, the same way as bitpack.write, so writeUInt and writeInt accept both unsigned and negative values and never throw on overflow.

Constructor

BinaryWriter(data: any?): BinaryWriter

Fields

NameTypeDescription
positionintegerThe cursor position in bits.
bytesBinaryWriter.BufferThe written bytes, 1-indexed from base, a table may have gaps.
baseintegerThe position in bits of bytes[ 1 ], the size of chunks (table backend), 0 otherwise.
capacitynumberThe size of bytes in bits, math.huge for a table.
bufferstring.buffer | nilThe string.buffer that holds the data (string.buffer backend).
chunksstring[] | nilThe data before base (table backend).
chunk_countinteger | nilThe number of chunks (table backend).
has_gapsbooleantrue if a table has bytes that were never written.
data_lengthintegerThe size of the data in bits.

Operators

OperatorOperandResult
leninteger
concat any string

Methods

alignMoves the cursor forward to the next multiple of bit_boundary, padding with 0 bits.
compileJoins everything written so far into a string.
isAlignedChecks if the cursor is at a multiple of bit_boundary.
isEndOfFileChecks if the cursor is at the end of the data, so the next write appends.
openReplaces the data of the writer and moves the cursor to its end, so the next writes append.
remainingReturns the size of the data after the cursor, that the next writes overwrite.
seekMoves the cursor to the absolute position.
sizeReturns the size of the data.
skipMoves the cursor relative to its position, moving after the end grows the data (zero-filled).
tellReturns the cursor position.
writeWrites the string as is, the cursor doesn't have to be aligned.
writeBitWrites one bit.
writeBooleanWrites one bit as a boolean, same as net.WriteBool.
writeBytesWrites bytes, the cursor doesn't have to be aligned.
writeCountedStringWrites the string prefixed with its length, read it back with BinaryReader:readCountedString.
writeDateWrites date in DOS format (16 bits), see bytepack.writeDate.
writeDoubleWrites signed 8-byte (64 bit) float, the cursor doesn't have to be aligned.
writeFixedPointWrites signed fixed-point number (Qm.n), rounded to the nearest step.
writeFixedStringWrites the string of a fixed size, shorter data is padded with \0 and longer data is cut, same as pack.writeFixedString.
writeFloatWrites signed 4-byte (32 bit) float, the cursor doesn't have to be aligned.
writeIntWrites signed (two's complement) integer of any size, read it back with BinaryReader:readInt.
writeLineWrites the line, the string followed by \n.
writeObjectWrites the object with its serialize( writer, ... ) method, read it back with BinaryReader:readObject or BinaryReader:r…
writeStringWrites C-style string, the string followed by the null terminator (\0), same as net.WriteString.
writeTerminatedStringWrites the string followed by the terminator byte, read it back with BinaryReader:readTerminatedString.
writeTimeWrites time in DOS format (16 bits), see bytepack.writeTime.
writeUIntWrites unsigned integer of any size, read it back with BinaryReader:readUInt.
writeUnsignedFixedPointWrites unsigned fixed-point number (UQm.n), rounded to the nearest step.

#BinaryWriter:align

sharedmenusource
function BinaryWriter:align(bit_boundary?: integer): integer

Moves the cursor forward to the next multiple of bit_boundary, padding with 0 bits.

Parameters
NameTypeDescription
bit_boundaryoptionalintegerThe boundary in bits, 8 (byte) by default.
Returns
TypeNameDescription
integerpositionThe new position in bits.

#BinaryWriter:compile

sharedmenunodiscardsource
function BinaryWriter:compile(): string

Joins everything written so far into a string.

The last byte is padded with 0 bits if the size isn't a whole number of bytes.

Returns
TypeNameDescription
stringdataThe binary data.

#BinaryWriter:isAligned

sharedmenunodiscardsource
function BinaryWriter:isAligned(bit_boundary?: integer): boolean

Checks if the cursor is at a multiple of bit_boundary.

Parameters
NameTypeDescription
bit_boundaryoptionalintegerThe boundary in bits, 8 (byte) by default.
Returns
TypeNameDescription
booleanis_alignedtrue if the cursor is aligned.

#BinaryWriter:isEndOfFile

sharedmenunodiscardsource
function BinaryWriter:isEndOfFile(): boolean

Checks if the cursor is at the end of the data, so the next write appends.

Returns
TypeNameDescription
booleanis_eoftrue if there is no data after the cursor.

#BinaryWriter:open

sharedmenusource
function BinaryWriter:open(data: any)

Replaces the data of the writer and moves the cursor to its end, so the next writes append.

Use seek() after it to overwrite the data from the start.

Parameters
NameTypeDescription
dataanyThe data, converted to a string with tostring.

#BinaryWriter:remaining

sharedmenunodiscardsource
function BinaryWriter:remaining(as_bytes?: boolean): integer

Returns the size of the data after the cursor, that the next writes overwrite.

Parameters
NameTypeDescription
as_bytesoptionalbooleantrue to return the number of whole bytes, false (bits) by default.
Returns
TypeNameDescription
integerremainingThe size of the data after the cursor.

#BinaryWriter:seek

sharedmenusource
function BinaryWriter:seek(position?: integer, as_bytes?: boolean): integer

Moves the cursor to the absolute position.

Positions after the end grow the data (zero-filled), negative positions count back from the end.

Parameters
NameTypeDescription
positionoptionalintegerThe new position, 0 by default.
as_bytesoptionalbooleantrue if position is in bytes, false (bits) by default.
Returns
TypeNameDescription
integerpositionThe new position in bits.

#BinaryWriter:size

sharedmenunodiscardsource
function BinaryWriter:size(as_bytes?: boolean): integer

Returns the size of the data.

Parameters
NameTypeDescription
as_bytesoptionalbooleantrue to return the size of the compiled string in bytes, false (bits) by default.
Returns
TypeNameDescription
integersizeThe size of the data.

#BinaryWriter:skip

sharedmenusource
function BinaryWriter:skip(length?: integer, as_bytes?: boolean): integer

Moves the cursor relative to its position, moving after the end grows the data (zero-filled).

lua
local length_position = writer:tell()
writer:skip( 4, true ) -- reserve 4 bytes for the length
writer:write( payload )

local end_position = writer:tell()
writer:seek( length_position )
writer:writeUInt( #payload, 32 )
writer:seek( end_position )
Parameters
NameTypeDescription
lengthoptionalintegerThe distance to move, negative to move back, 1 by default.
as_bytesoptionalbooleantrue if length is in bytes, false (bits) by default.
Returns
TypeNameDescription
integerpositionThe new position in bits.

#BinaryWriter:tell

sharedmenunodiscardsource
function BinaryWriter:tell(as_bytes?: boolean): integer

Returns the cursor position.

Parameters
NameTypeDescription
as_bytesoptionalbooleantrue to return the number of whole bytes before the cursor, false (bits) by default.
Returns
TypeNameDescription
integerpositionThe cursor position.

#BinaryWriter:write

sharedmenusource
function BinaryWriter:write(data: string): integer

Writes the string as is, the cursor doesn't have to be aligned.

Parameters
NameTypeDescription
datastringThe bytes.
Returns
TypeNameDescription
integerbyte_countThe number of bytes written.

#BinaryWriter:writeBit

sharedmenusource
function BinaryWriter:writeBit(value: 0 | 1 | boolean)

Writes one bit.

Parameters
NameTypeDescription
value0 | 1 | booleanThe bit.

#BinaryWriter:writeBoolean

sharedmenusource
function BinaryWriter:writeBoolean(value: boolean)

Writes one bit as a boolean, same as net.WriteBool.

Parameters
NameTypeDescription
valuebooleanThe boolean.

#BinaryWriter:writeBytes

sharedmenusource
function BinaryWriter:writeBytes(...: integer): integer

Writes bytes, the cursor doesn't have to be aligned.

Parameters
NameTypeDescription
...integerThe bytes (0 - 255).
Returns
TypeNameDescription
integerbyte_countThe number of bytes written.

#BinaryWriter:writeCountedString

sharedmenusource
function BinaryWriter:writeCountedString(data: string, bit_count: integer, is_little_endian?: boolean): integer

Writes the string prefixed with its length, read it back with BinaryReader:readCountedString.

Throws an error if the string is too long for the length size.

lua
writer:writeCountedString( "abc", 8 ) --> "\3abc"
Parameters
NameTypeDescription
datastringThe string.
bit_countintegerThe size of the length in bits (1 - 64).
is_little_endianoptionalbooleantrue to write the length as little endian, false by default.
Returns
TypeNameDescription
integerbyte_countThe size of the string in bytes.

#BinaryWriter:writeDate

sharedmenusource
function BinaryWriter:writeDate(day?: integer, month?: integer, year?: integer, is_little_endian?: boolean)

Writes date in DOS format (16 bits), see bytepack.writeDate.

DOS date layout
BitsFieldRange
15 - 9year - 19800 - 127 (1980 - 2107)
8 - 5month1 - 12
4 - 0day1 - 31
Parameters
NameTypeDescription
dayoptionalintegerThe day.
monthoptionalintegerThe month.
yearoptionalintegerThe year (1980 - 2107).
is_little_endianoptionalbooleantrue for little endian, false by default.

#BinaryWriter:writeDouble

sharedmenusource
function BinaryWriter:writeDouble(value: number, is_little_endian?: boolean)

Writes signed 8-byte (64 bit) float, the cursor doesn't have to be aligned.

IEEE 754 layout
BitsFieldNotes
63sign1 is negative
62 - 52exponent (11 bits)biased by 1023, 2047 is inf / nan
51 - 0mantissa (52 bits)~15-17 significant decimal digits

Range: 2.2250738585072014e-308 - 1.7976931348623157e308 (normal), Lua numbers are doubles, so nothing is lost.

Parameters
NameTypeDescription
valuenumberThe double.
is_little_endianoptionalbooleantrue for little endian (as net.WriteDouble), false by default.

#BinaryWriter:writeFixedPoint

sharedmenusource
function BinaryWriter:writeFixedPoint(value: number, m: integer, n: integer, is_little_endian?: boolean)

Writes signed fixed-point number (Qm.n), rounded to the nearest step.

Unlike bytepack.writeFixedPoint, m + n doesn't have to be a whole number of bytes.

Commonly Used Qm.n Formats (signed)
FormatRangePrecision (Step)
Q8.8-128.0 - 127.9960.00390625 (1/256)
Q10.6-512.0 - 511.9843750.015625 (1/64)
Q12.4-2048.0 - 2047.93750.0625 (1/16)
Q16.16-32768.0 - 32767.999980.0000152588 (1/65536)
Q24.8-8388608.0 - 8388607.9960.00390625 (1/256)
Q32.16-2147483648.0 - 2147483647.999980.0000152588 (1/65536)

m + n is the size of the field in bits (1 - 64), so the range is limited to 53 bits.

Parameters
NameTypeDescription
valuenumberThe signed fixed-point number.
mintegerThe number of integer bits, including the sign bit.
nintegerThe number of fractional bits.
is_little_endianoptionalbooleantrue for little endian, false by default.

#BinaryWriter:writeFixedString

sharedmenusource
function BinaryWriter:writeFixedString(data: string, byte_count: integer)

Writes the string of a fixed size, shorter data is padded with \0 and longer data is cut, same as pack.writeFixedString.

Parameters
NameTypeDescription
datastringThe string.
byte_countintegerThe size of the string in bytes.

#BinaryWriter:writeFloat

sharedmenusource
function BinaryWriter:writeFloat(value: number, is_little_endian?: boolean)

Writes signed 4-byte (32 bit) float, the cursor doesn't have to be aligned.

IEEE 754 layout
BitsFieldNotes
31sign1 is negative
30 - 23exponent (8 bits)biased by 127, 255 is inf / nan
22 - 0mantissa (23 bits)~6-9 significant decimal digits

Range: 1.1754944e-38 - 3.4028235e38 (normal), integers are exact up to 16777216.

Parameters
NameTypeDescription
valuenumberThe float, precision is reduced to float.
is_little_endianoptionalbooleantrue for little endian (as net.WriteFloat), false by default.

#BinaryWriter:writeInt

sharedmenusource
function BinaryWriter:writeInt(value: integer, bit_count: integer, is_little_endian?: boolean)

Writes signed (two's complement) integer of any size, read it back with BinaryReader:readInt.

Signed Integers limits for bit count
Bit countMin Value (-2^(n-1))Max Value (2^(n-1) - 1)
1-10
2-21
3-43
4-87
5-1615
6-3231
7-6463
8-128127
9-256255
10-512511
11-1,0241,023
12-2,0482,047
13-4,0964,095
14-8,1928,191
15-16,38416,383
16-32,76832,767
17-65,53665,535
18-131,072131,071
19-262,144262,143
20-524,288524,287
21-1,048,5761,048,575
22-2,097,1522,097,151
23-4,194,3044,194,303
24-8,388,6088,388,607
25-16,777,21616,777,215
26-33,554,43233,554,431
27-67,108,86467,108,863
28-134,217,728134,217,727
29-268,435,456268,435,455
30-536,870,912536,870,911
31-1,073,741,8241,073,741,823
32-2,147,483,6482,147,483,647
40-549,755,813,888549,755,813,887
48-140,737,488,355,328140,737,488,355,327
64-9,223,372,036,854,775,8089,223,372,036,854,775,807

Valid values without loss of precision: -9007199254740991 - 9007199254740991 (53 bits), all values above will have problems when working with them.

Parameters
NameTypeDescription
valueintegerThe signed integer, only the lowest bit_count bits are written.
bit_countintegerThe size of the integer in bits (1 - 64), 0 writes nothing.
is_little_endianoptionalbooleantrue for little endian, false by default.

#BinaryWriter:writeLine

sharedmenusource
function BinaryWriter:writeLine(data: string)

Writes the line, the string followed by \n.

Throws an error if the string contains \n.

Parameters
NameTypeDescription
datastringThe line.

#BinaryWriter:writeObject

sharedmenusource
function BinaryWriter:writeObject(obj: Object, ...: any)

Writes the object with its __serialize( writer, ... ) method, read it back with BinaryReader:readObject or BinaryReader:readClass.

Parameters
NameTypeDescription
objObjectThe object.
...anyThe arguments passed to __serialize.

#BinaryWriter:writeString

sharedmenusource
function BinaryWriter:writeString(data: string)

Writes C-style string, the string followed by the null terminator (\0), same as net.WriteString.

Throws an error if the string contains \0.

Parameters
NameTypeDescription
datastringThe string.

#BinaryWriter:writeTerminatedString

sharedmenusource
function BinaryWriter:writeTerminatedString(data: string, terminator: integer)

Writes the string followed by the terminator byte, read it back with BinaryReader:readTerminatedString.

Throws an error if the string contains the terminator.

Parameters
NameTypeDescription
datastringThe string.
terminatorintegerThe terminator byte (0 - 255).

#BinaryWriter:writeTime

sharedmenusource
function BinaryWriter:writeTime(hours?: integer, minutes?: integer, seconds?: integer, is_little_endian?: boolean)

Writes time in DOS format (16 bits), see bytepack.writeTime.

DOS time layout
BitsFieldRange
15 - 11hours0 - 23
10 - 5minutes0 - 59
4 - 0seconds / 20 - 29 (0 - 58 seconds)
Parameters
NameTypeDescription
hoursoptionalintegerThe number of hours.
minutesoptionalintegerThe number of minutes.
secondsoptionalintegerThe number of seconds, rounded down to even.
is_little_endianoptionalbooleantrue for little endian, false by default.

#BinaryWriter:writeUInt

sharedmenusource
function BinaryWriter:writeUInt(value: integer, bit_count: integer, is_little_endian?: boolean)

Writes unsigned integer of any size, read it back with BinaryReader:readUInt.

Unsigned Integers limits for bit count
Bit countMax Value (2^n - 1)
11
23
37
415
531
663
7127
8255
9511
101,023
112,047
124,095
138,191
1416,383
1532,767
1665,535
17131,071
18262,143
19524,287
201,048,575
212,097,151
224,194,303
238,388,607
2416,777,215
2533,554,431
2667,108,863
27134,217,727
28268,435,455
29536,870,911
301,073,741,823
312,147,483,647
324,294,967,295
401,099,511,627,775
48281,474,976,710,655
6418,446,744,073,709,551,615

Valid values without loss of precision: 0 - 9007199254740991 (53 bits), all values above will have problems when working with them.

lua
writer:writeUInt( 0xFF, 8 ) -- byte
writer:writeUInt( 300, 32, true ) -- same as `net.WriteUInt( 300, 32 )`
Parameters
NameTypeDescription
valueintegerThe unsigned integer, only the lowest bit_count bits are written.
bit_countintegerThe size of the integer in bits (1 - 64), 0 writes nothing.
is_little_endianoptionalbooleantrue for little endian, false by default.

#BinaryWriter:writeUnsignedFixedPoint

sharedmenusource
function BinaryWriter:writeUnsignedFixedPoint(value: number, m: integer, n: integer, is_little_endian?: boolean)

Writes unsigned fixed-point number (UQm.n), rounded to the nearest step.

Unlike bytepack.writeFixedPoint, m + n doesn't have to be a whole number of bytes.

Commonly Used UQm.n Formats (unsigned)
FormatRangePrecision (Step)
UQ8.80 - 255.9960.00390625 (1/256)
UQ10.60 - 1023.9843750.015625 (1/64)
UQ12.40 - 4095.93750.0625 (1/16)
UQ16.160 - 65535.999980.0000152588 (1/65536)
UQ24.80 - 16777215.9960.00390625 (1/256)
UQ32.160 - 4294967295.999980.0000152588 (1/65536)

m + n is the size of the field in bits (1 - 64), so the range is limited to 53 bits.

Parameters
NameTypeDescription
valuenumberThe unsigned fixed-point number.
mintegerThe number of integer bits.
nintegerThe number of fractional bits.
is_little_endianoptionalbooleantrue for little endian, false by default.
Generated from the dreamwork meta branch.