ECMAScript ArrayBuffer and TypedArrays
Handling Bytes in ECMAScript – Part 2
Writing ECMAScript Module
Foreword: In this part of the series I explain ECMAScript ArrayBuffer and TypedArrays for unsigned numbers.
By: Chrysanthus Date Published: 24 Jul 2016
Introduction
ArrayBuffer
An array buffer is an array of consecutive bytes. It is not an ordinary array. You can create an ArrayBuffer of any length. The statement to create an arraybuffer of length 3 is:
arrBuf = new ArrayBuffer(3);
where arrBuf is a name of your choice, and in the constructor the number for length must be typed.
An arraybuffer can be of any length. To know the length of an array buffer, you have to use the byteLength property of the arraybuffer, as in:
len = arrBuf.byteLength;
where len is a name of your choice.
To access the array buffer’s content, you need a Typed Array as explained below.
Position of Bytes
Immagine a buffer as a horizontal series of bytes. The first byte at index 0 is the leftmost byte. The second byte at index 1 is the byte just after the leftmost. The third byte at index 2 is the one that follows; and so on.
When an arraybuffer is created, each byte is initialized to zero (decimal).
TypedArrays
A typedarray is also a special kind of array. To manipulate a series of bytes, you need the typed array, Uint8Array. To manipulate pairs of bytes in a series (of bytes), you need the typed array, Uint16Array. To manipulate quadruple (4) bytes in a series (of bytes), you need the typed array, Uint32Array.
A typed array works with an array buffer of any length. To create an Uint8Array you type:
t8Arr = new Uint8Array(arrBuf);
where t8Arr is a name of your choice.
To create an Uint16Array you type:
t16Arr = new Uint16Array(arrBuf);
To create an Uint32Array you type:
T32Arr = new Uint32Array(arrBuf);
Remember, arrBuf is an array buffer of any length.
You can set the content of an arraybuffer using Uint8Array or Uint16Array or Uint32Array; it does not really matter.
The following code sets the first four bytes of an ArrayBuffer. In the code, 0x means hexadecimal.
arrBuf = new ArrayBuffer(9);
t8Arr = new Uint8Array(arrBuf);
t8Arr[0] = 0x01; t8Arr[1] = 0x02; t8Arr[2] = 0x03; t8Arr[3] = 0x04;
For the last statements you can use the decimal equivalent numbers as follows:
t8Arr[0] = 1; t8Arr[1] = 2; t8Arr[2] = 3; t8Arr[3] = 4;
The following code sets the first four bytes of an ArrayBuffer in groups of two bytes, using Uint16Array:
arrBuf = new ArrayBuffer(10);
t16Arr = new Uint16Array(arrBuf);
t16Arr[0] = 0x0201; t16Arr[1] = 0x0403;
There are certain things to note here: Since we are dealing with groups of two bytes, to set four bytes we need two elements at index 0 and index 1. In a hexadecinal number, the least significant byte is on the right while in the buffer, the same least significant byte is on the left. If a buffer is to be used by the Uint16Array, the buffer length has to be a multiple of 2.
For the last statements you can use the decimal equivalent numbers as follows:
t16Arr[0] = 513; t16Arr[1] = 1027;
The following code sets the first four bytes of an ArrayBuffer in groups of four bytes, using Uint32Array:
arrBuf = new ArrayBuffer(8);
t32Arr = new Uint32Array(arrBuf);
t32Arr[0] = 0x04030201;
The things to note here are similar to the above: Since we are dealing with groups of four bytes, to set four bytes we need one element at index 0. In a hexadecinal number, the least significant byte is on the right while in the buffer, the same least significant byte is on the left. If a buffer is to be used by the Uint32Array, the buffer length has to be a multiple of 4.
For the last statement you can use the decimal equivalent number as follows:
t32Arr[0] = 67305985;
You can get the contents of an arraybuffer in bytes using Uint8Array, or in groups of two bytes using Uint16Array, or in groups of four bytes using Uint32Array.
The following code displays the decimal equivaluent numbers of the bytes in the buffer:
arrBuf = new ArrayBuffer(9);
t8Arr = new Uint8Array(arrBuf);
t8Arr[0] = 1; t8Arr[1] = 2; t8Arr[2] = 3; t8Arr[3] = 4;
for (i=0; i<9; ++i)
console.log(t8Arr[i]);
The output is: 1, 2, 3, 4, 0, 0, 0, 0, 0
The following code displays the decimal equivaluent numbers of groups of two bytes in the buffer (it also displays the equivalent single bytes):
arrBuf = new ArrayBuffer(10);
t16Arr = new Uint16Array(arrBuf);
t16Arr[0] = 513; t16Arr[1] = 1027;
for (i=0; i<5; ++i)
console.log(t16Arr[i]);
t8Arr = new Uint8Array(arrBuf);
for (i=0; i<9; ++i)
console.log(t8Arr[i]);
The output is:
513, 1027, 0, 0, 0
and then
1, 2, 3, 4, 0, 0, 0, 0, 0.
The following code displays the decimal equivaluent numbers of groups of four bytes in the buffer (it also displays the equivalent single bytes):
arrBuf = new ArrayBuffer(8);
t32Arr = new Uint32Array(arrBuf);
t32Arr[0] = 67305985;
for (i=0; i<2; ++i)
console.log(t32Arr[i]);
t8Arr = new Uint8Array(arrBuf);
for (i=0; i<9; ++i)
console.log(t8Arr[i]);
The output is:
67305985, 0
and then
1, 2, 3, 4, 0, 0, 0, 0, undefined
The last value here is undefined because the buffer length here is 8, while the second iteration goes to the ninth position.
The following code places character codes in a buffer, one code per byte; it also displays the codes as decimal numbers:
givenstring = 'John Smith';
len = givenstring.length;
arrBuf = new ArrayBuffer(len);
t8Arr = new Uint8Array(arrBuf);
for (i=0; i<len; ++i)
{
t8Arr[i] = givenstring.charCodeAt(i);
}
for (i=0; i<len; ++i)
{
console.log(t8Arr[i]);
}
Note the use of the string object method, charCodeAt(i).
The output is: 74, 111, 104, 110, 32, 83, 109, 105, 116, 104
These numbers are called code units.
Converting Code Units to String Characters
The following code converts code units from a buffer to string characters:
givenstring = 'John Smith';
len = givenstring.length;
arrBuf = new ArrayBuffer(len);
t8Arr = new Uint8Array(arrBuf);
for (i=0; i<len; ++i)
{
t8Arr[i] = givenstring.charCodeAt(i);
}
str = '';
for (i=0; i<len; ++i)
{
str += String.fromCharCode(t8Arr [i]);
}
console.log(str);
Note the use of the String constructor and its method, fromCharCode().
The output is: John Smith
Comparing Western and Some Eastern Characters
Charaters of some eastern countries of the world, use pairs of bytes instead of single bytes. They use Uint16Array instead of Uint8Array. They have code points instead of code units. They use codePointAt() instead of charCodeAt() and use fromCodePoint() instead of fromCharCode().
The Buffer slice() Method
A slice is a copy of a segment from a series of bytes. You can use the buffer slice method to copy a segment to form another buffer. The syntax is:
newBuf = oldBuf.slice(start, end);
where start is an inclusive index and end is the exclusive index (just after).
The following code illustrates the use:
arrBuf = new ArrayBuffer(10);
t8Arr = new Uint8Array(arrBuf);
t8Arr[0] = 1; t8Arr[1] = 2; t8Arr[2] = 3; t8Arr[3] = 4; t8Arr[4] = 5; t8Arr[5] = 6;
newBuf = arrBuf.slice(2,4);
t16Arr = new Uint16Array(newBuf);
console.log(t16Arr[0]);
The output is: 1027.
That is it for this part of the series. We stop here and continue in the next part.
Chrys
Related Links
Internet Socket and ECMAScriptHandling Bytes in ECMAScript
ECMAScript Bitwise Operators
ECMAScript Module Essentials
More Related Links
Node Mailsend
EMySQL API
Node.js Web Development Course
Major in Website Design
Low Level Programming - Writing ECMAScript Module
ECMAScript Course
BACK NEXT