| 1313 | } |
| 1314 | |
| 1315 | function serializeString(value: string): string { |
| 1316 | // Validate ASCII printable and check if escaping needed |
| 1317 | let needsEscape = false; |
| 1318 | for (let i = 0; i < value.length; i++) { |
| 1319 | const code = value.charCodeAt(i); |
| 1320 | if (code < 0x20 || code > 0x7e) { |
| 1321 | throw new TypeError(`Invalid character in string at position ${i}`); |
| 1322 | } |
| 1323 | if (code === 0x22 || code === 0x5c) { // " or \ |
| 1324 | needsEscape = true; |
| 1325 | } |
| 1326 | } |
| 1327 | |
| 1328 | // Fast path: no escaping needed |
| 1329 | if (!needsEscape) { |
| 1330 | return `"${value}"`; |
| 1331 | } |
| 1332 | |
| 1333 | // Slow path: escape \ and " |
| 1334 | const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"'); |
| 1335 | return `"${escaped}"`; |
| 1336 | } |
| 1337 | |
| 1338 | function serializeToken(value: string): string { |
| 1339 | if (value.length === 0) { |