ScanString reads a quoted string from a rune reader.
(r io.RuneScanner)
| 517 | |
| 518 | // ScanString reads a quoted string from a rune reader. |
| 519 | func ScanString(r io.RuneScanner) (string, error) { |
| 520 | ending, _, err := r.ReadRune() |
| 521 | if err != nil { |
| 522 | return "", errBadString |
| 523 | } |
| 524 | |
| 525 | var buf bytes.Buffer |
| 526 | for { |
| 527 | ch0, _, err := r.ReadRune() |
| 528 | if ch0 == ending { |
| 529 | return buf.String(), nil |
| 530 | } else if err != nil || ch0 == '\n' { |
| 531 | return buf.String(), errBadString |
| 532 | } else if ch0 == '\\' { |
| 533 | // If the next character is an escape then write the escaped char. |
| 534 | // If it's not a valid escape then return an error. |
| 535 | ch1, _, _ := r.ReadRune() |
| 536 | if ch1 == 'n' { |
| 537 | _, _ = buf.WriteRune('\n') |
| 538 | } else if ch1 == '\\' { |
| 539 | _, _ = buf.WriteRune('\\') |
| 540 | } else if ch1 == '"' { |
| 541 | _, _ = buf.WriteRune('"') |
| 542 | } else if ch1 == '\'' { |
| 543 | _, _ = buf.WriteRune('\'') |
| 544 | } else { |
| 545 | return string(ch0) + string(ch1), errBadEscape |
| 546 | } |
| 547 | } else { |
| 548 | _, _ = buf.WriteRune(ch0) |
| 549 | } |
| 550 | } |
| 551 | } |
| 552 | |
| 553 | var errBadString = errors.New("bad string") |
| 554 | var errBadEscape = errors.New("bad escape") |