Skip to content

Commit

Permalink
SFTPStream: update Read/WriteStream implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
mscdex committed Jul 8, 2019
1 parent 053983a commit 6ecc420
Show file tree
Hide file tree
Showing 2 changed files with 348 additions and 132 deletions.
118 changes: 118 additions & 0 deletions lib/node-fs-compat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
'use strict';

var inspect = require('util').inspect;

function assert(value, message) {
if (!value)
throw new ERR_INTERNAL_ASSERTION(message);
}
assert.fail = function fail(message) {
throw new ERR_INTERNAL_ASSERTION(message);
};

// Only use this for integers! Decimal numbers do not work with this function.
function addNumericalSeparator(val) {
var res = '';
var i = val.length;
var start = val[0] === '-' ? 1 : 0;
for (; i >= start + 4; i -= 3)
res = `_${val.slice(i - 3, i)}${res}`;
return `${val.slice(0, i)}${res}`;
}

function oneOf(expected, thing) {
assert(typeof thing === 'string', '`thing` has to be of type string');
if (Array.isArray(expected)) {
var len = expected.length;
assert(len > 0, 'At least one expected value needs to be specified');
expected = expected.map((i) => String(i));
if (len > 2) {
return `one of ${thing} ${expected.slice(0, len - 1).join(', ')}, or `
+ expected[len - 1];
} else if (len === 2) {
return `one of ${thing} ${expected[0]} or ${expected[1]}`;
} else {
return `of ${thing} ${expected[0]}`;
}
} else {
return `of ${thing} ${String(expected)}`;
}
}



exports.ERR_INTERNAL_ASSERTION = class ERR_INTERNAL_ASSERTION extends Error {
constructor(message) {
super();
Error.captureStackTrace(this, ERR_INTERNAL_ASSERTION);

var suffix = 'This is caused by either a bug in ssh2-streams '
+ 'or incorrect usage of ssh2-streams internals.\n'
+ 'Please open an issue with this stack trace at '
+ 'https://github.com/mscdex/ssh2-streams/issues\n';

this.message = (message === undefined ? suffix : `${message}\n${suffix}`);
}
};

exports.ERR_OUT_OF_RANGE = class ERR_OUT_OF_RANGE extends RangeError {
constructor(str, range, input, replaceDefaultBoolean) {
super();
Error.captureStackTrace(this, ERR_OUT_OF_RANGE);

assert(range, 'Missing "range" argument');
var msg = (replaceDefaultBoolean
? str
: `The value of "${str}" is out of range.`);
var received;
if (Number.isInteger(input) && Math.abs(input) > 2 ** 32) {
received = addNumericalSeparator(String(input));
} else if (typeof input === 'bigint') {
received = String(input);
if (input > 2n ** 32n || input < -(2n ** 32n))
received = addNumericalSeparator(received);
received += 'n';
} else {
received = inspect(input);
}
msg += ` It must be ${range}. Received ${received}`;

this.message = msg;
}
};

exports.ERR_INVALID_ARG_TYPE = class ERR_INVALID_ARG_TYPE extends TypeError {
constructor(name, expected, actual) {
super();
Error.captureStackTrace(this, ERR_INVALID_ARG_TYPE);

assert(typeof name === 'string', `'name' must be a string`);

// determiner: 'must be' or 'must not be'
var determiner;
if (typeof expected === 'string' && expected.startsWith('not ')) {
determiner = 'must not be';
expected = expected.replace(/^not /, '');
} else {
determiner = 'must be';
}

var msg;
if (name.endsWith(' argument')) {
// For cases like 'first argument'
msg = `The ${name} ${determiner} ${oneOf(expected, 'type')}`;
} else {
var type = (name.includes('.') ? 'property' : 'argument');
msg = `The "${name}" ${type} ${determiner} ${oneOf(expected, 'type')}`;
}

msg += `. Received type ${typeof actual}`;

this.message = msg;
}
};

exports.validateNumber = function validateNumber(value, name) {
if (typeof value !== 'number')
throw new ERR_INVALID_ARG_TYPE(name, 'number', value);
};
Loading

0 comments on commit 6ecc420

Please sign in to comment.