| 849 | |
| 850 | #[inline] |
| 851 | pub fn write_latin1_simd(writer: &mut Writer, s: &str) { |
| 852 | if s.is_empty() { |
| 853 | return; |
| 854 | } |
| 855 | |
| 856 | let bytes = s.as_bytes(); |
| 857 | |
| 858 | // CRITICAL OPTIMIZATION: For ASCII strings, UTF-8 bytes == Latin1 bytes |
| 859 | // Check if all ASCII using SIMD |
| 860 | if is_ascii_bytes(bytes) { |
| 861 | // Zero-copy fast path: direct write |
| 862 | let len = bytes.len(); |
| 863 | writer.bf.reserve(len); |
| 864 | writer.bf.extend_from_slice(bytes); |
| 865 | } else { |
| 866 | // Non-ASCII: Must iterate chars to extract Latin1 byte values |
| 867 | // Example: 'À' in Rust String is UTF-8 [0xC3, 0x80] but Latin1 is [0xC0] |
| 868 | let mut buf: Vec<u8> = Vec::with_capacity(s.len()); |
| 869 | for c in s.chars() { |
| 870 | let v = c as u32; |
| 871 | assert!(v <= 0xFF, "Non-Latin1 character found"); |
| 872 | buf.push(v as u8); |
| 873 | } |
| 874 | let len = buf.len(); |
| 875 | writer.bf.reserve(len); |
| 876 | writer.bf.extend_from_slice(&buf); |
| 877 | } |
| 878 | } |
| 879 | |
| 880 | #[inline] |
| 881 | pub fn read_latin1_simd(reader: &mut Reader, len: usize) -> Result<String, Error> { |