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