History

refactor

Sebastian Thiel committed 6 years ago

Commit 8ebdcbd1 parent 58543cb2 files · +56 −33Browse files

Unified · Split

2 files
  1. git-protocol/src/packet_line/decode.rs +45 −24
  2. git-protocol/src/packet_line/mod.rs +11 −9
git-protocol/src/packet_line/decode.rs+45−24
@@ -6,6 +6,7 @@ use crate::{ · 5 unmodified lines
66 };
77 use bstr::BString;
88 use quick_error::quick_error;
9+use std::convert::TryInto;
910
1011 quick_error! {
1112 #[derive(Debug)]
@@ -39,6 +40,43 @@ pub enum Stream<'a> { · 27 unmodified lines
3940 },
4041 }
4142
43+pub enum PacketLineOrWantedSize<'a> {
44+ Line(PacketLine<'a>),
45+ Wanted(u16),
46+}
47+
48+pub fn hex_prefix(data: &[u8; 4]) -> Result<PacketLineOrWantedSize, Error> {
49+ for (line_bytes, line_type) in &[
50+ (FLUSH_LINE, PacketLine::Flush),
51+ (DELIMITER_LINE, PacketLine::Delimiter),
52+ (RESPONSE_END_LINE, PacketLine::ResponseEnd),
53+ ] {
54+ if data == *line_bytes {
55+ return Ok(PacketLineOrWantedSize::Line(*line_type));
56+ }
57+ }
58+
59+ let mut buf = [0u8; U16_HEX_BYTES / 2];
60+ hex::decode_to_slice(data, &mut buf)?;
61+ let wanted_bytes = u16::from_be_bytes(buf);
62+ if wanted_bytes == 4 {
63+ return Err(Error::DataIsEmpty);
64+ }
65+ Ok(PacketLineOrWantedSize::Wanted(wanted_bytes))
66+}
67+
68+pub fn to_data_line(data: &[u8]) -> Result<PacketLine, Error> {
69+ if data.len() > MAX_LINE_LEN {
70+ return Err(Error::DataLengthLimitExceeded(data.len()));
71+ }
72+
73+ if data.len() >= ERR_PREFIX.len() && &data[..ERR_PREFIX.len()] == ERR_PREFIX {
74+ return Err(Error::Line(data[ERR_PREFIX.len()..].into(), data.len()));
75+ }
76+ Ok(PacketLine::Data(data))
77+}
78+
79+// TODO: verify this one is actually needed in the end
4280 pub fn streaming(data: &[u8]) -> Result<Stream, Error> {
4381 let data_len = data.len();
4482 if data_len < U16_HEX_BYTES {
@@ -46,23 +84,15 @@ pub fn streaming(data: &[u8]) -> Result<Stream, Error> { · 1 unmodified line
4684 bytes_needed: U16_HEX_BYTES - data_len,
4785 });
4886 }
49− let hex_bytes = &data[..U16_HEX_BYTES];
50− for (line_bytes, line_type) in &[
51− (FLUSH_LINE, PacketLine::Flush),
52− (DELIMITER_LINE, PacketLine::Delimiter),
53− (RESPONSE_END_LINE, PacketLine::ResponseEnd),
54− ] {
55− if hex_bytes == *line_bytes {
87+ let wanted_bytes = match hex_prefix(data[..U16_HEX_BYTES].try_into().expect("sizes to match"))? {
88+ PacketLineOrWantedSize::Wanted(s) => s as usize,
89+ PacketLineOrWantedSize::Line(line) => {
5690 return Ok(Stream::Complete {
57− line: *line_type,
91+ line,
5892 bytes_consumed: 4,
59− });
93+ })
6094 }
61− }
62−
63− let mut buf = [0u8; U16_HEX_BYTES / 2];
64− hex::decode_to_slice(hex_bytes, &mut buf)?;
65− let wanted_bytes = u16::from_be_bytes(buf) as usize;
95+ };
6696 if wanted_bytes > MAX_LINE_LEN {
6797 return Err(Error::DataLengthLimitExceeded(wanted_bytes));
6898 }
@@ -72,17 +102,8 @@ pub fn streaming(data: &[u8]) -> Result<Stream, Error> { · 3 unmodified lines
72102 });
73103 }
74104
75− if wanted_bytes == 4 {
76− return Err(Error::DataIsEmpty);
77− }
78−
79− let data = &data[U16_HEX_BYTES..wanted_bytes];
80− if data.len() >= ERR_PREFIX.len() && &data[..ERR_PREFIX.len()] == ERR_PREFIX {
81− return Err(Error::Line(data[ERR_PREFIX.len()..].into(), wanted_bytes));
82− }
83−
84105 Ok(Stream::Complete {
85− line: PacketLine::Data(data),
106+ line: to_data_line(&data[U16_HEX_BYTES..wanted_bytes])?,
86107 bytes_consumed: wanted_bytes,
87108 })
88109 }
git-protocol/src/packet_line/mod.rs+11−9
@@ -52,9 +52,9 @@ mod read { · 51 unmodified lines
5252 ) -> io::Result<Result<Borrowed<'a>, decode::Error>> {
5353 let mut buf_end = 4;
5454 reader.read_exact(&mut buf[..buf_end])?;
55− let (from, rest) = buf.split_at_mut(buf_end);
55+ let (hex_bytes, potential_data) = buf.split_at_mut(buf_end);
5656
57− match decode::streaming(from) {
57+ match decode::streaming(hex_bytes) {
5858 Err(err) => Ok(Err(err)),
5959 Ok(stream) => match stream {
6060 decode::Stream::Complete {
@@ -62,14 +62,16 @@ mod read { · 1 unmodified line
6262 bytes_consumed: _,
6363 } => Ok(Ok(line)),
6464 decode::Stream::Incomplete { bytes_needed } => {
65− reader.read_exact(rest)?;
65+ reader.read_exact(potential_data)?;
6666 buf_end += bytes_needed;
67− Ok(decode::streaming(&rest[..buf_end]).map(|stream| match stream {
68− decode::Stream::Complete { line, .. } => line,
69− decode::Stream::Incomplete { .. } => {
70− unreachable!("we know that our streamer is happy once the missing bytes are provided")
71− }
72− }))
67+ Ok(
68+ decode::streaming(&potential_data[..buf_end]).map(|stream| match stream {
69+ decode::Stream::Complete { line, .. } => line,
70+ decode::Stream::Incomplete { .. } => unreachable!(
71+ "we know that our streamer is happy once the missing bytes are provided"
72+ ),
73+ }),
74+ )
7375 }
7476 },
7577 }