[lib.es5] TypeScript interface of ArrayBuffer and DataView

TypeScript interface of ArrayBuffer and DataView
Email: 291148484@163.com
CSDN home page: https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343
Address: https://blog.csdn.net/qq_28550263/article/details/123169738
catalogue

1. ArrayBuffer

2. DataView

1. ArrayBuffer

The ArrayBuffer object is used to represent a generic, fixed length raw binary data buffer.

It is a byte array, which is usually called "byte array" in other languages.

You cannot directly manipulate the contents of ArrayBuffer, but through type array objects or DataView objects. They will represent the data in the buffer in specific formats and read and write the contents of the buffer through these formats.

1.1 grammar

new ArrayBuffer(length)
  • length: the size of the ArrayBuffer to be created, in bytes.

1.1.1 return value

An ArrayBuffer object of a specified size whose contents are initialized to 0.

1.1.2 abnormality

If length is greater than number MAX_ SAFE_ If integer (> = 2 * * 53) or is negative, a RangeError exception is thrown.

The ArrayBuffer constructor is used to create an ArrayBuffer object with a specified byte length.

1.2 description

1.2.1 properties

attributedescribe
ArrayBuffer.lengthThe length property of the ArrayBuffer constructor, with a value of 1.
ArrayBuffer.prototype.byteLengthRead only attribute, indicating the byte size of ArrayBuffer. It is generated when ArrayBuffer construction is completed and cannot be changed.
get ArrayBuffer[@@species]Returns the constructor of ArrayBuffer.
ArrayBuffer.prototype (en-US)Through the prototype object of ArrayBuffer, you can add attributes to all ArrayBuffer objects.

1.2.2 method

methoddescribe
ArrayBuffer.isView(arg)If the parameter is a view instance of ArrayBuffer, return true, such as type array object or DataView object; Otherwise, false is returned.
ArrayBuffer.transfer(oldBuffer [, newByteLength]) (experimental)Returns a new ArrayBuffer object whose contents are taken from the data in oldBuffer, and intercepts or supplements the data with 0 according to the size of newByteLength.

1.2.3 JavaScript example

The following example creates an 8-byte buffer and uses an Int32Array to reference it:

var buffer = new ArrayBuffer(8);
var view   = new Int32Array(buffer);

1.2.4 TypeScript interface

/**
 * Represents the original buffer of binary data, which is used to store data of different types of arrays.
 * ArrayBuffers Cannot read or write directly, but can be passed to a typed array or DataView object to interpret the original buffer as needed.
 */
interface ArrayBuffer {
    /**
     * Read only. Length of ArrayBuffer (bytes).
     */
    readonly byteLength: number;

    /**
     * Returns part of the ArrayBuffer.
     */
    slice(begin: number, end?: number): ArrayBuffer;
}

/**
 * ArrayBufferView And the ArrayBuffer type allowed by the buffer of the related typed array.
 */
interface ArrayBufferTypes {
    ArrayBuffer: ArrayBuffer;
}
type ArrayBufferLike = ArrayBufferTypes[keyof ArrayBufferTypes];

interface ArrayBufferConstructor {
    readonly prototype: ArrayBuffer;
    new(byteLength: number): ArrayBuffer;
    isView(arg: any): arg is ArrayBufferView;
}
declare var ArrayBuffer: ArrayBufferConstructor;

interface ArrayBufferView {
    /**
     * The ArrayBuffer instance referenced by the array.
     */
    buffer: ArrayBufferLike;

    /**
     * The byte length of the array.
     */
    byteLength: number;

    /**
     * The offset of the array, in bytes.
     */
    byteOffset: number;
}

2. DataView

DataView view is a low-level interface that can read and write multiple numeric types from binary ArrayBuffer objects. When using it, the byte order of different platforms does not need to be considered.

2.1 grammar

new DataView(buffer [, byteOffset [, byteLength]])
  • buffer an existing ArrayBuffer or SharedArrayBuffer object, which is the data source of DataView object.
  • byteOffset is optional. The byte offset of the first byte of the DataView object in the buffer. If not specified, it starts from the first byte by default.
  • byteLength is optional. The byte offset of the first byte of the DataView object in the buffer. If not specified, it starts from the first byte by default.

