Skip to content

Commit bfc16a4

Browse files
committed
Make starting packets with an END token optional.
1 parent 538455a commit bfc16a4

File tree

6 files changed

+111
-72
lines changed

6 files changed

+111
-72
lines changed

Cargo.lock

+17-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+7-5
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ edition = "2018"
55
license = "MIT"
66
name = "slip-codec"
77
repository = "https://github.com/jmaygarden/slip-codec"
8-
version = "0.2.4"
8+
version = "0.3.0"
99

1010
[features]
1111
default = []
12-
async = ["bytes", "tokio-util"]
12+
async-codec = ["asynchronous-codec", "bytes"]
13+
tokio-codec = ["bytes", "tokio-util"]
1314

1415
[dependencies]
15-
bytes = { version = "1.0", optional = true }
16-
tokio-util = { version ="0.6", features = ["codec"], optional = true }
16+
asynchronous-codec = { version = "0.6", optional = true }
17+
bytes = { version = "1", optional = true }
18+
tokio-util = { version = "0.6", features = ["codec"], optional = true }
1719

1820
[dev-dependencies]
1921
futures = "0.3"
@@ -23,4 +25,4 @@ tokio = { version = "1.0", features = ["full"] }
2325

2426
[[example]]
2527
name = "tokio-serial"
26-
required-features = ["async"]
28+
required-features = ["tokio-codec"]

src/default/decoder.rs src/decoder.rs

+37-23
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,38 @@
11
use crate::{END, ESC, ESC_END, ESC_ESC};
2-
32
use std::io::{Read, Write};
43

