Skip to content

Instantly share code, notes, and snippets.

@jozip
Created February 20, 2011 00:03
Show Gist options
  • Save jozip/835529 to your computer and use it in GitHub Desktop.
Save jozip/835529 to your computer and use it in GitHub Desktop.
A simple byte buffer
# byte_buffer.rb -- A simple byte buffer
#
# A sad story by Johan Persson <johan.z.persson@gmail.com>
#
# This hack makes it easy to read, write, manipulate and interpret
# sequences of bytes. It's heavily modelled on the way Jinterface
# (of Erlang) codes and decodes data, so it might be a bit inelegant.
#
# The code should be kind of self-explanatory.
# Yes, I know, but map_with_index is just so damn useful here!
class Array
def map_with_index
i = 0
map do |x|
t = yield x, i
i += 1
t
end
end
end
class ByteBuffer
def initialize
@buf = []
rewind()
end
def rewind
@pos = 0
end
def <<(io)
@buf = io.bytes.to_a
end
def >>(io)
io.write(@buf.pack("C#{@buf.length}"))
end
def write(num, bytes = 4, endian = :big)
@buf += byteify(num, bytes, endian)
self
end
def poke(offset, num, bytes = 4, endian = :big)
if offset < size()
b = byteify(num, bytes, endian)
@buf = @buf[0, offset] + b + @buf[offset + b.length, @buf.length]
end
self
end
def read(bytes = 4, endian = :big)
n = peek(@pos, bytes, endian)
@pos += bytes
n
end
def peek(offset, bytes = 4, endian = :big)
b = @buf[offset, bytes]
((endian == :little) ? b.reverse : b).map_with_index { |n,i|
(n << 8*i) & (0xFF << i*8)
}.reduce(0) { |sum, n| sum += n }
end
def size
@buf.length
end
protected
def byteify(num, bytes, endian)
b = Array.new(bytes, 0).map_with_index { |_, n| (num & (0xFF << n*8)) >> n*8 }
(endian == :little) ? b : b.reverse
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment