docs, preparing for publication
This commit is contained in:
parent
131859ffba
commit
e06d553ed7
@ -26,7 +26,13 @@ into_u64!(u8, u16, u32, usize, u64);
|
|||||||
|
|
||||||
/// Data sink to encode bipack binary format.
|
/// Data sink to encode bipack binary format.
|
||||||
///
|
///
|
||||||
/// To implement just override [put_u8] and optionally [put_fixed_bytes]
|
/// To implement just override [put_u8] and optionally [put_fixed_bytes].
|
||||||
|
///
|
||||||
|
/// Note that the sink is not returning errors, unlike [crate::bipack_source::BipackSource].
|
||||||
|
/// It is supposed that the sink has unlimited
|
||||||
|
/// size for the context of data it is used for. This is practical. For the case of overflow-aware
|
||||||
|
/// sink you can create one that ignores extra data when overflow is detected and report it
|
||||||
|
/// somehow, but for encoding it does not worth effort (data size could be estimated in advance).
|
||||||
pub trait BipackSink {
|
pub trait BipackSink {
|
||||||
fn put_u8(self: &mut Self, data: u8);
|
fn put_u8(self: &mut Self, data: u8);
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ use std::string::FromUtf8Error;
|
|||||||
use crate::bipack_source::BipackError::NoDataError;
|
use crate::bipack_source::BipackError::NoDataError;
|
||||||
|
|
||||||
/// Result of error-aware bipack function
|
/// Result of error-aware bipack function
|
||||||
pub(crate) type Res<T> = Result<T, BipackError>;
|
pub(crate) type Result<T> = std::result::Result<T, BipackError>;
|
||||||
|
|
||||||
/// There is not enought data to fulfill the request
|
/// There is not enought data to fulfill the request
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -29,25 +29,29 @@ impl Error for BipackError {}
|
|||||||
///
|
///
|
||||||
/// To implement source for other type, implement just [u8()] or mayve also
|
/// To implement source for other type, implement just [u8()] or mayve also
|
||||||
/// [fixed_bytes] for effectiveness.
|
/// [fixed_bytes] for effectiveness.
|
||||||
|
///
|
||||||
|
/// Unlike the [crate::bipack_sink::BipackSink] the source is returning errors. This is because
|
||||||
|
/// it often appears when reading data do not correspond to the packed one, and this is an often
|
||||||
|
/// case that requires proper reaction, not just a panic attack :)
|
||||||
pub trait BipackSource {
|
pub trait BipackSource {
|
||||||
fn get_u8(self: &mut Self) -> Res<u8>;
|
fn get_u8(self: &mut Self) -> Result<u8>;
|
||||||
|
|
||||||
fn get_u16(self: &mut Self) -> Res<u16> {
|
fn get_u16(self: &mut Self) -> Result<u16> {
|
||||||
Ok(((self.get_u8()? as u16) << 8) + (self.get_u8()? as u16))
|
Ok(((self.get_u8()? as u16) << 8) + (self.get_u8()? as u16))
|
||||||
}
|
}
|
||||||
fn get_u32(self: &mut Self) -> Res<u32> {
|
fn get_u32(self: &mut Self) -> Result<u32> {
|
||||||
Ok(((self.get_u16()? as u32) << 16) + (self.get_u16()? as u32))
|
Ok(((self.get_u16()? as u32) << 16) + (self.get_u16()? as u32))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_u64(self: &mut Self) -> Res<u64> {
|
fn get_u64(self: &mut Self) -> Result<u64> {
|
||||||
Ok(((self.get_u32()? as u64) << 32) | (self.get_u32()? as u64))
|
Ok(((self.get_u32()? as u64) << 32) | (self.get_u32()? as u64))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unpack variable-length packed unsigned value, used aslo internally to store size
|
/// Unpack variable-length packed unsigned value, used aslo internally to store size
|
||||||
/// of arrays, binary data, strings, etc. To pack use
|
/// of arrays, binary data, strings, etc. To pack use
|
||||||
/// [crate::bipack_sink::BipackSink::put_unsigned()].
|
/// [crate::bipack_sink::BipackSink::put_unsigned()].
|
||||||
fn get_unsigned(self: &mut Self) -> Res<u64> {
|
fn get_unsigned(self: &mut Self) -> Result<u64> {
|
||||||
let mut get = || -> Res<u64> { Ok(self.get_u8()? as u64) };
|
let mut get = || -> Result<u64> { Ok(self.get_u8()? as u64) };
|
||||||
let first = get()?;
|
let first = get()?;
|
||||||
let mut ty = first & 3;
|
let mut ty = first & 3;
|
||||||
|
|
||||||
@ -68,7 +72,7 @@ pub trait BipackSource {
|
|||||||
|
|
||||||
/// read 8-bytes varint-packed unsigned value from the source. We dont' recommend
|
/// read 8-bytes varint-packed unsigned value from the source. We dont' recommend
|
||||||
/// using it directly; use [get_unsigned] instead.
|
/// using it directly; use [get_unsigned] instead.
|
||||||
fn get_varint_unsigned(self: &mut Self) -> Res<u64> {
|
fn get_varint_unsigned(self: &mut Self) -> Result<u64> {
|
||||||
let mut result = 0u64;
|
let mut result = 0u64;
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
loop {
|
loop {
|
||||||
@ -81,17 +85,17 @@ pub trait BipackSource {
|
|||||||
|
|
||||||
/// read 2-bytes unsigned value from the source as smartint-encoded, same as [get_unsigned]
|
/// read 2-bytes unsigned value from the source as smartint-encoded, same as [get_unsigned]
|
||||||
/// as u16
|
/// as u16
|
||||||
fn get_packed_u16(self: &mut Self) -> Res<u16> {
|
fn get_packed_u16(self: &mut Self) -> Result<u16> {
|
||||||
Ok(self.get_unsigned()? as u16)
|
Ok(self.get_unsigned()? as u16)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// read 4-bytes unsigned value from the source
|
/// read 4-bytes unsigned value from the source
|
||||||
/// read 2-bytes unsigned value from the source as smartint-encoded, same as [get_unsigned]
|
/// read 2-bytes unsigned value from the source as smartint-encoded, same as [get_unsigned]
|
||||||
/// as u32
|
/// as u32
|
||||||
fn get_packed_u32(self: &mut Self) -> Res<u32> { Ok(self.get_unsigned()? as u32) }
|
fn get_packed_u32(self: &mut Self) -> Result<u32> { Ok(self.get_unsigned()? as u32) }
|
||||||
|
|
||||||
/// read exact number of bytes from the source as a vec.
|
/// read exact number of bytes from the source as a vec.
|
||||||
fn get_fixed_bytes(self: &mut Self, size: usize) -> Res<Vec<u8>> {
|
fn get_fixed_bytes(self: &mut Self, size: usize) -> Result<Vec<u8>> {
|
||||||
let mut result = Vec::with_capacity(size);
|
let mut result = Vec::with_capacity(size);
|
||||||
for i in 0..size { result.push(self.get_u8()?); }
|
for i in 0..size { result.push(self.get_u8()?); }
|
||||||
Ok(result)
|
Ok(result)
|
||||||
@ -101,7 +105,7 @@ pub trait BipackSource {
|
|||||||
/// by [BipackSink::put_var_bytes] or [BipackSink::put_string]. The size is encoded
|
/// by [BipackSink::put_var_bytes] or [BipackSink::put_string]. The size is encoded
|
||||||
/// the same way as does [BipackSink::put_unsigned] and can be manually read by
|
/// the same way as does [BipackSink::put_unsigned] and can be manually read by
|
||||||
/// [BipackSource::get_unsigned].
|
/// [BipackSource::get_unsigned].
|
||||||
fn var_bytes(self: &mut Self) -> Res<Vec<u8>> {
|
fn var_bytes(self: &mut Self) -> Result<Vec<u8>> {
|
||||||
let size = self.get_unsigned()? as usize;
|
let size = self.get_unsigned()? as usize;
|
||||||
self.get_fixed_bytes(size)
|
self.get_fixed_bytes(size)
|
||||||
}
|
}
|
||||||
@ -109,7 +113,7 @@ pub trait BipackSource {
|
|||||||
/// REad a variable length string from a source packed with
|
/// REad a variable length string from a source packed with
|
||||||
/// [BipavkSink::put_string]. It is a variable sized array fo utf8 encoded
|
/// [BipavkSink::put_string]. It is a variable sized array fo utf8 encoded
|
||||||
/// characters.
|
/// characters.
|
||||||
fn str(self: &mut Self) -> Res<String> {
|
fn str(self: &mut Self) -> Result<String> {
|
||||||
String::from_utf8(
|
String::from_utf8(
|
||||||
self.var_bytes()?
|
self.var_bytes()?
|
||||||
).or_else(|e| Err(BipackError::BadEncoding(e)))
|
).or_else(|e| Err(BipackError::BadEncoding(e)))
|
||||||
@ -130,7 +134,7 @@ impl<'a> SliceSource<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'x> BipackSource for SliceSource<'x> {
|
impl<'x> BipackSource for SliceSource<'x> {
|
||||||
fn get_u8(self: &mut Self) -> Res<u8> {
|
fn get_u8(self: &mut Self) -> Result<u8> {
|
||||||
if self.position >= self.data.len() {
|
if self.position >= self.data.len() {
|
||||||
Err(NoDataError)
|
Err(NoDataError)
|
||||||
} else {
|
} else {
|
||||||
|
@ -19,14 +19,13 @@ mod to_dump;
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::error::Error;
|
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use crate::bipack_sink::{BipackSink};
|
use crate::bipack_sink::{BipackSink};
|
||||||
use crate::bipack_source::{BipackSource, Res, SliceSource};
|
use crate::bipack_source::{BipackSource, Result, SliceSource};
|
||||||
use crate::to_dump::to_dump;
|
use crate::to_dump::to_dump;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fixed_unpack() -> Result<(),Box<dyn Error>> {
|
fn fixed_unpack() -> Result<()> {
|
||||||
let mut src = Vec::new();
|
let mut src = Vec::new();
|
||||||
base64::engine::general_purpose::STANDARD_NO_PAD
|
base64::engine::general_purpose::STANDARD_NO_PAD
|
||||||
.decode_vec("B/oAAAEB0AAAANjLgKAv", &mut src)
|
.decode_vec("B/oAAAEB0AAAANjLgKAv", &mut src)
|
||||||
@ -42,7 +41,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn smartint_unpack() -> Res<()> {
|
fn smartint_unpack() -> Result<()> {
|
||||||
let mut src = Vec::new();
|
let mut src = Vec::new();
|
||||||
base64::engine::general_purpose::STANDARD_NO_PAD
|
base64::engine::general_purpose::STANDARD_NO_PAD
|
||||||
.decode_vec("BwLoA0IHBL+AAq7GDQ", &mut src)
|
.decode_vec("BwLoA0IHBL+AAq7GDQ", &mut src)
|
||||||
|
Loading…
Reference in New Issue
Block a user