Skip to content

Commit

Permalink
packet line writer deals with long lines and definitely isn't smart
Browse files Browse the repository at this point in the history
…so it doesn't do anything on drop.
  • Loading branch information
Byron committed Aug 19, 2020
1 parent 721c215 commit 549e6e6
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 16 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ Please see _'Development Status'_ for a listing of all crates and their capabili
* [x] [V2 additions](https://github.com/git/git/blob/master/Documentation/technical/protocol-v2.txt#L35:L36)
* [x] [side-band mode](https://github.com/git/git/blob/master/Documentation/technical/pack-protocol.txt#L467:L467)
* [x] `Read` from packet line with (optional) progress support via sidebands
* [ ] `Write` with built-in packet line encoding
* [x] `Write` with built-in packet line encoding

### git-transport
* [ ] general purpose `connect(…)` for clients
Expand Down
35 changes: 21 additions & 14 deletions git-packetline/src/write.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::MAX_DATA_LEN;
use std::io;

/// An implementor of `Write` which passes all input to an inner `Write` in packet line data encoding, one line per `write(…)`
Expand All @@ -22,28 +23,34 @@ impl<T: io::Write> Writer<T> {
}

impl<T: io::Write> io::Write for Writer<T> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
fn write(&mut self, mut buf: &[u8]) -> io::Result<usize> {
if buf.is_empty() {
return Err(io::Error::new(
io::ErrorKind::Other,
"empty packet lines are not permitted as '0004' is invalid",
));
}

if self.binary {
crate::encode::data_to_write(buf, &mut self.inner)
} else {
crate::encode::text_to_write(buf, &mut self.inner)
}
.map_err(|err| {
use crate::encode::Error::*;
match err {
Io(err) => err,
DataIsEmpty | DataLengthLimitExceeded(_) => {
unreachable!("We are handling empty and large data here, so this can't ever happen")
}
let mut written = 0;
while !buf.is_empty() {
let (data, rest) = buf.split_at(buf.len().min(MAX_DATA_LEN));
written += if self.binary {
crate::encode::data_to_write(data, &mut self.inner)
} else {
crate::encode::text_to_write(data, &mut self.inner)
}
})
.map_err(|err| {
use crate::encode::Error::*;
match err {
Io(err) => err,
DataIsEmpty | DataLengthLimitExceeded(_) => {
unreachable!("We are handling empty and large data here, so this can't ever happen")
}
}
})?;
buf = rest;
}
Ok(written)
}

fn flush(&mut self) -> io::Result<()> {
Expand Down
8 changes: 8 additions & 0 deletions git-packetline/tests/packet_line/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,11 @@ fn empty_writes_fail_with_error() {
"empty packet lines are not permitted as '0004' is invalid"
)
}

#[test]
fn nothing_happens_on_drop() {
let mut out = Vec::new();
let w = Writer::new(&mut out);
drop(w);
assert!(out.is_empty());
}
2 changes: 1 addition & 1 deletion tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* [x] Disable sideband support (e.g. github http V2 doesn't have it)
* [x] don't coerce line delimiters into empty slices.
* [x] Make 'ERR <error>' handling as error optional, as it may occur only in certain contexts.
* [ ] `Write` with packet line encoding
* [x] `Write` with packet line encoding
* **git-url**
* [ ] parse into components to make them easy to understand
* **connect**
Expand Down

0 comments on commit 549e6e6

Please sign in to comment.