Skip to content

Instantly share code, notes, and snippets.

@jmshal
Created March 21, 2015 06:35
Show Gist options
  • Save jmshal/40cf2f7983dde5807cdc to your computer and use it in GitHub Desktop.
Save jmshal/40cf2f7983dde5807cdc to your computer and use it in GitHub Desktop.
Playing around with DataView and ArrayBuffer in JavaScript...
var typeReference = [
['Byte', 'Int8' ],
['UnsignedByte', 'Uint8' ],
['Short', 'Int16' ],
['UnsignedShort', 'Uint16' ],
['Long', 'Int32' ],
['UnsignedLong', 'Uint32' ],
['Float', 'Float32'],
['Double', 'Float64']
];
function PacketBuilder () {
this.packetData = [];
}
typeReference.forEach(function (info) {
PacketBuilder.prototype['set' + info[0]] =
function (offset, value) {
this.packetData[offset] = [info[1], value];
};
});
PacketBuilder.prototype.setString = function (offset, value) {
var chars = Array.prototype.slice.call(value);
this.setByte(offset++, value.length);
chars.forEach(function (char, index) {
this.setUnsignedByte(offset + index, char.charCodeAt(0));
}, this);
};
PacketBuilder.prototype.toDataView = function () {
var view = new DataView(new ArrayBuffer(this.packetData.length));
this.packetData.forEach(function (packetData, offset) {
view['set' + packetData[0]](offset, packetData[1]);
});
return view;
};
//
function PacketReader (arrayBuffer) {
this.dataView = new DataView(arrayBuffer);
}
typeReference.forEach(function (info) {
PacketReader.prototype['get' + info[0]] =
function (offset) {
return this.dataView['get' + info[1]](offset);
};
});
PacketReader.prototype.getString = function (offset) {
var data = '',
length = this.getByte(offset++);
while (length--) {
data += String.fromCharCode(this.getUnsignedByte(offset++));
}
return data;
};
//
function PacketStructure (packetId, definition) {
this.packetId = packetId;
this.definition = definition;
this.keys = Object.keys(definition);
}
PacketStructure.prototype.create = function (data) {
var index = 0;
var packet = new PacketBuilder();
packet.setUnsignedShort(index++, this.packetId);
this.keys.forEach(function (key) {
packet['set' + this.definition[key]](index++, data[key]);
switch (this.definition[key]) {
case 'String':
index += data[key].length;
break;
}
}, this);
return packet.toDataView().buffer;
};
PacketStructure.prototype.parse = function (arrayBuffer) {
var index = 0;
var reader = new PacketReader(arrayBuffer);
var packetId = reader.getUnsignedShort(index++);
console.log('packetId %s', packetId);
var data = {};
this.keys.forEach(function (key) {
data[key] = reader['get' + this.definition[key]](index++);
switch (this.definition[key]) {
case 'String':
index += data[key].length;
break;
}
}, this);
return data;
};
//
var messageStructure = new PacketStructure(10, {
test: 'Byte',
userId: 'UnsignedShort',
userName: 'String',
message: 'String'
});
var input = {
test: 6,
userId: 1000,
userName: 'Jacob Marshall',
message: 'Hello World!'
};
var packet = messageStructure.create(input);
var output = messageStructure.parse(packet); // {userId, userName, message}
console.log(input);
console.log(output);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment