Source: util/buffer.js

/**
 * Creates an instance of MessageBuffer.<br/>
 *
 * The buffer accumulates received data and returns true or false for when a delimiter has been recieved.<br/>
 *
 * If a delimiter is recieved into the buffer, the message up to that point can be
 * removed from the buffer and returned.
 *
 * @example
 * // We can receive whole messages or parital, so we need to buffer
 *
 * {"jsonrpc": 2.0, "params": ["hello"], id: 1}\n // whole message
 * // or
 * {"jsonrpc": 2.0, "params" // partial message
 */
class MessageBuffer {
  /**
   * @param {string} delimiter The delimiter to use to determine if a message is complete
   * @example
   *    const messageBuffer = new MessageBuffer('\n')
   */
  constructor(delimiter) {
    this.delimiter = delimiter;
    this.buffer = "";
  }

  /**
   * Used to determine if the buffer is empty. Buffer is considered
   * empty if its an empty string or contains no delimiter
   *
   * @returns {boolean}
   * @example
   * while(!messageBuffer.isFinished()){
   *    // get current data and verify
   * }
   */
  isFinished() {
    if (
      this.buffer.length === 0
      || this.buffer.indexOf(this.delimiter) === -1
    ) {
      return true;
    }
    return false;
  }

  /**
   * Accumulate the buffer with messages.
   *
   * If the server isnt sending delimiters for some reason
   * then nothing will ever come back for these requests.
   *
   * @param {string} data Data to push into buffer
   * @example
   *    messageBuffer.push("hello\n")
   */
  push(data) {
    this.buffer += data;
  }

  /**
   * Return the message from the buffer if delimiter is found, and null otherwise.
   *
   * The message is everything before the delimiter.
   *
   * Replace message string in buffer with empty string.
   *
   * @returns {string|null} message
   * @example
   * const message = messageBuffer.getMessage()
   * console.log(message) // "hello"
   *
   */
  getMessage() {
    const delimiterIndex = this.buffer.indexOf(this.delimiter);
    if (delimiterIndex !== -1) {
      const message = this.buffer.slice(0, delimiterIndex);
      this.buffer = this.buffer.replace(message + this.delimiter, "");
      return message;
    }
    return null;
  }

  /**
   *
   * Returns the contents of `this.buffer`.
   *
   * Particularily useful for http buffering, where delimiters might not be used.
   *
   * @returns {string} message
   */
  emptyBuffer() {
    const data = this.buffer;
    this.buffer = "";
    return data;
  }

  /**
   * @returns {function} MessageBuffer.getMessage()
   */
  handleData() {
    return this.getMessage();
  }
}

module.exports = MessageBuffer;