| 671 | } |
| 672 | |
| 673 | pub fn parse_bytes_traditional(s: &str) -> Result<Vec<u8>, ParseError> { |
| 674 | // Bytes are interpreted literally, save for the special escape sequences |
| 675 | // "\\", which represents a single backslash, and "\NNN", where each N |
| 676 | // is an octal digit, which represents the byte whose octal value is NNN. |
| 677 | let mut out = Vec::with_capacity(s.len()); |
| 678 | let mut bytes = s.as_bytes().iter().fuse(); |
| 679 | while let Some(&b) = bytes.next() { |
| 680 | if b != b'\\' { |
| 681 | out.push(b); |
| 682 | continue; |
| 683 | } |
| 684 | match bytes.next() { |
| 685 | None => { |
| 686 | return Err(ParseError::invalid_input_syntax("bytea", s) |
| 687 | .with_details("ends with escape character")); |
| 688 | } |
| 689 | Some(b'\\') => out.push(b'\\'), |
| 690 | b => match (b, bytes.next(), bytes.next()) { |
| 691 | (Some(d2 @ b'0'..=b'3'), Some(d1 @ b'0'..=b'7'), Some(d0 @ b'0'..=b'7')) => { |
| 692 | out.push(((d2 - b'0') << 6) + ((d1 - b'0') << 3) + (d0 - b'0')); |
| 693 | } |
| 694 | _ => { |
| 695 | return Err(ParseError::invalid_input_syntax("bytea", s) |
| 696 | .with_details("invalid escape sequence")); |
| 697 | } |
| 698 | }, |
| 699 | } |
| 700 | } |
| 701 | Ok(out) |
| 702 | } |
| 703 | |
| 704 | pub fn format_bytes<F>(buf: &mut F, bytes: &[u8]) -> Nestable |
| 705 | where |