mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-20 14:56:19 -04:00
Dish._translate now uses ArrayBuffer as its intermediate type instead of byteArray. This should speed up operations on large files.
This commit is contained in:
parent
27677adbe8
commit
7d03be3a77
2 changed files with 100 additions and 27 deletions
|
@ -149,78 +149,75 @@ class Dish {
|
|||
*/
|
||||
async _translate(toType, notUTF8=false) {
|
||||
log.debug(`Translating Dish from ${Dish.enumLookup(this.type)} to ${Dish.enumLookup(toType)}`);
|
||||
const byteArrayToStr = notUTF8 ? Utils.byteArrayToChars : Utils.byteArrayToUtf8;
|
||||
|
||||
// Convert data to intermediate byteArray type
|
||||
// Convert data to intermediate ArrayBuffer type
|
||||
try {
|
||||
switch (this.type) {
|
||||
case Dish.STRING:
|
||||
this.value = this.value ? Utils.strToByteArray(this.value) : [];
|
||||
this.value = this.value ? Utils.strToArrayBuffer(this.value) : new ArrayBuffer;
|
||||
break;
|
||||
case Dish.NUMBER:
|
||||
this.value = typeof this.value === "number" ? Utils.strToByteArray(this.value.toString()) : [];
|
||||
this.value = typeof this.value === "number" ? Utils.strToArrayBuffer(this.value.toString()) : new ArrayBuffer;
|
||||
break;
|
||||
case Dish.HTML:
|
||||
this.value = this.value ? Utils.strToByteArray(Utils.unescapeHtml(Utils.stripHtmlTags(this.value, true))) : [];
|
||||
this.value = this.value ? Utils.strToArrayBuffer(Utils.unescapeHtml(Utils.stripHtmlTags(this.value, true))) : new ArrayBuffer;
|
||||
break;
|
||||
case Dish.ARRAY_BUFFER:
|
||||
// Array.from() would be nicer here, but it's slightly slower
|
||||
this.value = Array.prototype.slice.call(new Uint8Array(this.value));
|
||||
case Dish.BYTE_ARRAY:
|
||||
this.value = new Uint8Array(this.value).buffer;
|
||||
break;
|
||||
case Dish.BIG_NUMBER:
|
||||
this.value = BigNumber.isBigNumber(this.value) ? Utils.strToByteArray(this.value.toFixed()) : [];
|
||||
this.value = BigNumber.isBigNumber(this.value) ? Utils.strToArrayBuffer(this.value.toFixed()) : new ArrayBuffer;
|
||||
break;
|
||||
case Dish.JSON:
|
||||
this.value = this.value ? Utils.strToByteArray(JSON.stringify(this.value, null, 4)) : [];
|
||||
this.value = this.value ? Utils.strToArrayBuffer(JSON.stringify(this.value, null, 4)) : new ArrayBuffer;
|
||||
break;
|
||||
case Dish.FILE:
|
||||
this.value = await Utils.readFile(this.value);
|
||||
this.value = Array.prototype.slice.call(this.value);
|
||||
this.value = (await Utils.readFile(this.value)).buffer;
|
||||
break;
|
||||
case Dish.LIST_FILE:
|
||||
this.value = await Promise.all(this.value.map(async f => Utils.readFile(f)));
|
||||
this.value = this.value.map(b => Array.prototype.slice.call(b));
|
||||
this.value = [].concat.apply([], this.value);
|
||||
this.value = concatenateTypedArrays(...this.value).buffer;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} catch (err) {
|
||||
throw new DishError(`Error translating from ${Dish.enumLookup(this.type)} to byteArray: ${err}`);
|
||||
throw new DishError(`Error translating from ${Dish.enumLookup(this.type)} to ArrayBuffer: ${err}`);
|
||||
}
|
||||
|
||||
this.type = Dish.BYTE_ARRAY;
|
||||
this.type = Dish.ARRAY_BUFFER;
|
||||
|
||||
// Convert from byteArray to toType
|
||||
// Convert from ArrayBuffer to toType
|
||||
try {
|
||||
switch (toType) {
|
||||
case Dish.STRING:
|
||||
case Dish.HTML:
|
||||
this.value = this.value ? byteArrayToStr(this.value) : "";
|
||||
this.value = this.value ? Utils.arrayBufferToStr(this.value, !notUTF8) : "";
|
||||
this.type = Dish.STRING;
|
||||
break;
|
||||
case Dish.NUMBER:
|
||||
this.value = this.value ? parseFloat(byteArrayToStr(this.value)) : 0;
|
||||
this.value = this.value ? parseFloat(Utils.arrayBufferToStr(this.value, !notUTF8)) : 0;
|
||||
this.type = Dish.NUMBER;
|
||||
break;
|
||||
case Dish.ARRAY_BUFFER:
|
||||
this.value = new Uint8Array(this.value).buffer;
|
||||
case Dish.BYTE_ARRAY:
|
||||
this.value = Array.prototype.slice.call(new Uint8Array(this.value));
|
||||
this.type = Dish.ARRAY_BUFFER;
|
||||
break;
|
||||
case Dish.BIG_NUMBER:
|
||||
try {
|
||||
this.value = new BigNumber(byteArrayToStr(this.value));
|
||||
this.value = new BigNumber(Utils.arrayBufferToStr(this.value, !notUTF8));
|
||||
} catch (err) {
|
||||
this.value = new BigNumber(NaN);
|
||||
}
|
||||
this.type = Dish.BIG_NUMBER;
|
||||
break;
|
||||
case Dish.JSON:
|
||||
this.value = JSON.parse(byteArrayToStr(this.value));
|
||||
this.value = JSON.parse(Utils.arrayBufferToStr(this.value, !notUTF8));
|
||||
this.type = Dish.JSON;
|
||||
break;
|
||||
case Dish.FILE:
|
||||
this.value = new File(this.value, "unknown");
|
||||
this.type = Dish.FILE;
|
||||
break;
|
||||
case Dish.LIST_FILE:
|
||||
this.value = [new File(this.value, "unknown")];
|
||||
|
@ -230,7 +227,7 @@ class Dish {
|
|||
break;
|
||||
}
|
||||
} catch (err) {
|
||||
throw new DishError(`Error translating from byteArray to ${Dish.enumLookup(toType)}: ${err}`);
|
||||
throw new DishError(`Error translating from ArrayBuffer to ${Dish.enumLookup(toType)}: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,6 +371,26 @@ class Dish {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates a list of Uint8Arrays together
|
||||
*
|
||||
* @param {Uint8Array[]} arrays
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
function concatenateTypedArrays(...arrays) {
|
||||
let totalLength = 0;
|
||||
for (const arr of arrays) {
|
||||
totalLength += arr.length;
|
||||
}
|
||||
const result = new Uint8Array(totalLength);
|
||||
let offset = 0;
|
||||
for (const arr of arrays) {
|
||||
result.set(arr, offset);
|
||||
offset += arr.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dish data type enum for byte arrays.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue