Skip to main content

mesh_protobuf/
protobuf.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Tools to encode and decode protobuf messages.
5
6use super::DecodeError;
7use super::InplaceOption;
8use super::MessageDecode;
9use super::MessageEncode;
10use super::RefCell;
11use super::Result;
12use super::buffer;
13use super::buffer::Buf;
14use super::buffer::Buffer;
15use crate::DefaultEncoding;
16use alloc::vec;
17use alloc::vec::Vec;
18use core::marker::PhantomData;
19use core::ops::Range;
20
21/// Writes a variable-length integer, as defined in the protobuf specification.
22fn write_varint(v: &mut Buf<'_>, mut n: u64) {
23    while n > 0x7f {
24        v.push(0x80 | (n & 0x7f) as u8);
25        n >>= 7;
26    }
27    v.push(n as u8);
28}
29
30/// Computes the length of an encoded variable-length integer.
31const fn varint_size(n: u64) -> usize {
32    if n == 0 {
33        1
34    } else {
35        let bits = 64 - n.leading_zeros() as usize;
36        (((bits - 1) / 7) + 1) & 0xff
37    }
38}
39
40/// Reads a variable-length integer, advancing `v`.
41pub(crate) fn read_varint(v: &mut &[u8]) -> Result<u64> {
42    let mut shift = 0;
43    let mut r = 0;
44    loop {
45        let (b, rest) = v.split_first().ok_or(DecodeError::EofVarInt)?;
46        *v = rest;
47        r |= (*b as u64 & 0x7f) << shift;
48        if *b & 0x80 == 0 {
49            break;
50        }
51        shift += 7;
52        if shift > 63 {
53            return Err(DecodeError::VarIntTooBig.into());
54        }
55    }
56    Ok(r)
57}
58
59/// Zigzag encodes a signed integer, as defined in the protobuf spec.
60///
61/// This is used when writing a variable-sized signed integer to keep the
62/// encoding small.
63fn zigzag(n: i64) -> u64 {
64    ((n << 1) ^ (n >> 63)) as u64
65}
66
67/// Reverses the zigzag encoding.
68fn unzigzag(n: u64) -> i64 {
69    ((n >> 1) as i64) ^ -((n & 1) as i64)
70}
71
72/// The protobuf wire type.
73#[repr(u32)]
74#[derive(Debug, Copy, Clone, PartialEq, Eq)]
75pub enum WireType {
76    /// Variable-length integer.
77    Varint = 0,
78    /// Fixed 64-bit value.
79    Fixed64 = 1,
80    /// Variable-length byte buffer.
81    Variable = 2,
82    /// Fixed 32-bit value.
83    Fixed32 = 5,
84
85    /// Mesh extension: just like Variable but prefixed with two varints:
86    /// * The number of ports used by the message.
87    /// * The number of resources used by the message.
88    MeshMessage = 6,
89
90    /// Mesh extension. Consumes the next resource.
91    Resource = 7,
92}
93
94struct DecodeInner<'a, R> {
95    resources: &'a mut [Option<R>],
96}
97
98struct DecodeState<'a, R>(RefCell<DecodeInner<'a, R>>);
99
100impl<'a, R> DecodeState<'a, R> {
101    fn new(resources: &'a mut [Option<R>]) -> Self {
102        Self(RefCell::new(DecodeInner { resources }))
103    }
104
105    /// Takes resource `index`.
106    fn resource(&self, index: u32) -> Result<R> {
107        (|| {
108            self.0
109                .borrow_mut()
110                .resources
111                .get_mut(index as usize)?
112                .take()
113        })()
114        .ok_or_else(|| DecodeError::MissingResource.into())
115    }
116}
117
118struct EncodeState<'a, R> {
119    data: Buf<'a>,
120    message_sizes: core::slice::Iter<'a, MessageSize>,
121    resources: &'a mut Vec<R>,
122    field_number: u32,
123    in_sequence: bool,
124}
125
126impl<'a, R> EncodeState<'a, R> {
127    fn new(data: Buf<'a>, message_sizes: &'a [MessageSize], resources: &'a mut Vec<R>) -> Self {
128        Self {
129            data,
130            resources,
131            message_sizes: message_sizes.iter(),
132            field_number: 0,
133            in_sequence: false,
134        }
135    }
136}
137
138/// Type used to write field values.
139pub struct FieldWriter<'a, 'buf, R> {
140    state: &'a mut EncodeState<'buf, R>,
141}
142
143impl<'a, 'buf, R> FieldWriter<'a, 'buf, R> {
144    /// Writes the field key.
145    fn key(&mut self, ty: WireType) {
146        write_varint(
147            &mut self.state.data,
148            ((self.state.field_number << 3) | ty as u32).into(),
149        );
150    }
151
152    fn cached_variable<F>(mut self, f: F)
153    where
154        F: FnOnce(&mut Self),
155    {
156        if let Some(expected_len) = self.write_next_cached_message_header() {
157            f(&mut self);
158            assert_eq!(expected_len, self.state.data.len(), "wrong size");
159        }
160    }
161
162    /// Returns the expected size of the message, or None if the message is
163    /// empty and `skip_empty` is true, and so the message does not need to be
164    /// encoded.
165    fn write_next_cached_message_header(&mut self) -> Option<usize> {
166        let size = self
167            .state
168            .message_sizes
169            .next()
170            .expect("not enough messages in size calculation");
171        if size.num_resources > 0 {
172            self.key(WireType::MeshMessage);
173            write_varint(&mut self.state.data, size.num_resources.into());
174        } else if size.len > 0 || self.state.in_sequence {
175            self.key(WireType::Variable);
176        } else {
177            return None;
178        }
179        write_varint(&mut self.state.data, size.len as u64);
180        Some(self.state.data.len() + size.len)
181    }
182
183    /// Returns a sequence writer for writing the field multiple times.
184    ///
185    /// Panics if called while already writing a sequence, since this would
186    /// result in an invalid protobuf message.
187    pub fn sequence(self) -> SequenceWriter<'a, 'buf, R> {
188        assert!(!self.state.in_sequence);
189        SequenceWriter {
190            field_number: self.state.field_number,
191            state: self.state,
192        }
193    }
194
195    /// Returns whether this write is occurring within a sequence.
196    pub fn write_empty(&self) -> bool {
197        self.state.in_sequence
198    }
199
200    /// Calls `f` with a writer for a message.
201    pub fn message<F>(self, f: F)
202    where
203        F: FnOnce(MessageWriter<'_, 'buf, R>),
204    {
205        self.cached_variable(|this| {
206            f(MessageWriter { state: this.state });
207        });
208    }
209
210    /// Writes a resource.
211    pub fn resource(mut self, resource: R) {
212        self.key(WireType::Resource);
213        self.state.resources.push(resource);
214    }
215
216    /// Writes an unsigned variable-sized integer.
217    pub fn varint(mut self, n: u64) {
218        if n != 0 || self.state.in_sequence {
219            self.key(WireType::Varint);
220            write_varint(&mut self.state.data, n);
221        }
222    }
223
224    /// Writes a signed variable-sized integer.
225    pub fn svarint(mut self, n: i64) {
226        if n != 0 || self.state.in_sequence {
227            self.key(WireType::Varint);
228            write_varint(&mut self.state.data, zigzag(n));
229        }
230    }
231
232    /// Writes a fixed 64-bit integer.
233    pub fn fixed64(mut self, n: u64) {
234        if n != 0 || self.state.in_sequence {
235            self.key(WireType::Fixed64);
236            self.state.data.append(&n.to_le_bytes());
237        }
238    }
239
240    /// Writes a fixed 32-bit integer.
241    pub fn fixed32(mut self, n: u32) {
242        if n != 0 || self.state.in_sequence {
243            self.key(WireType::Fixed32);
244            self.state.data.append(&n.to_le_bytes());
245        }
246    }
247
248    /// Writes a byte slice.
249    pub fn bytes(mut self, b: &[u8]) {
250        if !b.is_empty() || self.state.in_sequence {
251            self.key(WireType::Variable);
252            write_varint(&mut self.state.data, b.len() as u64);
253            self.state.data.append(b);
254        }
255    }
256
257    /// Calls `f` with a writer for the packed field.
258    pub fn packed<F>(self, f: F)
259    where
260        F: FnOnce(PackedWriter<'_, '_>),
261    {
262        self.cached_variable(|this| {
263            f(PackedWriter {
264                data: &mut this.state.data,
265            })
266        })
267    }
268}
269
270/// A writer for writing a sequence of fields.
271pub struct SequenceWriter<'a, 'buf, R> {
272    state: &'a mut EncodeState<'buf, R>,
273    field_number: u32,
274}
275
276impl<'buf, R> SequenceWriter<'_, 'buf, R> {
277    /// Gets a field writer to write the next field in the sequence.
278    pub fn field(&mut self) -> FieldWriter<'_, 'buf, R> {
279        self.state.field_number = self.field_number;
280        self.state.in_sequence = true;
281        FieldWriter { state: self.state }
282    }
283}
284
285/// A writer for a message.
286pub struct MessageWriter<'a, 'buf, R> {
287    state: &'a mut EncodeState<'buf, R>,
288}
289
290impl<'buf, R> MessageWriter<'_, 'buf, R> {
291    /// Returns a field writer for field number `n`.
292    ///
293    /// It's legal to write fields in any order and to write fields that
294    /// duplicate previous fields. By convention, later fields overwrite
295    /// previous ones (or append, in the case of sequences).
296    pub fn field(&mut self, n: u32) -> FieldWriter<'_, 'buf, R> {
297        self.state.field_number = n;
298        self.state.in_sequence = false;
299        FieldWriter { state: self.state }
300    }
301
302    /// Writes a raw message from bytes.
303    pub fn bytes(&mut self, data: &[u8]) {
304        self.state.data.append(data);
305    }
306
307    /// Writes a raw message.
308    pub fn raw_message(&mut self, data: &[u8], resources: impl IntoIterator<Item = R>) {
309        self.state.data.append(data);
310        self.state.resources.extend(resources);
311    }
312}
313
314#[derive(Copy, Clone, Default)]
315struct MessageSize {
316    len: usize,
317    num_resources: u32,
318}
319
320struct SizeState {
321    message_sizes: Vec<MessageSize>,
322    index: usize,
323    tag_size: u8,
324    in_sequence: bool,
325}
326
327impl SizeState {
328    fn new() -> Self {
329        Self {
330            message_sizes: vec![MessageSize::default()],
331            index: 0,
332            tag_size: 0,
333            in_sequence: false,
334        }
335    }
336}
337
338/// Type used to compute the size of field values.
339pub struct FieldSizer<'a> {
340    state: &'a mut SizeState,
341}
342
343struct PreviousSizeParams {
344    index: u32,
345    tag_size: u8,
346    in_sequence: bool,
347}
348
349impl<'a> FieldSizer<'a> {
350    fn add(&mut self, size: usize) {
351        // Add room for the field tag.
352        self.state.message_sizes[self.state.index].len += self.state.tag_size as usize + size;
353    }
354
355    /// Makes and returns a writer for a message.
356    fn cached_variable<F>(&mut self, f: F)
357    where
358        F: FnOnce(&mut Self),
359    {
360        // Cache the size for use when writing the message.
361        let prev = self.reserve_cached_message_size_entry();
362        f(self);
363        self.set_cached_message_size(prev);
364    }
365
366    fn reserve_cached_message_size_entry(&mut self) -> PreviousSizeParams {
367        let index = self.state.message_sizes.len();
368        self.state.message_sizes.push(MessageSize::default());
369        PreviousSizeParams {
370            index: core::mem::replace(&mut self.state.index, index) as u32,
371            tag_size: self.state.tag_size,
372            in_sequence: self.state.in_sequence,
373        }
374    }
375
376    fn set_cached_message_size(&mut self, prev: PreviousSizeParams) {
377        let size = self.state.message_sizes[self.state.index];
378        let index = core::mem::replace(&mut self.state.index, prev.index as usize);
379        let parent_size = &mut self.state.message_sizes[self.state.index];
380        let mut len = varint_size(size.len as u64) + size.len;
381        if size.num_resources > 0 {
382            // This will be a MeshMessage field.
383            len += varint_size(size.num_resources as u64);
384            parent_size.num_resources += size.num_resources;
385        } else if !prev.in_sequence && size.len == 0 {
386            // This message is empty, so skip it and any nested messages.
387            self.state.message_sizes[index] = Default::default();
388            self.state.message_sizes.truncate(index + 1);
389            return;
390        }
391        parent_size.len += prev.tag_size as usize + len;
392    }
393
394    /// Returns a sequence sizer for sizing the field multiple times.
395    ///
396    /// Panics if called while already sizing a sequence, since this would
397    /// result in an invalid protobuf message.
398    pub fn sequence(self) -> SequenceSizer<'a> {
399        SequenceSizer {
400            tag_size: self.state.tag_size,
401            state: self.state,
402        }
403    }
404
405    /// If true, encoders must write their fields even if they are empty.
406    pub fn write_empty(&self) -> bool {
407        self.state.in_sequence
408    }
409
410    /// Computes the size for a message. Calls `f` with a [`MessageSizer`] to
411    /// calculate the size of each field.
412    pub fn message<F>(mut self, f: F)
413    where
414        F: FnOnce(MessageSizer<'_>),
415    {
416        self.cached_variable(|this| {
417            f(MessageSizer::new(this.state));
418        })
419    }
420
421    /// Computes the size for a resource.
422    pub fn resource(mut self) {
423        self.state.message_sizes[self.state.index].num_resources += 1;
424        self.add(0);
425    }
426
427    /// Computes the size for an unsigned variable-sized integer.
428    pub fn varint(mut self, n: u64) {
429        if n != 0 || self.state.in_sequence {
430            self.add(varint_size(n));
431        }
432    }
433
434    /// Computes the size for a signed variable-sized integer.
435    pub fn svarint(mut self, n: i64) {
436        if n != 0 || self.state.in_sequence {
437            self.add(varint_size(zigzag(n)));
438        }
439    }
440
441    /// Computes the size for a fixed 64-bit integer.
442    pub fn fixed64(mut self, n: u64) {
443        if n != 0 || self.state.in_sequence {
444            self.add(8);
445        }
446    }
447
448    /// Computes the size for a fixed 32-bit integer.
449    pub fn fixed32(mut self, n: u32) {
450        if n != 0 || self.state.in_sequence {
451            self.add(4);
452        }
453    }
454
455    /// Computes the size for a byte slice.
456    pub fn bytes(mut self, len: usize) {
457        if len != 0 || self.state.in_sequence {
458            self.add(varint_size(len as u64) + len);
459        }
460    }
461
462    /// Computes the size of a packed value. Calls `f` with a [`PackedSizer`] to
463    /// sum the size of each element.
464    pub fn packed<F>(mut self, f: F)
465    where
466        F: FnOnce(PackedSizer<'_>),
467    {
468        self.cached_variable(|this| {
469            f(PackedSizer {
470                size: &mut this.state.message_sizes[this.state.index].len,
471            });
472        })
473    }
474}
475
476/// A sizer for computing the size of a sequence of fields.
477pub struct SequenceSizer<'a> {
478    state: &'a mut SizeState,
479    tag_size: u8,
480}
481
482impl SequenceSizer<'_> {
483    /// Gets a field sizer for the next field in the sequence.
484    pub fn field(&mut self) -> FieldSizer<'_> {
485        self.state.tag_size = self.tag_size;
486        self.state.in_sequence = true;
487        FieldSizer { state: self.state }
488    }
489}
490
491/// A type to compute the size of a message.
492pub struct MessageSizer<'a> {
493    state: &'a mut SizeState,
494}
495
496impl<'a> MessageSizer<'a> {
497    fn new(state: &'a mut SizeState) -> Self {
498        Self { state }
499    }
500
501    /// Returns a field sizer for field number `n`.
502    pub fn field(&mut self, n: u32) -> FieldSizer<'_> {
503        self.state.tag_size = varint_size((n as u64) << 3) as u8;
504        self.state.in_sequence = false;
505        FieldSizer { state: self.state }
506    }
507
508    /// Sizes the message as `n` bytes.
509    pub fn bytes(&mut self, n: usize) {
510        self.state.message_sizes[self.state.index] = MessageSize {
511            len: n,
512            ..Default::default()
513        };
514    }
515
516    /// Sizes the message as `n` bytes plus `num_resources` resources.
517    pub fn raw_message(&mut self, len: usize, num_resources: u32) {
518        self.state.message_sizes[self.state.index] = MessageSize { len, num_resources }
519    }
520}
521
522/// A parsed protobuf value.
523#[derive(Debug, Clone)]
524enum Value<'a> {
525    Varint(u64),
526    Fixed64(u64),
527    Variable(&'a [u8]),
528    Fixed32(u32),
529    Resource(u32),
530    MeshMessage {
531        data: &'a [u8],
532        resources: Range<u32>,
533    },
534}
535
536/// A reader for a payload field.
537pub struct FieldReader<'a, 'b, R> {
538    field: Value<'a>,
539    state: &'b DecodeState<'b, R>,
540}
541
542impl<'a, 'b, R> FieldReader<'a, 'b, R> {
543    /// Gets the wire type for the field.
544    pub fn wire_type(&self) -> WireType {
545        match &self.field {
546            Value::Varint(_) => WireType::Varint,
547            Value::Fixed64(_) => WireType::Fixed64,
548            Value::Variable(_) => WireType::Variable,
549            Value::Fixed32(_) => WireType::Fixed32,
550            Value::MeshMessage { .. } => WireType::MeshMessage,
551            Value::Resource { .. } => WireType::Resource,
552        }
553    }
554
555    /// Makes and returns an message reader.
556    pub fn message(self) -> Result<MessageReader<'a, 'b, R>> {
557        if let Value::Variable(data) = self.field {
558            Ok(MessageReader {
559                data,
560                state: self.state,
561                resources: 0..0,
562            })
563        } else if let Value::MeshMessage { data, resources } = self.field {
564            Ok(MessageReader {
565                data,
566                state: self.state,
567                resources,
568            })
569        } else {
570            Err(DecodeError::ExpectedMessage.into())
571        }
572    }
573
574    /// Reads a resource.
575    pub fn resource(self) -> Result<R> {
576        if let Value::Resource(index) = self.field {
577            self.state.resource(index)
578        } else {
579            Err(DecodeError::ExpectedResource.into())
580        }
581    }
582
583    /// Reads an unsigned variable-sized integer.
584    pub fn varint(self) -> Result<u64> {
585        if let Value::Varint(n) = self.field {
586            Ok(n)
587        } else {
588            Err(DecodeError::ExpectedVarInt.into())
589        }
590    }
591
592    /// Reads a signed variable-sized integer.
593    pub fn svarint(self) -> Result<i64> {
594        Ok(unzigzag(self.varint()?))
595    }
596
597    /// Reads a fixed 64-bit integer.
598    pub fn fixed64(self) -> Result<u64> {
599        if let Value::Fixed64(n) = self.field {
600            Ok(n)
601        } else {
602            Err(DecodeError::ExpectedFixed64.into())
603        }
604    }
605
606    /// Reads a fixed 32-bit integer.
607    pub fn fixed32(self) -> Result<u32> {
608        if let Value::Fixed32(n) = self.field {
609            Ok(n)
610        } else {
611            Err(DecodeError::ExpectedFixed32.into())
612        }
613    }
614
615    /// Reads a byte slice.
616    pub fn bytes(self) -> Result<&'a [u8]> {
617        if let Value::Variable(data) = self.field {
618            Ok(data)
619        } else {
620            Err(DecodeError::ExpectedByteArray.into())
621        }
622    }
623
624    /// Gets a reader for a packed field.
625    pub fn packed(self) -> Result<PackedReader<'a>> {
626        Ok(PackedReader {
627            data: self.bytes()?,
628        })
629    }
630}
631
632/// Reader for an message.
633///
634/// Implements [`Iterator`] to return (field number, [`FieldReader`]) pairs.
635/// Users must be prepared to handle fields in any order, allowing unknown and
636/// duplicate fields.
637pub struct MessageReader<'a, 'b, R> {
638    data: &'a [u8],
639    resources: Range<u32>,
640    state: &'b DecodeState<'b, R>,
641}
642
643impl<'a, 'b, R> IntoIterator for MessageReader<'a, 'b, R> {
644    type Item = Result<(u32, FieldReader<'a, 'b, R>)>;
645    type IntoIter = FieldIterator<'a, 'b, R>;
646
647    fn into_iter(self) -> Self::IntoIter {
648        FieldIterator(self)
649    }
650}
651
652impl<'a, 'b, R> MessageReader<'a, 'b, R> {
653    fn new(data: &'a [u8], state: &'b DecodeState<'b, R>) -> Self {
654        let num_resources = state.0.borrow().resources.len() as u32;
655        Self {
656            data,
657            state,
658            resources: 0..num_resources,
659        }
660    }
661
662    /// Gets the message data as a byte slice.
663    pub fn bytes(&self) -> &'a [u8] {
664        self.data
665    }
666
667    /// Returns an iterator to consume the resources for this message.
668    pub fn take_resources(&mut self) -> impl ExactSizeIterator<Item = Result<R>> + use<'b, R> {
669        let state = self.state;
670        self.resources.clone().map(move |i| {
671            state
672                .0
673                .borrow_mut()
674                .resources
675                .get_mut(i as usize)
676                .and_then(|x| x.take())
677                .ok_or_else(|| DecodeError::MissingResource.into())
678        })
679    }
680
681    fn parse_field(&mut self) -> Result<(u32, FieldReader<'a, 'b, R>)> {
682        let key = read_varint(&mut self.data)?;
683        let wire_type = (key & 7) as u32;
684        let field_number = (key >> 3) as u32;
685        let field = match wire_type {
686            0 => Value::Varint(read_varint(&mut self.data)?),
687            1 => {
688                if self.data.len() < 8 {
689                    return Err(DecodeError::EofFixed64.into());
690                }
691                let (n, rest) = self.data.split_at(8);
692                self.data = rest;
693                Value::Fixed64(u64::from_le_bytes(n.try_into().unwrap()))
694            }
695            2 => {
696                let len = read_varint(&mut self.data)?;
697                if (self.data.len() as u64) < len {
698                    return Err(DecodeError::EofByteArray.into());
699                }
700                let (data, rest) = self.data.split_at(len as usize);
701                self.data = rest;
702                Value::Variable(data)
703            }
704            5 => {
705                if self.data.len() < 4 {
706                    return Err(DecodeError::EofFixed32.into());
707                }
708                let (n, rest) = self.data.split_at(4);
709                self.data = rest;
710                Value::Fixed32(u32::from_le_bytes(n.try_into().unwrap()))
711            }
712            6 => {
713                let num_resources = read_varint(&mut self.data)? as u32;
714                let len = read_varint(&mut self.data)?;
715
716                if self.resources.len() < num_resources as usize {
717                    return Err(DecodeError::InvalidResourceRange.into());
718                }
719                if (self.data.len() as u64) < len {
720                    return Err(DecodeError::EofByteArray.into());
721                }
722
723                let (data, rest) = self.data.split_at(len as usize);
724                self.data = rest;
725
726                let resources = self.resources.start..self.resources.start + num_resources;
727                self.resources = resources.end..self.resources.end;
728
729                Value::MeshMessage { data, resources }
730            }
731            7 => {
732                let resource = self.resources.next().ok_or(DecodeError::MissingResource)?;
733                Value::Resource(resource)
734            }
735            n => return Err(DecodeError::UnknownWireType(n).into()),
736        };
737        Ok((
738            field_number,
739            FieldReader {
740                field,
741                state: self.state,
742            },
743        ))
744    }
745}
746
747/// An iterator over message fields.
748///
749/// Returned by [`MessageReader::into_iter()`].
750pub struct FieldIterator<'a, 'b, R>(MessageReader<'a, 'b, R>);
751
752impl<'a, 'b, R> Iterator for FieldIterator<'a, 'b, R> {
753    type Item = Result<(u32, FieldReader<'a, 'b, R>)>;
754
755    fn next(&mut self) -> Option<Self::Item> {
756        if self.0.data.is_empty() {
757            return None;
758        }
759        Some(self.0.parse_field())
760    }
761}
762
763/// A writer for a packed field.
764pub struct PackedWriter<'a, 'buf> {
765    data: &'a mut Buf<'buf>,
766}
767
768impl PackedWriter<'_, '_> {
769    /// Appends `bytes`.
770    pub fn bytes(&mut self, bytes: &[u8]) {
771        self.data.append(bytes);
772    }
773
774    /// Appends varint `v`.
775    pub fn varint(&mut self, v: u64) {
776        write_varint(self.data, v);
777    }
778
779    /// Appends signed (zigzag-encoded) varint `v`.
780    pub fn svarint(&mut self, v: i64) {
781        write_varint(self.data, zigzag(v));
782    }
783
784    /// Appends fixed 64-bit value `v`.
785    pub fn fixed64(&mut self, v: u64) {
786        self.bytes(&v.to_le_bytes());
787    }
788
789    /// Appends fixed 32-bit value `v`.
790    pub fn fixed32(&mut self, v: u32) {
791        self.bytes(&v.to_le_bytes());
792    }
793}
794
795/// A type to help compute the size of a packed field.
796pub struct PackedSizer<'a> {
797    size: &'a mut usize,
798}
799
800impl PackedSizer<'_> {
801    /// Adds the size of `len` bytes.
802    pub fn bytes(&mut self, len: usize) {
803        *self.size += len;
804    }
805
806    /// Adds the size of a varint value `v`.
807    pub fn varint(&mut self, v: u64) {
808        *self.size += varint_size(v);
809    }
810
811    /// Adds the size of a signed (zigzag-encoded) varint value `v`.
812    pub fn svarint(&mut self, v: i64) {
813        *self.size += varint_size(zigzag(v));
814    }
815
816    /// Adds the size of a fixed 64-bit value.
817    pub fn fixed64(&mut self) {
818        *self.size += 8;
819    }
820
821    /// Adds the size of a fixed 32-bit value.
822    pub fn fixed32(&mut self) {
823        *self.size += 4;
824    }
825}
826
827/// Reader for packed fields.
828pub struct PackedReader<'a> {
829    data: &'a [u8],
830}
831
832impl<'a> PackedReader<'a> {
833    /// Reads the remaining bytes.
834    pub fn bytes(&mut self) -> &'a [u8] {
835        core::mem::take(&mut self.data)
836    }
837
838    /// Reads a varint.
839    ///
840    /// Returns `Ok(None)` if there are no more values.
841    pub fn varint(&mut self) -> Result<Option<u64>> {
842        if self.data.is_empty() {
843            Ok(None)
844        } else {
845            read_varint(&mut self.data).map(Some)
846        }
847    }
848
849    /// Reads a signed (zigzag-encoded) varint.
850    ///
851    /// Returns `Ok(None)` if there are no more values.
852    pub fn svarint(&mut self) -> Result<Option<i64>> {
853        if self.data.is_empty() {
854            Ok(None)
855        } else {
856            read_varint(&mut self.data).map(|n| Some(unzigzag(n)))
857        }
858    }
859
860    /// Reads a fixed 64-bit value.
861    ///
862    /// Returns `Ok(None)` if there are no more values.
863    pub fn fixed64(&mut self) -> Result<Option<u64>> {
864        if self.data.is_empty() {
865            Ok(None)
866        } else if self.data.len() < 8 {
867            Err(DecodeError::EofFixed64.into())
868        } else {
869            let (b, data) = self.data.split_at(8);
870            self.data = data;
871            Ok(Some(u64::from_le_bytes(b.try_into().unwrap())))
872        }
873    }
874
875    /// Reads a fixed 32-bit value.
876    ///
877    /// Returns `Ok(None)` if there are no more values.
878    pub fn fixed32(&mut self) -> Result<Option<u32>> {
879        if self.data.is_empty() {
880            Ok(None)
881        } else if self.data.len() < 4 {
882            Err(DecodeError::EofFixed32.into())
883        } else {
884            let (b, data) = self.data.split_at(4);
885            self.data = data;
886            Ok(Some(u32::from_le_bytes(b.try_into().unwrap())))
887        }
888    }
889}
890
891/// An encoder for a single message of type `T`, using the messaging encoding
892/// `E`.
893pub struct Encoder<T, E, R> {
894    message: T,
895    message_sizes: Vec<MessageSize>,
896    _phantom: PhantomData<(fn() -> R, E)>,
897}
898
899impl<R, T: DefaultEncoding> Encoder<T, T::Encoding, R>
900where
901    T::Encoding: MessageEncode<T, R>,
902{
903    /// Creates an encoder for `message`.F
904    pub fn new(message: T) -> Self {
905        Encoder::with_encoding(message)
906    }
907}
908
909impl<T, R, E: MessageEncode<T, R>> Encoder<T, E, R> {
910    /// Creates an encoder for `message` with a specific encoder.
911    pub fn with_encoding(mut message: T) -> Self {
912        let mut state = SizeState::new();
913        E::compute_message_size(&mut message, MessageSizer::new(&mut state));
914        Self {
915            message,
916            message_sizes: state.message_sizes,
917            _phantom: PhantomData,
918        }
919    }
920
921    /// Returns the length of the message in bytes.
922    pub fn len(&self) -> usize {
923        self.message_sizes[0].len
924    }
925
926    /// Returns the number of resources in the message.
927    pub fn resource_count(&self) -> usize {
928        self.message_sizes[0].num_resources as usize
929    }
930
931    /// Encodes the message into `buffer`.
932    pub fn encode_into(self, buffer: &mut dyn Buffer, resources: &mut Vec<R>) {
933        buffer::write_with(buffer, |buf| {
934            let capacity = buf.remaining();
935            let init_resources = resources.len();
936            let mut state = EncodeState::new(buf, &self.message_sizes, resources);
937            let size = state.message_sizes.next().unwrap();
938            E::write_message(self.message, MessageWriter { state: &mut state });
939            assert_eq!(capacity - state.data.remaining(), size.len);
940            assert_eq!(
941                state.resources.len() - init_resources,
942                size.num_resources as usize
943            );
944            assert!(state.message_sizes.next().is_none());
945        })
946    }
947
948    /// Encodes the message.
949    pub fn encode(self) -> (Vec<u8>, Vec<R>) {
950        let mut data = Vec::with_capacity(self.len());
951        let mut resources = Vec::with_capacity(self.resource_count());
952        self.encode_into(&mut data, &mut resources);
953        (data, resources)
954    }
955}
956
957/// Decodes a protobuf message into `message` using encoding `T`.
958///
959/// If `message` already exists, then the fields are merged according to
960/// protobuf rules.
961pub fn decode_with<'a, E: MessageDecode<'a, T, R>, T, R>(
962    message: &mut InplaceOption<'_, T>,
963    data: &'a [u8],
964    resources: &mut [Option<R>],
965) -> Result<()> {
966    let state = DecodeState::new(resources);
967    let reader = MessageReader::new(data, &state);
968    E::read_message(message, reader)?;
969    Ok(())
970}
971
972#[cfg(test)]
973mod tests {
974    extern crate std;
975
976    use super::*;
977    use crate::buffer;
978    use std::eprintln;
979
980    #[test]
981    fn test_zigzag() {
982        let cases: &[(i64, u64)] = &[
983            (0, 0),
984            (-1, 1),
985            (1, 2),
986            (-2, 3),
987            (2147483647, 4294967294),
988            (-2147483648, 4294967295),
989            (i64::MAX, u64::MAX - 1),
990            (i64::MIN, u64::MAX),
991        ];
992        for (a, b) in cases.iter().copied() {
993            assert_eq!(zigzag(a), b);
994            assert_eq!(a, unzigzag(b));
995        }
996    }
997
998    #[test]
999    fn test_varint() {
1000        let cases: &[(u64, &[u8])] = &[
1001            (0, &[0]),
1002            (1, &[1]),
1003            (0x80, &[0x80, 1]),
1004            (
1005                -1i64 as u64,
1006                &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1],
1007            ),
1008        ];
1009        for (a, mut b) in cases.iter().copied() {
1010            eprintln!("{:#x}, {:#x?}", a, b);
1011            assert_eq!(varint_size(a), b.len());
1012            let mut v = Vec::with_capacity(10);
1013            buffer::write_with(&mut v, |mut buf| write_varint(&mut buf, a));
1014            assert_eq!(&v, b);
1015            assert_eq!(a, read_varint(&mut b).unwrap());
1016            assert!(b.is_empty());
1017        }
1018    }
1019
1020    #[test]
1021    fn test_resource() {
1022        let mut state = SizeState::new();
1023        let mut sizer = MessageSizer::new(&mut state);
1024        sizer.field(1).resource();
1025        sizer.field(2).resource();
1026        sizer.field(3).message(|mut sizer| {
1027            sizer.field(1).resource();
1028            sizer.field(1).resource();
1029            sizer.field(1).resource();
1030        });
1031        let size = state.message_sizes.remove(0);
1032        assert_eq!(size.num_resources, 5);
1033
1034        let mut data = Vec::with_capacity(size.len);
1035        let mut resources = Vec::with_capacity(size.num_resources as usize);
1036        buffer::write_with(&mut data, |buf| {
1037            let mut state = EncodeState::new(buf, &state.message_sizes, &mut resources);
1038            let mut writer = MessageWriter { state: &mut state };
1039            writer.field(1).resource(());
1040            writer.field(2).resource(());
1041            writer.field(3).message(|mut writer| {
1042                writer.field(1).resource(());
1043                writer.field(1).resource(());
1044                writer.field(1).resource(());
1045            });
1046        });
1047
1048        let mut resources: Vec<_> = resources.into_iter().map(Some).collect();
1049        let state = DecodeState(RefCell::new(DecodeInner {
1050            resources: &mut resources,
1051        }));
1052        let reader = MessageReader {
1053            data: &data,
1054            state: &state,
1055            resources: 0..5,
1056        };
1057
1058        let mut it = reader.into_iter();
1059        let (n, r) = it.next().unwrap().unwrap();
1060        assert_eq!(n, 1);
1061        r.resource().unwrap();
1062        let (n, r) = it.next().unwrap().unwrap();
1063        assert_eq!(n, 2);
1064        r.resource().unwrap();
1065        let (n, r) = it.next().unwrap().unwrap();
1066        assert_eq!(n, 3);
1067        let message = r.message().unwrap();
1068        assert!(it.next().is_none());
1069
1070        let mut it = message.into_iter();
1071        let (n, r) = it.next().unwrap().unwrap();
1072        assert_eq!(n, 1);
1073        r.resource().unwrap();
1074        let (n, r) = it.next().unwrap().unwrap();
1075        assert_eq!(n, 1);
1076        r.resource().unwrap();
1077        let (n, r) = it.next().unwrap().unwrap();
1078        assert_eq!(n, 1);
1079        r.resource().unwrap();
1080        assert!(it.next().is_none());
1081    }
1082}