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)?)?)
|
||||
}
|
||||
|
||||
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)> {
|
||||
let mut shift = 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> {
|
||||
packed: &'de [u8],
|
||||
offset: usize,
|
||||
}
|
||||
|
||||
impl<'de> Indexer<'de> {
|
||||
fn skip_annotations(&mut self) -> io::Result<()> {
|
||||
loop {
|
||||
let next_i = match tag_at(packed, i)? {
|
||||
Tag::False => i + 1,
|
||||
Tag::True => i + 1,
|
||||
Tag::Float => i + 5,
|
||||
Tag::Double => i + 9,
|
||||
if tag_at(&self.packed, self.offset)? == Tag::Annotation {
|
||||
self.offset += 1;
|
||||
self.skip_value()?;
|
||||
} else {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn tag(&mut self) -> io::Result<Tag> {
|
||||
let tag = tag_at(&self.packed, self.offset)?;
|
||||
Ok(tag)
|
||||
}
|
||||
|
||||
fn varint(&mut self) -> io::Result<u64> {
|
||||
let (n, i) = varint(&self.packed, self.offset + 1)?;
|
||||
self.offset = i;
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
fn skip_value(&mut self) -> io::Result<()> {
|
||||
loop {
|
||||
match self.tag()? {
|
||||
Tag::False => self.offset += 1,
|
||||
Tag::True => self.offset += 1,
|
||||
Tag::Float => self.offset += 5,
|
||||
Tag::Double => self.offset += 9,
|
||||
Tag::End => Err(io::Error::new(io::ErrorKind::InvalidData, "Unexpected end tag"))?,
|
||||
Tag::Annotation => {
|
||||
i = skip_value(packed, i + 1)?;
|
||||
self.offset += 1;
|
||||
self.skip_value()?;
|
||||
continue;
|
||||
}
|
||||
Tag::Embedded => {
|
||||
i = i + 1;
|
||||
self.offset += 1;
|
||||
continue;
|
||||
}
|
||||
Tag::SmallInteger(_) => i + 1,
|
||||
Tag::MediumInteger(n) => i + 1 + (n as usize),
|
||||
Tag::SmallInteger(_) => self.offset += 1,
|
||||
Tag::MediumInteger(n) => self.offset += 1 + n as usize,
|
||||
Tag::SignedInteger | Tag::ByteString => {
|
||||
let (n, i) = varint(packed, i + 1)?;
|
||||
i + (n as usize)
|
||||
let n = self.varint()?;
|
||||
self.offset += n as usize;
|
||||
}
|
||||
Tag::String | Tag::Symbol => {
|
||||
let (n, i) = varint(packed, i + 1)?;
|
||||
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)
|
||||
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 => {
|
||||
i = i + 1;
|
||||
while tag_at(packed, i)? != Tag::End {
|
||||
i = skip_value(packed, i)?;
|
||||
self.offset += 1;
|
||||
while tag_at(&self.packed, self.offset)? != Tag::End {
|
||||
self.skip_value()?;
|
||||
}
|
||||
i + 1
|
||||
self.offset += 1;
|
||||
}
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
return Ok(next_i);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, Packed: AsRef<[u8]> + 'de> View<'de, Packed> {
|
||||
pub fn new(packed: Packed) -> io::Result<Self> {
|
||||
// println!("packed {:?}", &packed.as_ref());
|
||||
let value_offset = skip_annotations(packed.as_ref(), 0)?;
|
||||
let value_end = skip_value(packed.as_ref(), value_offset)?;
|
||||
let mut indexer = Indexer { packed: packed.as_ref(), offset: 0 };
|
||||
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())? }
|
||||
Ok(View { packed, value_offset, value_end, phantom: PhantomData })
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue