Package up Indexer
This commit is contained in:
parent
4a1b021635
commit
384644f5ea
|
@ -40,16 +40,6 @@ fn tag_at(packed: &[u8], i: usize) -> io::Result<Tag> {
|
||||||
Ok(Tag::try_from(at(packed, i)?)?)
|
Ok(Tag::try_from(at(packed, i)?)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn skip_annotations(packed: &[u8], mut i: usize) -> io::Result<usize> {
|
|
||||||
loop {
|
|
||||||
if tag_at(packed, i)? == Tag::Annotation {
|
|
||||||
i = skip_value(packed, i + 1)?;
|
|
||||||
} else {
|
|
||||||
return Ok(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn varint(packed: &[u8], mut i: usize) -> io::Result<(u64, usize)> {
|
fn varint(packed: &[u8], mut i: usize) -> io::Result<(u64, usize)> {
|
||||||
let mut shift = 0;
|
let mut shift = 0;
|
||||||
let mut acc: u64 = 0;
|
let mut acc: u64 = 0;
|
||||||
|
@ -64,51 +54,84 @@ fn varint(packed: &[u8], mut i: usize) -> io::Result<(u64, usize)> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn skip_value(packed: &[u8], mut i: usize) -> io::Result<usize> {
|
struct Indexer<'de> {
|
||||||
loop {
|
packed: &'de [u8],
|
||||||
let next_i = match tag_at(packed, i)? {
|
offset: usize,
|
||||||
Tag::False => i + 1,
|
}
|
||||||
Tag::True => i + 1,
|
|
||||||
Tag::Float => i + 5,
|
impl<'de> Indexer<'de> {
|
||||||
Tag::Double => i + 9,
|
fn skip_annotations(&mut self) -> io::Result<()> {
|
||||||
Tag::End => Err(io::Error::new(io::ErrorKind::InvalidData, "Unexpected end tag"))?,
|
loop {
|
||||||
Tag::Annotation => {
|
if tag_at(&self.packed, self.offset)? == Tag::Annotation {
|
||||||
i = skip_value(packed, i + 1)?;
|
self.offset += 1;
|
||||||
continue;
|
self.skip_value()?;
|
||||||
|
} else {
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
Tag::Embedded => {
|
}
|
||||||
i = i + 1;
|
}
|
||||||
continue;
|
|
||||||
}
|
fn tag(&mut self) -> io::Result<Tag> {
|
||||||
Tag::SmallInteger(_) => i + 1,
|
let tag = tag_at(&self.packed, self.offset)?;
|
||||||
Tag::MediumInteger(n) => i + 1 + (n as usize),
|
Ok(tag)
|
||||||
Tag::SignedInteger | Tag::ByteString => {
|
}
|
||||||
let (n, i) = varint(packed, i + 1)?;
|
|
||||||
i + (n as usize)
|
fn varint(&mut self) -> io::Result<u64> {
|
||||||
}
|
let (n, i) = varint(&self.packed, self.offset + 1)?;
|
||||||
Tag::String | Tag::Symbol => {
|
self.offset = i;
|
||||||
let (n, i) = varint(packed, i + 1)?;
|
Ok(n)
|
||||||
std::str::from_utf8(&packed[i .. i + (n as usize)]).map_err(
|
}
|
||||||
|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid UTF-8"))?;
|
|
||||||
i + (n as usize)
|
fn skip_value(&mut self) -> io::Result<()> {
|
||||||
}
|
loop {
|
||||||
Tag::Record | Tag::Sequence | Tag::Set | Tag::Dictionary => {
|
match self.tag()? {
|
||||||
i = i + 1;
|
Tag::False => self.offset += 1,
|
||||||
while tag_at(packed, i)? != Tag::End {
|
Tag::True => self.offset += 1,
|
||||||
i = skip_value(packed, i)?;
|
Tag::Float => self.offset += 5,
|
||||||
|
Tag::Double => self.offset += 9,
|
||||||
|
Tag::End => Err(io::Error::new(io::ErrorKind::InvalidData, "Unexpected end tag"))?,
|
||||||
|
Tag::Annotation => {
|
||||||
|
self.offset += 1;
|
||||||
|
self.skip_value()?;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Tag::Embedded => {
|
||||||
|
self.offset += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Tag::SmallInteger(_) => self.offset += 1,
|
||||||
|
Tag::MediumInteger(n) => self.offset += 1 + n as usize,
|
||||||
|
Tag::SignedInteger | Tag::ByteString => {
|
||||||
|
let n = self.varint()?;
|
||||||
|
self.offset += n as usize;
|
||||||
|
}
|
||||||
|
Tag::String | Tag::Symbol => {
|
||||||
|
let n = self.varint()?;
|
||||||
|
std::str::from_utf8(&self.packed[self.offset .. self.offset + (n as usize)])
|
||||||
|
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid UTF-8"))?;
|
||||||
|
self.offset += n as usize;
|
||||||
|
}
|
||||||
|
Tag::Record | Tag::Sequence | Tag::Set | Tag::Dictionary => {
|
||||||
|
self.offset += 1;
|
||||||
|
while tag_at(&self.packed, self.offset)? != Tag::End {
|
||||||
|
self.skip_value()?;
|
||||||
|
}
|
||||||
|
self.offset += 1;
|
||||||
}
|
}
|
||||||
i + 1
|
|
||||||
}
|
}
|
||||||
};
|
return Ok(());
|
||||||
return Ok(next_i);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, Packed: AsRef<[u8]> + 'de> View<'de, Packed> {
|
impl<'de, Packed: AsRef<[u8]> + 'de> View<'de, Packed> {
|
||||||
pub fn new(packed: Packed) -> io::Result<Self> {
|
pub fn new(packed: Packed) -> io::Result<Self> {
|
||||||
// println!("packed {:?}", &packed.as_ref());
|
// println!("packed {:?}", &packed.as_ref());
|
||||||
let value_offset = skip_annotations(packed.as_ref(), 0)?;
|
let mut indexer = Indexer { packed: packed.as_ref(), offset: 0 };
|
||||||
let value_end = skip_value(packed.as_ref(), value_offset)?;
|
indexer.skip_annotations()?;
|
||||||
|
let value_offset = indexer.offset;
|
||||||
|
indexer.skip_value()?;
|
||||||
|
let value_end = indexer.offset;
|
||||||
if value_end > packed.as_ref().len() { Err(io_eof())? }
|
if value_end > packed.as_ref().len() { Err(io_eof())? }
|
||||||
Ok(View { packed, value_offset, value_end, phantom: PhantomData })
|
Ok(View { packed, value_offset, value_end, phantom: PhantomData })
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue