# all files / lib/spdy-transport/protocol/base/ parser.js

100% Statements 59/59
100% Branches 18/18
100% Functions 8/8
100% Lines 58/58

    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107

    1×

    1×
    1×
    1×
    1×

    1×
    642×

    642×
    642×
    642×

    642×

    642×
    642×
    642×

    1×
    1×

    1×

    1×
    32×

    1×
    6361×

    6361×

    1×
    17289×

    1×
    10956×
    28×

    10928×
    33×
    66×

    10895×
    5291×

    10928×
    470×

    10458×
    10458×

    17289×
    31×

    17258×

    6306×
    5999×

    307×
    4×
    4×
    4×

    4×
    4×

    303×

    10952×

    10952×
    10952×

    10952×
    10925×

    1×
    728×
    728×

    1×
    642×

     'use strict'

    var transport = require('../../../spdy-transport')

    var util = require('util')
    var utils = require('./').utils
    var OffsetBuffer = require('obuf')
    var Transform = require('readable-stream').Transform

    function Parser (options) {
      Transform.call(this, {
        readableObjectMode: true
      })

      this.buffer = new OffsetBuffer()
      this.partial = false
      this.waiting = 0

      this.window = options.window

      this.version = null
      this.decompress = null
      this.dead = false
    }
    module.exports = Parser
    util.inherits(Parser, Transform)

    Parser.prototype.error = utils.error

    Parser.prototype.kill = function kill () {
      this.dead = true
    }

    Parser.prototype._transform = function transform (data, encoding, cb) {
      if (!this.dead) { this.buffer.push(data) }

      this._consume(cb)
    }

    Parser.prototype._consume = function _consume (cb) {
      var self = this

      function next (err, frame) {
        if (err) {
          return cb(err)
        }

        if (Array.isArray(frame)) {
          for (var i = 0; i < frame.length; i++) {
            self.push(frame[i])
          }
        } else if (frame) {
          self.push(frame)
        }

        // Consume more packets
        if (!sync) {
          return self._consume(cb)
        }

        process.nextTick(function () {
          self._consume(cb)
        })
      }

      if (this.dead) {
        return cb()
      }

      if (this.buffer.size < this.waiting) {
        // No data at all
        if (this.buffer.size === 0) {
          return cb()
        }

        // Partial DATA frame or something that we can process partially
        if (this.partial) {
          var partial = this.buffer.clone(this.buffer.size)
          this.buffer.skip(partial.size)
          this.waiting -= partial.size

          this.executePartial(partial, next)
          return
        }

        // We shall not do anything until we get all expected data
        return cb()
      }

      var sync = true

      var content = this.buffer.clone(this.waiting)
      this.buffer.skip(this.waiting)

      this.execute(content, next)
      sync = false
    }

    Parser.prototype.setVersion = function setVersion (version) {
      this.version = version
      this.emit('version', version)
    }

    Parser.prototype.setCompression = function setCompresion (pair) {
      this.decompress = new transport.utils.LockStream(pair.decompress)
    }