Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
More work on test cases and some impl changes
  • Loading branch information
cretz committed Dec 7, 2011
1 parent dde4b70 commit 4f913e0
Show file tree
Hide file tree
Showing 31 changed files with 1,824 additions and 51 deletions.
4 changes: 2 additions & 2 deletions Cakefile
Expand Up @@ -7,8 +7,8 @@ run = (cmd, args, cb) ->
proc = spawn cmd, args
proc.stderr.pipe process.stderr, end: false
proc.stdout.pipe process.stdout, end: false
proc.on 'exit', (status) ->
process.kill(1) if status != 0
proc.on 'exit', (status) ->
process.kill(1) if status != 0
cb() if typeof cb is 'function'

compile = (includeTests, cb) ->
Expand Down
147 changes: 147 additions & 0 deletions lib/buffer-builder.js
@@ -0,0 +1,147 @@

exports.BufferBuilder = (function() {

function BufferBuilder() {}

BufferBuilder.getUcs2StringLength = function(string) {
return string.length * 2;
};

BufferBuilder.prototype._values = [];

BufferBuilder.prototype.length = 0;

BufferBuilder.prototype.appendByte = function(byte) {
this.length++;
this._values.push({
type: 'byte',
value: byte
});
return this;
};

BufferBuilder.prototype.appendBytes = function(bytes) {
this.length += bytes.length;
this._values.push({
type: 'byte array',
value: bytes
});
return this;
};

BufferBuilder.prototype.appendInt32LE = function(int) {
this.length += 4;
this._values.push({
type: 'int32LE',
value: int
});
return this;
};

BufferBuilder.prototype.appendString = function(string, encoding) {
var len;
len = Buffer.byteLength(string, encoding);
this.length += len;
this._values.push({
type: 'string',
encoding: encoding,
value: string,
length: len
});
return this;
};

BufferBuilder.prototype.appendUcs2String = function(string) {
return this.appendString(string, 'ucs2');
};

BufferBuilder.prototype.appendAsciiString = function(string) {
return this.appendString(string, 'ascii');
};

BufferBuilder.prototype.appendUInt16LE = function(int) {
this.length += 2;
this._values.push({
type: 'uint16LE',
value: int
});
return this;
};

BufferBuilder.prototype.appendUInt32LE = function(int) {
this.length += 4;
this._values.push({
type: 'uint32LE',
value: int
});
return this;
};

BufferBuilder.prototype.insertByte = function(byte, position) {
this.length++;
this._values.splice(position, 0, {
type: 'byte',
value: byte
});
return this;
};

BufferBuilder.prototype.insertUInt16BE = function(int, position) {
this.length += 2;
this._values.splice(position, 0, {
type: 'uint16BE',
value: int
});
return this;
};

BufferBuilder.prototype.toBuffer = function() {
var buff, byte, offset, value, _i, _j, _len, _len2, _ref, _ref2;
buff = new Buffer(this.length);
offset = 0;
_ref = this._values;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
value = _ref[_i];
switch (value.type) {
case 'byte':
buff.set(offset, value.value);
offset++;
break;
case 'byte array':
_ref2 = value.value;
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
byte = _ref2[_j];
buff.set(offset, byte);
offset++;
}
break;
case 'int32LE':
buff.writeInt32LE(value.value, offset);
offset += 4;
break;
case 'string':
buff.write(value.value, offset, value.length, value.encoding);
offset += value.length;
break;
case 'uint16BE':
buff.writeUInt16BE(value.value, offset);
offset += 2;
break;
case 'uint16LE':
buff.writeUInt16LE(value.value, offset);
offset += 2;
break;
case 'uint32LE':
buff.writeUInt32LE(value.value, offset);
offset += 4;
break;
default:
throw new Error('Unrecognized type: ' + value.type);
}
}
return buff;
};

return BufferBuilder;

})();
183 changes: 183 additions & 0 deletions lib/buffer-stream.js
@@ -0,0 +1,183 @@
var __hasProp = Object.prototype.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; };

