1 /*
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 use crate::binary_type::{CopyFromBuf, Discard};
18 use crate::bufext::BufMutExt;
19 use crate::errors::ProtocolError;
20 use crate::framing::{Framing, FramingDecoded, FramingEncoded, FramingEncodedFinal};
21 use crate::thrift_protocol::{MessageType, ProtocolID};
22 use crate::ttype::TType;
23 use crate::Result;
24
25 /// The maximum recursive depth the skip() function will traverse
26 pub const DEFAULT_RECURSION_DEPTH: i32 = 64;
27
28 /// Helper type alias to get the pre-finalization encoded type of a protocol frame.
29 pub type ProtocolEncoded<P> = FramingEncoded<<P as Protocol>::Frame>;
30
31 /// Helper type alias to get the final encoded type of a protocol frame
32 pub type ProtocolEncodedFinal<P> = FramingEncodedFinal<<P as Protocol>::Frame>;
33
34 /// Helper type alias to get the buffer type for a frame to be decoded.
35 pub type ProtocolDecoded<P> = FramingDecoded<<P as Protocol>::Frame>;
36
37 /// An instance of Protocol glues a Framing implementation to a serializer
38 /// (ProtocolWriter) and deserializer (ProtocolReader). It constructs, as
39 /// needed, a serializer to construct a frame with a given protocol, or a
40 /// deserializer from a frame into a stream of deserialized objects.
41 pub trait Protocol: 'static {
42 /// Type of the framing implementation
43 type Frame: Framing;
44
45 /// Compute the size of a frame for a given protocol. This can be exact or too large, but
46 /// must not be too small.
47 type Sizer: ProtocolWriter<Final = usize>;
48
49 /// Serialize into a buffer. The buffer is allocated with the size computed by Sizer, so
50 /// it must be large enough.
51 type Serializer: ProtocolWriter<Final = <<Self::Frame as Framing>::EncBuf as BufMutExt>::Final>;
52
53 /// Set up a deserializer from a frame's buffer.
54 type Deserializer: ProtocolReader;
55
56 const PROTOCOL_ID: ProtocolID;
57
serializer<SZ, SER>(sz: SZ, ser: SER) -> <Self::Serializer as ProtocolWriter>::Final where SZ: FnOnce(&mut Self::Sizer), SER: FnOnce(&mut Self::Serializer)58 fn serializer<SZ, SER>(sz: SZ, ser: SER) -> <Self::Serializer as ProtocolWriter>::Final
59 where
60 SZ: FnOnce(&mut Self::Sizer),
61 SER: FnOnce(&mut Self::Serializer);
62
deserializer(buf: <Self::Frame as Framing>::DecBuf) -> Self::Deserializer63 fn deserializer(buf: <Self::Frame as Framing>::DecBuf) -> Self::Deserializer;
64
into_buffer(_: Self::Deserializer) -> <Self::Frame as Framing>::DecBuf65 fn into_buffer(_: Self::Deserializer) -> <Self::Frame as Framing>::DecBuf;
66 }
67
skip_inner<P: ProtocolReader + ?Sized>( p: &mut P, field_type: TType, max_depth: i32, ) -> Result<()>68 fn skip_inner<P: ProtocolReader + ?Sized>(
69 p: &mut P,
70 field_type: TType,
71 max_depth: i32,
72 ) -> Result<()> {
73 if max_depth <= 0 {
74 bail_err!(ProtocolError::SkipDepthExceeded)
75 }
76
77 match field_type {
78 TType::Void => {}
79 TType::Bool => {
80 p.read_bool()?;
81 }
82 TType::Byte => {
83 p.read_byte()?;
84 }
85 TType::I16 => {
86 p.read_i16()?;
87 }
88 TType::I32 => {
89 p.read_i32()?;
90 }
91 TType::I64 => {
92 p.read_i64()?;
93 }
94 TType::Double => {
95 p.read_double()?;
96 }
97 TType::Float => {
98 p.read_float()?;
99 }
100 TType::Struct => {
101 p.read_struct_begin(|_| ())?;
102 loop {
103 let fields = &[];
104 let (_, type_id, _) = p.read_field_begin(|_| (), fields)?;
105 if type_id == TType::Stop {
106 break;
107 }
108 skip_inner(p, type_id, max_depth - 1)?;
109 p.read_field_end()?;
110 }
111 p.read_struct_end()?;
112 }
113 TType::Map => {
114 let (key_type, value_type, len) = p.read_map_begin()?;
115 if len != Some(0) {
116 let mut idx = 0;
117 loop {
118 let more = p.read_map_key_begin()?;
119 if !more {
120 break;
121 }
122 skip_inner(p, key_type, max_depth - 1)?;
123 p.read_map_value_begin()?;
124 skip_inner(p, value_type, max_depth)?;
125 p.read_map_value_end()?;
126
127 idx += 1;
128 if should_break(len, more, idx) {
129 break;
130 }
131 }
132 }
133 p.read_map_end()?;
134 }
135 TType::Set => {
136 let (elem_type, len) = p.read_set_begin()?;
137 if len != Some(0) {
138 let mut idx = 0;
139 loop {
140 let more = p.read_set_value_begin()?;
141 if !more {
142 break;
143 }
144 skip_inner(p, elem_type, max_depth - 1)?;
145 p.read_set_value_end()?;
146
147 idx += 1;
148 if should_break(len, more, idx) {
149 break;
150 }
151 }
152 }
153 p.read_set_end()?;
154 }
155 TType::List => {
156 let (elem_type, len) = p.read_list_begin()?;
157 if len != Some(0) {
158 let mut idx = 0;
159 loop {
160 let more = p.read_list_value_begin()?;
161 if !more {
162 break;
163 }
164 skip_inner(p, elem_type, max_depth - 1)?;
165 p.read_list_value_end()?;
166
167 idx += 1;
168 if should_break(len, more, idx) {
169 break;
170 }
171 }
172 }
173 p.read_list_end()?;
174 }
175 TType::UTF8 => {
176 p.read_string()?;
177 }
178 TType::UTF16 => {
179 p.read_string()?;
180 }
181 TType::String => {
182 p.read_binary::<Discard>()?;
183 }
184 TType::Stream => bail_err!(ProtocolError::StreamUnsupported),
185 TType::Stop => bail_err!(ProtocolError::UnexpectedStopInSkip),
186 };
187 Ok(())
188 }
189
190 /// Trait for emitting a frame formatted in a given protocol
191 pub trait ProtocolWriter {
192 type Final;
193
write_message_begin(&mut self, name: &str, type_id: MessageType, seqid: u32)194 fn write_message_begin(&mut self, name: &str, type_id: MessageType, seqid: u32);
write_message_end(&mut self)195 fn write_message_end(&mut self);
write_struct_begin(&mut self, name: &str)196 fn write_struct_begin(&mut self, name: &str);
write_struct_end(&mut self)197 fn write_struct_end(&mut self);
write_field_begin(&mut self, name: &str, type_id: TType, id: i16)198 fn write_field_begin(&mut self, name: &str, type_id: TType, id: i16);
write_field_end(&mut self)199 fn write_field_end(&mut self);
write_field_stop(&mut self)200 fn write_field_stop(&mut self);
write_map_begin(&mut self, key_type: TType, value_type: TType, size: usize)201 fn write_map_begin(&mut self, key_type: TType, value_type: TType, size: usize);
write_map_key_begin(&mut self)202 fn write_map_key_begin(&mut self);
write_map_value_begin(&mut self)203 fn write_map_value_begin(&mut self);
write_map_end(&mut self)204 fn write_map_end(&mut self);
write_list_begin(&mut self, elem_type: TType, size: usize)205 fn write_list_begin(&mut self, elem_type: TType, size: usize);
write_list_value_begin(&mut self)206 fn write_list_value_begin(&mut self);
write_list_end(&mut self)207 fn write_list_end(&mut self);
write_set_begin(&mut self, elem_type: TType, size: usize)208 fn write_set_begin(&mut self, elem_type: TType, size: usize);
write_set_value_begin(&mut self)209 fn write_set_value_begin(&mut self);
write_set_end(&mut self)210 fn write_set_end(&mut self);
write_bool(&mut self, value: bool)211 fn write_bool(&mut self, value: bool);
write_byte(&mut self, value: i8)212 fn write_byte(&mut self, value: i8);
write_i16(&mut self, value: i16)213 fn write_i16(&mut self, value: i16);
write_i32(&mut self, value: i32)214 fn write_i32(&mut self, value: i32);
write_i64(&mut self, value: i64)215 fn write_i64(&mut self, value: i64);
write_double(&mut self, value: f64)216 fn write_double(&mut self, value: f64);
write_float(&mut self, value: f32)217 fn write_float(&mut self, value: f32);
write_string(&mut self, value: &str)218 fn write_string(&mut self, value: &str);
write_binary(&mut self, value: &[u8])219 fn write_binary(&mut self, value: &[u8]);
220
finish(self) -> Self::Final221 fn finish(self) -> Self::Final;
222 }
223
224 /// Trait for decoding a frame in a given protocol
225 pub trait ProtocolReader {
read_message_begin<F, T>(&mut self, method: F) -> Result<(T, MessageType, u32)> where F: FnOnce(&[u8]) -> T226 fn read_message_begin<F, T>(&mut self, method: F) -> Result<(T, MessageType, u32)>
227 where
228 F: FnOnce(&[u8]) -> T;
read_message_end(&mut self) -> Result<()>229 fn read_message_end(&mut self) -> Result<()>;
read_struct_begin<F, T>(&mut self, strukt: F) -> Result<T> where F: FnOnce(&[u8]) -> T230 fn read_struct_begin<F, T>(&mut self, strukt: F) -> Result<T>
231 where
232 F: FnOnce(&[u8]) -> T;
read_struct_end(&mut self) -> Result<()>233 fn read_struct_end(&mut self) -> Result<()>;
read_field_begin<F, T>(&mut self, field: F, fields: &[Field]) -> Result<(T, TType, i16)> where F: FnOnce(&[u8]) -> T234 fn read_field_begin<F, T>(&mut self, field: F, fields: &[Field]) -> Result<(T, TType, i16)>
235 where
236 F: FnOnce(&[u8]) -> T;
read_field_end(&mut self) -> Result<()>237 fn read_field_end(&mut self) -> Result<()>;
read_map_begin(&mut self) -> Result<(TType, TType, Option<usize>)>238 fn read_map_begin(&mut self) -> Result<(TType, TType, Option<usize>)>;
read_map_key_begin(&mut self) -> Result<bool>239 fn read_map_key_begin(&mut self) -> Result<bool>;
read_map_value_begin(&mut self) -> Result<()>240 fn read_map_value_begin(&mut self) -> Result<()>;
read_map_value_end(&mut self) -> Result<()>241 fn read_map_value_end(&mut self) -> Result<()>;
read_map_end(&mut self) -> Result<()>242 fn read_map_end(&mut self) -> Result<()>;
read_list_begin(&mut self) -> Result<(TType, Option<usize>)>243 fn read_list_begin(&mut self) -> Result<(TType, Option<usize>)>;
read_list_value_begin(&mut self) -> Result<bool>244 fn read_list_value_begin(&mut self) -> Result<bool>;
read_list_value_end(&mut self) -> Result<()>245 fn read_list_value_end(&mut self) -> Result<()>;
read_list_end(&mut self) -> Result<()>246 fn read_list_end(&mut self) -> Result<()>;
read_set_begin(&mut self) -> Result<(TType, Option<usize>)>247 fn read_set_begin(&mut self) -> Result<(TType, Option<usize>)>;
read_set_value_begin(&mut self) -> Result<bool>248 fn read_set_value_begin(&mut self) -> Result<bool>;
read_set_value_end(&mut self) -> Result<()>249 fn read_set_value_end(&mut self) -> Result<()>;
read_set_end(&mut self) -> Result<()>250 fn read_set_end(&mut self) -> Result<()>;
read_bool(&mut self) -> Result<bool>251 fn read_bool(&mut self) -> Result<bool>;
read_byte(&mut self) -> Result<i8>252 fn read_byte(&mut self) -> Result<i8>;
read_i16(&mut self) -> Result<i16>253 fn read_i16(&mut self) -> Result<i16>;
read_i32(&mut self) -> Result<i32>254 fn read_i32(&mut self) -> Result<i32>;
read_i64(&mut self) -> Result<i64>255 fn read_i64(&mut self) -> Result<i64>;
read_double(&mut self) -> Result<f64>256 fn read_double(&mut self) -> Result<f64>;
read_float(&mut self) -> Result<f32>257 fn read_float(&mut self) -> Result<f32>;
read_string(&mut self) -> Result<String>258 fn read_string(&mut self) -> Result<String>;
read_binary<V: CopyFromBuf>(&mut self) -> Result<V>259 fn read_binary<V: CopyFromBuf>(&mut self) -> Result<V>;
260
261 /// Skip over the next data element from the provided input Protocol object
skip(&mut self, field_type: TType) -> Result<()>262 fn skip(&mut self, field_type: TType) -> Result<()> {
263 skip_inner(self, field_type, DEFAULT_RECURSION_DEPTH)
264 }
265 }
266
should_break(len: Option<usize>, more: bool, idx: usize) -> bool267 pub fn should_break(len: Option<usize>, more: bool, idx: usize) -> bool {
268 match (len, more) {
269 (Some(real_length), _) => idx >= real_length,
270 (None, true) => false,
271 (None, false) => true,
272 }
273 }
274
275 /// Protocol::serializer wants the same serializer closure passed twice so
276 /// that it can specialize it for two types: once to compute the size, and a second time to
277 /// actually serialize the content. This macro helps by taking the factory type and
278 /// applying the serializer expression twice.
279 #[macro_export]
280 macro_rules! serialize {
281 ($protocol:ty, $serializer:expr) => {
282 <$protocol as $crate::Protocol>::serializer($serializer, $serializer)
283 };
284 }
285
286 pub struct Field {
287 pub name: &'static str,
288 pub ttype: TType,
289 pub id: i16,
290 }
291
292 impl Field {
new(name: &'static str, ttype: TType, id: i16) -> Self293 pub const fn new(name: &'static str, ttype: TType, id: i16) -> Self {
294 Field { name, ttype, id }
295 }
296 }
297