84 lines
2.7 KiB
JavaScript
84 lines
2.7 KiB
JavaScript
import { isBinary } from "./is-binary.js";
|
|
/**
|
|
* Replaces every Buffer | ArrayBuffer | Blob | File in packet with a numbered placeholder.
|
|
*
|
|
* @param {Object} packet - socket.io event packet
|
|
* @return {Object} with deconstructed packet and list of buffers
|
|
* @public
|
|
*/
|
|
export function deconstructPacket(packet) {
|
|
const buffers = [];
|
|
const packetData = packet.data;
|
|
const pack = packet;
|
|
pack.data = _deconstructPacket(packetData, buffers);
|
|
pack.attachments = buffers.length; // number of binary 'attachments'
|
|
return { packet: pack, buffers: buffers };
|
|
}
|
|
function _deconstructPacket(data, buffers) {
|
|
if (!data)
|
|
return data;
|
|
if (isBinary(data)) {
|
|
const placeholder = { _placeholder: true, num: buffers.length };
|
|
buffers.push(data);
|
|
return placeholder;
|
|
}
|
|
else if (Array.isArray(data)) {
|
|
const newData = new Array(data.length);
|
|
for (let i = 0; i < data.length; i++) {
|
|
newData[i] = _deconstructPacket(data[i], buffers);
|
|
}
|
|
return newData;
|
|
}
|
|
else if (typeof data === "object" && !(data instanceof Date)) {
|
|
const newData = {};
|
|
for (const key in data) {
|
|
if (Object.prototype.hasOwnProperty.call(data, key)) {
|
|
newData[key] = _deconstructPacket(data[key], buffers);
|
|
}
|
|
}
|
|
return newData;
|
|
}
|
|
return data;
|
|
}
|
|
/**
|
|
* Reconstructs a binary packet from its placeholder packet and buffers
|
|
*
|
|
* @param {Object} packet - event packet with placeholders
|
|
* @param {Array} buffers - binary buffers to put in placeholder positions
|
|
* @return {Object} reconstructed packet
|
|
* @public
|
|
*/
|
|
export function reconstructPacket(packet, buffers) {
|
|
packet.data = _reconstructPacket(packet.data, buffers);
|
|
delete packet.attachments; // no longer useful
|
|
return packet;
|
|
}
|
|
function _reconstructPacket(data, buffers) {
|
|
if (!data)
|
|
return data;
|
|
if (data && data._placeholder === true) {
|
|
const isIndexValid = typeof data.num === "number" &&
|
|
data.num >= 0 &&
|
|
data.num < buffers.length;
|
|
if (isIndexValid) {
|
|
return buffers[data.num]; // appropriate buffer (should be natural order anyway)
|
|
}
|
|
else {
|
|
throw new Error("illegal attachments");
|
|
}
|
|
}
|
|
else if (Array.isArray(data)) {
|
|
for (let i = 0; i < data.length; i++) {
|
|
data[i] = _reconstructPacket(data[i], buffers);
|
|
}
|
|
}
|
|
else if (typeof data === "object") {
|
|
for (const key in data) {
|
|
if (Object.prototype.hasOwnProperty.call(data, key)) {
|
|
data[key] = _reconstructPacket(data[key], buffers);
|
|
}
|
|
}
|
|
}
|
|
return data;
|
|
}
|