Skip to content

Commit

Permalink
Merge pull request #22 from mafintosh/es-class
Browse files Browse the repository at this point in the history
Drop inherits, buffer-alloc dependencies
  • Loading branch information
feross authored Aug 7, 2019
2 parents dd6a76e + 5b160bb commit 953b3a3
Show file tree
Hide file tree
Showing 4 changed files with 248 additions and 259 deletions.
292 changes: 142 additions & 150 deletions decode.js
Original file line number Diff line number Diff line change
@@ -1,191 +1,183 @@
var stream = require('readable-stream')
var inherits = require('inherits')
var nextEvent = require('next-event')
var Box = require('mp4-box-encoding')
var bufferAlloc = require('buffer-alloc')

var EMPTY = bufferAlloc(0)
var EMPTY = Buffer.alloc(0)

module.exports = Decoder
class Decoder extends stream.Writable {
constructor (opts) {
super(opts)

function Decoder () {
if (!(this instanceof Decoder)) return new Decoder()
stream.Writable.call(this)
this.destroyed = false

this.destroyed = false
this._pending = 0
this._missing = 0
this._ignoreEmpty = false
this._buf = null
this._str = null
this._cb = null
this._ondrain = null
this._writeBuffer = null
this._writeCb = null

this._pending = 0
this._missing = 0
this._ignoreEmpty = false
this._buf = null
this._str = null
this._cb = null
this._ondrain = null
this._writeBuffer = null
this._writeCb = null
this._ondrain = null
this._kick()
}

this._ondrain = null
this._kick()
}
destroy (err) {
if (this.destroyed) return
this.destroyed = true
if (err) this.emit('error', err)
this.emit('close')
}

inherits(Decoder, stream.Writable)
_write (data, enc, next) {
if (this.destroyed) return
var drained = !this._str || !this._str._writableState.needDrain

Decoder.prototype.destroy = function (err) {
if (this.destroyed) return
this.destroyed = true
if (err) this.emit('error', err)
this.emit('close')
}
while (data.length && !this.destroyed) {
if (!this._missing && !this._ignoreEmpty) {
this._writeBuffer = data
this._writeCb = next
return
}

Decoder.prototype._write = function (data, enc, next) {
if (this.destroyed) return
var drained = !this._str || !this._str._writableState.needDrain
var consumed = data.length < this._missing ? data.length : this._missing
if (this._buf) data.copy(this._buf, this._buf.length - this._missing)
else if (this._str) drained = this._str.write(consumed === data.length ? data : data.slice(0, consumed))

while (data.length && !this.destroyed) {
if (!this._missing && !this._ignoreEmpty) {
this._writeBuffer = data
this._writeCb = next
return
}
this._missing -= consumed

var consumed = data.length < this._missing ? data.length : this._missing
if (this._buf) data.copy(this._buf, this._buf.length - this._missing)
else if (this._str) drained = this._str.write(consumed === data.length ? data : data.slice(0, consumed))
if (!this._missing) {
var buf = this._buf
var cb = this._cb
var stream = this._str

this._missing -= consumed
this._buf = this._cb = this._str = this._ondrain = null
drained = true

if (!this._missing) {
var buf = this._buf
var cb = this._cb
var stream = this._str
this._ignoreEmpty = false
if (stream) stream.end()
if (cb) cb(buf)
}

this._buf = this._cb = this._str = this._ondrain = null
drained = true
data = consumed === data.length ? EMPTY : data.slice(consumed)
}

this._ignoreEmpty = false
if (stream) stream.end()
if (cb) cb(buf)
if (this._pending && !this._missing) {
this._writeBuffer = data
this._writeCb = next
return
}

data = consumed === data.length ? EMPTY : data.slice(consumed)
if (drained) next()
else this._ondrain(next)
}

if (this._pending && !this._missing) {
this._writeBuffer = data
this._writeCb = next
return
_buffer (size, cb) {
this._missing = size
this._buf = Buffer.alloc(size)
this._cb = cb
}

if (drained) next()
else this._ondrain(next)
}
_stream (size, cb) {
this._missing = size
this._str = new MediaData(this)
this._ondrain = nextEvent(this._str, 'drain')
this._pending++
this._str.on('end', () => {
this._pending--
this._kick()
})
this._cb = cb
return this._str
}

Decoder.prototype._buffer = function (size, cb) {
this._missing = size
this._buf = bufferAlloc(size)
this._cb = cb
}
_readBox () {
const bufferHeaders = (len, buf) => {
this._buffer(len, additionalBuf => {
if (buf) {
buf = Buffer.concat([buf, additionalBuf])
} else {
buf = additionalBuf
}
var headers = Box.readHeaders(buf)
if (typeof headers === 'number') {
bufferHeaders(headers - buf.length, buf)
} else {
this._pending++
this._headers = headers
this.emit('box', headers)
}
})
}

Decoder.prototype._stream = function (size, cb) {
var self = this
this._missing = size
this._str = new MediaData(this)
this._ondrain = nextEvent(this._str, 'drain')
this._pending++
this._str.on('end', function () {
self._pending--
self._kick()
})
this._cb = cb
return this._str
}
bufferHeaders(8)
}

Decoder.prototype._readBox = function () {
var self = this
bufferHeaders(8)
stream () {
if (!this._headers) throw new Error('this function can only be called once after \'box\' is emitted')
var headers = this._headers
this._headers = null

function bufferHeaders (len, buf) {
self._buffer(len, function (additionalBuf) {
if (buf) {
buf = Buffer.concat([buf, additionalBuf])
} else {
buf = additionalBuf
}
var headers = Box.readHeaders(buf)
if (typeof headers === 'number') {
bufferHeaders(headers - buf.length, buf)
} else {
self._pending++
self._headers = headers
self.emit('box', headers)
}
})
return this._stream(headers.contentLen, null)
}
}

Decoder.prototype.stream = function () {
var self = this
if (!self._headers) throw new Error('this function can only be called once after \'box\' is emitted')
var headers = self._headers
self._headers = null
decode (cb) {
if (!this._headers) throw new Error('this function can only be called once after \'box\' is emitted')
var headers = this._headers
this._headers = null

return self._stream(headers.contentLen, null)
}

Decoder.prototype.decode = function (cb) {
var self = this
if (!self._headers) throw new Error('this function can only be called once after \'box\' is emitted')
var headers = self._headers
self._headers = null

self._buffer(headers.contentLen, function (buf) {
var box = Box.decodeWithoutHeaders(headers, buf)
cb(box)
self._pending--
self._kick()
})
}
this._buffer(headers.contentLen, buf => {
var box = Box.decodeWithoutHeaders(headers, buf)
cb(box)
this._pending--
this._kick()
})
}

Decoder.prototype.ignore = function () {
var self = this
if (!self._headers) throw new Error('this function can only be called once after \'box\' is emitted')
var headers = self._headers
self._headers = null
ignore () {
if (!this._headers) throw new Error('this function can only be called once after \'box\' is emitted')
var headers = this._headers
this._headers = null

this._missing = headers.contentLen
if (this._missing === 0) {
this._ignoreEmpty = true
this._missing = headers.contentLen
if (this._missing === 0) {
this._ignoreEmpty = true
}
this._cb = () => {
this._pending--
this._kick()
}
}
this._cb = function () {
self._pending--
self._kick()

_kick () {
if (this._pending) return
if (!this._buf && !this._str) this._readBox()
if (this._writeBuffer) {
var next = this._writeCb
var buffer = this._writeBuffer
this._writeBuffer = null
this._writeCb = null
this._write(buffer, null, next)
}
}
}

Decoder.prototype._kick = function () {
if (this._pending) return
if (!this._buf && !this._str) this._readBox()
if (this._writeBuffer) {
var next = this._writeCb
var buffer = this._writeBuffer
this._writeBuffer = null
this._writeCb = null
this._write(buffer, null, next)
class MediaData extends stream.PassThrough {
constructor (parent) {
super()
this._parent = parent
this.destroyed = false
}
}

function MediaData (parent) {
this._parent = parent
this.destroyed = false
stream.PassThrough.call(this)
destroy (err) {
if (this.destroyed) return
this.destroyed = true
this._parent.destroy(err)
if (err) this.emit('error', err)
this.emit('close')
}
}

inherits(MediaData, stream.PassThrough)

MediaData.prototype.destroy = function (err) {
if (this.destroyed) return
this.destroyed = true
this._parent.destroy(err)
if (err) this.emit('error', err)
this.emit('close')
}
module.exports = Decoder
Loading

0 comments on commit 953b3a3

Please sign in to comment.