Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial Commit

  • Loading branch information...
commit ad59bd1101818f96596c965a6fc7a311772b4ced 1 parent a730700
@vjeux authored
View
121 src/jparser.js
@@ -0,0 +1,121 @@
+(function () {
+
+// Extend code from underscorejs
+var extend = function (obj) {
+ for (var i = 1; i < arguments.length; ++i) {
+ var source = arguments[i];
+ for (var prop in source) {
+ if (source[prop] !== undefined) {
+ obj[prop] = source[prop];
+ }
+ }
+ }
+ return obj;
+};
+
+function jParser(view, structure) {
+ if (!(this instanceof arguments.callee)) {
+ throw new Error("Constructor may not be called as a function");
+ }
+ this.view = view;
+ this.view.seek(0);
+ this.structure = extend({}, jParser.prototype.structure, structure);
+}
+
+jParser.prototype.structure = {
+ uint8: function () { return this.view.getUint8(); },
+ uint16: function () { return this.view.getUint16(); },
+ uint32: function () { return this.view.getUint32(); },
+ int8: function () { return this.view.getInt8(); },
+ int16: function () { return this.view.getInt16(); },
+ int32: function () { return this.view.getInt32(); },
+ float32: function () { return this.view.getFloat32(); },
+ float64: function () { return this.view.getFloat64(); },
+ char: function () { return this.view.getChar(); },
+ string: function (length) { return this.view.getString(length); },
+ array: function (type, length) {
+ if (typeof length === 'function') {
+ length = length();
+ }
+ var results = [];
+ for (var i = 0; i < length; ++i) {
+ results.push(this.parse(type));
+ }
+ return results;
+ },
+ seek: function (position, block) {
+ if (typeof position === 'function') {
+ position = position();
+ }
+ if (block instanceof Function) {
+ var old_position = this.view.tell();
+ this.view.seek(position);
+ block();
+ return this.view.seek(old_position);
+ } else {
+ return this.view.seek(position);
+ }
+ },
+ tell: function () {
+ return this.view.tell();
+ }
+};
+
+jParser.prototype.seek = jParser.prototype.structure.seek;
+jParser.prototype.tell = jParser.prototype.structure.tell;
+jParser.prototype.skip = function (offset) {
+ if (typeof offset === 'function') {
+ offset = offset();
+ }
+ return this.view.seek(this.view.tell() + offset);
+};
+
+jParser.prototype.parse = function (structure) {
+ // f, 1, 2 means f(1, 2)
+ if (structure instanceof Function) {
+ return structure.apply(this, Array.prototype.slice.call(arguments, 1));
+ }
+
+ // 'int32' is a shortcut for ['int32']
+ if (typeof structure === 'string') {
+ structure = [structure];
+ }
+
+ // ['string', 256] means structure['string'](256)
+ if (structure instanceof Array) {
+ var key = structure[0];
+ if (!(key in this.structure)) {
+ throw new Error("Missing structure for `" + key + "`");
+ }
+ return this.parse.apply(this, [this.structure[key]].concat(structure.slice(1)));
+ }
+
+ // {key: val} means {key: parse(val)}
+ if (typeof structure === 'object') {
+ var output = {};
+ for (var key in structure) {
+ output[key] = this.parse(structure[key]);
+ }
+ return output;
+ }
+
+ throw new Error("Unknown structure type `" + structure + "`");
+};
+
+
+var all;
+if (typeof self !== 'undefined') {
+ all = self;
+} else if (typeof window !== 'undefined') {
+ all = window;
+} else if (typeof global !== 'undefined') {
+ all = global;
+}
+// Browser + Web Worker
+all.jParser = jParser;
+// NodeJS + NPM
+if (typeof module !== 'undefined') {
+ module.exports = jParser;
+}
+
+})();
View
82 test/test.js
@@ -0,0 +1,82 @@
+
+if (typeof jDataView === 'undefined') {
+ jDataView = require('jDataView');
+}
+var module = QUnit.module;
+var test = QUnit.test;
+
+
+var buffer = jDataView.createBuffer(0x00,
+ 0xff, 0xfe, 0xfd, 0xfc,
+ 0xfa, 0x00, 0xba, 0x01);
+var view = new jDataView(buffer, 1);
+var parser = new jParser(view);
+
+function chr (x) {
+ return String.fromCharCode(x);
+}
+
+
+module("Values");
+test('uint', function () {
+ parser.seek(0);
+ equal(parser.parse('uint8'), 255);
+ equal(parser.parse('uint16'), 65022);
+ equal(parser.parse('uint32'), 3120626428);
+});
+
+test('int', function () {
+ parser.seek(0);
+ equal(parser.parse('int8'), -1);
+ equal(parser.parse('int16'), -514);
+ equal(parser.parse('int32'), -1174340868);
+});
+
+test('float', function () {
+ parser.seek(0);
+ equal(parser.parse('float32'), -1.055058432344064e+37);
+ parser.seek(0);
+ equal(parser.parse('float64'), 2.426842827241402e-300);
+});
+
+test('string', function () {
+ parser.seek(5);
+ equal(parser.parse('char'), chr(0));
+ equal(parser.parse(['string', 2]), chr(65533) + chr(1));
+});
+
+test('array', function () {
+ parser.seek(0);
+ deepEqual(parser.parse(['array', 'uint8', 8]),
+ [0xff, 0xfe, 0xfd, 0xfc, 0xfa, 0x00, 0xba, 0x01]);
+ parser.seek(0);
+ deepEqual(parser.parse(['array', 'int32', 2]),
+ [-50462977, 28967162]);
+});
+
+test('object', function () {
+ parser.seek(0);
+ deepEqual(parser.parse({
+ a: 'int32',
+ b: 'int8',
+ c: ['array', 'uint8', 2]
+ }), {
+ a: -50462977,
+ b: -6,
+ c: [0, 186]
+ });
+});
+
+test('seek', function () {
+ parser.seek(5);
+ equal(parser.tell(), 5);
+ parser.seek(parser.tell() - 2);
+ equal(parser.tell(), 3);
+
+ parser.seek(5, function () {
+ equal(parser.tell(), 5);
+ parser.seek(0);
+ equal(parser.tell(), 0);
+ });
+ equal(parser.tell(), 3);
+});
View
12 test/test.runner.html
@@ -0,0 +1,12 @@
+<link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css" type="text/css" media="screen" />
+<script type="text/javascript" src="http://code.jquery.com/qunit/git/qunit.js"></script>
+<script type="text/javascript" src="../../jDataView/src/jdataview.js"></script>
+<script type="text/javascript" src="../src/jparser.js"></script>
+
+<h1 id="qunit-header">QUnit example</h1>
+<h2 id="qunit-banner"></h2>
+<div id="qunit-testrunner-toolbar"></div>
+<h2 id="qunit-userAgent"></h2>
+<ol id="qunit-tests"></ol>
+
+<script type="text/javascript" src="test.js"></script>
View
10 test/test.runner.js
@@ -0,0 +1,10 @@
+
+var testrunner = require('qunit');
+testrunner.options.errorsOnly = true;
+testrunner.options.assertions = false;
+testrunner.options.summary = false;
+testrunner.options.coverage = false;
+testrunner.run({
+ code: '../src/jparser.js',
+ tests: './test.js'
+});
Please sign in to comment.
Something went wrong with that request. Please try again.