Module: Melos::Vec

Extended by:
Vec
Included in:
Vec
Defined in:
lib/melos/vec.rb

Instance Method Summary collapse

Instance Method Details

#from_string(str) ⇒ Object

to_vec



39
40
41
# File 'lib/melos/vec.rb', line 39

def from_string(str) # = to_vec
  write_varint(str.bytesize) + str
end

#parse_stringio(vec_as_stringio) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/melos/vec.rb', line 63

def parse_stringio(vec_as_stringio)
  prefix = prefix_from_stringio(vec_as_stringio)
  length = length_from_stringio(vec_as_stringio)
  case prefix
  when 0..2
    vec_as_stringio.pos = (vec_as_stringio.pos + (2 ** prefix))
    str = vec_as_stringio.read(length)
  else
    raise ArgumentError.new('invalid header')
  end

  str
end

#parse_vec(vec_as_string) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/melos/vec.rb', line 43

def parse_vec(vec_as_string)
  prefix = vec_as_string[0].ord >> 6
  length = read_varint(vec_as_string)
  case prefix
  when 0
    str = vec_as_string.byteslice(1, length)
    rest = vec_as_string.byteslice((1 + length)..)
  when 1
    str = vec_as_string.byteslice(2, length)
    rest = vec_as_string.byteslice((2 + length)..)
  when 2
    str = vec_as_string[4, length]
    rest = vec_as_string[(4 + length)..]
  else
    raise ArgumentError.new('invalid header')
  end

  [str, rest]
end

#read_varint(data) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/melos/vec.rb', line 4

def read_varint(data)
  byte = 0
  v = data[byte].ord
  prefix = v >> 6
  length = 1 << prefix

  v = v & 0x3f
  (length - 1).times do
    byte += 1
    v = (v << 8) + data[byte].ord
  end

  return v
end

#write_varint(len) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/melos/vec.rb', line 19

def write_varint(len)
  header = []
  case len
  when 0..63
    header[0] = len
  when 64..16383
    header[0] = (1 << 6) | ((len & 0x3f00) >> 8)
    header[1] = len & 0x00ff
  when 16384..1073741823
    header[0] = (2 << 6) | ((len & 0x3f000000) >> 24)
    header[1] = ((len & 0x00ff0000) >> 16)
    header[2] = ((len & 0x0000ff00) >> 8)
    header[3] = len & 0x000000ff
  else
    raise ArgumentError.new('too long to be encoded in variable length vector')
  end

  header.pack('C*')
end