My Octopress Blog

A blogging framework for hackers.

JavaScript - Typed Arrays, ArrayBuffer and DataView

JavaScript - 

Typed arrays

It has become clear that there are times when it would be helpful for JavaScript code to be able to quickly and easily manipulate raw binary data.In the past, this had to be simulated by treating the raw data as a string and using the charCodeAt() method to read the bytes from the data buffer.

Consider this C structure:

1
2
3
4
5
struct someStruct {
  unsigned long id;
  char username[16];
  float amountDue;
};

You can access a buffer containing data in this format like this:

1
2
3
4
5
var buffer = new ArrayBuffer(24);
// ... read the data into the buffer ...
var idView = new Uint32Array(buffer, 0, 1);
var usernameView = new Uint8Array(buffer, 4, 16);
var amountDueView = new Float32Array(buffer, 20, 1);

ArrayBuffer

The ArrayBuffer is a data type that is used to represent a generic, fixed-length binary data buffer. You can’t directly manipulate the contents of an ArrayBuffer; instead, you create an ArrayBufferView object which represents the buffer in a specific format, and use that to read and write the contents of the buffer.

1
var buf = new ArrayBuffer(32);

DataView

An ArrayBuffer is a useful object for representing an arbitrary chunk of data. In many cases, such data will be read from disk or from the network, and will not follow the alignment restrictions that are imposed on the Typed Array Views described earlier. In addition, the data will often be heterogeneous in nature and have a defined byte order. The DataView view provides a low-level interface for reading such data from and writing it to an ArrayBuffer.

1
2
3
4
5
6
7
8
let buffer = new ArrayBuffer(NTP_PACKET_SIZE);
let data = new DataView(buffer);
// Set the first byte.
data.setUint8(0, NTP_MODE_CLIENT | (NTP_VERSION << 3));
// Set the 40th byte. 
data.setUint32(TRANSMIT_TIME_OFFSET, s, false);
// Set the 44th byte. 
data.setUint32(TRANSMIT_TIME_OFFSET+4, f, false);

Trick to check the Endian type of architecture your script is running: 

1
2
3
4
5
var littleEndian = (function() {
  var buffer = new ArrayBuffer(2);
  new DataView(buffer).setInt16(0, 256, true);
  return new Int16Array(buffer)[0] === 256;
})();

Reference:

DataView:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays/DataView ArrayBuffer:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays/ArrayBuffer Typed Array Specification:http://www.khronos.org/registry/typedarray/specs/latest/