blob: 65c50f6d4f1251da88bc7ea697afd87141d9547f [file] [log] [blame]
(function() {
var Parser, Promise, Protocol,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Promise = require('bluebird');
Protocol = require('./protocol');
Parser = (function() {
Parser.FailError = (function(_super) {
__extends(FailError, _super);
function FailError(message) {
Error.call(this);
this.name = 'FailError';
this.message = "Failure: '" + message + "'";
Error.captureStackTrace(this, Parser.FailError);
}
return FailError;
})(Error);
Parser.PrematureEOFError = (function(_super) {
__extends(PrematureEOFError, _super);
function PrematureEOFError(howManyMissing) {
Error.call(this);
this.name = 'PrematureEOFError';
this.message = "Premature end of stream, needed " + howManyMissing + " more bytes";
this.missingBytes = howManyMissing;
Error.captureStackTrace(this, Parser.PrematureEOFError);
}
return PrematureEOFError;
})(Error);
Parser.UnexpectedDataError = (function(_super) {
__extends(UnexpectedDataError, _super);
function UnexpectedDataError(unexpected, expected) {
Error.call(this);
this.name = 'UnexpectedDataError';
this.message = "Unexpected '" + unexpected + "', was expecting " + expected;
this.unexpected = unexpected;
this.expected = expected;
Error.captureStackTrace(this, Parser.UnexpectedDataError);
}
return UnexpectedDataError;
})(Error);
function Parser(stream) {
this.stream = stream;
}
Parser.prototype.raw = function() {
return this.stream;
};
Parser.prototype.readAll = function() {
var all, endListener, errorListener, resolver, tryRead;
all = new Buffer(0);
resolver = Promise.defer();
tryRead = (function(_this) {
return function() {
var chunk, _results;
_results = [];
while (chunk = _this.stream.read()) {
_results.push(all = Buffer.concat([all, chunk]));
}
return _results;
};
})(this);
this.stream.on('readable', tryRead);
this.stream.on('error', errorListener = function(err) {
return resolver.reject(err);
});
this.stream.on('end', endListener = function() {
return resolver.resolve(all);
});
tryRead();
return resolver.promise.cancellable()["finally"]((function(_this) {
return function() {
_this.stream.removeListener('readable', tryRead);
_this.stream.removeListener('error', errorListener);
return _this.stream.removeListener('end', endListener);
};
})(this));
};
Parser.prototype.readAscii = function(howMany) {
return this.readBytes(howMany).then(function(chunk) {
return chunk.toString('ascii');
});
};
Parser.prototype.readBytes = function(howMany) {
var endListener, errorListener, resolver, tryRead;
resolver = Promise.defer();
tryRead = (function(_this) {
return function() {
var chunk;
if (howMany) {
if (chunk = _this.stream.read(howMany)) {
howMany -= chunk.length;
if (howMany === 0) {
return resolver.resolve(chunk);
}
}
} else {
return resolver.resolve(new Buffer(0));
}
};
})(this);
endListener = function() {
return resolver.reject(new Parser.PrematureEOFError(howMany));
};
errorListener = function(err) {
return resolver.reject(err);
};
this.stream.on('readable', tryRead);
this.stream.on('error', errorListener);
this.stream.on('end', endListener);
tryRead();
return resolver.promise.cancellable()["finally"]((function(_this) {
return function() {
_this.stream.removeListener('readable', tryRead);
_this.stream.removeListener('error', errorListener);
return _this.stream.removeListener('end', endListener);
};
})(this));
};
Parser.prototype.readByteFlow = function(howMany) {
var endListener, errorListener, resolver, tryRead;
resolver = Promise.defer();
tryRead = (function(_this) {
return function() {
var chunk, _results;
if (howMany) {
_results = [];
while (chunk = _this.stream.read(howMany) || _this.stream.read()) {
howMany -= chunk.length;
if (howMany === 0) {
resolver.progress(chunk);
resolver.resolve();
break;
}
_results.push(resolver.progress(chunk));
}
return _results;
} else {
return resolver.resolve();
}
};
})(this);
endListener = function() {
return resolver.reject(new Parser.PrematureEOFError(howMany));
};
errorListener = function(err) {
return resolver.reject(err);
};
this.stream.on('readable', tryRead);
this.stream.on('error', errorListener);
this.stream.on('end', endListener);
tryRead();
return resolver.promise.cancellable()["finally"]((function(_this) {
return function() {
_this.stream.removeListener('readable', tryRead);
_this.stream.removeListener('error', errorListener);
return _this.stream.removeListener('end', endListener);
};
})(this));
};
Parser.prototype.readError = function() {
return this.readValue().then(function(value) {
return Promise.reject(new Parser.FailError(value.toString()));
});
};
Parser.prototype.readValue = function() {
return this.readAscii(4).then((function(_this) {
return function(value) {
var length;
length = Protocol.decodeLength(value);
return _this.readBytes(length);
};
})(this));
};
Parser.prototype.readUntil = function(code) {
var read, skipped;
skipped = new Buffer(0);
read = (function(_this) {
return function() {
return _this.readBytes(1).then(function(chunk) {
if (chunk[0] === code) {
return skipped;
} else {
skipped = Buffer.concat([skipped, chunk]);
return read();
}
});
};
})(this);
return read();
};
Parser.prototype.searchLine = function(re) {
return this.readLine().then((function(_this) {
return function(line) {
var match;
if (match = re.exec(line)) {
return match;
} else {
return _this.searchLine(re);
}
};
})(this));
};
Parser.prototype.readLine = function() {
return this.readUntil(0x0a).then(function(line) {
if (line[line.length - 1] === 0x0d) {
return line.slice(0, -1);
} else {
return line;
}
});
};
Parser.prototype.unexpected = function(data, expected) {
return Promise.reject(new Parser.UnexpectedDataError(data, expected));
};
return Parser;
})();
module.exports = Parser;
}).call(this);