improve text reading format

master
Avril 4 years ago
parent 95359c2a81
commit be11573230
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -17,6 +17,77 @@ use tokio::{
};
use futures::future::Future;
pub trait FindSliceBounds
{
type SliceType: ?Sized;
fn slice_bounds(&self, from: &Self::SliceType) -> Range<usize>;
}
pub trait SliceInPlace
{
fn slice_in_place(&mut self, slice: Range<usize>);
}
impl SliceInPlace for String
{
fn slice_in_place(&mut self, slice: Range<usize>) {
let mut i=0;
self.retain(|_| (slice.contains(&i), i+=1).0);
}
}
impl<T> SliceInPlace for Vec<T>
{
fn slice_in_place(&mut self, slice: Range<usize>) {
let mut i=0;
self.retain(|_| (slice.contains(&i), i+=1).0);
}
}
impl<T: ?Sized + AsRef<str>> FindSliceBounds for T
{
type SliceType = str;
fn slice_bounds(&self, from: &Self::SliceType) -> Range<usize>{
let this = self.as_ref();
unsafe {
let sptr = from.as_ptr();
let eptr = sptr.add(from.len());
let ssptr = this.as_ptr();
let septr = ssptr.add(this.len());
let sptr = sptr as usize;
let ssptr = ssptr as usize;
let eptr = eptr as usize;
let septr = septr as usize;
assert!(sptr >= ssptr && sptr <= septr, "Start index of slice is outside the bounds of self");
assert!(eptr >= ssptr && eptr <= septr, "End index of slice is outside the bounds of self");
(sptr - ssptr)..(eptr - ssptr)
}
}
}
#[cfg(test)]
mod test_slice_in_place
{
use super::*;
#[test]
fn slice_in_place_str()
{
let mut string = String::from(" hello world ");
assert_eq!(&string[string.slice_bounds(string.trim())], string.trim());
assert_eq!(&string[string.slice_bounds(string.trim())], "hello world");
string.slice_in_place(string.slice_bounds(string.trim()));
assert_eq!(&string[..], "hello world");
let string = String::from("hello world");
assert_eq!(&string[string.slice_bounds(string.trim())], string.trim());
assert_eq!(&string[string.slice_bounds(string.trim())], "hello world");
}
}
#[derive(Debug)]
pub struct GroupIter<I, T, U=Box<[T]>>(std::iter::Fuse<I>, Vec<T>, usize, PhantomData<U>);
@ -78,7 +149,7 @@ pub trait GroupIterExt<I, T>: Sized
impl<T: IntoIterator> GroupIterExt<<T as IntoIterator>::IntoIter, <T as IntoIterator>::Item> for T
{
fn group_into<U>(self, every: usize) -> GroupIter<<T as IntoIterator>::IntoIter, <T as IntoIterator>::Item, U>
where U: From<Vec<<T as IntoIterator>::Item>>
where U: From<Vec<<T as IntoIterator>::Item>>
{
GroupIter(self.into_iter().fuse(), Vec::with_capacity(every), every, PhantomData)
}
@ -130,7 +201,7 @@ impl<'a, T: ?Sized> StrChunks<'a, T>
/// Set the number of chars to break at.
///
/// # Note
/// Probably don't do this unless you know what you're doing.
/// Probably don't do this as it modifies the iterators internal state weirdly. But it should be fine generally.
pub fn every_mut(&mut self) -> &mut usize
{
&mut self.1

@ -207,9 +207,8 @@ impl KeyHeader
out.write_u8(b'\n').await?;
written += bytes.len() + 1;
}
out.write_all(b"---\n>BEGIN\nBODY<\n").await?; // We can add a comment after > as long as it doesn't have any newlines.
// this is because of the retarded way i did read_text with mpsc.
Ok(written + 8 + 9)
out.write_all(b"---\n").await?;
Ok(written + 4)
}
/// Read a superheader as text bytes from this stream
#[instrument(err, skip(input, passwd))]
@ -266,34 +265,40 @@ impl KeyHeader
let line_sender = async move { //this causes the >\n<\n dumbness in the encoding. Rewrite this to not use mpsc pls
let mut buffer = String::new();
while input.read_line(&mut buffer).await? != 0 {
let bounds = {
let trimmed = buffer.trim();
if trimmed.len() == 0 {
continue;
} else if trimmed == "---" {
return Ok(true)
}
buffer.slice_bounds(trimmed)
};
buffer.slice_in_place(bounds);
if {
let bytes = buffer.as_bytes();
if bytes.len() > 0 && bytes[bytes.len()-1] == b'\n' {
true
} else {
false
}
} {
buffer.truncate(buffer.len()-1);
}
tx.send(buffer.clone()).await?;
buffer.clear();
}
Ok::<(), SendError>(())
warn!("Buffer contained no end-of-entry delimiter");
Ok::<bool, SendError>(false)
};
let line_reader = async move {
macro_rules! take_one {
($msg:literal $($tt:tt)*) => {
loop {
if let Some(mut line) = rx.recv().await {
if line.trim().len() == 0 {
continue;
}
if {
let bytes = line.as_bytes();
if bytes.len() > 0 && bytes[bytes.len()-1] == b'\n' {
true
} else {
false
}
} {
line.truncate(line.len()-1);
}
break line;
} else {
return Err(eyre::eyre!(format!($msg $($tt)*))).wrap_err(eyre::eyre!("Failed to deserialise string"));
}
if let Some(line) = rx.recv().await {
line
} else {
return Err(eyre::eyre!(format!($msg $($tt)*))).wrap_err(eyre::eyre!("Failed to deserialise string"));
}
}
}
@ -312,21 +317,9 @@ impl KeyHeader
};
trace!("Decoded hex");
let mut enc = String::new();
let mut had_delim =false;
while let Some(line) = rx.recv().await {
let line = line.trim();
if line.len() == 0 {
continue;
}
if line == "---" {
had_delim=true;
break;
} else if line.len()>0 {
enc.push_str(line)
}
}
if !had_delim {
warn!("Buffer contained no end-of-entry delimiter");
debug_assert_eq!(&line[..], line.trim());
enc.push_str(&line[..]);
}
trace!("Done reading lines");
@ -361,12 +354,13 @@ impl KeyHeader
let (sres, rres) = tokio::join!(line_sender, line_reader);
match sres {
Err(x @ SendError::IO(_)) => Err(x).with_note(|| "In line reader"),
Err(_) => {
Err(_) | Ok(true) => {
trace!("We completed without reading whole file");
Ok(rres?)
},
_ => {
warn!("Header reading completed to EOF, there is no body in this stream.");
Ok(rres?)
},
}

@ -157,21 +157,21 @@ async fn fuck() -> eyre::Result<()>
let password = "hello world. I am a password";
let superheader = SuperHeader::<KeyHeader>::new_for(&header);
println!("Writing: {:?}\n\t{:?}\n\t{:?}", superheader, header, body);
let mut written = superheader.write_bytes(&mut ser, |salt| Some(Password::derive(password, salt.as_ref()))).await?;
ser.extend(header.into_memory(serialise::Mode::Binary, |salt| Some(Password::derive(password, salt.as_ref())))?); //header.write_text(&mut ser).await?;
written += body.write_bytes(&mut ser, header.body_key()).await?;
let mut written = superheader.write_text(&mut ser, |salt| Some(Password::derive(password, salt.as_ref()))).await?;
ser.extend(header.into_memory(serialise::Mode::Text, |salt| Some(Password::derive(password, salt.as_ref())))?); //header.write_text(&mut ser).await?;
written += body.write_text(&mut ser, header.body_key()).await?;
println!("Wrote {} bytes", written);
println!("{}\n", ser.fmt_view());
println!("As text:\n{}\n", ser.fmt_ascii());
let mut read = &ser[..];
let (reads, readn) = SuperHeader::from_memory(&mut read, serialise::Mode::Binary, |salt| Some(Password::derive(password, salt)))?; // SuperHeader::read_text(read).await?;
let (reads, readn) = SuperHeader::from_memory(&mut read, serialise::Mode::Text, |salt| Some(Password::derive(password, salt)))?; // SuperHeader::read_text(read).await?;
let mut read = &read[readn..];
println!("Read super: {:?}", reads);
let readheader = KeyHeader::read_bytes(&mut read, |salt| Some(Password::derive(password, salt))).await?;
let readheader = KeyHeader::read_text(&mut read, |salt| Some(Password::derive(password, salt))).await?;
println!("Read real: {:?}", readheader);
let readbody = key::aes::AesBody::read_bytes(&mut read, readheader.body_key()).await?;
let readbody = key::aes::AesBody::read_text(&mut read, readheader.body_key()).await?;
println!("Read body: {:?}", readbody);
reads.verify_for(&header)?;
reads.verify_for(&readheader)?;

Loading…
Cancel
Save