Support for negative values in 'Drop bytes' and 'Take bytes'. Closes #266

This commit is contained in:
n1474335 2018-08-23 23:23:00 +01:00
parent e4fdadc573
commit 383fe50fc9
2 changed files with 75 additions and 19 deletions

View File

@ -5,7 +5,6 @@
*/
import Operation from "../Operation";
import OperationError from "../errors/OperationError";
/**
* Drop bytes operation
@ -20,7 +19,7 @@ class DropBytes extends Operation {
this.name = "Drop bytes";
this.module = "Default";
this.description = "Cuts a slice of the specified number of bytes out of the data.";
this.description = "Cuts a slice of the specified number of bytes out of the data. Negative values are allowed.";
this.inputType = "ArrayBuffer";
this.outputType = "ArrayBuffer";
this.args = [
@ -50,14 +49,25 @@ class DropBytes extends Operation {
* @throws {OperationError} if invalid input
*/
run(input, args) {
const start = args[0],
length = args[1],
applyToEachLine = args[2];
if (start < 0 || length < 0)
throw new OperationError("Error: Invalid value");
let start = args[0],
length = args[1];
const applyToEachLine = args[2];
if (!applyToEachLine) {
if (start < 0) { // Take from the end
start = input.byteLength + start;
}
if (length < 0) { // Flip start point
start = start + length;
if (start < 0) {
start = input.byteLength + start;
length = start - length;
} else {
length = -length;
}
}
const left = input.slice(0, start),
right = input.slice(start + length, input.byteLength);
const result = new Uint8Array(left.byteLength + right.byteLength);
@ -82,10 +92,28 @@ class DropBytes extends Operation {
}
lines.push(line);
let output = [];
let output = [],
s = start,
l = length;
for (i = 0; i < lines.length; i++) {
output = output.concat(lines[i].slice(0, start).concat(lines[i].slice(start+length, lines[i].length)));
if (s < 0) { // Take from the end
s = lines[i].length + s;
}
if (l < 0) { // Flip start point
s = s + l;
if (s < 0) {
s = lines[i].length + s;
l = s - l;
} else {
l = -l;
}
}
output = output.concat(lines[i].slice(0, s).concat(lines[i].slice(s+l, lines[i].length)));
output.push(0x0a);
s = start;
l = length;
}
return new Uint8Array(output.slice(0, output.length-1)).buffer;
}

View File

@ -5,7 +5,6 @@
*/
import Operation from "../Operation";
import OperationError from "../errors/OperationError";
/**
* Take bytes operation
@ -20,7 +19,7 @@ class TakeBytes extends Operation {
this.name = "Take bytes";
this.module = "Default";
this.description = "Takes a slice of the specified number of bytes from the data.";
this.description = "Takes a slice of the specified number of bytes from the data. Negative values are allowed.";
this.inputType = "ArrayBuffer";
this.outputType = "ArrayBuffer";
this.args = [
@ -50,15 +49,27 @@ class TakeBytes extends Operation {
* @throws {OperationError} if invalid value
*/
run(input, args) {
const start = args[0],
length = args[1],
applyToEachLine = args[2];
let start = args[0],
length = args[1];
const applyToEachLine = args[2];
if (start < 0 || length < 0)
throw new OperationError("Error: Invalid value");
if (!applyToEachLine) {
if (start < 0) { // Take from the end
start = input.byteLength + start;
}
if (length < 0) { // Flip start point
start = start + length;
if (start < 0) {
start = input.byteLength + start;
length = start - length;
} else {
length = -length;
}
}
if (!applyToEachLine)
return input.slice(start, start+length);
}
// Split input into lines
const data = new Uint8Array(input);
@ -77,9 +88,26 @@ class TakeBytes extends Operation {
lines.push(line);
let output = [];
let s = start,
l = length;
for (i = 0; i < lines.length; i++) {
output = output.concat(lines[i].slice(start, start+length));
if (s < 0) { // Take from the end
s = lines[i].length + s;
}
if (l < 0) { // Flip start point
s = s + l;
if (s < 0) {
s = lines[i].length + s;
l = s - l;
} else {
l = -l;
}
}
output = output.concat(lines[i].slice(s, s+l));
output.push(0x0a);
s = start;
l = length;
}
return new Uint8Array(output.slice(0, output.length-1)).buffer;
}