| 'use strict'; | 
|   | 
| var Buffer = require('safe-buffer').Buffer; | 
|   | 
| var StreamReader = function() { | 
|   this._queue     = []; | 
|   this._queueSize = 0; | 
|   this._offset    = 0; | 
| }; | 
|   | 
| StreamReader.prototype.put = function(buffer) { | 
|   if (!buffer || buffer.length === 0) return; | 
|   if (!Buffer.isBuffer(buffer)) buffer = Buffer.from(buffer); | 
|   this._queue.push(buffer); | 
|   this._queueSize += buffer.length; | 
| }; | 
|   | 
| StreamReader.prototype.read = function(length) { | 
|   if (length > this._queueSize) return null; | 
|   if (length === 0) return Buffer.alloc(0); | 
|   | 
|   this._queueSize -= length; | 
|   | 
|   var queue  = this._queue, | 
|       remain = length, | 
|       first  = queue[0], | 
|       buffers, buffer; | 
|   | 
|   if (first.length >= length) { | 
|     if (first.length === length) { | 
|       return queue.shift(); | 
|     } else { | 
|       buffer = first.slice(0, length); | 
|       queue[0] = first.slice(length); | 
|       return buffer; | 
|     } | 
|   } | 
|   | 
|   for (var i = 0, n = queue.length; i < n; i++) { | 
|     if (remain < queue[i].length) break; | 
|     remain -= queue[i].length; | 
|   } | 
|   buffers = queue.splice(0, i); | 
|   | 
|   if (remain > 0 && queue.length > 0) { | 
|     buffers.push(queue[0].slice(0, remain)); | 
|     queue[0] = queue[0].slice(remain); | 
|   } | 
|   return Buffer.concat(buffers, length); | 
| }; | 
|   | 
| StreamReader.prototype.eachByte = function(callback, context) { | 
|   var buffer, n, index; | 
|   | 
|   while (this._queue.length > 0) { | 
|     buffer = this._queue[0]; | 
|     n = buffer.length; | 
|   | 
|     while (this._offset < n) { | 
|       index = this._offset; | 
|       this._offset += 1; | 
|       callback.call(context, buffer[index]); | 
|     } | 
|     this._offset = 0; | 
|     this._queue.shift(); | 
|   } | 
| }; | 
|   | 
| module.exports = StreamReader; |