All files / js.socket/src/payload-stack index.js

100% Statements 15/15
100% Branches 2/2
100% Functions 3/3
100% Lines 15/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59  1x 1x                                 11x 11x                     8x 8x   8x 1x     7x 7x 7x   7x   7x                 7x       1x  
const
PAYLOAD_HEADER_SIZE     = require('../payload').HEADER_SIZE,
IncompleteMessageError  = require('./error/incomplete-message')
 
/**
 * Stacking payloads in a buffer. When you recieve a message through the
 * network, it's added to the stack. As mesages can come in partial chunks,
 * they need to be buffered until we have recieved the complete message.
 * Messages can also be recieved in a batch of multiple messages, requiring an
 * instance to segregate the message stack.
 */
class PayloadStack
{
  /**
   * @param {Buffer} buffer initial buffer
   * @param {PayloadFactory} payloadFactory
   */
  constructor(buffer, payloadFactory)
  {
    this.stack          = buffer
    this.payloadFactory = payloadFactory
  }
 
  /**
   * Attempts to cut out the first message of the stack
   * @throws ERR_OUT_OF_RANGE
   * @throws ERR_INCOMPLETE_MESSAGE
   */
  shift()
  {
    const
    dtoSize     = this.stack.readInt32BE(0),
    payloadSize = dtoSize + PAYLOAD_HEADER_SIZE
 
    if(this.stack.length < payloadSize)
      throw new IncompleteMessageError
 
    const
    buffer  = this.stack.slice(PAYLOAD_HEADER_SIZE, payloadSize),
    dto     = JSON.parse(buffer.toString()),
    payload = this.payloadFactory.create(dto.event, dto.data)
 
    this.stack = this.stack.slice(payloadSize)
 
    return payload
  }
 
  /**
   * Adds a buffer to the stack
   * @param {...Buffer} buffer buffers to add to the stack
   */
  push(...buffer)
  {
    this.stack = Buffer.concat([this.stack, ...buffer])
  }
}
 
module.exports = PayloadStack