Return value
A new DataView object that represents the specified data cache. (this sentence may not be very helpful to clarify)

You can think of the returned object as an "interpreter" of the binary byte buffer array buffer - it knows how to convert the bytecode correctly when reading or writing. This means that it can handle integer and floating-point conversion, byte order and other related details at the binary level.

abnormal
RangeError
This exception is thrown if the value of the byteOffset or byteLength parameter causes the view to exceed the end of the buffer.
For example, if the buffer (buffer object) is 16 bytes long, the byteOffset parameter is 8, and the byteLength parameter is 10, this error will be thrown because the result view attempts to exceed the total length of the buffer object by 2 bytes.

2.2 description

2.2.1 Endianness (byte order)

The relative order of bytes in memory of a value that needs to be represented by multiple bytes varies according to the platform architecture.

Byte order, or byte order ("Endian", "endianness" or "byte order"), describes how a computer organizes bytes into corresponding numbers.
Each memory storage location has an index or address. Each byte can store an 8-bit number (i.e. between 0x00 and 0xff).
Therefore, you must reserve more than one byte to store a larger number. Now, most of the numbers that need to occupy multiple bytes are sorted in little endian, that is, the low-order bytes are arranged at the low address end of the memory and the high-order bytes are arranged at the high address end of the memory.

In contrast to the corresponding big endian arrangement, which can be called large byte order and high byte order), all Intel processors use little endian. Little endian means to use low bits to store more important information. Least to most significant (the least significant byte takes the first position, or the lowest address), which can be compared with the common date writing method in Europe (for example, 31 December 2050).

Naturally, big endian is in the opposite order and can be compared to ISO date format (e.g. 2050-12-31). Big endian is often called "network byte order", because Internet standards usually require big endian storage of data, starting from the standard Unix socket layer to the standardized binary data structure of the network. In addition, big endian was used in the 68000 series of old Mac computers and PowerPC microprocessors.

For example: store the number 0x12345678 in different byte order (i.e. 305 419 896 in decimal system):

little-endian: 0x78 0x56 0x34 0x12
big-endian: 0x12 0x34 0x56 0x78

var littleEndian = (function() {
  var buffer = new ArrayBuffer(2);
  new DataView(buffer).setInt16(0, 256, true /* When setting the value, the small endian byte order is used */);
  // Int16Array uses the system byte order (from which we can judge whether the system byte order is the small end byte order)
  return new Int16Array(buffer)[0] === 256;
})();
console.log(littleEndian); // Return true or false

2.2.2 digit integer value

Because JavaScript currently does not contain standards that support 64 bit integer values, DataView does not provide native 64 bit operations. As an alternative, you can implement your own getUint64() function to achieve an accuracy of up to number MAX_ SAFE_ The value of integer can meet the needs of some specific situations.

function getUint64(dataview, byteOffset, littleEndian) {
  // Divide the 64 bit integer value into two 32-bit integer values
  const left =  dataview.getUint32(byteOffset, littleEndian);
  const right = dataview.getUint32(byteOffset+4, littleEndian);

  // Merge two 32-bit integer values
  const combined = littleEndian? left + 2**32*right : 2**32*left + right;

  if (!Number.isSafeInteger(combined))
    console.warn(combined, 'exceeds MAX_SAFE_INTEGER. Precision may be lost');

  return combined;
}

Alternatively, if you need to fill 64 bits, you can create a BigInt. In addition, although native BigInt is much faster than the BigInt simulated in the client-side library, BigInt is always much slower than 32-bit integers in JavaScript because the size of BigInt is variable.

const BigInt = window.BigInt, bigThirtyTwo = BigInt(32), bigZero = BigInt(0);
function getUint64BigInt(dataview, byteOffset, littleEndian) {
  // Divide the 64 bit integer value into two 32-bit integer values
  const left = BigInt(dataview.getUint32(byteOffset|0, !!littleEndian)>>>0);
  const right = BigInt(dataview.getUint32((byteOffset|0) + 4|0, !!littleEndian)>>>0);

  // Combines two 32-bit integer values and returns
  return littleEndian ? (right<<bigThirtyTwo)|left : (left<<bigThirtyTwo)|right;
}

2.2.3 constructors, properties and methods

