Function git_packetline::decode
source · pub fn decode(data: &[u8]) -> Result<PacketLineRef<'_>, Error>
Expand description
Decode an entire packet line from data or fail.
Note that failure also happens if there is not enough data to parse a complete packet line, as opposed to streaming()
decoding
succeeds in that case, stating how much more bytes are required.
Examples found in repository?
src/read/blocking_io.rs (line 72)
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
fn read_line_inner_exhaustive<'a>(
reader: &mut T,
buf: &'a mut Vec<u8>,
delimiters: &[PacketLineRef<'static>],
fail_on_err_lines: bool,
buf_resize: bool,
) -> ExhaustiveOutcome<'a> {
(
false,
None,
Some(match Self::read_line_inner(reader, buf) {
Ok(Ok(line)) => {
if delimiters.contains(&line) {
let stopped_at = delimiters.iter().find(|l| **l == line).cloned();
buf.clear();
return (true, stopped_at, None);
} else if fail_on_err_lines {
if let Some(err) = line.check_error() {
let err = err.0.as_bstr().to_owned();
buf.clear();
return (
true,
None,
Some(Err(io::Error::new(
io::ErrorKind::Other,
crate::read::Error { message: err },
))),
);
}
}
let len = line
.as_slice()
.map(|s| s.len() + U16_HEX_BYTES)
.unwrap_or(U16_HEX_BYTES);
if buf_resize {
buf.resize(len, 0);
}
Ok(Ok(crate::decode(buf).expect("only valid data here")))
}
Ok(Err(err)) => {
buf.clear();
Ok(Err(err))
}
Err(err) => {
buf.clear();
Err(err)
}
}),
)
}
/// Read a packet line into the internal buffer and return it.
///
/// Returns `None` if the end of iteration is reached because of one of the following:
///
/// * natural EOF
/// * ERR packet line encountered if [`fail_on_err_lines()`][StreamingPeekableIter::fail_on_err_lines()] is true.
/// * A `delimiter` packet line encountered
pub fn read_line(&mut self) -> Option<io::Result<Result<PacketLineRef<'_>, decode::Error>>> {
if self.is_done {
return None;
}
if !self.peek_buf.is_empty() {
std::mem::swap(&mut self.peek_buf, &mut self.buf);
self.peek_buf.clear();
Some(Ok(Ok(crate::decode(&self.buf).expect("only valid data in peek buf"))))
} else {
if self.buf.len() != MAX_LINE_LEN {
self.buf.resize(MAX_LINE_LEN, 0);
}
let (is_done, stopped_at, res) = Self::read_line_inner_exhaustive(
&mut self.read,
&mut self.buf,
self.delimiters,
self.fail_on_err_lines,
false,
);
self.is_done = is_done;
self.stopped_at = stopped_at;
res
}
}
/// Peek the next packet line without consuming it.
///
/// Multiple calls to peek will return the same packet line, if there is one.
pub fn peek_line(&mut self) -> Option<io::Result<Result<PacketLineRef<'_>, decode::Error>>> {
if self.is_done {
return None;
}
if self.peek_buf.is_empty() {
self.peek_buf.resize(MAX_LINE_LEN, 0);
let (is_done, stopped_at, res) = Self::read_line_inner_exhaustive(
&mut self.read,
&mut self.peek_buf,
self.delimiters,
self.fail_on_err_lines,
true,
);
self.is_done = is_done;
self.stopped_at = stopped_at;
res
} else {
Some(Ok(Ok(crate::decode(&self.peek_buf).expect("only valid data here"))))
}
}