An overview of the

This article provides readers with an understanding of how numeric types (including but not limited to Number types) are handled in JavaScript by converting numeric data to binary data.

Binary data is rarely encountered in everyday JavaScript, but it is possible to use binary data formats when you use Websockets to interact with data from the back end. Therefore, in order to better understand WebSocket transport binaries in future posts in this series, it is important to understand how binary data is manipulated and stored in JavaScript.

The main contents of this paper are as follows:

  • How to operate and store binary data in JavaScript — ArrayBuffer storage structure related basic knowledge and corresponding DataView related data type basic knowledge and API interface, at the same time the byte order problem is introduced.
  • Int and Short are examples of how numeric data in JavaScript can be converted to binary data.
  • Using the Long type as an example, you can see how the Long type is represented in JavaScript and converted to binary data.
  • How to convert binary data into digital data in JavaScript.

This article is not strongly related to WebSocket, but is included in this series as a foundation for passing binary data in WebSocket.

If you are not familiar with WebSocket, or don’t understand its usage scenarios and details, you can read my previous blog, The Basics of WebSocket series.

If you want to learn about the handling and conversion between String and binary, you can refer to a later article in the WebSocket series (this will be replaced later).

If you want to learn about binary delivery and parsing in WebSocket, you can read a later article in the WebSocket series (this will be replaced when the article is published).

How do you store and manipulate binary data in JavaScript

Now that you know why you need to use binary data, let’s take a look at how to store and manipulate binary data in JavaScript.

ArrayBuffer

First, we’ll look at the ArrayBuffer used in JavaScript to store binary data.

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

In the MDN documentation, you can see an introduction to ArrayBuffer. It is a data object used in JavaScript for binary data storage.

The following uses an example to briefly introduce the operations related to ArrayBuffer.

const buffer = new ArrayBuffer(8);

buffer.byteLength; // The result is 8
Copy the code

The above example creates a binary data buffer of 8 bytes in length. A buffer is just a space of data storage, and how this storage space is read is entirely up to the user. For example, 8 bytes can be considered as 2 ints, 1 Long, or 4 Short.

DataView

Having looked at the ArrayBuffer that stores data, let’s look at the DataView that reads and writes data.

DataView is a low-level interface that can read and write multiple numeric types from an ArrayBuffer object, regardless of platform byte order.

This is an introduction to DataView in MDN. DataView provides a number of APIS for reading and writing data, which will be illustrated in the next three chapters. First, however, we need to look at the problem of byte order mentioned in the instructions.

Byte order

In current computer systems, there are two kinds of byte order:

  • Big-endian byte order: the highest byte is first, the lowest byte is last. In line with human reading habits.
  • Small-endian byte order: the lowest byte is first, the highest byte is last. Conforms to computer reading habits.

The order mentioned above is for multi-byte objects, such as Int and Long. Int 0x1234, for example. If the byte order is big endian, the data is 0x1234 in the usual human notation. If the order is small endian, the usual human way of writing numbers would be 0x3412.

For single-byte objects such as Byte data, there is no such thing as Byte order.

Different byte orders may be used on different platforms, which is known as the byte order problem. DataView’s so-called platform-free byte order problem means that data written and read simultaneously with DataView is consistent.

How can numeric data in JavaScript be converted to binary data

With an overview of ArrayBuffer and DataView, let’s take a look at how it performs binary data manipulation.

In this chapter, I take the Short and Int types as examples to explain related operations.

let buffer = new ArrayBuffer(6); // Initializes a binary data buffer of 6 bytes
let dataView = new DataView(buffer);

dataView.setInt16(0.3); // Place a Short of type 3 starting at the 0th Byte (2 bytes)
dataView.setInt32(2.15); // Start with the second Byte and place a Short of 15 (4 bytes).
Copy the code

In the example above, we initialized a total of six bytes of storage space, filling it with one Short (2 bytes) and one Int (4 bytes).

DataView also provides a number of APIS for handling other data types, such as unsigned, floating point, and so on. They are used in the same way as the apis described above, which we will not cover here, but those who want to learn more about the API can refer to the MDN documentation.

How do YOU represent Long in JavaScript and convert it to binary data

Through the API provided by DataView, we know how to handle Short, Int, Float, and Double types. So what if it’s a Long type that doesn’t have a handler in the native API?

First, we need to understand the structure of the Long data type, which is a data type consisting of a high four bytes and a low four bytes. Since Long represents a larger range of data than Number, we use two objects of type Int in JavaScript to represent data of type Long. For details, see my previous blog long.js source code analysis and learning.

Now that we understand how to store Long types in JavaScript, we know how to store them.

import Long from 'long';

let long = Long.fromString('123');
let buffer = new ArrayBuffer(8);
let dataView = new DataView(buffer);

dataView.setInt32(0, long.high); // Place it in big-endian order
dataView.setInt32(4, long.low);
Copy the code

In the example above, we split a Long into two ints and put them into an ArrayBuffer in big-endian order. Similarly, if you want to place the data in small endian order, you only need to partially process the data before putting it in, and I won’t go into more details here.

How do I convert binary data to JavaScript data types

Once you know how to convert data to binary data stored in an ArrayBuffer, you can easily figure out how to do the reverse — read the data from the ArrayBuffer and convert it to data types commonly used in JavaScript.

import Long from 'long';

let buffer = new ArrayBuffer(14); // Initialize a binary data buffer of 14 bytes
let dataView = new DataView(buffer);
let long = Long.fromString('123');


// Data writing process

dataView.setInt16(0.3); // Place a Short of type 3 starting at the 0th Byte (2 bytes)
dataView.setInt32(2.15); // Start with the second Byte and place a Short of 15 (4 bytes).

dataView.setInt32(6, long.high); // Place it in big-endian order
dataView.setInt32(10, long.low);

// Data read process

let shortNumber = dataView.getInt16(0);
let intNumber = dataView.getInt32(2);

let longNumber = Long.fromBits(dataView.getInt32(10), dataView.getInt32(6)); // The constructor takes 16 bits lower and 16 bits higher
Copy the code

In the example above, we converted a string of binary data into a common data type in JavaScript.

conclusion

By using ArrayBuffer and DataView, we can quickly convert digital data from binary to JavaScript common data types such as Int and Short. We can also convert these data types to binary data. With this basic knowledge, we should be able to understand the process and processing logic of using WebSocket for binary data transfer in a later blog post.

In the next blog post, we will cover the binary processing and conversion operations related to String types, for those who are interested.

Some references

Ruan Yifeng’s introduction on byte order