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 (spec encoding, mirroring BlockParser#read_vint)

Parameters:

  • io (IO)

    Input stream

Returns:

  • (Integer)

    Decoded value



36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/omnizip/formats/rar/rar5/vint.rb', line 36

def self.decode(io)
  result = 0
  shift = 0
  loop do
    byte = io.readbyte
    result |= (byte & 0x7F) << shift
    break if byte.nobits?(0x80)

    shift += 7
  end

  result
end

.encode(value) ⇒ Array<Integer>

Encode integer as VINT bytes per the RAR 5.0 spec: one or more bytes, each carrying 7 data bits starting with the least significant group; the high bit of every byte but the last is the continuation flag.

Parameters:

  • value (Integer)

    Value to encode (0 to 2^63)

Returns:

  • (Array<Integer>)

    VINT bytes

Raises:

  • (ArgumentError)


16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/omnizip/formats/rar/rar5/vint.rb', line 16

def self.encode(value)
  raise ArgumentError, "VINT cannot encode negative values" if value.negative?

  bytes = []
  loop do
    byte = value & 0x7F
    value >>= 7
    byte |= 0x80 if value.positive?
    bytes << byte
    break if value.zero?
  end

  bytes
end