You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					177 lines
				
				4.3 KiB
			
		
		
			
		
	
	
					177 lines
				
				4.3 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								const rxParseJson = /position\s(\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]
							 | 
						||
| 
								 | 
							
								          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'
							 |