All DataView instances inherit from DataView.prototype And allows you to add additional properties to the DataView object.

2.2.3.1 constructor

DataView(): create a new DataView object.

2.2.3.2 instance properties

attributedescribe
DataView.prototype.bufferThe ArrayBuffer referenced by this view. Fixed at construction time, so it is read-only.
DataView.prototype.byteLengthThe length (in bytes) of this view from its ArrayBuffer. Fixed at construction time, so it is read-only.
DataView.prototype.byteOffsetThe offset (in bytes) of this view from its ArrayBuffer. Fixed at construction time, so it is read-only.

2.2.3.3 example method

methoddescribe
DataView.prototype.getInt8()Gets a signed 8-bit integer (in bytes) from the specified byte offset at the beginning of the view.
DataView.prototype.getUint8()Gets an unsigned 8-bit integer (unsigned byte) from the specified byte offset at the beginning of the view.
DataView.prototype.getInt16()Gets a signed 16 bit integer (short integer) from the specified byte offset at the beginning of the view.
DataView.prototype.getUint16()Gets an unsigned 16 bit integer (unsigned short) from the specified byte offset at the beginning of the view.
DataView.prototype.getInt32()Gets a signed 32-bit integer (long integer) from the specified byte offset at the beginning of the view.
DataView.prototype.getUint32()Gets an unsigned 32-bit integer (unsigned long) from the specified byte offset at the beginning of the view.
DataView.prototype.getFloat32()Gets a signed 32-bit floating point (float) from the specified byte offset at the beginning of the view.
DataView.prototype.getFloat64()Gets a signed 64 bit floating-point type (double precision) from the specified byte offset at the beginning of the view.
DataView.prototype.getBigInt64()Gets a signed 64 bit integer (long) from the specified byte offset at the beginning of the view.
DataView.prototype.getBigUint64()Gets an unsigned 64 bit integer (unsigned long) from the specified byte offset at the beginning of the view.
DataView.prototype.setInt8()Stores a signed 8-bit integer (byte) value at a specified byte offset from the beginning of the view.
DataView.prototype.setUint8()Stores an unsigned 8-bit integer (unsigned byte) value at a specified byte offset from the beginning of the view.
DataView.prototype.setInt16()Stores a signed 16 bit integer (short) value at the specified byte offset from the beginning of the view.
DataView.prototype.setUint16()Stores an unsigned 16 bit integer (unsigned short) value at a specified byte offset from the beginning of the view.
DataView.prototype.setInt32()Stores a signed 32-bit integer (long integer) value at the specified byte offset from the beginning of the view.
DataView.prototype.setUint32()Stores an unsigned 32-bit integer (unsigned long) value at a specified byte offset from the beginning of the view.
DataView.prototype.setFloat32()Stores a signed 32-bit floating-point value at a specified byte offset from the beginning of the view.
DataView.prototype.setFloat64()Stores a signed 64 bit floating-point (double precision) value at a specified byte offset from the beginning of the view.
DataView.prototype.setBigInt64()Stores a signed 64 bit integer value (long long) at the specified byte offset from the beginning of the view.
DataView.prototype.setBigUint64()Stores an unsigned 64 bit integer value (unsigned long) at the specified byte offset from the beginning of the view.

2.2.4 JavaScript example

var buffer = new ArrayBuffer(16);
var view = new DataView(buffer, 0);

view.setInt16(1, 42);
view.getInt16(1); // 42

2.2.5 TypeScript interface

interface DataView {
    readonly buffer: ArrayBuffer;
    readonly byteLength: number;
    readonly byteOffset: number;
    /**
     * Gets the Float32 value at the specified byte offset from the beginning of the view. No alignment constraints; Multibyte values can be obtained from any offset.
     * @param byteOffset The location in the buffer where the value should be retrieved.
     */
    getFloat32(byteOffset: number, littleEndian?: boolean): number;

    /**
     * Gets the Float64 value at the specified byte offset from the beginning of the view. No alignment constraints; Multibyte values can be obtained from any offset.
     * @param byteOffset The location in the buffer where the value should be retrieved.
     */
    getFloat64(byteOffset: number, littleEndian?: boolean): number;

