From 46a8554b77e0c290c1d0bd9a4c5a2ccfcff1f415 Mon Sep 17 00:00:00 2001 From: leaty Date: Thu, 3 Jun 2021 17:21:45 +0200 Subject: [PATCH] Add for escaping the delimiter in writer --- csv-core/src/writer.rs | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/csv-core/src/writer.rs b/csv-core/src/writer.rs index 4f94301..93578a0 100644 --- a/csv-core/src/writer.rs +++ b/csv-core/src/writer.rs @@ -1,7 +1,7 @@ use core::fmt; use core::str; -use memchr::memchr; +use memchr::{memchr, memchr2}; use crate::{QuoteStyle, Terminator}; @@ -299,7 +299,7 @@ impl Writer { let (res, i, o) = if self.state.quoting { quote(input, output, self.quote, self.escape, self.double_quote) } else { - write_optimistic(input, output) + escape(input, output, self.escape, self.delimiter) }; nin += i; nout += o; @@ -572,6 +572,44 @@ pub fn quote( } } +pub fn escape( + mut input: &[u8], + mut output: &mut [u8], + escape: u8, + delimiter: u8, +) -> (WriteResult, usize, usize) { + let (mut nin, mut nout) = (0, 0); + loop { + match memchr2(delimiter, escape, input) { + None => { + let (res, i, o) = write_optimistic(input, output); + nin += i; + nout += o; + return (res, nin, nout); + } + Some(next) => { + let char = input[next]; + let (res, i, o) = write_optimistic(&input[..next], output); + input = &input[i..]; + output = &mut moving(output)[o..]; + nin += i; + nout += o; + if let WriteResult::OutputFull = res { + return (res, nin, nout); + } + let (res, o) = write_pessimistic(&[escape, char], output); + if let WriteResult::OutputFull = res { + return (res, nin, nout); + } + nout += o; + output = &mut moving(output)[o..]; + nin += 1; + input = &input[1..]; + } + } + } +} + /// Copy the bytes from `input` to `output`. If `output` is too small to fit /// everything from `input`, then copy `output.len()` bytes from `input`. /// Otherwise, copy everything from `input` into `output`.