Spaces:
Sleeping
Sleeping
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; | |
} | |