Class: Optimize::Codec::BinaryWriter
- Inherits:
-
Object
- Object
- Optimize::Codec::BinaryWriter
- Defined in:
- lib/optimize/codec/binary_writer.rb
Instance Method Summary collapse
-
#align_to(alignment) ⇒ Object
Pad with zero bytes until pos is aligned to
alignmentbytes. - #buffer ⇒ Object
-
#initialize ⇒ BinaryWriter
constructor
A new instance of BinaryWriter.
- #pos ⇒ Object
- #write_bytes(bytes) ⇒ Object
- #write_cstr(s) ⇒ Object
-
#write_small_value(value) ⇒ Object
Encode a small_value (variable-length unsigned integer).
- #write_u16(v) ⇒ Object
- #write_u32(v) ⇒ Object
- #write_u64(v) ⇒ Object
- #write_u8(v) ⇒ Object
Constructor Details
#initialize ⇒ BinaryWriter
Returns a new instance of BinaryWriter.
6 7 8 |
# File 'lib/optimize/codec/binary_writer.rb', line 6 def initialize @buffer = String.new(encoding: Encoding::ASCII_8BIT) end |
Instance Method Details
#align_to(alignment) ⇒ Object
Pad with zero bytes until pos is aligned to alignment bytes.
23 24 25 26 |
# File 'lib/optimize/codec/binary_writer.rb', line 23 def align_to(alignment) remainder = @buffer.bytesize % alignment write_bytes("\x00" * (alignment - remainder)) if remainder != 0 end |
#buffer ⇒ Object
10 |
# File 'lib/optimize/codec/binary_writer.rb', line 10 def buffer = @buffer |
#pos ⇒ Object
20 |
# File 'lib/optimize/codec/binary_writer.rb', line 20 def pos = @buffer.bytesize |
#write_bytes(bytes) ⇒ Object
17 |
# File 'lib/optimize/codec/binary_writer.rb', line 17 def write_bytes(bytes) = @buffer << bytes.b |
#write_cstr(s) ⇒ Object
18 |
# File 'lib/optimize/codec/binary_writer.rb', line 18 def write_cstr(s) = @buffer << s.b << "\x00".b |
#write_small_value(value) ⇒ Object
Encode a small_value (variable-length unsigned integer). See research/cruby/ibf-format.md §6 for the encoding.
Layout: the first byte carries a unary marker in its trailing bits:
XXXXXXX1 → 1 byte, value ≤ 0x7f
XXXXXX10 → 2 bytes, value ≤ 0x3fff
XXXXX100 → 3 bytes, value ≤ 0x1fffff
XXXX1000 → 4 bytes, value ≤ 0x0fffffff
00000000 → 9 bytes, full uint64
The value bits after the marker are stored big-endian across subsequent bytes.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/optimize/codec/binary_writer.rb', line 38 def write_small_value(value) raise ArgumentError, "small_value must be non-negative, got #{value}" if value.negative? if value <= 0x7f @buffer << [((value << 1) | 1)].pack("C") elsif value <= 0x3fff b1 = value & 0xff b0 = ((value >> 8) << 2) | 2 @buffer << [b0, b1].pack("CC") elsif value <= 0x1f_ffff b2 = value & 0xff b1 = (value >> 8) & 0xff b0 = ((value >> 16) << 3) | 4 @buffer << [b0, b1, b2].pack("CCC") elsif value <= 0x0fff_ffff b3 = value & 0xff b2 = (value >> 8) & 0xff b1 = (value >> 16) & 0xff b0 = ((value >> 24) << 4) | 8 @buffer << [b0, b1, b2, b3].pack("CCCC") else # 9-byte form for large values: full uint64 big-endian # (ibf_dump_small_value uses the same big-endian shift algorithm as the # general case: "value = (value << 8) | byte[i]" for i in [1..8)). @buffer << "\x00".b << [value].pack("Q>") end end |
#write_u16(v) ⇒ Object
13 |
# File 'lib/optimize/codec/binary_writer.rb', line 13 def write_u16(v) = write_int(v, "v") |
#write_u32(v) ⇒ Object
14 |
# File 'lib/optimize/codec/binary_writer.rb', line 14 def write_u32(v) = write_int(v, "V") |
#write_u64(v) ⇒ Object
15 |
# File 'lib/optimize/codec/binary_writer.rb', line 15 def write_u64(v) = write_int(v, "Q<") |
#write_u8(v) ⇒ Object
12 |
# File 'lib/optimize/codec/binary_writer.rb', line 12 def write_u8(v) = write_int(v, "C") |