Class: VCDIFF::VCDIFFInt
- Inherits:
-
BinData::BasePrimitive
- Object
- BinData::BasePrimitive
- VCDIFF::VCDIFFInt
- Defined in:
- lib/vcdiff/integer.rb
Overview
As described in RFC 3284 (tools.ietf.org/html/rfc3284) unsigned integers are treated as a number in base 128. Each digit in this representation is encoded in the lower 7 bits of a byte. Runs of bytes b_1, b_2, b_3, …, b_n for one integer have the most significant bit set to 1 for each b_i, i = 1, …, n-1, and set to 0 for b_n.
So 123456789 encodes to four 7-bit digits with values 58, 111, 26, 21:
+-------------------------------------------+
| 10111010 | 11101111 | 10011010 | 00010101 |
+-------------------------------------------+
MSB+58 MSB+111 MSB+26 0+21
Instance Method Summary collapse
- #read_and_return_value(io) ⇒ Object
- #sensible_default ⇒ Object
-
#to_i ⇒ Object
Gives the VCDIFF integer as a regular Ruby Integer.
- #value_to_binary_string(value) ⇒ Object
-
#value_to_zero_one_string ⇒ Object
Converts a Ruby Integer into a string where each character is either 0 or 1, fully representing the bytes in the array.
Instance Method Details
#read_and_return_value(io) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/vcdiff/integer.rb', line 40 def read_and_return_value(io) byte_values = [] value = 0 loop do b = next_byte(io) last_byte = (b[7] == 0) byte_values << (b & 0b01111111) break if last_byte end byte_values.reverse.each_with_index do |e, i| # add byte * 128**i, since e is considered to be # a number in base 128 value += e * (1 << (7 * i)) end value end |
#sensible_default ⇒ Object
62 63 64 |
# File 'lib/vcdiff/integer.rb', line 62 def sensible_default 0 end |
#to_i ⇒ Object
Gives the VCDIFF integer as a regular Ruby Integer
75 76 77 |
# File 'lib/vcdiff/integer.rb', line 75 def to_i snapshot end |
#value_to_binary_string(value) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/vcdiff/integer.rb', line 20 def value_to_binary_string(value) bytes = [] loop do # get the value of the lowest 7 bits next_value = value & 0b01111111 value >>= 7 # on every byte except the first one, flip the 8th bit on next_value = 0b10000000 | next_value unless bytes.empty? bytes.unshift(next_value) break if value == 0 end bytes.pack("C*") end |
#value_to_zero_one_string ⇒ Object
Converts a Ruby Integer into a string where each character is either 0 or 1, fully representing the bytes in the array.
TODO: a non-awful method name and non-awful implementation
70 71 72 |
# File 'lib/vcdiff/integer.rb', line 70 def value_to_zero_one_string to_binary_s.unpack("C*").map { |e| e.to_s(2).rjust(8, "0") }.join("") end |