Merge branch 'add-generated-markers' and resolve conflicts in src/generator.rs
This commit is contained in:
+49
-5
@@ -189,7 +189,7 @@ impl<'a> ProtoAccessor<'a> {
|
||||
pub fn get_value(&self, field_number: u32) -> Result<(&'a [u8], WireType)> {
|
||||
let mut last_value = None;
|
||||
for item in self.fields() {
|
||||
let (tag, value) = item?;
|
||||
let (_offset, tag, value) = item?;
|
||||
if tag.field_number == field_number {
|
||||
last_value = Some((value, tag.wire_type));
|
||||
}
|
||||
@@ -201,6 +201,32 @@ impl<'a> ProtoAccessor<'a> {
|
||||
pub fn iter_repeated(&self, field_number: u32) -> RepeatedFieldIterator<'a> {
|
||||
RepeatedFieldIterator::new(self.data, field_number)
|
||||
}
|
||||
|
||||
/// Returns the value and wire type of a field at a specific offset.
|
||||
pub fn get_value_at(&self, offset: usize) -> Result<(&'a [u8], WireType)> {
|
||||
if offset >= self.data.len() {
|
||||
return Err(RotoError::UnexpectedEndOfBuffer);
|
||||
}
|
||||
let (tag, tag_len) = Tag::decode(&self.data[offset..])?;
|
||||
let cursor_after_tag = offset + tag_len;
|
||||
if cursor_after_tag > self.data.len() {
|
||||
return Err(RotoError::UnexpectedEndOfBuffer);
|
||||
}
|
||||
let value_len = skip_value(tag.wire_type, &self.data[cursor_after_tag..])?;
|
||||
let (value_offset, actual_value_len) = match tag.wire_type {
|
||||
WireType::LengthDelimited => {
|
||||
let (_, varint_len) = read_varint(&self.data[cursor_after_tag..])?;
|
||||
(cursor_after_tag + varint_len, value_len - varint_len)
|
||||
}
|
||||
_ => (cursor_after_tag, value_len),
|
||||
};
|
||||
Ok((&self.data[value_offset..value_offset + actual_value_len], tag.wire_type))
|
||||
}
|
||||
|
||||
/// Returns an iterator that scans a specific range of the buffer for all occurrences of the specified field.
|
||||
pub fn iter_repeated_range(&self, field_number: u32, start: usize, end: usize) -> RepeatedFieldIterator<'a> {
|
||||
RepeatedFieldIterator::new_range(self.data, field_number, start, end)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FieldIterator<'a> {
|
||||
@@ -209,7 +235,7 @@ pub struct FieldIterator<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Iterator for FieldIterator<'a> {
|
||||
type Item = Result<(Tag, &'a [u8])>;
|
||||
type Item = Result<(usize, Tag, &'a [u8])>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.cursor >= self.data.len() {
|
||||
@@ -254,23 +280,36 @@ impl<'a> Iterator for FieldIterator<'a> {
|
||||
|
||||
self.cursor = cursor_after_tag + value_len;
|
||||
|
||||
Some(Ok((tag, &self.data[value_offset..value_offset + actual_value_len])))
|
||||
Some(Ok((self.cursor - tag_len - value_len, tag, &self.data[value_offset..value_offset + actual_value_len])))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RepeatedFieldIterator<'a> {
|
||||
iterator: FieldIterator<'a>,
|
||||
field_number: u32,
|
||||
end_offset: Option<usize>,
|
||||
}
|
||||
|
||||
impl<'a> RepeatedFieldIterator<'a> {
|
||||
fn new(data: &'a [u8], field_number: u32) -> Self {
|
||||
pub fn new(data: &'a [u8], field_number: u32) -> Self {
|
||||
Self {
|
||||
iterator: FieldIterator {
|
||||
data,
|
||||
cursor: 0,
|
||||
},
|
||||
field_number,
|
||||
end_offset: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_range(data: &'a [u8], field_number: u32, start: usize, end: usize) -> Self {
|
||||
Self {
|
||||
iterator: FieldIterator {
|
||||
data,
|
||||
cursor: start,
|
||||
},
|
||||
field_number,
|
||||
end_offset: Some(end),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -281,7 +320,12 @@ impl<'a> Iterator for RepeatedFieldIterator<'a> {
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
while let Some(item) = self.iterator.next() {
|
||||
match item {
|
||||
Ok((tag, value)) if tag.field_number == self.field_number => {
|
||||
Ok((offset, tag, value)) if tag.field_number == self.field_number => {
|
||||
if let Some(end) = self.end_offset {
|
||||
if offset > end {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
return Some(Ok((value, tag.wire_type)));
|
||||
}
|
||||
Ok(_) => continue,
|
||||
|
||||
Reference in New Issue
Block a user