-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Utils): Move json-bigint implementation to
utils
(#486)
- Loading branch information
Showing
5 changed files
with
321 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,317 @@ | ||
/* eslint-disable */ | ||
export default { | ||
parse: ((options) => { | ||
// This is a function that can parse a JSON text, producing a JavaScript | ||
// data structure. It is a simple, recursive descent parser. It does not use | ||
// eval or regular expressions, so it can be used as a model for implementing | ||
// a JSON parser in other languages. | ||
|
||
// We are defining the function inside of another function to avoid creating | ||
// global letiables. | ||
|
||
// Default options one can override by passing options to the parse() | ||
const _options = { | ||
'strict': false, // not being strict means do not generate syntax errors for "duplicate key" | ||
'storeAsString': false // toggles whether the values should be stored as BigNumber (default) or a string | ||
} | ||
|
||
const escapee = { | ||
'"': '"', | ||
'\\': '\\', | ||
'/': '/', | ||
b: '\b', | ||
f: '\f', | ||
n: '\n', | ||
r: '\r', | ||
t: '\t' | ||
} | ||
|
||
// If there are options, then use them to override the default _options | ||
if (options !== undefined && options !== null) { | ||
if (options.strict === true) { | ||
_options.strict = true | ||
} | ||
if (options.storeAsString === true) { | ||
_options.storeAsString = true | ||
} | ||
} | ||
|
||
let at | ||
// The index of the current character | ||
|
||
let ch | ||
// The current character | ||
|
||
let text | ||
|
||
let error = function (m) { | ||
// Call error when something is wrong. | ||
|
||
throw { | ||
name: 'SyntaxError', | ||
message: m, | ||
at: at, | ||
text: text | ||
} | ||
} | ||
|
||
let next = function (c) { | ||
// If a c parameter is provided, verify that it matches the current character. | ||
|
||
if (c && c !== ch) { | ||
error('Expected \'' + c + '\' instead of \'' + ch + '\'') | ||
} | ||
|
||
// Get the next character. When there are no more characters, | ||
// return the empty string. | ||
|
||
ch = text.charAt(at) | ||
at += 1 | ||
return ch | ||
} | ||
|
||
let number = function () { | ||
// Parse a number value. | ||
|
||
let number | ||
|
||
let string = '' | ||
|
||
if (ch === '-') { | ||
string = '-' | ||
next('-') | ||
} | ||
while (ch >= '0' && ch <= '9') { | ||
string += ch | ||
next() | ||
} | ||
if (ch === '.') { | ||
string += '.' | ||
while (next() && ch >= '0' && ch <= '9') { | ||
string += ch | ||
} | ||
} | ||
if (ch === 'e' || ch === 'E') { | ||
string += ch | ||
next() | ||
if (ch === '-' || ch === '+') { | ||
string += ch | ||
next() | ||
} | ||
while (ch >= '0' && ch <= '9') { | ||
string += ch | ||
next() | ||
} | ||
} | ||
number = +string | ||
if (!isFinite(number)) { | ||
error('Bad number') | ||
} else { | ||
// if (number > 9007199254740992 || number < -9007199254740992) | ||
// Bignumber has stricter check: everything with length > 15 digits disallowed | ||
if (string.length > 15) { return string } | ||
return number | ||
} | ||
} | ||
|
||
let string = function () { | ||
// Parse a string value. | ||
|
||
let hex | ||
|
||
let i | ||
|
||
let string = '' | ||
|
||
let uffff | ||
|
||
// When parsing for string values, we must look for " and \ characters. | ||
|
||
if (ch === '"') { | ||
while (next()) { | ||
if (ch === '"') { | ||
next() | ||
return string | ||
} | ||
if (ch === '\\') { | ||
next() | ||
if (ch === 'u') { | ||
uffff = 0 | ||
for (i = 0; i < 4; i += 1) { | ||
hex = parseInt(next(), 16) | ||
if (!isFinite(hex)) { | ||
break | ||
} | ||
uffff = uffff * 16 + hex | ||
} | ||
string += String.fromCharCode(uffff) | ||
} else if (typeof escapee[ch] === 'string') { | ||
string += escapee[ch] | ||
} else { | ||
break | ||
} | ||
} else { | ||
string += ch | ||
} | ||
} | ||
} | ||
error('Bad string') | ||
} | ||
|
||
let white = function () { | ||
// Skip whitespace. | ||
|
||
while (ch && ch <= ' ') { | ||
next() | ||
} | ||
} | ||
|
||
let word = function () { | ||
// true, false, or null. | ||
|
||
switch (ch) { | ||
case 't': | ||
next('t') | ||
next('r') | ||
next('u') | ||
next('e') | ||
return true | ||
case 'f': | ||
next('f') | ||
next('a') | ||
next('l') | ||
next('s') | ||
next('e') | ||
return false | ||
case 'n': | ||
next('n') | ||
next('u') | ||
next('l') | ||
next('l') | ||
return null | ||
} | ||
error('Unexpected \'' + ch + '\'') | ||
} | ||
|
||
let value | ||
// Place holder for the value function. | ||
|
||
let array = function () { | ||
// Parse an array value. | ||
|
||
let array = [] | ||
|
||
if (ch === '[') { | ||
next('[') | ||
white() | ||
if (ch === ']') { | ||
next(']') | ||
return array // empty array | ||
} | ||
while (ch) { | ||
array.push(value()) | ||
white() | ||
if (ch === ']') { | ||
next(']') | ||
return array | ||
} | ||
next(',') | ||
white() | ||
} | ||
} | ||
error('Bad array') | ||
} | ||
|
||
let object = function () { | ||
// Parse an object value. | ||
|
||
let key | ||
|
||
let object = {} | ||
|
||
if (ch === '{') { | ||
next('{') | ||
white() | ||
if (ch === '}') { | ||
next('}') | ||
return object // empty object | ||
} | ||
while (ch) { | ||
key = string() | ||
white() | ||
next(':') | ||
if (_options.strict === true && Object.hasOwnProperty.call(object, key)) { | ||
error('Duplicate key "' + key + '"') | ||
} | ||
object[key] = value() | ||
white() | ||
if (ch === '}') { | ||
next('}') | ||
return object | ||
} | ||
next(',') | ||
white() | ||
} | ||
} | ||
error('Bad object') | ||
} | ||
|
||
value = function () { | ||
// Parse a JSON value. It could be an object, an array, a string, a number, | ||
// or a word. | ||
|
||
white() | ||
switch (ch) { | ||
case '{': | ||
return object() | ||
case '[': | ||
return array() | ||
case '"': | ||
return string() | ||
case '-': | ||
return number() | ||
default: | ||
return ch >= '0' && ch <= '9' ? number() : word() | ||
} | ||
} | ||
|
||
// Return the json_parse function. It will have access to all of the above | ||
// functions and letiables. | ||
|
||
return function (source, reviver) { | ||
let result | ||
|
||
text = source + '' | ||
at = 0 | ||
ch = ' ' | ||
result = value() | ||
white() | ||
if (ch) { | ||
error('Syntax error') | ||
} | ||
|
||
// If there is a reviver function, we recursively walk the new structure, | ||
// passing each name/value pair to the reviver function for possible | ||
// transformation, starting with a temporary root object that holds the result | ||
// in an empty key. If there is not a reviver function, we simply return the | ||
// result. | ||
|
||
return typeof reviver === 'function' | ||
? (function walk (holder, key) { | ||
let k; let v; let value = holder[key] | ||
if (value && typeof value === 'object') { | ||
Object.keys(value).forEach(function (k) { | ||
v = walk(value, k) | ||
if (v !== undefined) { | ||
value[k] = v | ||
} else { | ||
delete value[k] | ||
} | ||
}) | ||
} | ||
return reviver.call(holder, key, value) | ||
}({ '': result }, '')) | ||
: result | ||
} | ||
})() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters