|
|
|
'use strict';
|
|
|
|
|
|
|
|
const binding = process.binding('util');
|
|
|
|
|
|
|
|
const kArrowMessagePrivateSymbolIndex = binding['arrow_message_private_symbol'];
|
|
|
|
const kDecoratedPrivateSymbolIndex = binding['decorated_private_symbol'];
|
|
|
|
|
|
|
|
// The `buffer` module uses this. Defining it here instead of in the public
|
|
|
|
// `util` module makes it accessible without having to `require('util')` there.
|
|
|
|
exports.customInspectSymbol = Symbol('util.inspect.custom');
|
|
|
|
|
|
|
|
// Mark that a method should not be used.
|
|
|
|
// Returns a modified function which warns once by default.
|
|
|
|
// If --no-deprecation is set, then it is a no-op.
|
|
|
|
exports.deprecate = function deprecate(fn, msg, code) {
|
|
|
|
// Allow for deprecating things in the process of starting up.
|
|
|
|
if (global.process === undefined) {
|
|
|
|
return function() {
|
|
|
|
return exports.deprecate(fn, msg, code).apply(this, arguments);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (process.noDeprecation === true) {
|
|
|
|
return fn;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (code !== undefined && typeof code !== 'string')
|
|
|
|
throw new TypeError('`code` argument must be a string');
|
|
|
|
|
|
|
|
var warned = false;
|
|
|
|
function deprecated() {
|
|
|
|
if (!warned) {
|
|
|
|
warned = true;
|
|
|
|
if (code !== undefined) {
|
|
|
|
process.emitWarning(msg, 'DeprecationWarning', code, deprecated);
|
|
|
|
} else {
|
|
|
|
process.emitWarning(msg, 'DeprecationWarning', deprecated);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (new.target) {
|
|
|
|
return Reflect.construct(fn, arguments, new.target);
|
|
|
|
}
|
|
|
|
return fn.apply(this, arguments);
|
|
|
|
}
|
|
|
|
|
|
|
|
// The wrapper will keep the same prototype as fn to maintain prototype chain
|
|
|
|
Object.setPrototypeOf(deprecated, fn);
|
|
|
|
if (fn.prototype) {
|
|
|
|
// Setting this (rather than using Object.setPrototype, as above) ensures
|
|
|
|
// that calling the unwrapped constructor gives an instanceof the wrapped
|
|
|
|
// constructor.
|
|
|
|
deprecated.prototype = fn.prototype;
|
|
|
|
}
|
|
|
|
|
|
|
|
return deprecated;
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.decorateErrorStack = function decorateErrorStack(err) {
|
|
|
|
if (!(exports.isError(err) && err.stack) ||
|
|
|
|
binding.getHiddenValue(err, kDecoratedPrivateSymbolIndex) === true)
|
|
|
|
return;
|
|
|
|
|
|
|
|
const arrow = binding.getHiddenValue(err, kArrowMessagePrivateSymbolIndex);
|
|
|
|
|
|
|
|
if (arrow) {
|
|
|
|
err.stack = arrow + err.stack;
|
|
|
|
binding.setHiddenValue(err, kDecoratedPrivateSymbolIndex, true);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.isError = function isError(e) {
|
|
|
|
return exports.objectToString(e) === '[object Error]' || e instanceof Error;
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.objectToString = function objectToString(o) {
|
|
|
|
return Object.prototype.toString.call(o);
|
|
|
|
};
|
|
|
|
|
|
|
|
const noCrypto = !process.versions.openssl;
|
|
|
|
exports.assertCrypto = function() {
|
|
|
|
if (noCrypto)
|
|
|
|
throw new Error('Node.js is not compiled with openssl crypto support');
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.kIsEncodingSymbol = Symbol('node.isEncoding');
|
|
|
|
|
|
|
|
// The loop should only run at most twice, retrying with lowercased enc
|
|
|
|
// if there is no match in the first pass.
|
|
|
|
// We use a loop instead of branching to retry with a helper
|
|
|
|
// function in order to avoid the performance hit.
|
|
|
|
// Return undefined if there is no match.
|
|
|
|
exports.normalizeEncoding = function normalizeEncoding(enc) {
|
|
|
|
if (!enc) return 'utf8';
|
|
|
|
var retried;
|
|
|
|
while (true) {
|
|
|
|
switch (enc) {
|
|
|
|
case 'utf8':
|
|
|
|
case 'utf-8':
|
|
|
|
return 'utf8';
|
|
|
|
case 'ucs2':
|
|
|
|
case 'ucs-2':
|
|
|
|
case 'utf16le':
|
|
|
|
case 'utf-16le':
|
|
|
|
return 'utf16le';
|
|
|
|
case 'latin1':
|
|
|
|
case 'binary':
|
|
|
|
return 'latin1';
|
|
|
|
case 'base64':
|
|
|
|
case 'ascii':
|
|
|
|
case 'hex':
|
|
|
|
return enc;
|
|
|
|
default:
|
|
|
|
if (retried) return; // undefined
|
|
|
|
enc = ('' + enc).toLowerCase();
|
|
|
|
retried = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Filters duplicate strings. Used to support functions in crypto and tls
|
|
|
|
// modules. Implemented specifically to maintain existing behaviors in each.
|
|
|
|
exports.filterDuplicateStrings = function filterDuplicateStrings(items, low) {
|
|
|
|
const map = new Map();
|
|
|
|
for (var i = 0; i < items.length; i++) {
|
|
|
|
const item = items[i];
|
|
|
|
const key = item.toLowerCase();
|
|
|
|
if (low) {
|
|
|
|
map.set(key, key);
|
|
|
|
} else {
|
|
|
|
map.set(key, item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Array.from(map.values()).sort();
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.cachedResult = function cachedResult(fn) {
|
|
|
|
var result;
|
|
|
|
return () => {
|
|
|
|
if (result === undefined)
|
|
|
|
result = fn();
|
|
|
|
return result.slice();
|
|
|
|
};
|
|
|
|
};
|
buffer: convert offset & length to int properly
As per ecma-262 2015's #sec-%typedarray%-buffer-byteoffset-length,
`offset` would be an integer, not a 32 bit unsigned integer. Also,
`length` would be an integer with the maximum value of 2^53 - 1, not a
32 bit unsigned integer.
This would be a problem because, if we create a buffer from an
arraybuffer, from an offset which is greater than 2^32, it would be
actually pointing to a different location in arraybuffer. For example,
if we use 2^40 as offset, then the actual value used will be 0,
because `byteOffset >>>= 0` will convert `byteOffset` to a 32 bit
unsigned int, which is based on 2^32 modulo.
This is a redo, as the ca37fa527f174b547893817fe8c67a3befa02317 broke
CI.
Refer: https://github.com/nodejs/node/pull/9814
Refer: https://github.com/nodejs/node/pull/9492
PR-URL: https://github.com/nodejs/node/pull/9815
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
|
|
|
|
/*
|
|
|
|
* Implementation of ToInteger as per ECMAScript Specification
|
|
|
|
* Refer: http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger
|
|
|
|
*/
|
|
|
|
const toInteger = exports.toInteger = function toInteger(argument) {
|
|
|
|
const number = +argument;
|
|
|
|
return Number.isNaN(number) ? 0 : Math.trunc(number);
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Implementation of ToLength as per ECMAScript Specification
|
|
|
|
* Refer: http://www.ecma-international.org/ecma-262/6.0/#sec-tolength
|
|
|
|
*/
|
|
|
|
exports.toLength = function toLength(argument) {
|
|
|
|
const len = toInteger(argument);
|
|
|
|
return len <= 0 ? 0 : Math.min(len, Number.MAX_SAFE_INTEGER);
|
|
|
|
};
|
|
|
|
|
|
|
|
// Useful for Wrapping an ES6 Class with a constructor Function that
|
|
|
|
// does not require the new keyword. For instance:
|
|
|
|
// class A { constructor(x) {this.x = x;}}
|
|
|
|
// const B = createClassWrapper(A);
|
|
|
|
// B() instanceof A // true
|
|
|
|
// B() instanceof B // true
|
|
|
|
exports.createClassWrapper = function createClassWrapper(type) {
|
|
|
|
const fn = function(...args) {
|
|
|
|
return Reflect.construct(type, args, new.target || type);
|
|
|
|
};
|
|
|
|
// Mask the wrapper function name and length values
|
|
|
|
Object.defineProperties(fn, {
|
|
|
|
name: {value: type.name},
|
|
|
|
length: {value: type.length}
|
|
|
|
});
|
|
|
|
Object.setPrototypeOf(fn, type);
|
|
|
|
fn.prototype = type.prototype;
|
|
|
|
return fn;
|
|
|
|
};
|