You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
2.7 KiB
83 lines
2.7 KiB
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); |
|
packet.attachments = undefined; // 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; |
|
}
|
|
|