54
#[derive(Debug)]
6-
pub enum Error {
5+
pub enum SlipError {
76
FramingError,
87
OversizedPacket,
98
EndOfStream,
109
ReadError(std::io::Error),
1110
}
1211

13-
impl From<Error> for std::io::Error {
14-
fn from(err: Error) -> std::io::Error {
12+
impl From<SlipError> for std::io::Error {
13+
fn from(err: SlipError) -> std::io::Error {
1514
match err {
16-
Error::FramingError => std::io::Error::new(std::io::ErrorKind::Other, format!("{:?}", err)),
17-
Error::OversizedPacket => std::io::Error::new(std::io::ErrorKind::Other, format!("{:?}", err)),
18-
Error::EndOfStream => std::io::Error::new(std::io::ErrorKind::Other, format!("{:?}", err)),
19-
Error::ReadError(err) => err,
15+
SlipError::FramingError => {
16+
std::io::Error::new(std::io::ErrorKind::Other, format!("{:?}", err))
17+
}
18+
SlipError::OversizedPacket => {
19+
std::io::Error::new(std::io::ErrorKind::Other, format!("{:?}", err))
20+
}
21+
SlipError::EndOfStream => {
22+
std::io::Error::new(std::io::ErrorKind::Other, format!("{:?}", err))
23+
}
24+
SlipError::ReadError(err) => err,
2025
}
2126
}
2227
}
2328

24-
impl From<std::io::Error> for Error {
29+
impl From<std::io::Error> for SlipError {
2530
fn from(err: std::io::Error) -> Self {
26-
Error::ReadError(err)
31+
SlipError::ReadError(err)
2732
}
2833
}
2934

30-
pub type Result = std::result::Result<usize, self::Error>;
35+
pub type SlipResult = std::result::Result<usize, self::SlipError>;
3136

3237
enum State {
3338
Normal,
@@ -36,12 +41,12 @@ enum State {
3641
}
3742

3843
/// SLIP decoding context
39-
pub struct Decoder {
44+
pub struct SlipDecoder {
4045
count: usize,
4146
state: State,
4247
}
4348

44-
impl Decoder {
49+
impl SlipDecoder {
4550
/// Creates a new context with the given maximum buffer size.
4651
pub fn new() -> Self {
4752
Self {
@@ -50,11 +55,11 @@ impl Decoder {
5055
}
5156
}
5257

53-
fn push(self: &mut Self, sink: &mut dyn Write, value: u8) -> self::Result {
58+
fn push(&mut self, sink: &mut dyn Write, value: u8) -> self::SlipResult {
5459
match sink.write(&[value]) {
5560
Ok(len) => {
5661
if len != 1 {
57-
Err(Error::OversizedPacket)
62+
Err(SlipError::OversizedPacket)
5863
} else {
5964
self.count += 1;
6065
Ok(1usize)
@@ -74,10 +79,13 @@ impl Decoder {
7479
/// Returns a Vec<u8> containing a decoded message or an empty Vec<u8> if
7580
/// of the source data was reached.
7681
///
77-
pub fn decode(self: &mut Self, source: &mut dyn Read, sink: &mut dyn Write) -> self::Result {
82+
pub fn decode(&mut self, source: &mut dyn Read, sink: &mut dyn Write) -> self::SlipResult {
83+
eprintln!("{}:{}", file!(), line!());
7884
for value in source.bytes() {
7985
let value = value?;
8086

87+
eprintln!("{}:{} value => {:02X}", file!(), line!(), value);
88+
8189
match self.state {
8290
State::Normal => match value {
8391
END => {
@@ -114,13 +122,19 @@ impl Decoder {
114122
_ => {
115123
self.state = State::Error;
116124

117-
return Err(Error::FramingError);
125+
return Err(SlipError::FramingError);
118126
}
119127
},
120128
}
121129
}
122130

123-
Err(Error::EndOfStream)
131+
Err(SlipError::EndOfStream)
132+
}
133+
}
134+
135+
impl Default for SlipDecoder {
136+
fn default() -> Self {
137+
Self::new()
124138
}
125139
}
126140

@@ -132,7 +146,7 @@ mod tests {
132146
fn empty_decode() {
133147
const INPUT: [u8; 2] = [0xc0, 0xc0];
134148

135-
let mut slip = Decoder::new();
149+
let mut slip = SlipDecoder::new();
136150
let mut buf: Vec<u8> = Vec::new();
137151
let res = slip.decode(&mut INPUT.as_ref(), &mut buf);
138152
assert!(res.is_err());
@@ -144,7 +158,7 @@ mod tests {
144158
const INPUT: [u8; 7] = [0xc0, 0x01, 0x02, 0x03, 0x04, 0x05, 0xc0];
145159
const DATA: [u8; 5] = [0x01, 0x02, 0x03, 0x04, 0x05];
146160

147-
let mut slip = Decoder::new();
161+
let mut slip = SlipDecoder::new();
148162
let mut buf = [0u8; DATA.len()];
149163
let len = slip.decode(&mut INPUT.as_ref(), &mut buf.as_mut()).unwrap();
150164
assert_eq!(DATA.len(), len);
@@ -158,7 +172,7 @@ mod tests {
158172
const INPUT: [u8; 6] = [0xc0, 0x01, 0xdb, 0xdc, 0x03, 0xc0];
159173
const DATA: [u8; 3] = [0x01, 0xc0, 0x03];
160174

161-
let mut slip = Decoder::new();
175+
let mut slip = SlipDecoder::new();
162176
let mut buf: Vec<u8> = Vec::new();
163177
let len = slip.decode(&mut INPUT.as_ref(), &mut buf).unwrap();
164178
assert_eq!(DATA.len(), len);
@@ -172,7 +186,7 @@ mod tests {
172186
const INPUT: [u8; 6] = [0xc0, 0x01, 0xdb, 0xdd, 0x03, 0xc0];
173187
const DATA: [u8; 3] = [0x01, 0xdb, 0x03];
174188

175-
let mut slip = Decoder::new();
189+
let mut slip = SlipDecoder::new();
176190
let mut buf: Vec<u8> = Vec::new();
177191
let len = slip.decode(&mut INPUT.as_ref(), &mut buf).unwrap();
178192
assert_eq!(DATA.len(), len);
@@ -186,7 +200,7 @@ mod tests {
186200
const INPUT_2: [u8; 6] = [0x05, 0x06, 0x07, 0x08, 0x09, 0xc0];
187201
const DATA: [u8; 10] = [0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x09];
188202

189-
let mut slip = Decoder::new();
203+
let mut slip = SlipDecoder::new();
190204
let mut buf: Vec<u8> = Vec::new();
191205

192206
{

src/default/mod.rs

-5
This file was deleted.

src/default/encoder.rs src/encoder.rs

+40-30
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,14 @@
11
use crate::{END, ESC, ESC_END, ESC_ESC};
22

3-
pub fn encode(buf: &[u8], sink: &mut dyn std::io::Write) -> std::io::Result<usize> {
4-
let mut len = sink.write(&[END])?;
5-
6-
for value in buf.iter() {
7-
match *value {
8-
END => {
9-
len += sink.write(&[ESC, ESC_END])?;
10-
}
11-
ESC => {
12-
len += sink.write(&[ESC, ESC_ESC])?;
13-
}
14-
_ => {
15-
len += sink.write(&[*value])?;
16-
}
17-
}
18-
}
19-
20-
len += sink.write(&[END])?;
21-
22-
Ok(len)
23-
}
24-
253
/// SLIP encoder context
26-
pub struct Encoder {}
4+
pub struct SlipEncoder {
5+
begin_with_end: bool,
6+
}
277

28-
impl Encoder {
8+
impl SlipEncoder {
299
/// Creates a new encoder context
30-
pub fn new() -> Self {
31-
Self {}
10+
pub fn new(begin_with_end: bool) -> Self {
11+
Self { begin_with_end }
3212
}
3313

3414
/// Encodes the given buffer in a SLIP frame and forwards it to the sink.
@@ -41,7 +21,37 @@ impl Encoder {
4121
/// Returns the number of bytes written to the sink.
4222
///
4323
pub fn encode(&mut self, buf: &[u8], sink: &mut dyn std::io::Write) -> std::io::Result<usize> {
44-
encode(buf, sink)
24+
let mut len = if self.begin_with_end {
25+
sink.write(&[END])?
26+
} else {
27+
0
28+
};
29+
30+
for value in buf.iter() {
31+
match *value {
32+
END => {
33+
len += sink.write(&[ESC, ESC_END])?;
34+
}
35+
ESC => {
36+
len += sink.write(&[ESC, ESC_ESC])?;
37+
}
38+
_ => {
39+
len += sink.write(&[*value])?;
40+
}
41+
}
42+
}
43+
44+
len += sink.write(&[END])?;
45+
46+
sink.flush()?;
47+
48+
Ok(len)
49+
}
50+
}
51+
52+
impl Default for SlipEncoder {
53+
fn default() -> Self {
54+
Self::new(true)
4555
}
4656
}
4757

@@ -54,7 +64,7 @@ mod tests {
5464
const EXPECTED: [u8; 2] = [0xc0, 0xc0];
5565
let mut output = Vec::<u8>::new();
5666

57-
let mut slip = Encoder::new();
67+
let mut slip = SlipEncoder::new(true);
5868
let len = slip.encode(&[0; 0], &mut output).unwrap();
5969
assert_eq!(EXPECTED.len(), len);
6070
assert_eq!(&EXPECTED, output.as_slice());
@@ -66,7 +76,7 @@ mod tests {
6676
const EXPECTED: [u8; 6] = [0xc0, 0x01, ESC, ESC_ESC, 0x03, 0xc0];
6777
let mut output = Vec::<u8>::new();
6878

69-
let mut slip = Encoder::new();
79+
let mut slip = SlipEncoder::new(true);
7080
let len = slip.encode(&INPUT, &mut output).unwrap();
7181
assert_eq!(EXPECTED.len(), len);
7282
assert_eq!(&EXPECTED, output.as_slice());
@@ -78,7 +88,7 @@ mod tests {
7888
const EXPECTED: [u8; 6] = [0xc0, 0x01, ESC, ESC_END, 0x03, 0xc0];
7989
let mut output = Vec::<u8>::new();
8090

81-
let mut slip = Encoder::new();
91+
let mut slip = SlipEncoder::new(true);
8292
let len = slip.encode(&INPUT, &mut output).unwrap();
8393
assert_eq!(EXPECTED.len(), len);
8494
assert_eq!(&EXPECTED, output.as_slice());

src/lib.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
#[cfg(not(feature = "async"))]
2-
mod default;
1+
mod encoder;
2+
pub use encoder::SlipEncoder;
33

4-
#[cfg(not(feature = "async"))]
5-
pub use crate::default::{encode, Decoder, Encoder, Error, Result};
4+
mod decoder;
5+
pub use decoder::{SlipDecoder, SlipError, SlipResult};
66

7-
#[cfg(feature = "async")]
8-
mod tokio;
7+
#[cfg(feature = "async-codec")]
8+
pub mod aio;
99

10-
#[cfg(feature = "async")]
11-
pub use crate::tokio::{SlipCodec, SlipCodecError, SlipDecoder, SlipEncoder};
10+
#[cfg(feature = "tokio-codec")]
11+
pub mod tokio;
1212

1313
const END: u8 = 0xC0;
1414
const ESC: u8 = 0xDB;
1515
const ESC_END: u8 = 0xDC;
1616
const ESC_ESC: u8 = 0xDD;
17+
18+
const MAX_PACKET_SIZE: usize = 1006;

0 commit comments

Comments
 (0)