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
						
					
					
				| 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'
 |