index.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. var assert = require('assert')
  2. var Reader = module.exports = function(options) {
  3. //TODO - remove for version 1.0
  4. if(typeof options == 'number') {
  5. options = { headerSize: options }
  6. }
  7. options = options || {}
  8. this.offset = 0
  9. this.lastChunk = false
  10. this.chunk = null
  11. this.chunkLength = 0
  12. this.headerSize = options.headerSize || 0
  13. this.lengthPadding = options.lengthPadding || 0
  14. this.header = null
  15. assert(this.headerSize < 2, 'pre-length header of more than 1 byte length not currently supported')
  16. }
  17. Reader.prototype.addChunk = function(chunk) {
  18. if (!this.chunk || this.offset === this.chunkLength) {
  19. this.chunk = chunk
  20. this.chunkLength = chunk.length
  21. this.offset = 0
  22. return
  23. }
  24. var newChunkLength = chunk.length
  25. var newLength = this.chunkLength + newChunkLength
  26. if (newLength > this.chunk.length) {
  27. var newBufferLength = this.chunk.length * 2
  28. while (newLength >= newBufferLength) {
  29. newBufferLength *= 2
  30. }
  31. var newBuffer = Buffer.alloc(newBufferLength)
  32. this.chunk.copy(newBuffer)
  33. this.chunk = newBuffer
  34. }
  35. chunk.copy(this.chunk, this.chunkLength)
  36. this.chunkLength = newLength
  37. }
  38. Reader.prototype.read = function() {
  39. if(this.chunkLength < (this.headerSize + 4 + this.offset)) {
  40. return false
  41. }
  42. if(this.headerSize) {
  43. this.header = this.chunk[this.offset]
  44. }
  45. //read length of next item
  46. var length = this.chunk.readUInt32BE(this.offset + this.headerSize) + this.lengthPadding
  47. //next item spans more chunks than we have
  48. var remaining = this.chunkLength - (this.offset + 4 + this.headerSize)
  49. if(length > remaining) {
  50. return false
  51. }
  52. this.offset += (this.headerSize + 4)
  53. var result = this.chunk.slice(this.offset, this.offset + length)
  54. this.offset += length
  55. return result
  56. }