/*jslint laxbreak:true */ /*jslint laxcomma:true */ /*jslint loopfunc:true */ /*jslint strict:true */ /*jslint browser:true */ /*jslint devel:true */ define([ "underscore" , "toolbox" ] , function (_, Toolbox) { "use strict"; var Types = function(code) { this.code = code; this.length = null; this.unpack = null; this.typeMap = typeMap; this.getCode = function() { return this.code; }; this.getByteLength = function() { return this.length; }; if (_.isNumber(this.code)) { if (!_.isUndefined(typeMap[this.code])) { _.extend(this, typeMap[this.code]); } else { } } return this; } , TypesPrototype = { getInt8: function (chunk) { return new DataView(chunk.slice(0,typeMap[1].length)).getInt8(0, false); } , getUint8: function (chunk) { return new DataView(chunk.slice(0,typeMap[2].length)).getUint8(0, false); } , getInt16: function (chunk) { return new DataView(chunk.slice(0,typeMap[3].length)).getInt16(0, false); } , getUint16: function (chunk) { return new DataView(chunk.slice(0,typeMap[4].length)).getUint16(0, false); } , getInt32: function (chunk) { return new DataView(chunk.slice(0,typeMap[5].length)).getInt32(0, false); } , getUint32: function (chunk) { return new DataView(chunk.slice(0,typeMap[6].length)).getUint32(0, false); } , getFloat64: function (chunk) { return new DataView(chunk.slice(0,typeMap[7].length)).getFloat64(0, false); } , getString: function(chunk, length) { if (!_.isNumber(length) || length > chunk.byteLength) { length = chunk.byteLength; } return String.fromCharCode.apply(null, new Uint8Array(chunk.slice(0, length))); } // TODO: This might be optimizable , getUTFString: function (chunk, length) { var str = ''; if (!_.isNumber(length) || length > chunk.byteLength) { length = chunk.byteLength; } for (var i = 0; i < length; i++) { var slice = chunk.slice(i, i+1); var num = new DataView(slice).getUint8(0, false); str += num <= 0x7F ? num === 0x25 ? "%25" : String.fromCharCode(num) : "%" + num.toString(16); } return decodeURIComponent(str); } , getDate: function (chunk) { return new Date(TypesPrototype.getUint32(chunk) * 1000); } , getVersion: function (chunk) { return TypesPrototype.getInt8(chunk.slice(0,1)) + "." + TypesPrototype.getInt8(chunk.slice(1,2)); } , getModel: function (chunk) { return chunk; } , getUnknown: function (chunk) { // Unimplemented throw "ERROR_UNIMPLEMENTED"; // switch (chunk.byteLength) { // // We can tring a string // default: // // break; // } } , getType: function (chunk) { return TypesPrototype.getString(chunk.slice(0, 4)).toLowerCase(); } } , typeMap = { 1: { length: 1 , unpack: TypesPrototype.getInt8 } , 2: { length: 1 , unpack: TypesPrototype.getUint8 } , 3: { length: 2 , unpack: TypesPrototype.getInt16 } , 4: { length: 2 , unpack: TypesPrototype.getUint16 } , 5: { length: 4 , unpack: TypesPrototype.getInt32 } , 6: { length: 4 , unpack: TypesPrototype.getUint32 } , 7: { length: 8 , unpack: TypesPrototype.getFloat64 } // There is no unsigned 64bit integer in JS. , 8: { length: 8 , unpack: TypesPrototype.getFloat64 } , 9: { length: null , unpack: TypesPrototype.getUTFString } , 10: { length: 4 , unpack: TypesPrototype.getDate } , 11: { length: 2 , unpack: TypesPrototype.getVersion } , 12: { length: null , unpack: TypesPrototype.getModel } }; Types.prototype = TypesPrototype; return Types; });