Created
February 20, 2011 00:03
-
-
Save jozip/835529 to your computer and use it in GitHub Desktop.
A simple byte buffer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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