ethers.js/utils/convert.js

173 lines
3.8 KiB
JavaScript

/**
* Conversion Utilities
*
*/
var defineProperty = require('./properties.js').defineProperty;
var throwError = require('./throw-error');
function addSlice(array) {
if (array.slice) { return array; }
array.slice = function() {
var args = Array.prototype.slice.call(arguments);
return new Uint8Array(Array.prototype.slice.apply(array, args));
}
return array;
}
function isArrayish(value) {
if (!value || parseInt(value.length) != value.length || typeof(value) === 'string') {
return false;
}
for (var i = 0; i < value.length; i++) {
var v = value[i];
if (v < 0 || v >= 256 || parseInt(v) != v) {
return false;
}
}
return true;
}
function arrayify(value, name) {
if (value && value.toHexString) {
value = value.toHexString();
}
if (isHexString(value)) {
value = value.substring(2);
if (value.length % 2) { value = '0' + value; }
var result = [];
for (var i = 0; i < value.length; i += 2) {
result.push(parseInt(value.substr(i, 2), 16));
}
return addSlice(new Uint8Array(result));
}
if (isArrayish(value)) {
return addSlice(new Uint8Array(value));
}
throwError('invalid arrayify value', { name: name, input: value });
}
function concat(objects) {
var arrays = [];
var length = 0;
for (var i = 0; i < objects.length; i++) {
var object = arrayify(objects[i])
arrays.push(object);
length += object.length;
}
var result = new Uint8Array(length);
var offset = 0;
for (var i = 0; i < arrays.length; i++) {
result.set(arrays[i], offset);
offset += arrays[i].length;
}
return addSlice(result);
}
function stripZeros(value) {
value = arrayify(value);
if (value.length === 0) { return value; }
// Find the first non-zero entry
var start = 0;
while (value[start] === 0) { start++ }
// If we started with zeros, strip them
if (start) {
value = value.slice(start);
}
return value;
}
function padZeros(value, length) {
value = arrayify(value);
if (length < value.length) { throw new Error('cannot pad'); }
var result = new Uint8Array(length);
result.set(value, length - value.length);
return addSlice(result);
}
function isHexString(value, length) {
if (typeof(value) !== 'string' || !value.match(/^0x[0-9A-Fa-f]*$/)) {
return false
}
if (length && value.length !== 2 + 2 * length) { return false; }
return true;
}
var HexCharacters = '0123456789abcdef';
function hexlify(value, name) {
if (value && value.toHexString) {
return value.toHexString();
}
if (typeof(value) === 'number') {
if (value < 0) {
throwError('cannot hexlify negative value', { name: name, input: value });
}
var hex = '';
while (value) {
hex = HexCharacters[value & 0x0f] + hex;
value = parseInt(value / 16);
}
if (hex.length) {
if (hex.length % 2) { hex = '0' + hex; }
return '0x' + hex;
}
return '0x00';
}
if (isHexString(value)) {
if (value.length % 2) {
value = '0x0' + value.substring(2);
}
return value;
}
if (isArrayish(value)) {
var result = [];
for (var i = 0; i < value.length; i++) {
var v = value[i];
result.push(HexCharacters[(v & 0xf0) >> 4] + HexCharacters[v & 0x0f]);
}
return '0x' + result.join('');
}
throwError('invalid hexlify value', { name: name, input: value });
}
module.exports = {
arrayify: arrayify,
isArrayish: isArrayish,
concat: concat,
padZeros: padZeros,
stripZeros: stripZeros,
hexlify: hexlify,
isHexString: isHexString,
};