Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use more modern streams2 streaming api #72

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 41 additions & 39 deletions lib/asf.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,46 @@
var fs = require('fs');
var util = require('util');
var events = require('events');
var strtok = require('strtok2');
var Calippo = require('Calippo');
var common = require('./common');
var equal = require('deep-equal');

var decodeString = common.decodeString;

module.exports = function (stream, callback, done) {
module.exports = function () {
var currentState = startState;

strtok.parse(stream, function (v, cb) {
currentState = currentState.parse(callback, v, done);
return currentState.getExpectedType();
return new Calippo({'objectMode': true}, function (v) {
currentState = currentState.parse(this, v);
return currentState.getExpectedType(this);
})
};

var startState = {
parse: function (callback) {
parse: function (parser) {
return idState;
},
}

var finishedState = {
parse: function (callback) {
parse: function (parser) {
return this;
},
getExpectedType: function () {
return strtok.DONE;
getExpectedType: function (parser) {
parser.push(null);
}
}

var idState = {
parse: function (callback, data, done) {
parse: function (parser, data) {
if (!equal(common.asfGuidBuf, data)) {
done(new Error('expected asf header but was not found'));
parser.emit('error', new Error('expected asf header but was not found'));
return finishedState;
}
return headerDataState;
},
getExpectedType: function () {
return new strtok.BufferType(common.asfGuidBuf.length);
getExpectedType: function (parser) {
return parser.Buffer(common.asfGuidBuf.length);
}
};

Expand All @@ -50,7 +50,7 @@ function ReadObjectState(size, objectCount) {
this.objectCount = objectCount;
}

ReadObjectState.prototype.parse = function(callback, data, done) {
ReadObjectState.prototype.parse = function(parser, data) {
var guid = data.slice(0, 16);
var size = readUInt64LE(data, 16)
var State = stateByGuid(guid) || IgnoreObjectState;
Expand All @@ -60,21 +60,21 @@ ReadObjectState.prototype.parse = function(callback, data, done) {
return new State(nextState, size - 24);
}

ReadObjectState.prototype.getExpectedType = function() {
return new strtok.BufferType(24);
ReadObjectState.prototype.getExpectedType = function(parser) {
return parser.Buffer(24);
}

var headerDataState = {
parse: function (callback, data, done) {
parse: function (parser, data) {
var size = readUInt64LE(data, 0);
var objectCount = data.readUInt32LE(8);
return new ReadObjectState(size, objectCount);
},
getExpectedType: function () {
getExpectedType: function (parser) {
// 8 bytes size
// 4 bytes object count
// 2 bytes ignore
return new strtok.BufferType(14);
return parser.Buffer(14);
}
};

Expand All @@ -83,13 +83,13 @@ function IgnoreObjectState(nextState, size) {
this.size = size;
}

IgnoreObjectState.prototype.parse = function(callback, data, done) {
if (this.nextState === finishedState) done();
IgnoreObjectState.prototype.parse = function(parser, data) {
if (this.nextState === finishedState) parser.push(null);
return this.nextState;
}

IgnoreObjectState.prototype.getExpectedType = function() {
return new strtok.IgnoreType(this.size);
IgnoreObjectState.prototype.getExpectedType = function(parser) {
return parser.Skip(this.size)
}

function ContentDescriptionObjectState(nextState, size) {
Expand All @@ -98,7 +98,7 @@ function ContentDescriptionObjectState(nextState, size) {
}

var contentDescTags = ['Title', 'Author', 'Copyright', 'Description', 'Rating'];
ContentDescriptionObjectState.prototype.parse = function(callback, data, done) {
ContentDescriptionObjectState.prototype.parse = function(parser, data) {
var lengths = [
data.readUInt16LE(0),
data.readUInt16LE(2),
Expand All @@ -113,16 +113,17 @@ ContentDescriptionObjectState.prototype.parse = function(callback, data, done) {
var end = pos + length;
if (length > 0) {
var value = parseUnicodeAttr(data.slice(pos, end));
callback(tagName, value);
parser.push([tagName, value])
}
pos = end;
}
if (this.nextState === finishedState) done();
// if (this.nextState === finishedState) done();
// TODO: what to do about this
return this.nextState;
}

ContentDescriptionObjectState.prototype.getExpectedType = function() {
return new strtok.BufferType(this.size);
ContentDescriptionObjectState.prototype.getExpectedType = function(parser) {
return parser.Buffer(this.size);
}

ContentDescriptionObjectState.guid = new Buffer([
Expand All @@ -145,7 +146,7 @@ var attributeParsers = [
parseByteArrayAttr,
];

ExtendedContentDescriptionObjectState.prototype.parse = function(callback, data, done) {
ExtendedContentDescriptionObjectState.prototype.parse = function(parser, data) {
var attrCount = data.readUInt16LE(0);
var pos = 2;
for (var i = 0; i < attrCount; i += 1) {
Expand All @@ -161,18 +162,19 @@ ExtendedContentDescriptionObjectState.prototype.parse = function(callback, data,
pos += valueLen;
var parseAttr = attributeParsers[valueType];
if (!parseAttr) {
done(new Error('unexpected value type: ' + valueType));
parser.emit(['error', new Error('unexpected value type: ' + valueType)]);
// TODO: startstate?
return finishedState;
}
var attr = parseAttr(value);
callback(name, attr);
parser.push([name, attr])
}
if (this.nextState === finishedState) done();
if (this.nextState === finishedState) parser.push(null);
return this.nextState;
}

ExtendedContentDescriptionObjectState.prototype.getExpectedType = function() {
return new strtok.BufferType(this.size);
ExtendedContentDescriptionObjectState.prototype.getExpectedType = function(parser) {
return parser.Buffer(this.size);
}

ExtendedContentDescriptionObjectState.guid = new Buffer([
Expand All @@ -185,17 +187,17 @@ function FilePropertiesObject(nextState, size) {
this.size = size;
}

FilePropertiesObject.prototype.parse = function (callback, data, done) {
FilePropertiesObject.prototype.parse = function (parser, data) {
// in miliseconds
var playDuration = parseQWordAttr(data.slice(40, 48)) / 10000
callback('duration', Math.round(playDuration / 1000))
parser.push(['duration', Math.round(playDuration / 1000)])

if (this.nextState === finishedState) done();
if (this.nextState === finishedState) parser.push(null);
return this.nextState;
}

FilePropertiesObject.prototype.getExpectedType = function() {
return new strtok.BufferType(this.size);
FilePropertiesObject.prototype.getExpectedType = function(parser) {
return parser.Buffer(this.size);
}

FilePropertiesObject.guid = new Buffer([
Expand Down
54 changes: 26 additions & 28 deletions lib/flac.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
'use strict';
var strtok = require('strtok2');
var Calippo = require('calippo');
var common = require('./common');

module.exports = function (stream, callback, done) {
module.exports = function () {
var currentState = startState;

strtok.parse(stream, function (v, cb) {
currentState = currentState.parse(callback, v, done);
return currentState.getExpectedType();
return new Calippo({'objectMode': true}, function (v) {
currentState = currentState.parse(this, v);
return currentState.getExpectedType(this);
})
}

Expand All @@ -17,7 +17,7 @@ var DataDecoder = function (data) {
}

DataDecoder.prototype.readInt32 = function () {
var value = strtok.UINT32_LE.get(this.data, this.offset);
var value = this.data.readUInt32LE(this.offset);
this.offset += 4;
return value;
}
Expand All @@ -30,11 +30,11 @@ DataDecoder.prototype.readStringUtf8 = function () {
};

var finishedState = {
parse: function (callback) {
parse: function (parser, data) {
return this;
},
getExpectedType: function () {
return strtok.DONE;
getExpectedType: function (parser) {
parser.push(null)
}
}

Expand All @@ -44,7 +44,7 @@ var BlockDataState = function (type, length, nextStateFactory) {
this.nextStateFactory = nextStateFactory;
}

BlockDataState.prototype.parse = function (callback, data) {
BlockDataState.prototype.parse = function (parser, data) {
if (this.type === 4) {
var decoder = new DataDecoder(data);
var vendorString = decoder.readStringUtf8();
Expand All @@ -56,64 +56,62 @@ BlockDataState.prototype.parse = function (callback, data) {
for (i = 0; i < commentListLength; i++) {
comment = decoder.readStringUtf8();
split = comment.split('=');
callback(split[0].toUpperCase(), split[1]);
parser.push([split[0].toUpperCase(), split[1]])
}
} else if (this.type === 6) {
var picture = common.readVorbisPicture(data);
callback('METADATA_BLOCK_PICTURE', picture);
parser.push(['METADATA_BLOCK_PICTURE', picture])
} else if (this.type === 0) { // METADATA_BLOCK_STREAMINFO
if (data.length < 34) return; // invalid streaminfo
var sampleRate = common.strtokUINT24_BE.get(data, 10) >> 4;
var totalSamples = data.readUInt32BE(14);
var duration = totalSamples / sampleRate;
callback('duration', Math.round(duration));
parser.push(['duration', Math.round(duration)]);
}

return this.nextStateFactory();
}

BlockDataState.prototype.getExpectedType = function () {
return new strtok.BufferType(this.length);
BlockDataState.prototype.getExpectedType = function (parser) {
return parser.Buffer(this.length);
}

var blockHeaderState = {
parse: function (callback, data, done) {
parse: function (parser, data) {
var header = {
lastBlock: (data[0] & 0x80) == 0x80,
type: data[0] & 0x7f,
length: common.strtokUINT24_BE.get(data, 1)
}
var followingStateFactory = header.lastBlock ? function() {
done();
return finishedState;
} : function() {
return blockHeaderState;
}

return new BlockDataState(header.type, header.length, followingStateFactory);
},
getExpectedType: function () {
return new strtok.BufferType(4);
getExpectedType: function (parser) {
return parser.Buffer(4);
}
}

var idState = {
parse: function (callback, data, done) {
parse: function (parser, data) {
if (data !== 'fLaC') {
done(new Error('expected flac header but was not found'));
// TODO: shouldn't the param be wrapped in an array?? []
parser.emit('error', new Error('expected flac header but was not found'))
return startState;
}
return blockHeaderState;
},
getExpectedType: function () {
return new strtok.StringType(4);
getExpectedType: function (parser) {
return parser.String(4);
}
};

var startState = {
parse: function (callback) {
parse: function (parser, data) {
return idState;
},
getExpectedType: function () {
return strtok.DONE;
}
getExpectedType: function (parser) {}
}
Loading