    /**
     * Gets the Int8 value at the specified byte offset from the beginning of the view. No alignment constraints; Multibyte values can be obtained from any offset.
     * @param byteOffset The location in the buffer where the value should be retrieved.
     */
    getInt8(byteOffset: number): number;

    /**
     * Gets the Int16 value at the specified byte offset from the beginning of the view. No alignment constraints; Multibyte values can be obtained from any offset.
     * @param byteOffset The location in the buffer where the value should be retrieved.
     */
    getInt16(byteOffset: number, littleEndian?: boolean): number;
    /**
     * Gets the Int32 value at the specified byte offset from the beginning of the view. No alignment constraints; Multibyte values can be obtained from any offset.
     * @param byteOffset The location in the buffer where the value should be retrieved.
     */
    getInt32(byteOffset: number, littleEndian?: boolean): number;

    /**
     * Gets the Uint8 value at the specified byte offset from the beginning of the view. No alignment constraints; Multibyte values can be obtained from any offset.
     * @param byteOffset The location in the buffer where the value should be retrieved.
     */
    getUint8(byteOffset: number): number;

    /**
     * Gets the Uint16 value at the specified byte offset from the beginning of the view. No alignment constraints; Multibyte values can be obtained from any offset.
     * @param byteOffset The location in the buffer where the value should be retrieved.
     */
    getUint16(byteOffset: number, littleEndian?: boolean): number;

    /**
     * Gets the Uint32 value at the specified byte offset from the beginning of the view. No alignment constraints; Multibyte values can be obtained from any offset.
     * @param byteOffset The location in the buffer where the value should be retrieved.
     */
    getUint32(byteOffset: number, littleEndian?: boolean): number;

    /**
     * Stores the Float32 value at the specified byte offset from the beginning of the view.
     * @param byteOffset The position in the buffer where the value should be set.
     * @param value The value to set.
     * @param littleEndian If it is false or undefined, the large end value should be written, otherwise the small end value should be written.
     */
    setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void;

    /**
     * Stores a Float64 value at the specified byte offset from the beginning of the view.
     * @param byteOffset The position in the buffer where the value should be set.
     * @param value The value to set.
     * @param littleEndian If it is false or undefined, the large end value should be written, otherwise the small end value should be written.
     */
    setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void;

    /**
     * Stores an Int8 value at the specified byte offset from the beginning of the view.
     * @param byteOffset The position in the buffer where the value should be set.
     * @param value The value to set.
     */
    setInt8(byteOffset: number, value: number): void;

    /**
     * Stores an Int16 value at the specified byte offset from the beginning of the view.
     * @param byteOffset The position in the buffer where the value should be set.
     * @param value The value to set.
     * @param littleEndian If it is false or undefined, the large end value should be written, otherwise the small end value should be written.
     */
    setInt16(byteOffset: number, value: number, littleEndian?: boolean): void;

    /**
     * Stores an Int32 value at the specified byte offset from the beginning of the view.
     * @param byteOffset The position in the buffer where the value should be set.
     * @param value The value to set.
     * @param littleEndian If it is false or undefined, the large end value should be written, otherwise the small end value should be written.
     */
    setInt32(byteOffset: number, value: number, littleEndian?: boolean): void;

    /**
     * Stores a Uint8 value at the specified byte offset from the beginning of the view.
     * @param byteOffset The position in the buffer where the value should be set.
     * @param value The value to set.
     */
    setUint8(byteOffset: number, value: number): void;

    /**
     * Stores a Uint16 value at the specified byte offset from the beginning of the view.
     * @param byteOffset The position in the buffer where the value should be set.
     * @param value The value to set.
     * @param littleEndian If it is false or undefined, the large end value should be written, otherwise the small end value should be written.
     */
    setUint16(byteOffset: number, value: number, littleEndian?: boolean): void;

    /**
     * Stores a Uint32 value at the specified byte offset from the beginning of the view.
     * @param byteOffset The position in the buffer where the value should be set.
     * @param value The value to set.
     * @param littleEndian If it is false or undefined, the large end value should be written, otherwise the small end value should be written.
     */
    setUint32(byteOffset: number, value: number, littleEndian?: boolean): void;
}

Keywords: Javascript TypeScript

Added by MemphiS on Sun, 27 Feb 2022 18:04:26 +0200