123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- const rxParseJson = /position\s(\d+)(?: \(line \d+ column \d+\))?$/
- export function parseJson(s: string, pos: number): unknown {
- let endPos: number | undefined
- parseJson.message = undefined
- let matches: RegExpExecArray | null
- if (pos) s = s.slice(pos)
- try {
- parseJson.position = pos + s.length
- return JSON.parse(s)
- } catch (e) {
- matches = rxParseJson.exec((e as Error).message)
- if (!matches) {
- parseJson.message = "unexpected end"
- return undefined
- }
- endPos = +matches[1]
- const c = s[endPos]
- s = s.slice(0, endPos)
- parseJson.position = pos + endPos
- try {
- return JSON.parse(s)
- } catch (e1) {
- parseJson.message = `unexpected token ${c}`
- return undefined
- }
- }
- }
- parseJson.message = undefined as string | undefined
- parseJson.position = 0 as number
- parseJson.code = 'require("ajv/dist/runtime/parseJson").parseJson'
- export function parseJsonNumber(s: string, pos: number, maxDigits?: number): number | undefined {
- let numStr = ""
- let c: string
- parseJsonNumber.message = undefined
- if (s[pos] === "-") {
- numStr += "-"
- pos++
- }
- if (s[pos] === "0") {
- numStr += "0"
- pos++
- } else {
- if (!parseDigits(maxDigits)) {
- errorMessage()
- return undefined
- }
- }
- if (maxDigits) {
- parseJsonNumber.position = pos
- return +numStr
- }
- if (s[pos] === ".") {
- numStr += "."
- pos++
- if (!parseDigits()) {
- errorMessage()
- return undefined
- }
- }
- if (((c = s[pos]), c === "e" || c === "E")) {
- numStr += "e"
- pos++
- if (((c = s[pos]), c === "+" || c === "-")) {
- numStr += c
- pos++
- }
- if (!parseDigits()) {
- errorMessage()
- return undefined
- }
- }
- parseJsonNumber.position = pos
- return +numStr
- function parseDigits(maxLen?: number): boolean {
- let digit = false
- while (((c = s[pos]), c >= "0" && c <= "9" && (maxLen === undefined || maxLen-- > 0))) {
- digit = true
- numStr += c
- pos++
- }
- return digit
- }
- function errorMessage(): void {
- parseJsonNumber.position = pos
- parseJsonNumber.message = pos < s.length ? `unexpected token ${s[pos]}` : "unexpected end"
- }
- }
- parseJsonNumber.message = undefined as string | undefined
- parseJsonNumber.position = 0 as number
- parseJsonNumber.code = 'require("ajv/dist/runtime/parseJson").parseJsonNumber'
- const escapedChars: {[X in string]?: string} = {
- b: "\b",
- f: "\f",
- n: "\n",
- r: "\r",
- t: "\t",
- '"': '"',
- "/": "/",
- "\\": "\\",
- }
- const CODE_A: number = "a".charCodeAt(0)
- const CODE_0: number = "0".charCodeAt(0)
- export function parseJsonString(s: string, pos: number): string | undefined {
- let str = ""
- let c: string | undefined
- parseJsonString.message = undefined
- // eslint-disable-next-line no-constant-condition, @typescript-eslint/no-unnecessary-condition
- while (true) {
- c = s[pos++]
- if (c === '"') break
- if (c === "\\") {
- c = s[pos]
- if (c in escapedChars) {
- str += escapedChars[c]
- pos++
- } else if (c === "u") {
- pos++
- let count = 4
- let code = 0
- while (count--) {
- code <<= 4
- c = s[pos]
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
- if (c === undefined) {
- errorMessage("unexpected end")
- return undefined
- }
- c = c.toLowerCase()
- if (c >= "a" && c <= "f") {
- code += c.charCodeAt(0) - CODE_A + 10
- } else if (c >= "0" && c <= "9") {
- code += c.charCodeAt(0) - CODE_0
- } else {
- errorMessage(`unexpected token ${c}`)
- return undefined
- }
- pos++
- }
- str += String.fromCharCode(code)
- } else {
- errorMessage(`unexpected token ${c}`)
- return undefined
- }
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
- } else if (c === undefined) {
- errorMessage("unexpected end")
- return undefined
- } else {
- if (c.charCodeAt(0) >= 0x20) {
- str += c
- } else {
- errorMessage(`unexpected token ${c}`)
- return undefined
- }
- }
- }
- parseJsonString.position = pos
- return str
- function errorMessage(msg: string): void {
- parseJsonString.position = pos
- parseJsonString.message = msg
- }
- }
- parseJsonString.message = undefined as string | undefined
- parseJsonString.position = 0 as number
- parseJsonString.code = 'require("ajv/dist/runtime/parseJson").parseJsonString'
|