/*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 that , Types = Toolbox.Base.extend({ constructor: function (code) { this.code = code , this.length = null ; if (_.isNumber(code)) { if (!_.isUndefined(Types.typeMap[code])) { _.extend(this, Types.typeMap[code]); } else { } } return this; } , code: null , length: null , unpack: null , getCode: function() { return this.code; } , getByteLength: function() { return this.length; } } , { typeMap: { 1: { length: 1 , unpack: function (chunk) { Types.getInt8(chunk); } } , 2: { length: 1 , unpack: function (chunk) { Types.getUint8(chunk); } } , 3: { length: 2 , unpack: function (chunk) { Types.getInt16(chunk); } } , 4: { length: 2 , unpack: function (chunk) { Types.getUint16(chunk); } } , 5: { length: 4 , unpack: function (chunk) { Types.getInt32(chunk); } } , 6: { length: 4 , unpack: function (chunk) { Types.getUint32(chunk); } } , 7: { length: 8 , unpack: function (chunk) { Types.getFloat64(chunk); } } // There is no unsigned 64bit integer in JS. , 8: { length: 8 , unpack: function (chunk) { Types.getFloat64(chunk); } } , 9: { length: null , unpack: function (chunk, length) { Types.getUTFString(chunk, length); } } , 10: { length: 4 , unpack: function (chunk) { Types.getDate(chunk); } } , 11: { length: 2 , unpack: function (chunk) { Types.getVersion(chunk); } } , 12: { length: null , unpack: function (chunk, length) { Types.getModel(chunk, length); } } } , getInt8: function (chunk) { return new DataView(chunk.slice(0,Types.typeMap[1].length)).getInt8(0, false); } , getUint8: function (chunk) { return new DataView(chunk.slice(0,Types.typeMap[2].length)).getUint8(0, false); } , getInt16: function (chunk) { return new DataView(chunk.slice(0,Types.typeMap[3].length)).getInt16(0, false); } , getUint16: function (chunk) { return new DataView(chunk.slice(0,Types.typeMap[4].length)).getUint16(0, false); } , getInt32: function (chunk) { return new DataView(chunk.slice(0,Types.typeMap[5].length)).getInt32(0, false); } , getUint32: function (chunk) { return new DataView(chunk.slice(0,Types.typeMap[6].length)).getUint32(0, false); } , getFloat64: function (chunk) { return new DataView(chunk.slice(0,Types.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(Types.getUint32(chunk)); } , getVersion: function (chunk) { return Types.getInt8(chunk.slice(0,1)) + "." + Types.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 Types.getString(chunk.slice(0, 4)).toLowerCase(); } }); return Types; });