| 398 | } |
| 399 | |
| 400 | private void string(String value) throws IOException { |
| 401 | out.write("\""); |
| 402 | for (int i = 0, length = value.length(); i < length; i++) { |
| 403 | char c = value.charAt(i); |
| 404 | |
| 405 | /* |
| 406 | * From RFC 4627, "All Unicode characters may be placed within the |
| 407 | * quotation marks except for the characters that must be escaped: |
| 408 | * quotation mark, reverse solidus, and the control characters |
| 409 | * (U+0000 through U+001F)." |
| 410 | * |
| 411 | * We also escape '\u2028' and '\u2029', which JavaScript interprets |
| 412 | * as newline characters. This prevents eval() from failing with a |
| 413 | * syntax error. |
| 414 | * http://code.google.com/p/google-gson/issues/detail?id=341 |
| 415 | */ |
| 416 | switch (c) { |
| 417 | case '"': |
| 418 | case '\\': |
| 419 | out.write('\\'); |
| 420 | out.write(c); |
| 421 | break; |
| 422 | |
| 423 | case '\t': |
| 424 | out.write("\\t"); |
| 425 | break; |
| 426 | |
| 427 | case '\b': |
| 428 | out.write("\\b"); |
| 429 | break; |
| 430 | |
| 431 | case '\n': |
| 432 | out.write("\\n"); |
| 433 | break; |
| 434 | |
| 435 | case '\r': |
| 436 | out.write("\\r"); |
| 437 | break; |
| 438 | |
| 439 | case '\f': |
| 440 | out.write("\\f"); |
| 441 | break; |
| 442 | |
| 443 | case '\u2028': |
| 444 | case '\u2029': |
| 445 | out.write(String.format("\\u%04x", (int) c)); |
| 446 | break; |
| 447 | |
| 448 | default: |
| 449 | if (c <= 0x1F) { |
| 450 | out.write(String.format("\\u%04x", (int) c)); |
| 451 | } else { |
| 452 | out.write(c); |
| 453 | } |
| 454 | break; |
| 455 | } |
| 456 | |
| 457 | } |