ArrayBuffer

Буфер типизированных массивов, предназначен для хранения данных в бинарном виде.

Объект данных не содержит информации о типе хранимых данных — это исключительно поток байтов. В отличии от стандартного ESMAScript, в реализации JavaScript на Iskra JS можно работать с каждым байтом информации напрямую.

// Создаем новый объект ArrayBuffer длиной 8 байт
var buffer = new ArrayBuffer(8);
 
buffer[0] = 128;  // Запишется 128, так как значение в диапазоне 0-255
buffer[2] = 257;  // Запишется 1, так как берутся младшие 8 бит переданного значения
 
print(buffer);
// Результат: new ArrayBuffer([128, 0, 1, 0, 0, 0, 0, 0])

Типизированные массивы

Для работы с данными различных типов, хранимых в объекте ArrayBuffer, используется экземпляр класса DataView. В реализации JavaScript для Iskra JS, ввиду ограничений платформы, у пользователя нет доступа к конструктору объекта DataView . Но существуют типовой набор ArrayBufferView для работы с данными большинства необходимых типов:

  • Uint8Array — массив целых чисел от 0 до 255 (2^8−1)
  • Uint8ClampedArray — массив целых чисел от 0 до 255 (2^8−1)
  • Uint16Array — массив целых чисел от 0 до 65535 (2^16−1)
  • Uint32Array — массив целых чисел от 0 до 4294967295 (2^32−1)
  • Float32Array — массив чисел с плавающей точкой одинарной точности
  • Float64Array — массив чисел с плавающей точкой двойной точности

Различие между Uint8ClampedArray и Uint8Array заключается в обработке значений, если они лежат вне диапазона 0–255. При работе с типизированным массивом Uint8ClampedArray, все значение меньше 0 будут записаны как 0, а более 255 будут равны 255. При работе с типизированным массивом Uint8Array, будет присвоено значение, формирующееся из первых 8 бит. Так число 259 (0000 0001 0000 0011) будет записано как число 3 (0000 0011). Аналогичным образом присваиваются значения элементов массивов Uint16Array и Uint32Array, с отличием в количестве используемых битов.

// Создадим типизированный массив, длинной 4 элемента.
// Если при создании не указан ArrayBuffer - он будет создан автоматически нужной длины
var z = new Uint8Array(4);
z[0] = 123;
z[2] = 321;
 
print(z);
// Выведет new Uint8Array([123, 0, 65, 0]), где 65 - это значение первых 8-и бит числа 321
 
 
 
// Создаем новый объект ArrayBuffer длиной 8 байт
var buffer = new ArrayBuffer(8);
 
buffer[0] = 128; // Запишет 128 в 0-й байт буфера
buffer[1] = 257; // Запишет 1 в 1-й байт буфера (берутся первые 8 бит)
print(buffer);
// Выведет =new ArrayBuffer([128, 1, 0, 0, 0, 0, 0, 0])
 
// Создаем объект типизированного массива, хранящего данные в buffer
// начиная с 0-го байта и длиной 2 элемента.
// Для класса Uint16Array - каждый элемент занимает 2 байта (16 бит)
// При указания буфера при создании - содержимое занятых байт не обнуляется
var x = new Uint16Array(buffer, 0, 2);
x[1] = 2343;
 
print(x);
// Выведет new Uint16Array([384, 2343])
// Так как первый элемент занимает два байта и его значение = buffer[1]*256+buffer[0] =
// = 1 * 256 + 128 = 384 (присвоено ранее и не обнулено), а второй элемент - мы присвоили
// обращаясь к типизированному массиву.
 
// Создаем еще один объект типизированного массива, хранящего данные в buffer
// Один буфер может содержать данные различных типов типизированных массивов
var y = new Uint32Array(buffer, 4, 1);
y[0] = 1234234234;
 
print(y);
// Выведет new Uint32Array([1234234234]) - типизированный массив с присвоенным нами элементу значением
 
print(buffer);
// Выведет  ArrayBuffer([128, 1, 39, 9, 122, 235, 144, 73])
// где первые два элемента - это элемент x[0],
// вторые два элемента - это элемент x[1],
// и оставшиеся 4 элемента (32 бита) - это элемент y[0]

Работа напрямую с буферами и типизированными массивами особенно удобна, когда необходимо получить поток побайтовых данных (например из файла), и отобразить содержимое этих данных, как различные структуры или переменные.