Skip to content

Commit

Permalink
Make crlf the codec's problem
Browse files Browse the repository at this point in the history
  • Loading branch information
jwodder committed Nov 28, 2023
1 parent 2a8050f commit 46e8ac6
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 28 deletions.
29 changes: 26 additions & 3 deletions src/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

use crate::util::CharEncoding;
use crate::util::{latin1ify, CharEncoding};
use bytes::{BufMut, BytesMut};
use std::{cmp, io};
use tokio_util::codec::{Decoder, Encoder};
Expand All @@ -66,6 +66,9 @@ pub(crate) struct ConfabCodec {

/// Character encoding for converting between strings and bytes
encoding: CharEncoding,

/// Whether prepared lines should end in CR LF (true) or LF (false)
crlf: bool,
}

impl ConfabCodec {
Expand All @@ -81,6 +84,7 @@ impl ConfabCodec {
next_index: 0,
max_length: usize::MAX,
encoding: CharEncoding::Utf8,
crlf: false,
}
}

Expand All @@ -104,8 +108,27 @@ impl ConfabCodec {
ConfabCodec { encoding, ..self }
}

pub(crate) fn get_encoding(&self) -> CharEncoding {
self.encoding
pub(crate) fn crlf(self, crlf: bool) -> ConfabCodec {
ConfabCodec { crlf, ..self }
}

/// Prepare a line that is about to be sent through the codec. If
/// `encoding` is `CharEncoding::Latin`, non-Latin-1 characters are
/// converted to question marks. A line ending — either LF or CR LF,
/// depending on the value of `crlf` — is then appended to the line.
///
/// These conversions need to be done outside of encoding proper so that
/// they can be reflected in reported events.
pub(crate) fn prepare_line(&self, mut line: String) -> String {
if self.encoding == CharEncoding::Latin1 {
line = latin1ify(line);
}
if self.crlf {
line.push_str("\r\n");
} else {
line.push('\n');
}
line
}
}

Expand Down
35 changes: 10 additions & 25 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::codec::ConfabCodec;
use crate::errors::{InetError, InterfaceError, IoError};
use crate::events::Event;
use crate::input::{readline_stream, Input, StartupScript};
use crate::util::{latin1ify, now_hms, CharEncoding};
use crate::util::{now_hms, CharEncoding};
use anyhow::Context;
use clap::Parser;
use futures::{SinkExt, Stream, StreamExt};
Expand Down Expand Up @@ -136,14 +136,14 @@ impl Arguments {
transcript,
show_times: self.show_times,
},
crlf: self.crlf,
connector: Connector {
tls: self.tls,
host: self.host,
port: self.port,
servername: self.servername,
encoding: self.encoding,
max_line_length: self.max_line_length,
crlf: self.crlf,
},
})
}
Expand Down Expand Up @@ -191,6 +191,7 @@ struct Connector {
servername: Option<String>,
encoding: CharEncoding,
max_line_length: NonZeroUsize,
crlf: bool,
}

impl Connector {
Expand All @@ -216,14 +217,15 @@ impl Connector {
}

fn codec(&self) -> ConfabCodec {
ConfabCodec::new_with_max_length(self.max_line_length.get()).encoding(self.encoding)
ConfabCodec::new_with_max_length(self.max_line_length.get())
.encoding(self.encoding)
.crlf(self.crlf)
}
}

struct Runner {
startup_script: Option<StartupScript>,
reporter: Reporter,
crlf: bool,
connector: Connector,
}

Expand All @@ -242,7 +244,7 @@ impl Runner {
async fn try_run(&mut self) -> Result<(), IoError> {
let mut frame = self.connector.connect(&mut self.reporter).await?;
if let Some(script) = self.startup_script.take() {
ioloop(&mut frame, script, self.crlf, &mut self.reporter).await?;
ioloop(&mut frame, script, &mut self.reporter).await?;
}
let (mut rl, shared) = init_readline()?;
// Lines written to the SharedWriter are only output when
Expand All @@ -253,7 +255,6 @@ impl Runner {
let r = ioloop(
&mut frame,
readline_stream(&mut rl).await,
self.crlf,
&mut self.reporter,
)
.await;
Expand All @@ -270,12 +271,7 @@ impl Runner {
}
}

async fn ioloop<S>(
frame: &mut Connection,
input: S,
crlf: bool,
reporter: &mut Reporter,
) -> Result<(), IoError>
async fn ioloop<S>(frame: &mut Connection, input: S, reporter: &mut Reporter) -> Result<(), IoError>
where
S: Stream<Item = Result<Input, InterfaceError>> + Send,
{
Expand All @@ -288,19 +284,8 @@ where
None => break,
},
r = input.next() => match r {
Some(Ok(Input::Line(mut line))) => {
if frame.codec().get_encoding() == CharEncoding::Latin1 {
// We need to convert non-Latin-1 characters to '?'
// here rather than waiting for the codec to do it so
// that the Event will reflect the actual characters
// sent.
line = latin1ify(line);
}
if crlf {
line.push_str("\r\n");
} else {
line.push('\n');
}
Some(Ok(Input::Line(line))) => {
let line = frame.codec().prepare_line(line);
frame.send(&line).await.map_err(InetError::Send)?;
Event::send(line)
}
Expand Down

0 comments on commit 46e8ac6

Please sign in to comment.