protobuf/
wire_format.rs
1use crate::descriptor::field_descriptor_proto;
4use crate::error::WireError;
5
6pub(crate) const TAG_TYPE_BITS: u32 = 3;
8pub(crate) const TAG_TYPE_MASK: u32 = (1u32 << TAG_TYPE_BITS as usize) - 1;
10pub(crate) const FIELD_NUMBER_MAX: u32 = 0x1fffffff;
12
13pub(crate) const MAX_MESSAGE_SIZE: u64 = i32::MAX as u64;
14
15#[inline]
16pub(crate) fn check_message_size(size: u64) -> crate::Result<u32> {
17 if size <= MAX_MESSAGE_SIZE {
18 Ok(size as u32)
19 } else {
20 #[cold]
21 fn message_too_large(size: u64) -> crate::Error {
22 WireError::MessageTooLarge(size).into()
23 }
24
25 Err(message_too_large(size))
26 }
27}
28
29#[derive(PartialEq, Eq, Clone, Copy, Debug)]
31pub enum WireType {
32 Varint = 0,
34 Fixed64 = 1,
36 LengthDelimited = 2,
38 StartGroup = 3,
40 EndGroup = 4,
42 Fixed32 = 5,
44}
45
46impl WireType {
47 pub fn new(n: u32) -> Option<WireType> {
49 match n {
50 0 => Some(WireType::Varint),
51 1 => Some(WireType::Fixed64),
52 2 => Some(WireType::LengthDelimited),
53 3 => Some(WireType::StartGroup),
54 4 => Some(WireType::EndGroup),
55 5 => Some(WireType::Fixed32),
56 _ => None,
57 }
58 }
59
60 #[doc(hidden)]
61 pub fn for_type(field_type: field_descriptor_proto::Type) -> WireType {
62 use field_descriptor_proto::Type;
63 match field_type {
64 Type::TYPE_INT32 => WireType::Varint,
65 Type::TYPE_INT64 => WireType::Varint,
66 Type::TYPE_UINT32 => WireType::Varint,
67 Type::TYPE_UINT64 => WireType::Varint,
68 Type::TYPE_SINT32 => WireType::Varint,
69 Type::TYPE_SINT64 => WireType::Varint,
70 Type::TYPE_BOOL => WireType::Varint,
71 Type::TYPE_ENUM => WireType::Varint,
72 Type::TYPE_FIXED32 => WireType::Fixed32,
73 Type::TYPE_FIXED64 => WireType::Fixed64,
74 Type::TYPE_SFIXED32 => WireType::Fixed32,
75 Type::TYPE_SFIXED64 => WireType::Fixed64,
76 Type::TYPE_FLOAT => WireType::Fixed32,
77 Type::TYPE_DOUBLE => WireType::Fixed64,
78 Type::TYPE_STRING => WireType::LengthDelimited,
79 Type::TYPE_BYTES => WireType::LengthDelimited,
80 Type::TYPE_MESSAGE => WireType::LengthDelimited,
81 Type::TYPE_GROUP => WireType::LengthDelimited, }
83 }
84}
85
86#[derive(Clone, Copy, PartialEq, Eq, Debug)]
88pub(crate) struct Tag {
89 field_number: u32,
90 wire_type: WireType,
91}
92
93impl Tag {
94 pub(crate) fn value(self) -> u32 {
96 (self.field_number << TAG_TYPE_BITS) | (self.wire_type as u32)
97 }
98
99 pub(crate) fn new(value: u32) -> crate::Result<Tag> {
101 let wire_type = WireType::new(value & TAG_TYPE_MASK);
102 if wire_type.is_none() {
103 return Err(WireError::IncorrectTag(value).into());
104 }
105 let field_number = value >> TAG_TYPE_BITS;
106 if field_number == 0 {
107 return Err(WireError::IncorrectTag(value).into());
108 }
109 Ok(Tag {
110 field_number,
111 wire_type: wire_type.unwrap(),
112 })
113 }
114
115 pub(crate) fn make(field_number: u32, wire_type: WireType) -> Tag {
121 assert!(field_number > 0 && field_number <= FIELD_NUMBER_MAX);
122 Tag {
123 field_number,
124 wire_type,
125 }
126 }
127
128 pub(crate) fn unpack(self) -> (u32, WireType) {
130 (self.field_number(), self.wire_type())
131 }
132
133 fn wire_type(self) -> WireType {
135 self.wire_type
136 }
137
138 pub(crate) fn field_number(self) -> u32 {
140 self.field_number
141 }
142}