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
6};6};
7use bstr::BString;7use bstr::BString;
8use quick_error::quick_error;8use quick_error::quick_error;
9use std::convert::TryInto;
9 10
10quick_error! {11quick_error! {
11 #[derive(Debug)]12 #[derive(Debug)]
@@ -39,6 +40,43 @@ pub enum Stream<'a> { · 27 unmodified lines
39 },40 },
40}41}
41 42
43pub enum PacketLineOrWantedSize<'a> {
44 Line(PacketLine<'a>),
45 Wanted(u16),
46}
47
48pub 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
68pub 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
42pub fn streaming(data: &[u8]) -> Result<Stream, Error> {80pub fn streaming(data: &[u8]) -> Result<Stream, Error> {
43 let data_len = data.len();81 let data_len = data.len();
44 if data_len < U16_HEX_BYTES {82 if data_len < U16_HEX_BYTES {
@@ -46,23 +84,15 @@ pub fn streaming(data: &[u8]) -> Result<Stream, Error> { · 1 unmodified line
46 bytes_needed: U16_HEX_BYTES - data_len,84 bytes_needed: U16_HEX_BYTES - data_len,
47 });85 });
48 }86 }
49 let hex_bytes = &data[..U16_HEX_BYTES];87 let wanted_bytes = match hex_prefix(data[..U16_HEX_BYTES].try_into().expect("sizes to match"))? {
50 for (line_bytes, line_type) in &[88 PacketLineOrWantedSize::Wanted(s) => s as usize,
51 (FLUSH_LINE, PacketLine::Flush),89 PacketLineOrWantedSize::Line(line) => {
52 (DELIMITER_LINE, PacketLine::Delimiter),
53 (RESPONSE_END_LINE, PacketLine::ResponseEnd),
54 ] {
55 if hex_bytes == *line_bytes {
56 return Ok(Stream::Complete {90 return Ok(Stream::Complete {
57 line: *line_type,91 line,
58 bytes_consumed: 4,92 bytes_consumed: 4,
59 });93 })
60 }94 }
61 }95 };
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;
66 if wanted_bytes > MAX_LINE_LEN {96 if wanted_bytes > MAX_LINE_LEN {
67 return Err(Error::DataLengthLimitExceeded(wanted_bytes));97 return Err(Error::DataLengthLimitExceeded(wanted_bytes));
68 }98 }
@@ -72,17 +102,8 @@ pub fn streaming(data: &[u8]) -> Result<Stream, Error> { · 3 unmodified lines
72 });102 });
73 }103 }
74 104
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
84 Ok(Stream::Complete {105 Ok(Stream::Complete {
85 line: PacketLine::Data(data),106 line: to_data_line(&data[U16_HEX_BYTES..wanted_bytes])?,
86 bytes_consumed: wanted_bytes,107 bytes_consumed: wanted_bytes,
87 })108 })
88}109}
git-protocol/src/packet_line/mod.rs+11−9
@@ -52,9 +52,9 @@ mod read { · 51 unmodified lines
52 ) -> io::Result<Result<Borrowed<'a>, decode::Error>> {52 ) -> io::Result<Result<Borrowed<'a>, decode::Error>> {
53 let mut buf_end = 4;53 let mut buf_end = 4;
54 reader.read_exact(&mut buf[..buf_end])?;54 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);
56 56
57 match decode::streaming(from) {57 match decode::streaming(hex_bytes) {
58 Err(err) => Ok(Err(err)),58 Err(err) => Ok(Err(err)),
59 Ok(stream) => match stream {59 Ok(stream) => match stream {
60 decode::Stream::Complete {60 decode::Stream::Complete {
@@ -62,14 +62,16 @@ mod read { · 1 unmodified line
62 bytes_consumed: _,62 bytes_consumed: _,
63 } => Ok(Ok(line)),63 } => Ok(Ok(line)),
64 decode::Stream::Incomplete { bytes_needed } => {64 decode::Stream::Incomplete { bytes_needed } => {
65 reader.read_exact(rest)?;65 reader.read_exact(potential_data)?;
66 buf_end += bytes_needed;66 buf_end += bytes_needed;
67 Ok(decode::streaming(&rest[..buf_end]).map(|stream| match stream {67 Ok(
68 decode::Stream::Complete { line, .. } => line,68 decode::streaming(&potential_data[..buf_end]).map(|stream| match stream {
69 decode::Stream::Incomplete { .. } => {69 decode::Stream::Complete { line, .. } => line,
70 unreachable!("we know that our streamer is happy once the missing bytes are provided")70 decode::Stream::Incomplete { .. } => unreachable!(
71 }71 "we know that our streamer is happy once the missing bytes are provided"
72 }))72 ),
73 }),
74 )
73 }75 }
74 },76 },
75 }77 }