Class: Kiwi::ByteBuffer

Inherits:
Object
  • Object
show all
Defined in:
lib/kiwi/byte_buffer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data = []) ⇒ ByteBuffer

Returns a new instance of ByteBuffer.



10
11
12
13
# File 'lib/kiwi/byte_buffer.rb', line 10

def initialize(data = [])
  @data = data
  @index = 0
end

Instance Attribute Details

#dataObject (readonly) Also known as: bytes

Returns the value of attribute data.



5
6
7
# File 'lib/kiwi/byte_buffer.rb', line 5

def data
  @data
end

#indexObject (readonly)

Returns the value of attribute index.



6
7
8
# File 'lib/kiwi/byte_buffer.rb', line 6

def index
  @index
end

Instance Method Details

#read_boolObject



39
40
41
# File 'lib/kiwi/byte_buffer.rb', line 39

def read_bool
  read_byte == 0x1
end

#read_byteObject



15
16
17
18
19
20
21
22
23
# File 'lib/kiwi/byte_buffer.rb', line 15

def read_byte
  if index >= data.length
    raise RangeError, "Index out of bounds"
  else
    value = data[index]
    @index += 1
    value
  end
end

#read_byte_arrayObject



25
26
27
# File 'lib/kiwi/byte_buffer.rb', line 25

def read_byte_array
  read_bytes(read_var_uint)
end

#read_bytes(len) ⇒ Object



29
30
31
32
33
34
35
36
37
# File 'lib/kiwi/byte_buffer.rb', line 29

def read_bytes(len)
  if index + len > data.length
    raise RangeError, "Read bytes out of bounds"
  else
    value = data[index..(index + len)]
    @index += len
    value
  end
end

#read_stringObject



79
80
81
82
83
84
85
86
87
88
89
# File 'lib/kiwi/byte_buffer.rb', line 79

def read_string
  result = []

  loop do
    char = read_byte
    break if char == 0
    result << char
  end

  result.pack("C*").force_encoding("UTF-8")
end

#read_var_floatObject

Raises:

  • (RangeError)


68
69
70
71
72
73
74
75
76
77
# File 'lib/kiwi/byte_buffer.rb', line 68

def read_var_float
  first = read_byte
  return 0.0 if first == 0
  raise RangeError, "Index out of bounds" if index + 3 > data.length
  bits = first | (data[index] << 8) | (data[index + 1] << 16) | (data[index + 2] << 24)
  bits = (bits << 23) | (bits >> 9) # Move the exponent back into place
  value = [bits].pack("L").unpack("F*")[0]
  @index += 3
  value
end

#read_var_intObject



43
44
45
46
47
48
49
50
51
# File 'lib/kiwi/byte_buffer.rb', line 43

def read_var_int
  value = read_var_uint

  if (value & 1) != 0
    ~(value >> 1)
  else
    value >> 1
  end
end

#read_var_uintObject



53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/kiwi/byte_buffer.rb', line 53

def read_var_uint
  shift = 0
  result = 0

  loop do
    byte = read_byte
    result |= (byte & 127) << shift
    shift += 7

    break if (byte & 128) == 0 || shift >= 35
  end

  result
end

#write_bool(value) ⇒ Object



91
92
93
# File 'lib/kiwi/byte_buffer.rb', line 91

def write_bool(value)
  data.push(value ? 0x1 : 0x0)
end

#write_byte(value) ⇒ Object



95
96
97
# File 'lib/kiwi/byte_buffer.rb', line 95

def write_byte(value)
  data.push(value & 255)
end

#write_byte_array(value) ⇒ Object



99
100
101
102
# File 'lib/kiwi/byte_buffer.rb', line 99

def write_byte_array(value)
  write_var_uint(value.length)
  data.push(*value)
end

#write_string(value) ⇒ Object



135
136
137
138
# File 'lib/kiwi/byte_buffer.rb', line 135

def write_string(value)
  data.push(*value.bytes)
  data.push(0)
end

#write_var_float(value) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
# File 'lib/kiwi/byte_buffer.rb', line 123

def write_var_float(value)
  bits = [value].pack("F*").unpack("L")[0]
  bits = (bits >> 23) | (bits << 9)
  bytes = [bits].pack("L").unpack("C*")

  if (bytes[0] & 255) == 0
    data.push(0)
  else
    data.push(*bytes)
  end
end

#write_var_int(value) ⇒ Object

Write a variable-length signed 32-bit integer to the end of the buffer.



105
106
107
# File 'lib/kiwi/byte_buffer.rb', line 105

def write_var_int(value)
  write_var_uint((value << 1) ^ (value >> 31))
end

#write_var_uint(value) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/kiwi/byte_buffer.rb', line 109

def write_var_uint(value)
  loop do
    byte = value & 127
    value = value >> 7

    if value == 0
      write_byte(byte)
      return
    end

    write_byte(byte | 128)
  end
end