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