Files

67 lines
1.4 KiB
Ruby

module WebSocket
class Driver
class StreamReader
MAX_CAPACITY = 0xfffffff
def initialize
@queue = []
@capacity = 0
@cursor = 0
end
def push(chunk)
if chunk.bytesize > MAX_CAPACITY - @capacity
return false
end
@queue << chunk.force_encoding(BINARY)
@capacity += chunk.bytesize
true
end
def read(length)
return nil if @capacity < length
target = ("\0" * length).force_encoding(BINARY)
offset = 0
while offset < length
chunk = @queue.first
available = chunk.bytesize - @cursor
required = length - offset
take_bytes = (available < required) ? available : required
target[offset ... offset + take_bytes] = chunk[@cursor ... @cursor + take_bytes]
offset += take_bytes
@capacity -= take_bytes
if take_bytes == available
@cursor = 0
@queue.shift
else
@cursor += take_bytes
end
end
target
end
def each_byte
until @queue.empty?
chunk = @queue.first
(@cursor ... chunk.bytesize).each do |i|
@cursor += 1
yield chunk.getbyte(i)
end
@cursor = 0
@queue.shift
end
end
end
end
end