code: function _data (stream, chunk, output, fn) {
    if (stream._parserBytesLeft <= 0) {
      return fn(new Error('got data but not currently parsing anything'));
    }
  
    if (chunk.length <= stream._parserBytesLeft) {
      // small buffer fits within the "_parserBytesLeft" window
      return function () {
        return process(stream, chunk, output, fn);
      };
    } else {
      // large buffer needs to be sliced on "_parserBytesLeft" and processed
      return function () {
        var b = chunk.slice(0, stream._parserBytesLeft);
        return process(stream, b, output, function (err) {
          if (err) return fn(err);
          if (chunk.length > b.length) {
            return function () {
              return _data(stream, chunk.slice(b.length), output, fn);
            };
          }
        });
      };
    }
  }
docs: The internal buffering/passthrough logic...
  
  This `_data` function get's "trampolined" to prevent stack overflows for tight
  loops. This technique requires us to return a "thunk" function for any
  synchronous action. Async stuff breaks the trampoline, but that's ok since it's
  working with a new stack at that point anyway.
  
  @api private