exports.BufferStream = (function() {

function BufferStream() {}

BufferStream.prototype._buffer = null;

BufferStream.prototype._offset = 0;

BufferStream.prototype._offsetStart = null;

BufferStream.prototype.append = function(buffer) {
var newBuffer;
if (!(this._buffer != null)) {
return this._buffer = buffer;
} else {
newBuffer = new Buffer(this._buffer.length + buffer.length);
this._buffer.copy(newBuffer);
buffer.copy(newBuffer, this._buffer.length);
return this._buffer = newBuffer;
}
};

BufferStream.prototype.getBuffer = function() {
return this._buffer;
};

BufferStream.prototype.beginTransaction = function() {
return this._offsetStart = this._offset;
};

BufferStream.prototype.commitTransaction = function() {
this._offsetStart = null;
this._buffer = this._buffer.slice(this._offset);
return this._offset = 0;
};

BufferStream.prototype.rollbackTransaction = function() {
this._offset = this._offsetStart;
return this._offsetStart = null;
};

BufferStream.prototype.assertBytesAvailable = function(amountNeeded) {
if (amountNeeded + this._offset > this._buffer.length) {
console.log('Need %d, length %d', amountNeeded + this._offset, this._buffer.length);
throw new BufferStream.StreamIndexOutOfBoundsError('Index out of bounds');
}
};

BufferStream.prototype.currentOffset = function() {
return this._offset - this._offsetStart;
};

/**
* Overrides the current transaction's offset with
* the given one. This doesn't validate
*
* @param {number} offset The offset to set, where 0 is
* the start of the transaction
*/

BufferStream.prototype.overrideOffset = function(offset) {
return this._offset = this._offsetStart + offset;
};

BufferStream.prototype.readBuffer = function(length) {
var ret;
this.assertBytesAvailable(length);
ret = this._buffer.slice(this._offset, this._offset + length);
this._offset += length;
return ret;
};

BufferStream.prototype.readByte = function() {
var ret;
this.assertBytesAvailable(1);
ret = this._buffer.get(this._offset);
this._offset++;
return ret;
};

BufferStream.prototype.readBytes = function(length) {
var i, ret, _ref;
this.assertBytesAvailable(length);
ret = [];
for (i = 0, _ref = length - 1; 0 <= _ref ? i <= _ref : i >= _ref; 0 <= _ref ? i++ : i--) {
ret.push(this._buffer.get(this._offset));
this._offset++;
}
return ret;
};

BufferStream.prototype.readInt32LE = function() {
var ret;
this.assertBytesAvailable(4);
ret = this._buffer.readInt32LE(this._offset);
this._offset += 4;
return ret;
};

BufferStream.prototype.readString = function(lengthInBytes, encoding) {
var ret;
this.assertBytesAvailable(lengthInBytes);
ret = this._buffer.toString(encoding, this._offset, this._offset + lengthInBytes);
this._offset += lengthInBytes;
return ret;
};

/**
* Does not move the offset
*/

BufferStream.prototype.readStringFromIndex = function(index, lengthInBytes, encoding) {
if (index + this._offsetStart >= this._buffer.length) {
throw new BufferStream.StreamIndexOutOfBoundsError('Index out of bounds');
}
return this._buffer.toString(encoding, index + this._offsetStart, index + this._offsetStart + lengthInBytes);
};

BufferStream.prototype.readUcs2String = function(length) {
return this.readString(length * 2, 'ucs2');
};

BufferStream.prototype.readAsciiString = function(length) {
return this.readString(length, 'ascii');
};

/**
* Does not move the offset
*/

BufferStream.prototype.readUcs2StringFromIndex = function(index, length) {
return this.readStringFromIndex(index, length * 2, 'ucs2');
};

BufferStream.prototype.readUInt16BE = function() {
var ret;
this.assertBytesAvailable(2);
ret = this._buffer.readUInt16BE(this._offset);
this._offset += 2;
return ret;
};

BufferStream.prototype.readUInt16LE = function() {
var ret;
this.assertBytesAvailable(2);
ret = this._buffer.readUInt16LE(this._offset);
this._offset += 2;
return ret;
};

BufferStream.prototype.readUInt32LE = function() {
var ret;
this.assertBytesAvailable(4);
ret = this._buffer.readUInt32LE(this._offset);
this._offset += 4;
return ret;
};

BufferStream.prototype.skip = function(length) {
this.assertBytesAvailable(length);
return this._offset += length;
};

BufferStream.StreamIndexOutOfBoundsError = exports.StreamIndexOutOfBoundsError = (function() {

__extends(StreamIndexOutOfBoundsError, Error);

StreamIndexOutOfBoundsError.prototype.name = 'StreamIndexOutOfBoundsError';

function StreamIndexOutOfBoundsError(message) {
this.message = message;
this.stack = (new Error).stack;
}

return StreamIndexOutOfBoundsError;

})();

return BufferStream;

})();

0 comments on commit 4f913e0

Please sign in to comment.