Module: Omnizip::Formats::Rar::Rar5::VINT

Defined in:
lib/omnizip/formats/rar/rar5/vint.rb

Overview

Variable-length integer encoding/decoding for RAR5 format

Class Method Summary collapse

Class Method Details

.decode(io) ⇒ Integer

Decode VINT from IO stream

Parameters:

  • io (IO)

    Input stream

Returns:

  • (Integer)

    Decoded value



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/omnizip/formats/rar/rar5/vint.rb', line 39

def self.decode(io)
  first_byte = io.readbyte
  return first_byte if first_byte < 0x80

  # Count continuation bits
  byte_count = 0
  mask = 0x80
  while first_byte.anybits?(mask)
    byte_count += 1
    mask >>= 1
  end

  # Extract value from first byte
  value = first_byte & (0xFF >> (byte_count + 1))

  # Read remaining bytes
  byte_count.times do
    value = (value << 8) | io.readbyte
  end

  value
end

.encode(value) ⇒ Array<Integer>

Encode integer as VINT bytes

Parameters:

  • value (Integer)

    Value to encode (0 to 2^62)

Returns:

  • (Array<Integer>)

    VINT bytes



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/omnizip/formats/rar/rar5/vint.rb', line 12

def self.encode(value)
  return [value] if value < 0x80

  bytes = []
  # Determine byte count needed
  byte_count = 1
  test_value = value
  while test_value >= (1 << (7 * byte_count))
    byte_count += 1
  end

  # First byte: continuation bits + high bits
  first_byte = (0xFF << (9 - byte_count)) & 0xFF
  first_byte |= (value >> (8 * (byte_count - 1))) & 0x7F
  bytes << first_byte

  # Remaining bytes
  (byte_count - 1).downto(1) do |i|
    bytes << ((value >> (8 * (i - 1))) & 0xFF)
  end

  bytes
end