Skip to content

rough draft of the serialization runtime #31

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

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
145 changes: 145 additions & 0 deletions KaitaiStream.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ var KaitaiStream = function(arrayBuffer, byteOffset) {
this.buffer = new ArrayBuffer(arrayBuffer || 1);
}
this.pos = 0;
this.childStreams = [];
this.alignToByte();
};

Expand Down Expand Up @@ -161,6 +162,47 @@ Object.defineProperty(KaitaiStream.prototype, 'size',
return this._byteLength - this._byteOffset;
}});

// ========================================================================
// Child streams
// ========================================================================

function WriteBackHandler(pos, handler) {
this.pos = pos;
this.handler = handler;
}

WriteBackHandler.prototype.writeBack = function (parent) {
parent.seek(this.pos);
this.handler(parent);
};

KaitaiStream.WriteBackHandler = function (pos, handler) {
return new WriteBackHandler(pos, handler);
};

KaitaiStream.prototype.addChildStream = function (child) {
if (!this.childStreams) {
this.childStreams = [];
}
this.childStreams.push(child);
};

KaitaiStream.prototype.writeBackChildStreams = function (parent = null) {
var _pos = this.pos;
for (let i = 0; i < this.childStreams.length; i++) {
this.childStreams[i].writeBackChildStreams(this);
}
this.childStreams.length = 0; // Clear the array
this.seek(_pos);
if (parent !== null) {
this._writeBack(parent);
}
};

KaitaiStream.prototype._writeBack = function (parent) {
this.writeBackHandler.writeBack(parent);
};

// ========================================================================
// Integer numbers
// ========================================================================
Expand Down Expand Up @@ -241,6 +283,17 @@ KaitaiStream.prototype.readS2le = function() {
return v;
};

/**
Writes a 16-bit little-endian unsigned int to the stream.
@param {number} value The number to write.
*/
KaitaiStream.prototype.writeS2le = function (value) {
var buffer = new ArrayBuffer(2);
var dataView = new DataView(buffer);
dataView.setInt16(0, value, true);
this.writeBytes(buffer);
};

/**
Reads a 32-bit little-endian signed int from the stream.
@return {number} The read number.
Expand Down Expand Up @@ -287,6 +340,17 @@ KaitaiStream.prototype.readU1 = function() {
return v;
};

/**
Writes an 8-bit unsigned int to the stream.
@param {number} value The number to write.
*/
KaitaiStream.prototype.writeU1 = function (value) {
var buffer = new ArrayBuffer(1);
var dataView = new DataView(buffer);
dataView.setUint8(0, value);
this.writeBytes(buffer);
};

// ........................................................................
// Big-endian
// ........................................................................
Expand Down Expand Up @@ -342,6 +406,17 @@ KaitaiStream.prototype.readU2le = function() {
return v;
};

/**
Writes a 16-bit little-endian unsigned int to the stream.
@param {number} value The number to write.
*/
KaitaiStream.prototype.writeU2le = function (value) {
var buffer = new ArrayBuffer(2);
var dataView = new DataView(buffer);
dataView.setUint16(0, value, true);
this.writeBytes(buffer);
};

/**
Reads a 32-bit little-endian unsigned int from the stream.
@return {number} The read number.
Expand All @@ -353,6 +428,17 @@ KaitaiStream.prototype.readU4le = function() {
return v;
};

/**
Writes a 32-bit little-endian unsigned int to the stream.
@param {number} value The number to write.
*/
KaitaiStream.prototype.writeU4le = function (value) {
var buffer = new ArrayBuffer(4);
var dataView = new DataView(buffer);
dataView.setUint32(0, value, true);
this.writeBytes(buffer);
};

/**
Reads a 64-bit little-endian unsigned int from the stream. Note that
JavaScript does not support 64-bit integers natively, so it will
Expand Down Expand Up @@ -400,6 +486,13 @@ KaitaiStream.prototype.readF4le = function() {
return v;
};

KaitaiStream.prototype.writeF4le = function (value) {
var buffer = new ArrayBuffer(4);
var dataView = new DataView(buffer);
dataView.setFloat32(0, value, true);
this.writeBytes(buffer);
};

KaitaiStream.prototype.readF8le = function() {
this.ensureBytesLeft(8);
var v = this._dataView.getFloat64(this.pos, true);
Expand Down Expand Up @@ -591,6 +684,34 @@ KaitaiStream.prototype.readBytesTermMulti = function(terminator, include, consum
return res;
};

KaitaiStream.prototype.writeBytes = function (buffer) {
this.writeAlignToByte();
this._writeBytesNotAligned(buffer);
};

KaitaiStream.prototype.writeAlignToByte = function () {
if (this.bitsLeft > 0) {
var b = this.bits;
if (!this.bitsLe) {
b <<= 8 - this.bitsLeft;
}
this.alignToByte();
this._writeBytesNotAligned(KaitaiStream.byteFromInt(b));
}
};

KaitaiStream.prototype._writeBytesNotAligned = function (buf) {
var n = buf.byteLength;
var pos = this.pos;
this.ensureBytesLeft(n, pos);
var arr = new Uint8Array(buf);

for (let i = 0; i < n; i++) {
this.dataView.setUint8(this.pos, arr[i]);
this.pos++;
}
};

// Unused since Kaitai Struct Compiler v0.9+ - compatibility with older versions
KaitaiStream.prototype.ensureFixedContents = function(expected) {
var actual = this.readBytes(expected.length);
Expand Down Expand Up @@ -677,6 +798,18 @@ KaitaiStream.bytesToStr = function(arr, encoding) {
}
}
}
}

KaitaiStream.prototype.toByteArray = function () {
var pos = this.pos;
this.seek(0);
var byteArray = this.readBytesFull();
this.seek(pos);
return byteArray;
};

KaitaiStream.prototype.byteFromInt = function (i) {
return new Uint8Array([i]);
};

// ========================================================================
Expand Down Expand Up @@ -885,6 +1018,18 @@ var ValidationExprError = KaitaiStream.ValidationExprError = function(actual, io
ValidationExprError.prototype = Object.create(Error.prototype);
ValidationExprError.prototype.constructor = ValidationExprError;

var ConsistencyError = (KaitaiStream.ConsistencyError = function (id, expected, actual) {
this.name = "ConsistencyError";
this.message =
"Check failed: " + id + ", expected [" + expected + "], but got [" + actual + "]";
this.expected = expected;
this.actual = actual;
this.stack = new Error().stack;
});

ConsistencyError.prototype = Object.create(Error.prototype);
ConsistencyError.prototype.constructor = ConsistencyError;

/**
Ensures that we have an least `length` bytes left in the stream.
If that's not true, throws an EOFError.
Expand Down