blob: f33c0202aff95c803ddeaddf7838288581bce16b [file] [log] [blame]
Allen George8b96bfb2016-11-02 08:01:08 -04001// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
Marcin Pajkowskib34680f2019-12-02 10:29:16 +010018use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
Allen George8b96bfb2016-11-02 08:01:08 -040019use integer_encoding::{VarIntReader, VarIntWriter};
Danny Browningddec4312019-03-08 14:20:41 -070020use std::convert::{From, TryFrom};
Vadim Chekand3355af2018-01-05 23:12:47 -050021use std::io;
Allen George8b96bfb2016-11-02 08:01:08 -040022
Allen Georgeef7a1892018-12-16 18:01:37 -050023use super::{
24 TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier, TMapIdentifier,
25 TMessageIdentifier, TMessageType,
26};
Allen George8b96bfb2016-11-02 08:01:08 -040027use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
Allen Georgeb0d14132020-03-29 11:48:55 -040028use crate::transport::{TReadTransport, TWriteTransport};
Allen George8b96bfb2016-11-02 08:01:08 -040029
30const COMPACT_PROTOCOL_ID: u8 = 0x82;
31const COMPACT_VERSION: u8 = 0x01;
32const COMPACT_VERSION_MASK: u8 = 0x1F;
33
34/// Read messages encoded in the Thrift compact protocol.
35///
36/// # Examples
37///
38/// Create and use a `TCompactInputProtocol`.
39///
40/// ```no_run
Allen George8b96bfb2016-11-02 08:01:08 -040041/// use thrift::protocol::{TCompactInputProtocol, TInputProtocol};
Allen George0e22c362017-01-30 07:15:00 -050042/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -040043///
Allen George0e22c362017-01-30 07:15:00 -050044/// let mut channel = TTcpChannel::new();
45/// channel.open("localhost:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -040046///
Allen George0e22c362017-01-30 07:15:00 -050047/// let mut protocol = TCompactInputProtocol::new(channel);
Allen George8b96bfb2016-11-02 08:01:08 -040048///
Allen George0e22c362017-01-30 07:15:00 -050049/// let recvd_bool = protocol.read_bool().unwrap();
50/// let recvd_string = protocol.read_string().unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -040051/// ```
Allen George0e22c362017-01-30 07:15:00 -050052#[derive(Debug)]
53pub struct TCompactInputProtocol<T>
54where
55 T: TReadTransport,
56{
Allen George8b96bfb2016-11-02 08:01:08 -040057 // Identifier of the last field deserialized for a struct.
58 last_read_field_id: i16,
59 // Stack of the last read field ids (a new entry is added each time a nested struct is read).
60 read_field_id_stack: Vec<i16>,
61 // Boolean value for a field.
62 // Saved because boolean fields and their value are encoded in a single byte,
63 // and reading the field only occurs after the field id is read.
64 pending_read_bool_value: Option<bool>,
65 // Underlying transport used for byte-level operations.
Allen George0e22c362017-01-30 07:15:00 -050066 transport: T,
Allen George8b96bfb2016-11-02 08:01:08 -040067}
68
Allen George0e22c362017-01-30 07:15:00 -050069impl<T> TCompactInputProtocol<T>
70where
71 T: TReadTransport,
72{
Allen George8b96bfb2016-11-02 08:01:08 -040073 /// Create a `TCompactInputProtocol` that reads bytes from `transport`.
Allen George0e22c362017-01-30 07:15:00 -050074 pub fn new(transport: T) -> TCompactInputProtocol<T> {
Allen George8b96bfb2016-11-02 08:01:08 -040075 TCompactInputProtocol {
76 last_read_field_id: 0,
77 read_field_id_stack: Vec::new(),
78 pending_read_bool_value: None,
79 transport: transport,
80 }
81 }
82
Allen Georgeb0d14132020-03-29 11:48:55 -040083 fn read_list_set_begin(&mut self) -> crate::Result<(TType, i32)> {
Allen George8b96bfb2016-11-02 08:01:08 -040084 let header = self.read_byte()?;
85 let element_type = collection_u8_to_type(header & 0x0F)?;
86
87 let element_count;
88 let possible_element_count = (header & 0xF0) >> 4;
89 if possible_element_count != 15 {
90 // high bits set high if count and type encoded separately
91 element_count = possible_element_count as i32;
92 } else {
Allen George0e22c362017-01-30 07:15:00 -050093 element_count = self.transport.read_varint::<u32>()? as i32;
Allen George8b96bfb2016-11-02 08:01:08 -040094 }
95
96 Ok((element_type, element_count))
97 }
98}
99
Allen George0e22c362017-01-30 07:15:00 -0500100impl<T> TInputProtocol for TCompactInputProtocol<T>
101where
102 T: TReadTransport,
103{
Allen Georgeb0d14132020-03-29 11:48:55 -0400104 fn read_message_begin(&mut self) -> crate::Result<TMessageIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400105 let compact_id = self.read_byte()?;
106 if compact_id != COMPACT_PROTOCOL_ID {
Allen Georgeb0d14132020-03-29 11:48:55 -0400107 Err(crate::Error::Protocol(crate::ProtocolError {
108 kind: crate::ProtocolErrorKind::BadVersion,
Allen Georgeef7a1892018-12-16 18:01:37 -0500109 message: format!("invalid compact protocol header {:?}", compact_id),
110 }))
Allen George8b96bfb2016-11-02 08:01:08 -0400111 } else {
112 Ok(())
113 }?;
114
115 let type_and_byte = self.read_byte()?;
116 let received_version = type_and_byte & COMPACT_VERSION_MASK;
117 if received_version != COMPACT_VERSION {
Allen Georgeb0d14132020-03-29 11:48:55 -0400118 Err(crate::Error::Protocol(crate::ProtocolError {
119 kind: crate::ProtocolErrorKind::BadVersion,
Allen Georgeef7a1892018-12-16 18:01:37 -0500120 message: format!(
121 "cannot process compact protocol version {:?}",
122 received_version
Allen George0e22c362017-01-30 07:15:00 -0500123 ),
Allen Georgeef7a1892018-12-16 18:01:37 -0500124 }))
Allen George8b96bfb2016-11-02 08:01:08 -0400125 } else {
126 Ok(())
127 }?;
128
129 // NOTE: unsigned right shift will pad with 0s
130 let message_type: TMessageType = TMessageType::try_from(type_and_byte >> 5)?;
131 let sequence_number = self.read_i32()?;
132 let service_call_name = self.read_string()?;
133
134 self.last_read_field_id = 0;
135
Allen Georgeef7a1892018-12-16 18:01:37 -0500136 Ok(TMessageIdentifier::new(
137 service_call_name,
138 message_type,
139 sequence_number,
140 ))
Allen George8b96bfb2016-11-02 08:01:08 -0400141 }
142
Allen Georgeb0d14132020-03-29 11:48:55 -0400143 fn read_message_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400144 Ok(())
145 }
146
Allen Georgeb0d14132020-03-29 11:48:55 -0400147 fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>> {
Allen George8b96bfb2016-11-02 08:01:08 -0400148 self.read_field_id_stack.push(self.last_read_field_id);
149 self.last_read_field_id = 0;
150 Ok(None)
151 }
152
Allen Georgeb0d14132020-03-29 11:48:55 -0400153 fn read_struct_end(&mut self) -> crate::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500154 self.last_read_field_id = self
155 .read_field_id_stack
Allen George8b96bfb2016-11-02 08:01:08 -0400156 .pop()
157 .expect("should have previous field ids");
158 Ok(())
159 }
160
Allen Georgeb0d14132020-03-29 11:48:55 -0400161 fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400162 // we can read at least one byte, which is:
163 // - the type
164 // - the field delta and the type
165 let field_type = self.read_byte()?;
166 let field_delta = (field_type & 0xF0) >> 4;
167 let field_type = match field_type & 0x0F {
168 0x01 => {
169 self.pending_read_bool_value = Some(true);
170 Ok(TType::Bool)
171 }
172 0x02 => {
173 self.pending_read_bool_value = Some(false);
174 Ok(TType::Bool)
175 }
176 ttu8 => u8_to_type(ttu8),
177 }?;
178
179 match field_type {
Allen Georgeef7a1892018-12-16 18:01:37 -0500180 TType::Stop => Ok(
181 TFieldIdentifier::new::<Option<String>, String, Option<i16>>(
182 None,
183 TType::Stop,
184 None,
185 ),
186 ),
Allen George8b96bfb2016-11-02 08:01:08 -0400187 _ => {
188 if field_delta != 0 {
189 self.last_read_field_id += field_delta as i16;
190 } else {
191 self.last_read_field_id = self.read_i16()?;
192 };
193
Allen Georgeef7a1892018-12-16 18:01:37 -0500194 Ok(TFieldIdentifier {
195 name: None,
196 field_type: field_type,
197 id: Some(self.last_read_field_id),
198 })
Allen George8b96bfb2016-11-02 08:01:08 -0400199 }
200 }
201 }
202
Allen Georgeb0d14132020-03-29 11:48:55 -0400203 fn read_field_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400204 Ok(())
205 }
206
Allen Georgeb0d14132020-03-29 11:48:55 -0400207 fn read_bool(&mut self) -> crate::Result<bool> {
Allen George8b96bfb2016-11-02 08:01:08 -0400208 match self.pending_read_bool_value.take() {
209 Some(b) => Ok(b),
210 None => {
211 let b = self.read_byte()?;
212 match b {
213 0x01 => Ok(true),
214 0x02 => Ok(false),
Allen Georgeb0d14132020-03-29 11:48:55 -0400215 unkn => Err(crate::Error::Protocol(crate::ProtocolError {
216 kind: crate::ProtocolErrorKind::InvalidData,
Allen Georgeef7a1892018-12-16 18:01:37 -0500217 message: format!("cannot convert {} into bool", unkn),
218 })),
Allen George8b96bfb2016-11-02 08:01:08 -0400219 }
220 }
221 }
222 }
223
Allen Georgeb0d14132020-03-29 11:48:55 -0400224 fn read_bytes(&mut self) -> crate::Result<Vec<u8>> {
Allen George0e22c362017-01-30 07:15:00 -0500225 let len = self.transport.read_varint::<u32>()?;
Allen George8b96bfb2016-11-02 08:01:08 -0400226 let mut buf = vec![0u8; len as usize];
Allen George0e22c362017-01-30 07:15:00 -0500227 self.transport
228 .read_exact(&mut buf)
229 .map_err(From::from)
230 .map(|_| buf)
Allen George8b96bfb2016-11-02 08:01:08 -0400231 }
232
Allen Georgeb0d14132020-03-29 11:48:55 -0400233 fn read_i8(&mut self) -> crate::Result<i8> {
Allen George8b96bfb2016-11-02 08:01:08 -0400234 self.read_byte().map(|i| i as i8)
235 }
236
Allen Georgeb0d14132020-03-29 11:48:55 -0400237 fn read_i16(&mut self) -> crate::Result<i16> {
Allen George0e22c362017-01-30 07:15:00 -0500238 self.transport.read_varint::<i16>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400239 }
240
Allen Georgeb0d14132020-03-29 11:48:55 -0400241 fn read_i32(&mut self) -> crate::Result<i32> {
Allen George0e22c362017-01-30 07:15:00 -0500242 self.transport.read_varint::<i32>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400243 }
244
Allen Georgeb0d14132020-03-29 11:48:55 -0400245 fn read_i64(&mut self) -> crate::Result<i64> {
Allen George0e22c362017-01-30 07:15:00 -0500246 self.transport.read_varint::<i64>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400247 }
248
Allen Georgeb0d14132020-03-29 11:48:55 -0400249 fn read_double(&mut self) -> crate::Result<f64> {
Marcin Pajkowskib34680f2019-12-02 10:29:16 +0100250 self.transport.read_f64::<LittleEndian>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400251 }
252
Allen Georgeb0d14132020-03-29 11:48:55 -0400253 fn read_string(&mut self) -> crate::Result<String> {
Allen George8b96bfb2016-11-02 08:01:08 -0400254 let bytes = self.read_bytes()?;
255 String::from_utf8(bytes).map_err(From::from)
256 }
257
Allen Georgeb0d14132020-03-29 11:48:55 -0400258 fn read_list_begin(&mut self) -> crate::Result<TListIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400259 let (element_type, element_count) = self.read_list_set_begin()?;
260 Ok(TListIdentifier::new(element_type, element_count))
261 }
262
Allen Georgeb0d14132020-03-29 11:48:55 -0400263 fn read_list_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400264 Ok(())
265 }
266
Allen Georgeb0d14132020-03-29 11:48:55 -0400267 fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400268 let (element_type, element_count) = self.read_list_set_begin()?;
269 Ok(TSetIdentifier::new(element_type, element_count))
270 }
271
Allen Georgeb0d14132020-03-29 11:48:55 -0400272 fn read_set_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400273 Ok(())
274 }
275
Allen Georgeb0d14132020-03-29 11:48:55 -0400276 fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier> {
Allen George0e22c362017-01-30 07:15:00 -0500277 let element_count = self.transport.read_varint::<u32>()? as i32;
Allen George8b96bfb2016-11-02 08:01:08 -0400278 if element_count == 0 {
279 Ok(TMapIdentifier::new(None, None, 0))
280 } else {
281 let type_header = self.read_byte()?;
282 let key_type = collection_u8_to_type((type_header & 0xF0) >> 4)?;
283 let val_type = collection_u8_to_type(type_header & 0x0F)?;
284 Ok(TMapIdentifier::new(key_type, val_type, element_count))
285 }
286 }
287
Allen Georgeb0d14132020-03-29 11:48:55 -0400288 fn read_map_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400289 Ok(())
290 }
291
292 // utility
293 //
294
Allen Georgeb0d14132020-03-29 11:48:55 -0400295 fn read_byte(&mut self) -> crate::Result<u8> {
Allen George8b96bfb2016-11-02 08:01:08 -0400296 let mut buf = [0u8; 1];
Allen George0e22c362017-01-30 07:15:00 -0500297 self.transport
298 .read_exact(&mut buf)
299 .map_err(From::from)
300 .map(|_| buf[0])
Allen George8b96bfb2016-11-02 08:01:08 -0400301 }
302}
303
Vadim Chekand3355af2018-01-05 23:12:47 -0500304impl<T> io::Seek for TCompactInputProtocol<T>
305where
306 T: io::Seek + TReadTransport,
307{
308 fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
309 self.transport.seek(pos)
310 }
311}
312
Allen George8b96bfb2016-11-02 08:01:08 -0400313/// Factory for creating instances of `TCompactInputProtocol`.
314#[derive(Default)]
315pub struct TCompactInputProtocolFactory;
316
317impl TCompactInputProtocolFactory {
318 /// Create a `TCompactInputProtocolFactory`.
319 pub fn new() -> TCompactInputProtocolFactory {
320 TCompactInputProtocolFactory {}
321 }
322}
323
324impl TInputProtocolFactory for TCompactInputProtocolFactory {
Danny Browning77d96c12019-08-21 13:41:07 -0600325 fn create(&self, transport: Box<dyn TReadTransport + Send>) -> Box<dyn TInputProtocol + Send> {
Allen George0e22c362017-01-30 07:15:00 -0500326 Box::new(TCompactInputProtocol::new(transport))
Allen George8b96bfb2016-11-02 08:01:08 -0400327 }
328}
329
330/// Write messages using the Thrift compact protocol.
331///
332/// # Examples
333///
334/// Create and use a `TCompactOutputProtocol`.
335///
336/// ```no_run
Allen George8b96bfb2016-11-02 08:01:08 -0400337/// use thrift::protocol::{TCompactOutputProtocol, TOutputProtocol};
Allen George0e22c362017-01-30 07:15:00 -0500338/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -0400339///
Allen George0e22c362017-01-30 07:15:00 -0500340/// let mut channel = TTcpChannel::new();
341/// channel.open("localhost:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400342///
Allen George0e22c362017-01-30 07:15:00 -0500343/// let mut protocol = TCompactOutputProtocol::new(channel);
Allen George8b96bfb2016-11-02 08:01:08 -0400344///
Allen George0e22c362017-01-30 07:15:00 -0500345/// protocol.write_bool(true).unwrap();
346/// protocol.write_string("test_string").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400347/// ```
Allen George0e22c362017-01-30 07:15:00 -0500348#[derive(Debug)]
349pub struct TCompactOutputProtocol<T>
350where
351 T: TWriteTransport,
352{
Allen George8b96bfb2016-11-02 08:01:08 -0400353 // Identifier of the last field serialized for a struct.
354 last_write_field_id: i16,
Allen George0e22c362017-01-30 07:15:00 -0500355 // Stack of the last written field ids (new entry added each time a nested struct is written).
Allen George8b96bfb2016-11-02 08:01:08 -0400356 write_field_id_stack: Vec<i16>,
357 // Field identifier of the boolean field to be written.
358 // Saved because boolean fields and their value are encoded in a single byte
359 pending_write_bool_field_identifier: Option<TFieldIdentifier>,
360 // Underlying transport used for byte-level operations.
Allen George0e22c362017-01-30 07:15:00 -0500361 transport: T,
Allen George8b96bfb2016-11-02 08:01:08 -0400362}
363
Allen George0e22c362017-01-30 07:15:00 -0500364impl<T> TCompactOutputProtocol<T>
365where
366 T: TWriteTransport,
367{
Allen George8b96bfb2016-11-02 08:01:08 -0400368 /// Create a `TCompactOutputProtocol` that writes bytes to `transport`.
Allen George0e22c362017-01-30 07:15:00 -0500369 pub fn new(transport: T) -> TCompactOutputProtocol<T> {
Allen George8b96bfb2016-11-02 08:01:08 -0400370 TCompactOutputProtocol {
371 last_write_field_id: 0,
372 write_field_id_stack: Vec::new(),
373 pending_write_bool_field_identifier: None,
374 transport: transport,
375 }
376 }
377
378 // FIXME: field_type as unconstrained u8 is bad
Allen Georgeb0d14132020-03-29 11:48:55 -0400379 fn write_field_header(&mut self, field_type: u8, field_id: i16) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400380 let field_delta = field_id - self.last_write_field_id;
381 if field_delta > 0 && field_delta < 15 {
382 self.write_byte(((field_delta as u8) << 4) | field_type)?;
383 } else {
384 self.write_byte(field_type)?;
385 self.write_i16(field_id)?;
386 }
387 self.last_write_field_id = field_id;
388 Ok(())
389 }
390
Allen Georgeb0d14132020-03-29 11:48:55 -0400391 fn write_list_set_begin(&mut self, element_type: TType, element_count: i32) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400392 let elem_identifier = collection_type_to_u8(element_type);
393 if element_count <= 14 {
394 let header = (element_count as u8) << 4 | elem_identifier;
395 self.write_byte(header)
396 } else {
397 let header = 0xF0 | elem_identifier;
398 self.write_byte(header)?;
399 self.transport
Allen George8b96bfb2016-11-02 08:01:08 -0400400 .write_varint(element_count as u32)
401 .map_err(From::from)
402 .map(|_| ())
403 }
404 }
405
406 fn assert_no_pending_bool_write(&self) {
407 if let Some(ref f) = self.pending_write_bool_field_identifier {
408 panic!("pending bool field {:?} not written", f)
409 }
410 }
411}
412
Allen George0e22c362017-01-30 07:15:00 -0500413impl<T> TOutputProtocol for TCompactOutputProtocol<T>
414where
415 T: TWriteTransport,
416{
Allen Georgeb0d14132020-03-29 11:48:55 -0400417 fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400418 self.write_byte(COMPACT_PROTOCOL_ID)?;
419 self.write_byte((u8::from(identifier.message_type) << 5) | COMPACT_VERSION)?;
420 self.write_i32(identifier.sequence_number)?;
421 self.write_string(&identifier.name)?;
422 Ok(())
423 }
424
Allen Georgeb0d14132020-03-29 11:48:55 -0400425 fn write_message_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400426 self.assert_no_pending_bool_write();
427 Ok(())
428 }
429
Allen Georgeb0d14132020-03-29 11:48:55 -0400430 fn write_struct_begin(&mut self, _: &TStructIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400431 self.write_field_id_stack.push(self.last_write_field_id);
432 self.last_write_field_id = 0;
433 Ok(())
434 }
435
Allen Georgeb0d14132020-03-29 11:48:55 -0400436 fn write_struct_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400437 self.assert_no_pending_bool_write();
Allen Georgeef7a1892018-12-16 18:01:37 -0500438 self.last_write_field_id = self
439 .write_field_id_stack
Allen George0e22c362017-01-30 07:15:00 -0500440 .pop()
441 .expect("should have previous field ids");
Allen George8b96bfb2016-11-02 08:01:08 -0400442 Ok(())
443 }
444
Allen Georgeb0d14132020-03-29 11:48:55 -0400445 fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400446 match identifier.field_type {
447 TType::Bool => {
448 if self.pending_write_bool_field_identifier.is_some() {
Allen George0e22c362017-01-30 07:15:00 -0500449 panic!(
450 "should not have a pending bool while writing another bool with id: \
Allen Georgeef7a1892018-12-16 18:01:37 -0500451 {:?}",
Allen George0e22c362017-01-30 07:15:00 -0500452 identifier
453 )
Allen George8b96bfb2016-11-02 08:01:08 -0400454 }
455 self.pending_write_bool_field_identifier = Some(identifier.clone());
456 Ok(())
457 }
458 _ => {
459 let field_type = type_to_u8(identifier.field_type);
Allen Georgeef7a1892018-12-16 18:01:37 -0500460 let field_id = identifier.id.expect("non-stop field should have field id");
Allen George8b96bfb2016-11-02 08:01:08 -0400461 self.write_field_header(field_type, field_id)
462 }
463 }
464 }
465
Allen Georgeb0d14132020-03-29 11:48:55 -0400466 fn write_field_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400467 self.assert_no_pending_bool_write();
468 Ok(())
469 }
470
Allen Georgeb0d14132020-03-29 11:48:55 -0400471 fn write_field_stop(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400472 self.assert_no_pending_bool_write();
473 self.write_byte(type_to_u8(TType::Stop))
474 }
475
Allen Georgeb0d14132020-03-29 11:48:55 -0400476 fn write_bool(&mut self, b: bool) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400477 match self.pending_write_bool_field_identifier.take() {
478 Some(pending) => {
479 let field_id = pending.id.expect("bool field should have a field id");
480 let field_type_as_u8 = if b { 0x01 } else { 0x02 };
481 self.write_field_header(field_type_as_u8, field_id)
482 }
483 None => {
484 if b {
485 self.write_byte(0x01)
486 } else {
487 self.write_byte(0x02)
488 }
489 }
490 }
491 }
492
Allen Georgeb0d14132020-03-29 11:48:55 -0400493 fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500494 self.transport.write_varint(b.len() as u32)?;
495 self.transport.write_all(b).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400496 }
497
Allen Georgeb0d14132020-03-29 11:48:55 -0400498 fn write_i8(&mut self, i: i8) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400499 self.write_byte(i as u8)
500 }
501
Allen Georgeb0d14132020-03-29 11:48:55 -0400502 fn write_i16(&mut self, i: i16) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500503 self.transport
504 .write_varint(i)
505 .map_err(From::from)
506 .map(|_| ())
Allen George8b96bfb2016-11-02 08:01:08 -0400507 }
508
Allen Georgeb0d14132020-03-29 11:48:55 -0400509 fn write_i32(&mut self, i: i32) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500510 self.transport
511 .write_varint(i)
512 .map_err(From::from)
513 .map(|_| ())
Allen George8b96bfb2016-11-02 08:01:08 -0400514 }
515
Allen Georgeb0d14132020-03-29 11:48:55 -0400516 fn write_i64(&mut self, i: i64) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500517 self.transport
518 .write_varint(i)
519 .map_err(From::from)
520 .map(|_| ())
Allen George8b96bfb2016-11-02 08:01:08 -0400521 }
522
Allen Georgeb0d14132020-03-29 11:48:55 -0400523 fn write_double(&mut self, d: f64) -> crate::Result<()> {
Marcin Pajkowskib34680f2019-12-02 10:29:16 +0100524 self.transport.write_f64::<LittleEndian>(d).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400525 }
526
Allen Georgeb0d14132020-03-29 11:48:55 -0400527 fn write_string(&mut self, s: &str) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400528 self.write_bytes(s.as_bytes())
529 }
530
Allen Georgeb0d14132020-03-29 11:48:55 -0400531 fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400532 self.write_list_set_begin(identifier.element_type, identifier.size)
533 }
534
Allen Georgeb0d14132020-03-29 11:48:55 -0400535 fn write_list_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400536 Ok(())
537 }
538
Allen Georgeb0d14132020-03-29 11:48:55 -0400539 fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400540 self.write_list_set_begin(identifier.element_type, identifier.size)
541 }
542
Allen Georgeb0d14132020-03-29 11:48:55 -0400543 fn write_set_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400544 Ok(())
545 }
546
Allen Georgeb0d14132020-03-29 11:48:55 -0400547 fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400548 if identifier.size == 0 {
549 self.write_byte(0)
550 } else {
Allen George0e22c362017-01-30 07:15:00 -0500551 self.transport.write_varint(identifier.size as u32)?;
Allen George8b96bfb2016-11-02 08:01:08 -0400552
Allen George0e22c362017-01-30 07:15:00 -0500553 let key_type = identifier
554 .key_type
Allen George8b96bfb2016-11-02 08:01:08 -0400555 .expect("map identifier to write should contain key type");
556 let key_type_byte = collection_type_to_u8(key_type) << 4;
557
Allen George0e22c362017-01-30 07:15:00 -0500558 let val_type = identifier
559 .value_type
Allen George8b96bfb2016-11-02 08:01:08 -0400560 .expect("map identifier to write should contain value type");
561 let val_type_byte = collection_type_to_u8(val_type);
562
563 let map_type_header = key_type_byte | val_type_byte;
564 self.write_byte(map_type_header)
565 }
566 }
567
Allen Georgeb0d14132020-03-29 11:48:55 -0400568 fn write_map_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400569 Ok(())
570 }
571
Allen Georgeb0d14132020-03-29 11:48:55 -0400572 fn flush(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500573 self.transport.flush().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400574 }
575
576 // utility
577 //
578
Allen Georgeb0d14132020-03-29 11:48:55 -0400579 fn write_byte(&mut self, b: u8) -> crate::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500580 self.transport.write(&[b]).map_err(From::from).map(|_| ())
Allen George8b96bfb2016-11-02 08:01:08 -0400581 }
582}
583
584/// Factory for creating instances of `TCompactOutputProtocol`.
585#[derive(Default)]
586pub struct TCompactOutputProtocolFactory;
587
588impl TCompactOutputProtocolFactory {
589 /// Create a `TCompactOutputProtocolFactory`.
590 pub fn new() -> TCompactOutputProtocolFactory {
591 TCompactOutputProtocolFactory {}
592 }
593}
594
595impl TOutputProtocolFactory for TCompactOutputProtocolFactory {
Danny Browning77d96c12019-08-21 13:41:07 -0600596 fn create(&self, transport: Box<dyn TWriteTransport + Send>) -> Box<dyn TOutputProtocol + Send> {
Allen George0e22c362017-01-30 07:15:00 -0500597 Box::new(TCompactOutputProtocol::new(transport))
Allen George8b96bfb2016-11-02 08:01:08 -0400598 }
599}
600
601fn collection_type_to_u8(field_type: TType) -> u8 {
602 match field_type {
603 TType::Bool => 0x01,
604 f => type_to_u8(f),
605 }
606}
607
608fn type_to_u8(field_type: TType) -> u8 {
609 match field_type {
610 TType::Stop => 0x00,
611 TType::I08 => 0x03, // equivalent to TType::Byte
612 TType::I16 => 0x04,
613 TType::I32 => 0x05,
614 TType::I64 => 0x06,
615 TType::Double => 0x07,
616 TType::String => 0x08,
617 TType::List => 0x09,
618 TType::Set => 0x0A,
619 TType::Map => 0x0B,
620 TType::Struct => 0x0C,
Allen Georgeef7a1892018-12-16 18:01:37 -0500621 _ => panic!(format!(
622 "should not have attempted to convert {} to u8",
623 field_type
624 )),
Allen George8b96bfb2016-11-02 08:01:08 -0400625 }
626}
627
Allen Georgeb0d14132020-03-29 11:48:55 -0400628fn collection_u8_to_type(b: u8) -> crate::Result<TType> {
Allen George8b96bfb2016-11-02 08:01:08 -0400629 match b {
630 0x01 => Ok(TType::Bool),
631 o => u8_to_type(o),
632 }
633}
634
Allen Georgeb0d14132020-03-29 11:48:55 -0400635fn u8_to_type(b: u8) -> crate::Result<TType> {
Allen George8b96bfb2016-11-02 08:01:08 -0400636 match b {
637 0x00 => Ok(TType::Stop),
638 0x03 => Ok(TType::I08), // equivalent to TType::Byte
639 0x04 => Ok(TType::I16),
640 0x05 => Ok(TType::I32),
641 0x06 => Ok(TType::I64),
642 0x07 => Ok(TType::Double),
643 0x08 => Ok(TType::String),
644 0x09 => Ok(TType::List),
645 0x0A => Ok(TType::Set),
646 0x0B => Ok(TType::Map),
647 0x0C => Ok(TType::Struct),
Allen Georgeb0d14132020-03-29 11:48:55 -0400648 unkn => Err(crate::Error::Protocol(crate::ProtocolError {
649 kind: crate::ProtocolErrorKind::InvalidData,
Allen Georgeef7a1892018-12-16 18:01:37 -0500650 message: format!("cannot convert {} into TType", unkn),
651 })),
Allen George8b96bfb2016-11-02 08:01:08 -0400652 }
653}
654
655#[cfg(test)]
656mod tests {
657
Allen Georgeb0d14132020-03-29 11:48:55 -0400658 use crate::protocol::{
Allen Georgeef7a1892018-12-16 18:01:37 -0500659 TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
660 TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType,
661 };
Allen Georgeb0d14132020-03-29 11:48:55 -0400662 use crate::transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
Allen George8b96bfb2016-11-02 08:01:08 -0400663
664 use super::*;
665
666 #[test]
667 fn must_write_message_begin_0() {
Allen George0e22c362017-01-30 07:15:00 -0500668 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400669
Allen Georgeef7a1892018-12-16 18:01:37 -0500670 assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new(
671 "foo",
672 TMessageType::Call,
673 431
674 )));
Allen George8b96bfb2016-11-02 08:01:08 -0400675
Allen Georgeef7a1892018-12-16 18:01:37 -0500676 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -0500677 let expected: [u8; 8] = [
678 0x82, /* protocol ID */
679 0x21, /* message type | protocol version */
680 0xDE,
681 0x06, /* zig-zag varint sequence number */
682 0x03, /* message-name length */
683 0x66,
684 0x6F,
685 0x6F /* "foo" */,
686 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400687
Allen George0e22c362017-01-30 07:15:00 -0500688 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400689 }
690
691 #[test]
692 fn must_write_message_begin_1() {
Allen George0e22c362017-01-30 07:15:00 -0500693 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400694
Allen Georgeef7a1892018-12-16 18:01:37 -0500695 assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new(
696 "bar",
697 TMessageType::Reply,
698 991828
699 )));
Allen George8b96bfb2016-11-02 08:01:08 -0400700
Allen Georgeef7a1892018-12-16 18:01:37 -0500701 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -0500702 let expected: [u8; 9] = [
703 0x82, /* protocol ID */
704 0x41, /* message type | protocol version */
705 0xA8,
706 0x89,
707 0x79, /* zig-zag varint sequence number */
708 0x03, /* message-name length */
709 0x62,
710 0x61,
711 0x72 /* "bar" */,
712 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400713
Allen George0e22c362017-01-30 07:15:00 -0500714 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400715 }
716
717 #[test]
Nik Claytone7917602020-03-05 11:51:15 +0100718 fn must_round_trip_upto_i64_maxvalue() {
719 // See https://issues.apache.org/jira/browse/THRIFT-5131
720 for i in 0..64 {
721 let (mut i_prot, mut o_prot) = test_objects();
722 let val: i64 = ((1u64 << i) - 1) as i64;
723
724 o_prot
725 .write_field_begin(&TFieldIdentifier::new(
726 "val",
727 TType::I64,
728 1
729 ))
730 .unwrap();
731 o_prot.write_i64(val).unwrap();
732 o_prot.write_field_end().unwrap();
733 o_prot.flush().unwrap();
734
735 copy_write_buffer_to_read_buffer!(o_prot);
736
737 i_prot.read_field_begin().unwrap();
738 assert_eq!(val, i_prot.read_i64().unwrap());
739 }
740 }
741
742 #[test]
Allen George8b96bfb2016-11-02 08:01:08 -0400743 fn must_round_trip_message_begin() {
Allen George0e22c362017-01-30 07:15:00 -0500744 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400745
746 let ident = TMessageIdentifier::new("service_call", TMessageType::Call, 1283948);
747
748 assert_success!(o_prot.write_message_begin(&ident));
749
Allen George0e22c362017-01-30 07:15:00 -0500750 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400751
752 let res = assert_success!(i_prot.read_message_begin());
753 assert_eq!(&res, &ident);
754 }
755
756 #[test]
757 fn must_write_message_end() {
758 assert_no_write(|o| o.write_message_end());
759 }
760
761 // NOTE: structs and fields are tested together
762 //
763
764 #[test]
765 fn must_write_struct_with_delta_fields() {
Allen George0e22c362017-01-30 07:15:00 -0500766 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400767
768 // no bytes should be written however
769 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
770
771 // write three fields with tiny field ids
772 // since they're small the field ids will be encoded as deltas
773
774 // since this is the first field (and it's zero) it gets the full varint write
775 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 0)));
776 assert_success!(o_prot.write_field_end());
777
778 // since this delta > 0 and < 15 it can be encoded as a delta
779 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I16, 4)));
780 assert_success!(o_prot.write_field_end());
781
782 // since this delta > 0 and < 15 it can be encoded as a delta
783 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::List, 9)));
784 assert_success!(o_prot.write_field_end());
785
786 // now, finish the struct off
787 assert_success!(o_prot.write_field_stop());
788 assert_success!(o_prot.write_struct_end());
789
Allen Georgeef7a1892018-12-16 18:01:37 -0500790 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -0500791 let expected: [u8; 5] = [
792 0x03, /* field type */
793 0x00, /* first field id */
794 0x44, /* field delta (4) | field type */
795 0x59, /* field delta (5) | field type */
796 0x00 /* field stop */,
797 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400798
Allen George0e22c362017-01-30 07:15:00 -0500799 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400800 }
801
802 #[test]
803 fn must_round_trip_struct_with_delta_fields() {
Allen George0e22c362017-01-30 07:15:00 -0500804 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400805
806 // no bytes should be written however
807 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
808
809 // write three fields with tiny field ids
810 // since they're small the field ids will be encoded as deltas
811
812 // since this is the first field (and it's zero) it gets the full varint write
813 let field_ident_1 = TFieldIdentifier::new("foo", TType::I08, 0);
814 assert_success!(o_prot.write_field_begin(&field_ident_1));
815 assert_success!(o_prot.write_field_end());
816
817 // since this delta > 0 and < 15 it can be encoded as a delta
818 let field_ident_2 = TFieldIdentifier::new("foo", TType::I16, 4);
819 assert_success!(o_prot.write_field_begin(&field_ident_2));
820 assert_success!(o_prot.write_field_end());
821
822 // since this delta > 0 and < 15 it can be encoded as a delta
823 let field_ident_3 = TFieldIdentifier::new("foo", TType::List, 9);
824 assert_success!(o_prot.write_field_begin(&field_ident_3));
825 assert_success!(o_prot.write_field_end());
826
827 // now, finish the struct off
828 assert_success!(o_prot.write_field_stop());
829 assert_success!(o_prot.write_struct_end());
830
Allen George0e22c362017-01-30 07:15:00 -0500831 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400832
833 // read the struct back
834 assert_success!(i_prot.read_struct_begin());
835
836 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500837 assert_eq!(
838 read_ident_1,
839 TFieldIdentifier {
840 name: None,
841 ..field_ident_1
842 }
843 );
Allen George8b96bfb2016-11-02 08:01:08 -0400844 assert_success!(i_prot.read_field_end());
845
846 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500847 assert_eq!(
848 read_ident_2,
849 TFieldIdentifier {
850 name: None,
851 ..field_ident_2
852 }
853 );
Allen George8b96bfb2016-11-02 08:01:08 -0400854 assert_success!(i_prot.read_field_end());
855
856 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500857 assert_eq!(
858 read_ident_3,
859 TFieldIdentifier {
860 name: None,
861 ..field_ident_3
862 }
863 );
Allen George8b96bfb2016-11-02 08:01:08 -0400864 assert_success!(i_prot.read_field_end());
865
866 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500867 assert_eq!(
868 read_ident_4,
869 TFieldIdentifier {
870 name: None,
871 field_type: TType::Stop,
872 id: None,
873 }
874 );
Allen George8b96bfb2016-11-02 08:01:08 -0400875
876 assert_success!(i_prot.read_struct_end());
877 }
878
879 #[test]
880 fn must_write_struct_with_non_zero_initial_field_and_delta_fields() {
Allen George0e22c362017-01-30 07:15:00 -0500881 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400882
883 // no bytes should be written however
884 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
885
886 // write three fields with tiny field ids
887 // since they're small the field ids will be encoded as deltas
888
889 // gets a delta write
890 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 1)));
891 assert_success!(o_prot.write_field_end());
892
893 // since this delta > 0 and < 15 it can be encoded as a delta
894 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2)));
895 assert_success!(o_prot.write_field_end());
896
897 // since this delta > 0 and < 15 it can be encoded as a delta
898 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 6)));
899 assert_success!(o_prot.write_field_end());
900
901 // now, finish the struct off
902 assert_success!(o_prot.write_field_stop());
903 assert_success!(o_prot.write_struct_end());
904
Allen Georgeef7a1892018-12-16 18:01:37 -0500905 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -0500906 let expected: [u8; 4] = [
907 0x15, /* field delta (1) | field type */
908 0x1A, /* field delta (1) | field type */
909 0x48, /* field delta (4) | field type */
910 0x00 /* field stop */,
911 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400912
Allen George0e22c362017-01-30 07:15:00 -0500913 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400914 }
915
916 #[test]
917 fn must_round_trip_struct_with_non_zero_initial_field_and_delta_fields() {
Allen George0e22c362017-01-30 07:15:00 -0500918 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400919
920 // no bytes should be written however
921 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
922
923 // write three fields with tiny field ids
924 // since they're small the field ids will be encoded as deltas
925
926 // gets a delta write
927 let field_ident_1 = TFieldIdentifier::new("foo", TType::I32, 1);
928 assert_success!(o_prot.write_field_begin(&field_ident_1));
929 assert_success!(o_prot.write_field_end());
930
931 // since this delta > 0 and < 15 it can be encoded as a delta
932 let field_ident_2 = TFieldIdentifier::new("foo", TType::Set, 2);
933 assert_success!(o_prot.write_field_begin(&field_ident_2));
934 assert_success!(o_prot.write_field_end());
935
936 // since this delta > 0 and < 15 it can be encoded as a delta
937 let field_ident_3 = TFieldIdentifier::new("foo", TType::String, 6);
938 assert_success!(o_prot.write_field_begin(&field_ident_3));
939 assert_success!(o_prot.write_field_end());
940
941 // now, finish the struct off
942 assert_success!(o_prot.write_field_stop());
943 assert_success!(o_prot.write_struct_end());
944
Allen George0e22c362017-01-30 07:15:00 -0500945 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400946
947 // read the struct back
948 assert_success!(i_prot.read_struct_begin());
949
950 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500951 assert_eq!(
952 read_ident_1,
953 TFieldIdentifier {
954 name: None,
955 ..field_ident_1
956 }
957 );
Allen George8b96bfb2016-11-02 08:01:08 -0400958 assert_success!(i_prot.read_field_end());
959
960 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500961 assert_eq!(
962 read_ident_2,
963 TFieldIdentifier {
964 name: None,
965 ..field_ident_2
966 }
967 );
Allen George8b96bfb2016-11-02 08:01:08 -0400968 assert_success!(i_prot.read_field_end());
969
970 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500971 assert_eq!(
972 read_ident_3,
973 TFieldIdentifier {
974 name: None,
975 ..field_ident_3
976 }
977 );
Allen George8b96bfb2016-11-02 08:01:08 -0400978 assert_success!(i_prot.read_field_end());
979
980 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500981 assert_eq!(
982 read_ident_4,
983 TFieldIdentifier {
984 name: None,
985 field_type: TType::Stop,
986 id: None,
987 }
988 );
Allen George8b96bfb2016-11-02 08:01:08 -0400989
990 assert_success!(i_prot.read_struct_end());
991 }
992
993 #[test]
994 fn must_write_struct_with_long_fields() {
Allen George0e22c362017-01-30 07:15:00 -0500995 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400996
997 // no bytes should be written however
998 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
999
1000 // write three fields with field ids that cannot be encoded as deltas
1001
1002 // since this is the first field (and it's zero) it gets the full varint write
1003 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 0)));
1004 assert_success!(o_prot.write_field_end());
1005
1006 // since this delta is > 15 it is encoded as a zig-zag varint
1007 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 16)));
1008 assert_success!(o_prot.write_field_end());
1009
1010 // since this delta is > 15 it is encoded as a zig-zag varint
1011 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 99)));
1012 assert_success!(o_prot.write_field_end());
1013
1014 // now, finish the struct off
1015 assert_success!(o_prot.write_field_stop());
1016 assert_success!(o_prot.write_struct_end());
1017
Allen Georgeef7a1892018-12-16 18:01:37 -05001018 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -05001019 let expected: [u8; 8] = [
1020 0x05, /* field type */
1021 0x00, /* first field id */
1022 0x06, /* field type */
1023 0x20, /* zig-zag varint field id */
1024 0x0A, /* field type */
1025 0xC6,
1026 0x01, /* zig-zag varint field id */
1027 0x00 /* field stop */,
1028 ];
Allen George8b96bfb2016-11-02 08:01:08 -04001029
Allen George0e22c362017-01-30 07:15:00 -05001030 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04001031 }
1032
1033 #[test]
1034 fn must_round_trip_struct_with_long_fields() {
Allen George0e22c362017-01-30 07:15:00 -05001035 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001036
1037 // no bytes should be written however
1038 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1039
1040 // write three fields with field ids that cannot be encoded as deltas
1041
1042 // since this is the first field (and it's zero) it gets the full varint write
1043 let field_ident_1 = TFieldIdentifier::new("foo", TType::I32, 0);
1044 assert_success!(o_prot.write_field_begin(&field_ident_1));
1045 assert_success!(o_prot.write_field_end());
1046
1047 // since this delta is > 15 it is encoded as a zig-zag varint
1048 let field_ident_2 = TFieldIdentifier::new("foo", TType::I64, 16);
1049 assert_success!(o_prot.write_field_begin(&field_ident_2));
1050 assert_success!(o_prot.write_field_end());
1051
1052 // since this delta is > 15 it is encoded as a zig-zag varint
1053 let field_ident_3 = TFieldIdentifier::new("foo", TType::Set, 99);
1054 assert_success!(o_prot.write_field_begin(&field_ident_3));
1055 assert_success!(o_prot.write_field_end());
1056
1057 // now, finish the struct off
1058 assert_success!(o_prot.write_field_stop());
1059 assert_success!(o_prot.write_struct_end());
1060
Allen George0e22c362017-01-30 07:15:00 -05001061 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04001062
1063 // read the struct back
1064 assert_success!(i_prot.read_struct_begin());
1065
1066 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001067 assert_eq!(
1068 read_ident_1,
1069 TFieldIdentifier {
1070 name: None,
1071 ..field_ident_1
1072 }
1073 );
Allen George8b96bfb2016-11-02 08:01:08 -04001074 assert_success!(i_prot.read_field_end());
1075
1076 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001077 assert_eq!(
1078 read_ident_2,
1079 TFieldIdentifier {
1080 name: None,
1081 ..field_ident_2
1082 }
1083 );
Allen George8b96bfb2016-11-02 08:01:08 -04001084 assert_success!(i_prot.read_field_end());
1085
1086 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001087 assert_eq!(
1088 read_ident_3,
1089 TFieldIdentifier {
1090 name: None,
1091 ..field_ident_3
1092 }
1093 );
Allen George8b96bfb2016-11-02 08:01:08 -04001094 assert_success!(i_prot.read_field_end());
1095
1096 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001097 assert_eq!(
1098 read_ident_4,
1099 TFieldIdentifier {
1100 name: None,
1101 field_type: TType::Stop,
1102 id: None,
1103 }
1104 );
Allen George8b96bfb2016-11-02 08:01:08 -04001105
1106 assert_success!(i_prot.read_struct_end());
1107 }
1108
1109 #[test]
1110 fn must_write_struct_with_mix_of_long_and_delta_fields() {
Allen George0e22c362017-01-30 07:15:00 -05001111 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001112
1113 // no bytes should be written however
1114 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1115
1116 // write three fields with field ids that cannot be encoded as deltas
1117
1118 // since the delta is > 0 and < 15 it gets a delta write
1119 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
1120 assert_success!(o_prot.write_field_end());
1121
1122 // since this delta > 0 and < 15 it gets a delta write
1123 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
1124 assert_success!(o_prot.write_field_end());
1125
1126 // since this delta is > 15 it is encoded as a zig-zag varint
1127 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 1000)));
1128 assert_success!(o_prot.write_field_end());
1129
1130 // since this delta is > 15 it is encoded as a zig-zag varint
1131 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2001)));
1132 assert_success!(o_prot.write_field_end());
1133
1134 // since this is only 3 up from the previous it is recorded as a delta
1135 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2004)));
1136 assert_success!(o_prot.write_field_end());
1137
1138 // now, finish the struct off
1139 assert_success!(o_prot.write_field_stop());
1140 assert_success!(o_prot.write_struct_end());
1141
Allen Georgeef7a1892018-12-16 18:01:37 -05001142 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -05001143 let expected: [u8; 10] = [
1144 0x16, /* field delta (1) | field type */
1145 0x85, /* field delta (8) | field type */
1146 0x0A, /* field type */
1147 0xD0,
1148 0x0F, /* zig-zag varint field id */
1149 0x0A, /* field type */
1150 0xA2,
1151 0x1F, /* zig-zag varint field id */
1152 0x3A, /* field delta (3) | field type */
1153 0x00 /* field stop */,
1154 ];
Allen George8b96bfb2016-11-02 08:01:08 -04001155
Allen George0e22c362017-01-30 07:15:00 -05001156 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04001157 }
1158
1159 #[test]
1160 fn must_round_trip_struct_with_mix_of_long_and_delta_fields() {
Allen George0e22c362017-01-30 07:15:00 -05001161 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001162
1163 // no bytes should be written however
1164 let struct_ident = TStructIdentifier::new("foo");
1165 assert_success!(o_prot.write_struct_begin(&struct_ident));
1166
1167 // write three fields with field ids that cannot be encoded as deltas
1168
1169 // since the delta is > 0 and < 15 it gets a delta write
1170 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1171 assert_success!(o_prot.write_field_begin(&field_ident_1));
1172 assert_success!(o_prot.write_field_end());
1173
1174 // since this delta > 0 and < 15 it gets a delta write
1175 let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
1176 assert_success!(o_prot.write_field_begin(&field_ident_2));
1177 assert_success!(o_prot.write_field_end());
1178
1179 // since this delta is > 15 it is encoded as a zig-zag varint
1180 let field_ident_3 = TFieldIdentifier::new("foo", TType::Set, 1000);
1181 assert_success!(o_prot.write_field_begin(&field_ident_3));
1182 assert_success!(o_prot.write_field_end());
1183
1184 // since this delta is > 15 it is encoded as a zig-zag varint
1185 let field_ident_4 = TFieldIdentifier::new("foo", TType::Set, 2001);
1186 assert_success!(o_prot.write_field_begin(&field_ident_4));
1187 assert_success!(o_prot.write_field_end());
1188
1189 // since this is only 3 up from the previous it is recorded as a delta
1190 let field_ident_5 = TFieldIdentifier::new("foo", TType::Set, 2004);
1191 assert_success!(o_prot.write_field_begin(&field_ident_5));
1192 assert_success!(o_prot.write_field_end());
1193
1194 // now, finish the struct off
1195 assert_success!(o_prot.write_field_stop());
1196 assert_success!(o_prot.write_struct_end());
1197
Allen George0e22c362017-01-30 07:15:00 -05001198 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04001199
1200 // read the struct back
1201 assert_success!(i_prot.read_struct_begin());
1202
1203 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001204 assert_eq!(
1205 read_ident_1,
1206 TFieldIdentifier {
1207 name: None,
1208 ..field_ident_1
1209 }
1210 );
Allen George8b96bfb2016-11-02 08:01:08 -04001211 assert_success!(i_prot.read_field_end());
1212
1213 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001214 assert_eq!(
1215 read_ident_2,
1216 TFieldIdentifier {
1217 name: None,
1218 ..field_ident_2
1219 }
1220 );
Allen George8b96bfb2016-11-02 08:01:08 -04001221 assert_success!(i_prot.read_field_end());
1222
1223 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001224 assert_eq!(
1225 read_ident_3,
1226 TFieldIdentifier {
1227 name: None,
1228 ..field_ident_3
1229 }
1230 );
Allen George8b96bfb2016-11-02 08:01:08 -04001231 assert_success!(i_prot.read_field_end());
1232
1233 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001234 assert_eq!(
1235 read_ident_4,
1236 TFieldIdentifier {
1237 name: None,
1238 ..field_ident_4
1239 }
1240 );
Allen George8b96bfb2016-11-02 08:01:08 -04001241 assert_success!(i_prot.read_field_end());
1242
1243 let read_ident_5 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001244 assert_eq!(
1245 read_ident_5,
1246 TFieldIdentifier {
1247 name: None,
1248 ..field_ident_5
1249 }
1250 );
Allen George8b96bfb2016-11-02 08:01:08 -04001251 assert_success!(i_prot.read_field_end());
1252
1253 let read_ident_6 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001254 assert_eq!(
1255 read_ident_6,
1256 TFieldIdentifier {
1257 name: None,
1258 field_type: TType::Stop,
1259 id: None,
1260 }
1261 );
Allen George8b96bfb2016-11-02 08:01:08 -04001262
1263 assert_success!(i_prot.read_struct_end());
1264 }
1265
1266 #[test]
1267 fn must_write_nested_structs_0() {
1268 // last field of the containing struct is a delta
1269 // first field of the the contained struct is a delta
1270
Allen George0e22c362017-01-30 07:15:00 -05001271 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001272
1273 // start containing struct
1274 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1275
1276 // containing struct
1277 // since the delta is > 0 and < 15 it gets a delta write
1278 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
1279 assert_success!(o_prot.write_field_end());
1280
1281 // containing struct
1282 // since this delta > 0 and < 15 it gets a delta write
1283 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
1284 assert_success!(o_prot.write_field_end());
1285
1286 // start contained struct
1287 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1288
1289 // contained struct
1290 // since the delta is > 0 and < 15 it gets a delta write
1291 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 7)));
1292 assert_success!(o_prot.write_field_end());
1293
1294 // contained struct
1295 // since this delta > 15 it gets a full write
1296 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 24)));
1297 assert_success!(o_prot.write_field_end());
1298
1299 // end contained struct
1300 assert_success!(o_prot.write_field_stop());
1301 assert_success!(o_prot.write_struct_end());
1302
1303 // end containing struct
1304 assert_success!(o_prot.write_field_stop());
1305 assert_success!(o_prot.write_struct_end());
1306
Allen Georgeef7a1892018-12-16 18:01:37 -05001307 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -05001308 let expected: [u8; 7] = [
1309 0x16, /* field delta (1) | field type */
1310 0x85, /* field delta (8) | field type */
1311 0x73, /* field delta (7) | field type */
1312 0x07, /* field type */
1313 0x30, /* zig-zag varint field id */
1314 0x00, /* field stop - contained */
1315 0x00 /* field stop - containing */,
1316 ];
Allen George8b96bfb2016-11-02 08:01:08 -04001317
Allen George0e22c362017-01-30 07:15:00 -05001318 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04001319 }
1320
1321 #[test]
1322 fn must_round_trip_nested_structs_0() {
1323 // last field of the containing struct is a delta
1324 // first field of the the contained struct is a delta
1325
Allen George0e22c362017-01-30 07:15:00 -05001326 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001327
1328 // start containing struct
1329 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1330
1331 // containing struct
1332 // since the delta is > 0 and < 15 it gets a delta write
1333 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1334 assert_success!(o_prot.write_field_begin(&field_ident_1));
1335 assert_success!(o_prot.write_field_end());
1336
1337 // containing struct
1338 // since this delta > 0 and < 15 it gets a delta write
1339 let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
1340 assert_success!(o_prot.write_field_begin(&field_ident_2));
1341 assert_success!(o_prot.write_field_end());
1342
1343 // start contained struct
1344 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1345
1346 // contained struct
1347 // since the delta is > 0 and < 15 it gets a delta write
1348 let field_ident_3 = TFieldIdentifier::new("foo", TType::I08, 7);
1349 assert_success!(o_prot.write_field_begin(&field_ident_3));
1350 assert_success!(o_prot.write_field_end());
1351
1352 // contained struct
1353 // since this delta > 15 it gets a full write
1354 let field_ident_4 = TFieldIdentifier::new("foo", TType::Double, 24);
1355 assert_success!(o_prot.write_field_begin(&field_ident_4));
1356 assert_success!(o_prot.write_field_end());
1357
1358 // end contained struct
1359 assert_success!(o_prot.write_field_stop());
1360 assert_success!(o_prot.write_struct_end());
1361
1362 // end containing struct
1363 assert_success!(o_prot.write_field_stop());
1364 assert_success!(o_prot.write_struct_end());
1365
Allen George0e22c362017-01-30 07:15:00 -05001366 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04001367
1368 // read containing struct back
1369 assert_success!(i_prot.read_struct_begin());
1370
1371 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001372 assert_eq!(
1373 read_ident_1,
1374 TFieldIdentifier {
1375 name: None,
1376 ..field_ident_1
1377 }
1378 );
Allen George8b96bfb2016-11-02 08:01:08 -04001379 assert_success!(i_prot.read_field_end());
1380
1381 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001382 assert_eq!(
1383 read_ident_2,
1384 TFieldIdentifier {
1385 name: None,
1386 ..field_ident_2
1387 }
1388 );
Allen George8b96bfb2016-11-02 08:01:08 -04001389 assert_success!(i_prot.read_field_end());
1390
1391 // read contained struct back
1392 assert_success!(i_prot.read_struct_begin());
1393
1394 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001395 assert_eq!(
1396 read_ident_3,
1397 TFieldIdentifier {
1398 name: None,
1399 ..field_ident_3
1400 }
1401 );
Allen George8b96bfb2016-11-02 08:01:08 -04001402 assert_success!(i_prot.read_field_end());
1403
1404 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001405 assert_eq!(
1406 read_ident_4,
1407 TFieldIdentifier {
1408 name: None,
1409 ..field_ident_4
1410 }
1411 );
Allen George8b96bfb2016-11-02 08:01:08 -04001412 assert_success!(i_prot.read_field_end());
1413
1414 // end contained struct
1415 let read_ident_6 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001416 assert_eq!(
1417 read_ident_6,
1418 TFieldIdentifier {
1419 name: None,
1420 field_type: TType::Stop,
1421 id: None,
1422 }
1423 );
Allen George8b96bfb2016-11-02 08:01:08 -04001424 assert_success!(i_prot.read_struct_end());
1425
1426 // end containing struct
1427 let read_ident_7 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001428 assert_eq!(
1429 read_ident_7,
1430 TFieldIdentifier {
1431 name: None,
1432 field_type: TType::Stop,
1433 id: None,
1434 }
1435 );
Allen George8b96bfb2016-11-02 08:01:08 -04001436 assert_success!(i_prot.read_struct_end());
1437 }
1438
1439 #[test]
1440 fn must_write_nested_structs_1() {
1441 // last field of the containing struct is a delta
1442 // first field of the the contained struct is a full write
1443
Allen George0e22c362017-01-30 07:15:00 -05001444 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001445
1446 // start containing struct
1447 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1448
1449 // containing struct
1450 // since the delta is > 0 and < 15 it gets a delta write
1451 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
1452 assert_success!(o_prot.write_field_end());
1453
1454 // containing struct
1455 // since this delta > 0 and < 15 it gets a delta write
1456 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
1457 assert_success!(o_prot.write_field_end());
1458
1459 // start contained struct
1460 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1461
1462 // contained struct
1463 // since this delta > 15 it gets a full write
1464 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 24)));
1465 assert_success!(o_prot.write_field_end());
1466
1467 // contained struct
1468 // since the delta is > 0 and < 15 it gets a delta write
1469 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 27)));
1470 assert_success!(o_prot.write_field_end());
1471
1472 // end contained struct
1473 assert_success!(o_prot.write_field_stop());
1474 assert_success!(o_prot.write_struct_end());
1475
1476 // end containing struct
1477 assert_success!(o_prot.write_field_stop());
1478 assert_success!(o_prot.write_struct_end());
1479
Allen Georgeef7a1892018-12-16 18:01:37 -05001480 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -05001481 let expected: [u8; 7] = [
1482 0x16, /* field delta (1) | field type */
1483 0x85, /* field delta (8) | field type */
1484 0x07, /* field type */
1485 0x30, /* zig-zag varint field id */
1486 0x33, /* field delta (3) | field type */
1487 0x00, /* field stop - contained */
1488 0x00 /* field stop - containing */,
1489 ];
Allen George8b96bfb2016-11-02 08:01:08 -04001490
Allen George0e22c362017-01-30 07:15:00 -05001491 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04001492 }
1493
1494 #[test]
1495 fn must_round_trip_nested_structs_1() {
1496 // last field of the containing struct is a delta
1497 // first field of the the contained struct is a full write
1498
Allen George0e22c362017-01-30 07:15:00 -05001499 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001500
1501 // start containing struct
1502 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1503
1504 // containing struct
1505 // since the delta is > 0 and < 15 it gets a delta write
1506 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1507 assert_success!(o_prot.write_field_begin(&field_ident_1));
1508 assert_success!(o_prot.write_field_end());
1509
1510 // containing struct
1511 // since this delta > 0 and < 15 it gets a delta write
1512 let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
1513 assert_success!(o_prot.write_field_begin(&field_ident_2));
1514 assert_success!(o_prot.write_field_end());
1515
1516 // start contained struct
1517 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1518
1519 // contained struct
1520 // since this delta > 15 it gets a full write
1521 let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 24);
1522 assert_success!(o_prot.write_field_begin(&field_ident_3));
1523 assert_success!(o_prot.write_field_end());
1524
1525 // contained struct
1526 // since the delta is > 0 and < 15 it gets a delta write
1527 let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 27);
1528 assert_success!(o_prot.write_field_begin(&field_ident_4));
1529 assert_success!(o_prot.write_field_end());
1530
1531 // end contained struct
1532 assert_success!(o_prot.write_field_stop());
1533 assert_success!(o_prot.write_struct_end());
1534
1535 // end containing struct
1536 assert_success!(o_prot.write_field_stop());
1537 assert_success!(o_prot.write_struct_end());
1538
Allen George0e22c362017-01-30 07:15:00 -05001539 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04001540
1541 // read containing struct back
1542 assert_success!(i_prot.read_struct_begin());
1543
1544 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001545 assert_eq!(
1546 read_ident_1,
1547 TFieldIdentifier {
1548 name: None,
1549 ..field_ident_1
1550 }
1551 );
Allen George8b96bfb2016-11-02 08:01:08 -04001552 assert_success!(i_prot.read_field_end());
1553
1554 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001555 assert_eq!(
1556 read_ident_2,
1557 TFieldIdentifier {
1558 name: None,
1559 ..field_ident_2
1560 }
1561 );
Allen George8b96bfb2016-11-02 08:01:08 -04001562 assert_success!(i_prot.read_field_end());
1563
1564 // read contained struct back
1565 assert_success!(i_prot.read_struct_begin());
1566
1567 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001568 assert_eq!(
1569 read_ident_3,
1570 TFieldIdentifier {
1571 name: None,
1572 ..field_ident_3
1573 }
1574 );
Allen George8b96bfb2016-11-02 08:01:08 -04001575 assert_success!(i_prot.read_field_end());
1576
1577 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001578 assert_eq!(
1579 read_ident_4,
1580 TFieldIdentifier {
1581 name: None,
1582 ..field_ident_4
1583 }
1584 );
Allen George8b96bfb2016-11-02 08:01:08 -04001585 assert_success!(i_prot.read_field_end());
1586
1587 // end contained struct
1588 let read_ident_6 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001589 assert_eq!(
1590 read_ident_6,
1591 TFieldIdentifier {
1592 name: None,
1593 field_type: TType::Stop,
1594 id: None,
1595 }
1596 );
Allen George8b96bfb2016-11-02 08:01:08 -04001597 assert_success!(i_prot.read_struct_end());
1598
1599 // end containing struct
1600 let read_ident_7 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001601 assert_eq!(
1602 read_ident_7,
1603 TFieldIdentifier {
1604 name: None,
1605 field_type: TType::Stop,
1606 id: None,
1607 }
1608 );
Allen George8b96bfb2016-11-02 08:01:08 -04001609 assert_success!(i_prot.read_struct_end());
1610 }
1611
1612 #[test]
1613 fn must_write_nested_structs_2() {
1614 // last field of the containing struct is a full write
1615 // first field of the the contained struct is a delta write
1616
Allen George0e22c362017-01-30 07:15:00 -05001617 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001618
1619 // start containing struct
1620 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1621
1622 // containing struct
1623 // since the delta is > 0 and < 15 it gets a delta write
1624 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
1625 assert_success!(o_prot.write_field_end());
1626
1627 // containing struct
1628 // since this delta > 15 it gets a full write
1629 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 21)));
1630 assert_success!(o_prot.write_field_end());
1631
1632 // start contained struct
1633 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1634
1635 // contained struct
1636 // since this delta > 0 and < 15 it gets a delta write
1637 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 7)));
1638 assert_success!(o_prot.write_field_end());
1639
1640 // contained struct
1641 // since the delta is > 0 and < 15 it gets a delta write
1642 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 10)));
1643 assert_success!(o_prot.write_field_end());
1644
1645 // end contained struct
1646 assert_success!(o_prot.write_field_stop());
1647 assert_success!(o_prot.write_struct_end());
1648
1649 // end containing struct
1650 assert_success!(o_prot.write_field_stop());
1651 assert_success!(o_prot.write_struct_end());
1652
Allen Georgeef7a1892018-12-16 18:01:37 -05001653 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -05001654 let expected: [u8; 7] = [
1655 0x16, /* field delta (1) | field type */
1656 0x08, /* field type */
1657 0x2A, /* zig-zag varint field id */
1658 0x77, /* field delta(7) | field type */
1659 0x33, /* field delta (3) | field type */
1660 0x00, /* field stop - contained */
1661 0x00 /* field stop - containing */,
1662 ];
Allen George8b96bfb2016-11-02 08:01:08 -04001663
Allen George0e22c362017-01-30 07:15:00 -05001664 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04001665 }
1666
1667 #[test]
1668 fn must_round_trip_nested_structs_2() {
Allen George0e22c362017-01-30 07:15:00 -05001669 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001670
1671 // start containing struct
1672 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1673
1674 // containing struct
1675 // since the delta is > 0 and < 15 it gets a delta write
1676 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1677 assert_success!(o_prot.write_field_begin(&field_ident_1));
1678 assert_success!(o_prot.write_field_end());
1679
1680 // containing struct
1681 // since this delta > 15 it gets a full write
1682 let field_ident_2 = TFieldIdentifier::new("foo", TType::String, 21);
1683 assert_success!(o_prot.write_field_begin(&field_ident_2));
1684 assert_success!(o_prot.write_field_end());
1685
1686 // start contained struct
1687 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1688
1689 // contained struct
1690 // since this delta > 0 and < 15 it gets a delta write
1691 let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 7);
1692 assert_success!(o_prot.write_field_begin(&field_ident_3));
1693 assert_success!(o_prot.write_field_end());
1694
1695 // contained struct
1696 // since the delta is > 0 and < 15 it gets a delta write
1697 let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 10);
1698 assert_success!(o_prot.write_field_begin(&field_ident_4));
1699 assert_success!(o_prot.write_field_end());
1700
1701 // end contained struct
1702 assert_success!(o_prot.write_field_stop());
1703 assert_success!(o_prot.write_struct_end());
1704
1705 // end containing struct
1706 assert_success!(o_prot.write_field_stop());
1707 assert_success!(o_prot.write_struct_end());
1708
Allen George0e22c362017-01-30 07:15:00 -05001709 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04001710
1711 // read containing struct back
1712 assert_success!(i_prot.read_struct_begin());
1713
1714 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001715 assert_eq!(
1716 read_ident_1,
1717 TFieldIdentifier {
1718 name: None,
1719 ..field_ident_1
1720 }
1721 );
Allen George8b96bfb2016-11-02 08:01:08 -04001722 assert_success!(i_prot.read_field_end());
1723
1724 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001725 assert_eq!(
1726 read_ident_2,
1727 TFieldIdentifier {
1728 name: None,
1729 ..field_ident_2
1730 }
1731 );
Allen George8b96bfb2016-11-02 08:01:08 -04001732 assert_success!(i_prot.read_field_end());
1733
1734 // read contained struct back
1735 assert_success!(i_prot.read_struct_begin());
1736
1737 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001738 assert_eq!(
1739 read_ident_3,
1740 TFieldIdentifier {
1741 name: None,
1742 ..field_ident_3
1743 }
1744 );
Allen George8b96bfb2016-11-02 08:01:08 -04001745 assert_success!(i_prot.read_field_end());
1746
1747 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001748 assert_eq!(
1749 read_ident_4,
1750 TFieldIdentifier {
1751 name: None,
1752 ..field_ident_4
1753 }
1754 );
Allen George8b96bfb2016-11-02 08:01:08 -04001755 assert_success!(i_prot.read_field_end());
1756
1757 // end contained struct
1758 let read_ident_6 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001759 assert_eq!(
1760 read_ident_6,
1761 TFieldIdentifier {
1762 name: None,
1763 field_type: TType::Stop,
1764 id: None,
1765 }
1766 );
Allen George8b96bfb2016-11-02 08:01:08 -04001767 assert_success!(i_prot.read_struct_end());
1768
1769 // end containing struct
1770 let read_ident_7 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001771 assert_eq!(
1772 read_ident_7,
1773 TFieldIdentifier {
1774 name: None,
1775 field_type: TType::Stop,
1776 id: None,
1777 }
1778 );
Allen George8b96bfb2016-11-02 08:01:08 -04001779 assert_success!(i_prot.read_struct_end());
1780 }
1781
1782 #[test]
1783 fn must_write_nested_structs_3() {
1784 // last field of the containing struct is a full write
1785 // first field of the the contained struct is a full write
1786
Allen George0e22c362017-01-30 07:15:00 -05001787 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001788
1789 // start containing struct
1790 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1791
1792 // containing struct
1793 // since the delta is > 0 and < 15 it gets a delta write
1794 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
1795 assert_success!(o_prot.write_field_end());
1796
1797 // containing struct
1798 // since this delta > 15 it gets a full write
1799 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 21)));
1800 assert_success!(o_prot.write_field_end());
1801
1802 // start contained struct
1803 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1804
1805 // contained struct
1806 // since this delta > 15 it gets a full write
1807 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 21)));
1808 assert_success!(o_prot.write_field_end());
1809
1810 // contained struct
1811 // since the delta is > 0 and < 15 it gets a delta write
1812 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 27)));
1813 assert_success!(o_prot.write_field_end());
1814
1815 // end contained struct
1816 assert_success!(o_prot.write_field_stop());
1817 assert_success!(o_prot.write_struct_end());
1818
1819 // end containing struct
1820 assert_success!(o_prot.write_field_stop());
1821 assert_success!(o_prot.write_struct_end());
1822
Allen Georgeef7a1892018-12-16 18:01:37 -05001823 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -05001824 let expected: [u8; 8] = [
1825 0x16, /* field delta (1) | field type */
1826 0x08, /* field type */
1827 0x2A, /* zig-zag varint field id */
1828 0x07, /* field type */
1829 0x2A, /* zig-zag varint field id */
1830 0x63, /* field delta (6) | field type */
1831 0x00, /* field stop - contained */
1832 0x00 /* field stop - containing */,
1833 ];
Allen George8b96bfb2016-11-02 08:01:08 -04001834
Allen George0e22c362017-01-30 07:15:00 -05001835 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04001836 }
1837
1838 #[test]
1839 fn must_round_trip_nested_structs_3() {
1840 // last field of the containing struct is a full write
1841 // first field of the the contained struct is a full write
1842
Allen George0e22c362017-01-30 07:15:00 -05001843 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001844
1845 // start containing struct
1846 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1847
1848 // containing struct
1849 // since the delta is > 0 and < 15 it gets a delta write
1850 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1851 assert_success!(o_prot.write_field_begin(&field_ident_1));
1852 assert_success!(o_prot.write_field_end());
1853
1854 // containing struct
1855 // since this delta > 15 it gets a full write
1856 let field_ident_2 = TFieldIdentifier::new("foo", TType::String, 21);
1857 assert_success!(o_prot.write_field_begin(&field_ident_2));
1858 assert_success!(o_prot.write_field_end());
1859
1860 // start contained struct
1861 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1862
1863 // contained struct
1864 // since this delta > 15 it gets a full write
1865 let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 21);
1866 assert_success!(o_prot.write_field_begin(&field_ident_3));
1867 assert_success!(o_prot.write_field_end());
1868
1869 // contained struct
1870 // since the delta is > 0 and < 15 it gets a delta write
1871 let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 27);
1872 assert_success!(o_prot.write_field_begin(&field_ident_4));
1873 assert_success!(o_prot.write_field_end());
1874
1875 // end contained struct
1876 assert_success!(o_prot.write_field_stop());
1877 assert_success!(o_prot.write_struct_end());
1878
1879 // end containing struct
1880 assert_success!(o_prot.write_field_stop());
1881 assert_success!(o_prot.write_struct_end());
1882
Allen George0e22c362017-01-30 07:15:00 -05001883 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04001884
1885 // read containing struct back
1886 assert_success!(i_prot.read_struct_begin());
1887
1888 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001889 assert_eq!(
1890 read_ident_1,
1891 TFieldIdentifier {
1892 name: None,
1893 ..field_ident_1
1894 }
1895 );
Allen George8b96bfb2016-11-02 08:01:08 -04001896 assert_success!(i_prot.read_field_end());
1897
1898 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001899 assert_eq!(
1900 read_ident_2,
1901 TFieldIdentifier {
1902 name: None,
1903 ..field_ident_2
1904 }
1905 );
Allen George8b96bfb2016-11-02 08:01:08 -04001906 assert_success!(i_prot.read_field_end());
1907
1908 // read contained struct back
1909 assert_success!(i_prot.read_struct_begin());
1910
1911 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001912 assert_eq!(
1913 read_ident_3,
1914 TFieldIdentifier {
1915 name: None,
1916 ..field_ident_3
1917 }
1918 );
Allen George8b96bfb2016-11-02 08:01:08 -04001919 assert_success!(i_prot.read_field_end());
1920
1921 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001922 assert_eq!(
1923 read_ident_4,
1924 TFieldIdentifier {
1925 name: None,
1926 ..field_ident_4
1927 }
1928 );
Allen George8b96bfb2016-11-02 08:01:08 -04001929 assert_success!(i_prot.read_field_end());
1930
1931 // end contained struct
1932 let read_ident_6 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001933 assert_eq!(
1934 read_ident_6,
1935 TFieldIdentifier {
1936 name: None,
1937 field_type: TType::Stop,
1938 id: None,
1939 }
1940 );
Allen George8b96bfb2016-11-02 08:01:08 -04001941 assert_success!(i_prot.read_struct_end());
1942
1943 // end containing struct
1944 let read_ident_7 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001945 assert_eq!(
1946 read_ident_7,
1947 TFieldIdentifier {
1948 name: None,
1949 field_type: TType::Stop,
1950 id: None,
1951 }
1952 );
Allen George8b96bfb2016-11-02 08:01:08 -04001953 assert_success!(i_prot.read_struct_end());
1954 }
1955
1956 #[test]
1957 fn must_write_bool_field() {
Allen George0e22c362017-01-30 07:15:00 -05001958 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001959
1960 // no bytes should be written however
1961 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1962
1963 // write three fields with field ids that cannot be encoded as deltas
1964
1965 // since the delta is > 0 and < 16 it gets a delta write
1966 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
1967 assert_success!(o_prot.write_bool(true));
1968 assert_success!(o_prot.write_field_end());
1969
1970 // since this delta > 0 and < 15 it gets a delta write
1971 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 9)));
1972 assert_success!(o_prot.write_bool(false));
1973 assert_success!(o_prot.write_field_end());
1974
1975 // since this delta > 15 it gets a full write
1976 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 26)));
1977 assert_success!(o_prot.write_bool(true));
1978 assert_success!(o_prot.write_field_end());
1979
1980 // since this delta > 15 it gets a full write
1981 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 45)));
1982 assert_success!(o_prot.write_bool(false));
1983 assert_success!(o_prot.write_field_end());
1984
1985 // now, finish the struct off
1986 assert_success!(o_prot.write_field_stop());
1987 assert_success!(o_prot.write_struct_end());
1988
Allen Georgeef7a1892018-12-16 18:01:37 -05001989 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -05001990 let expected: [u8; 7] = [
1991 0x11, /* field delta (1) | true */
1992 0x82, /* field delta (8) | false */
1993 0x01, /* true */
1994 0x34, /* field id */
1995 0x02, /* false */
1996 0x5A, /* field id */
1997 0x00 /* stop field */,
1998 ];
Allen George8b96bfb2016-11-02 08:01:08 -04001999
Allen George0e22c362017-01-30 07:15:00 -05002000 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04002001 }
2002
2003 #[test]
2004 fn must_round_trip_bool_field() {
Allen George0e22c362017-01-30 07:15:00 -05002005 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002006
2007 // no bytes should be written however
2008 let struct_ident = TStructIdentifier::new("foo");
2009 assert_success!(o_prot.write_struct_begin(&struct_ident));
2010
2011 // write two fields
2012
2013 // since the delta is > 0 and < 16 it gets a delta write
2014 let field_ident_1 = TFieldIdentifier::new("foo", TType::Bool, 1);
2015 assert_success!(o_prot.write_field_begin(&field_ident_1));
2016 assert_success!(o_prot.write_bool(true));
2017 assert_success!(o_prot.write_field_end());
2018
2019 // since this delta > 0 and < 15 it gets a delta write
2020 let field_ident_2 = TFieldIdentifier::new("foo", TType::Bool, 9);
2021 assert_success!(o_prot.write_field_begin(&field_ident_2));
2022 assert_success!(o_prot.write_bool(false));
2023 assert_success!(o_prot.write_field_end());
2024
2025 // since this delta > 15 it gets a full write
2026 let field_ident_3 = TFieldIdentifier::new("foo", TType::Bool, 26);
2027 assert_success!(o_prot.write_field_begin(&field_ident_3));
2028 assert_success!(o_prot.write_bool(true));
2029 assert_success!(o_prot.write_field_end());
2030
2031 // since this delta > 15 it gets a full write
2032 let field_ident_4 = TFieldIdentifier::new("foo", TType::Bool, 45);
2033 assert_success!(o_prot.write_field_begin(&field_ident_4));
2034 assert_success!(o_prot.write_bool(false));
2035 assert_success!(o_prot.write_field_end());
2036
2037 // now, finish the struct off
2038 assert_success!(o_prot.write_field_stop());
2039 assert_success!(o_prot.write_struct_end());
2040
Allen George0e22c362017-01-30 07:15:00 -05002041 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002042
2043 // read the struct back
2044 assert_success!(i_prot.read_struct_begin());
2045
2046 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05002047 assert_eq!(
2048 read_ident_1,
2049 TFieldIdentifier {
2050 name: None,
2051 ..field_ident_1
2052 }
2053 );
Allen George8b96bfb2016-11-02 08:01:08 -04002054 let read_value_1 = assert_success!(i_prot.read_bool());
2055 assert_eq!(read_value_1, true);
2056 assert_success!(i_prot.read_field_end());
2057
2058 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05002059 assert_eq!(
2060 read_ident_2,
2061 TFieldIdentifier {
2062 name: None,
2063 ..field_ident_2
2064 }
2065 );
Allen George8b96bfb2016-11-02 08:01:08 -04002066 let read_value_2 = assert_success!(i_prot.read_bool());
2067 assert_eq!(read_value_2, false);
2068 assert_success!(i_prot.read_field_end());
2069
2070 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05002071 assert_eq!(
2072 read_ident_3,
2073 TFieldIdentifier {
2074 name: None,
2075 ..field_ident_3
2076 }
2077 );
Allen George8b96bfb2016-11-02 08:01:08 -04002078 let read_value_3 = assert_success!(i_prot.read_bool());
2079 assert_eq!(read_value_3, true);
2080 assert_success!(i_prot.read_field_end());
2081
2082 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05002083 assert_eq!(
2084 read_ident_4,
2085 TFieldIdentifier {
2086 name: None,
2087 ..field_ident_4
2088 }
2089 );
Allen George8b96bfb2016-11-02 08:01:08 -04002090 let read_value_4 = assert_success!(i_prot.read_bool());
2091 assert_eq!(read_value_4, false);
2092 assert_success!(i_prot.read_field_end());
2093
2094 let read_ident_5 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05002095 assert_eq!(
2096 read_ident_5,
2097 TFieldIdentifier {
2098 name: None,
2099 field_type: TType::Stop,
2100 id: None,
2101 }
2102 );
Allen George8b96bfb2016-11-02 08:01:08 -04002103
2104 assert_success!(i_prot.read_struct_end());
2105 }
2106
2107 #[test]
2108 #[should_panic]
2109 fn must_fail_if_write_field_end_without_writing_bool_value() {
Allen George0e22c362017-01-30 07:15:00 -05002110 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002111 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
2112 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
2113 o_prot.write_field_end().unwrap();
2114 }
2115
2116 #[test]
2117 #[should_panic]
2118 fn must_fail_if_write_stop_field_without_writing_bool_value() {
Allen George0e22c362017-01-30 07:15:00 -05002119 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002120 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
2121 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
2122 o_prot.write_field_stop().unwrap();
2123 }
2124
2125 #[test]
2126 #[should_panic]
2127 fn must_fail_if_write_struct_end_without_writing_bool_value() {
Allen George0e22c362017-01-30 07:15:00 -05002128 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002129 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
2130 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
2131 o_prot.write_struct_end().unwrap();
2132 }
2133
2134 #[test]
2135 #[should_panic]
2136 fn must_fail_if_write_struct_end_without_any_fields() {
Allen George0e22c362017-01-30 07:15:00 -05002137 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002138 o_prot.write_struct_end().unwrap();
2139 }
2140
2141 #[test]
2142 fn must_write_field_end() {
2143 assert_no_write(|o| o.write_field_end());
2144 }
2145
2146 #[test]
2147 fn must_write_small_sized_list_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002148 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002149
2150 assert_success!(o_prot.write_list_begin(&TListIdentifier::new(TType::I64, 4)));
2151
2152 let expected: [u8; 1] = [0x46 /* size | elem_type */];
2153
Allen George0e22c362017-01-30 07:15:00 -05002154 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04002155 }
2156
2157 #[test]
2158 fn must_round_trip_small_sized_list_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002159 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002160
2161 let ident = TListIdentifier::new(TType::I08, 10);
2162
2163 assert_success!(o_prot.write_list_begin(&ident));
2164
Allen George0e22c362017-01-30 07:15:00 -05002165 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002166
2167 let res = assert_success!(i_prot.read_list_begin());
2168 assert_eq!(&res, &ident);
2169 }
2170
2171 #[test]
2172 fn must_write_large_sized_list_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002173 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002174
2175 let res = o_prot.write_list_begin(&TListIdentifier::new(TType::List, 9999));
2176 assert!(res.is_ok());
2177
Allen George0e22c362017-01-30 07:15:00 -05002178 let expected: [u8; 3] = [
2179 0xF9, /* 0xF0 | elem_type */
Allen Georgeef7a1892018-12-16 18:01:37 -05002180 0x8F, 0x4E, /* size as varint */
Allen George0e22c362017-01-30 07:15:00 -05002181 ];
Allen George8b96bfb2016-11-02 08:01:08 -04002182
Allen George0e22c362017-01-30 07:15:00 -05002183 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04002184 }
2185
2186 #[test]
2187 fn must_round_trip_large_sized_list_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002188 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002189
2190 let ident = TListIdentifier::new(TType::Set, 47381);
2191
2192 assert_success!(o_prot.write_list_begin(&ident));
2193
Allen George0e22c362017-01-30 07:15:00 -05002194 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002195
2196 let res = assert_success!(i_prot.read_list_begin());
2197 assert_eq!(&res, &ident);
2198 }
2199
2200 #[test]
2201 fn must_write_list_end() {
2202 assert_no_write(|o| o.write_list_end());
2203 }
2204
2205 #[test]
2206 fn must_write_small_sized_set_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002207 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002208
2209 assert_success!(o_prot.write_set_begin(&TSetIdentifier::new(TType::Struct, 2)));
2210
2211 let expected: [u8; 1] = [0x2C /* size | elem_type */];
2212
Allen George0e22c362017-01-30 07:15:00 -05002213 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04002214 }
2215
2216 #[test]
2217 fn must_round_trip_small_sized_set_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002218 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002219
2220 let ident = TSetIdentifier::new(TType::I16, 7);
2221
2222 assert_success!(o_prot.write_set_begin(&ident));
2223
Allen George0e22c362017-01-30 07:15:00 -05002224 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002225
2226 let res = assert_success!(i_prot.read_set_begin());
2227 assert_eq!(&res, &ident);
2228 }
2229
2230 #[test]
2231 fn must_write_large_sized_set_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002232 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002233
2234 assert_success!(o_prot.write_set_begin(&TSetIdentifier::new(TType::Double, 23891)));
2235
Allen George0e22c362017-01-30 07:15:00 -05002236 let expected: [u8; 4] = [
2237 0xF7, /* 0xF0 | elem_type */
Allen Georgeef7a1892018-12-16 18:01:37 -05002238 0xD3, 0xBA, 0x01, /* size as varint */
Allen George0e22c362017-01-30 07:15:00 -05002239 ];
Allen George8b96bfb2016-11-02 08:01:08 -04002240
Allen George0e22c362017-01-30 07:15:00 -05002241 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04002242 }
2243
2244 #[test]
2245 fn must_round_trip_large_sized_set_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002246 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002247
2248 let ident = TSetIdentifier::new(TType::Map, 3928429);
2249
2250 assert_success!(o_prot.write_set_begin(&ident));
2251
Allen George0e22c362017-01-30 07:15:00 -05002252 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002253
2254 let res = assert_success!(i_prot.read_set_begin());
2255 assert_eq!(&res, &ident);
2256 }
2257
2258 #[test]
2259 fn must_write_set_end() {
2260 assert_no_write(|o| o.write_set_end());
2261 }
2262
2263 #[test]
2264 fn must_write_zero_sized_map_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002265 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002266
2267 assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::String, TType::I32, 0)));
2268
2269 let expected: [u8; 1] = [0x00]; // since size is zero we don't write anything
2270
Allen George0e22c362017-01-30 07:15:00 -05002271 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04002272 }
2273
2274 #[test]
2275 fn must_read_zero_sized_map_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002276 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002277
2278 assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Double, TType::I32, 0)));
2279
Allen George0e22c362017-01-30 07:15:00 -05002280 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002281
2282 let res = assert_success!(i_prot.read_map_begin());
Allen George0e22c362017-01-30 07:15:00 -05002283 assert_eq!(
2284 &res,
2285 &TMapIdentifier {
Allen Georgeef7a1892018-12-16 18:01:37 -05002286 key_type: None,
2287 value_type: None,
2288 size: 0,
2289 }
Allen George0e22c362017-01-30 07:15:00 -05002290 );
Allen George8b96bfb2016-11-02 08:01:08 -04002291 }
2292
2293 #[test]
2294 fn must_write_map_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002295 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002296
Allen Georgeef7a1892018-12-16 18:01:37 -05002297 assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(
2298 TType::Double,
2299 TType::String,
2300 238
2301 )));
Allen George8b96bfb2016-11-02 08:01:08 -04002302
Allen George0e22c362017-01-30 07:15:00 -05002303 let expected: [u8; 3] = [
Allen Georgeef7a1892018-12-16 18:01:37 -05002304 0xEE, 0x01, /* size as varint */
2305 0x78, /* key type | val type */
Allen George0e22c362017-01-30 07:15:00 -05002306 ];
Allen George8b96bfb2016-11-02 08:01:08 -04002307
Allen George0e22c362017-01-30 07:15:00 -05002308 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04002309 }
2310
2311 #[test]
2312 fn must_round_trip_map_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002313 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002314
2315 let ident = TMapIdentifier::new(TType::Map, TType::List, 1928349);
2316
2317 assert_success!(o_prot.write_map_begin(&ident));
2318
Allen George0e22c362017-01-30 07:15:00 -05002319 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002320
2321 let res = assert_success!(i_prot.read_map_begin());
2322 assert_eq!(&res, &ident);
2323 }
2324
2325 #[test]
2326 fn must_write_map_end() {
2327 assert_no_write(|o| o.write_map_end());
2328 }
2329
2330 #[test]
2331 fn must_write_map_with_bool_key_and_value() {
Allen George0e22c362017-01-30 07:15:00 -05002332 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002333
2334 assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Bool, TType::Bool, 1)));
2335 assert_success!(o_prot.write_bool(true));
2336 assert_success!(o_prot.write_bool(false));
2337 assert_success!(o_prot.write_map_end());
2338
Allen George0e22c362017-01-30 07:15:00 -05002339 let expected: [u8; 4] = [
2340 0x01, /* size as varint */
2341 0x11, /* key type | val type */
2342 0x01, /* key: true */
Allen Georgeef7a1892018-12-16 18:01:37 -05002343 0x02, /* val: false */
Allen George0e22c362017-01-30 07:15:00 -05002344 ];
Allen George8b96bfb2016-11-02 08:01:08 -04002345
Allen George0e22c362017-01-30 07:15:00 -05002346 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04002347 }
2348
2349 #[test]
2350 fn must_round_trip_map_with_bool_value() {
Allen George0e22c362017-01-30 07:15:00 -05002351 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002352
2353 let map_ident = TMapIdentifier::new(TType::Bool, TType::Bool, 2);
2354 assert_success!(o_prot.write_map_begin(&map_ident));
2355 assert_success!(o_prot.write_bool(true));
2356 assert_success!(o_prot.write_bool(false));
2357 assert_success!(o_prot.write_bool(false));
2358 assert_success!(o_prot.write_bool(true));
2359 assert_success!(o_prot.write_map_end());
2360
Allen George0e22c362017-01-30 07:15:00 -05002361 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002362
2363 // map header
2364 let rcvd_ident = assert_success!(i_prot.read_map_begin());
2365 assert_eq!(&rcvd_ident, &map_ident);
2366 // key 1
2367 let b = assert_success!(i_prot.read_bool());
2368 assert_eq!(b, true);
2369 // val 1
2370 let b = assert_success!(i_prot.read_bool());
2371 assert_eq!(b, false);
2372 // key 2
2373 let b = assert_success!(i_prot.read_bool());
2374 assert_eq!(b, false);
2375 // val 2
2376 let b = assert_success!(i_prot.read_bool());
2377 assert_eq!(b, true);
2378 // map end
2379 assert_success!(i_prot.read_map_end());
2380 }
2381
2382 #[test]
2383 fn must_read_map_end() {
Allen George0e22c362017-01-30 07:15:00 -05002384 let (mut i_prot, _) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002385 assert!(i_prot.read_map_end().is_ok()); // will blow up if we try to read from empty buffer
2386 }
2387
Allen Georgeef7a1892018-12-16 18:01:37 -05002388 fn test_objects() -> (
2389 TCompactInputProtocol<ReadHalf<TBufferChannel>>,
2390 TCompactOutputProtocol<WriteHalf<TBufferChannel>>,
2391 ) {
Allen George0e22c362017-01-30 07:15:00 -05002392 let mem = TBufferChannel::with_capacity(80, 80);
Allen George8b96bfb2016-11-02 08:01:08 -04002393
Allen George0e22c362017-01-30 07:15:00 -05002394 let (r_mem, w_mem) = mem.split().unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -04002395
Allen George0e22c362017-01-30 07:15:00 -05002396 let i_prot = TCompactInputProtocol::new(r_mem);
2397 let o_prot = TCompactOutputProtocol::new(w_mem);
Allen George8b96bfb2016-11-02 08:01:08 -04002398
Allen George0e22c362017-01-30 07:15:00 -05002399 (i_prot, o_prot)
Allen George8b96bfb2016-11-02 08:01:08 -04002400 }
2401
Marcin Pajkowskib34680f2019-12-02 10:29:16 +01002402 #[test]
2403 fn must_read_write_double() {
2404 let (mut i_prot, mut o_prot) = test_objects();
2405
2406 let double = 3.141592653589793238462643;
2407 o_prot.write_double(double).unwrap();
2408 copy_write_buffer_to_read_buffer!(o_prot);
2409
2410 assert_eq!(i_prot.read_double().unwrap(), double);
2411 }
2412
2413 #[test]
2414 fn must_encode_double_as_other_langs() {
2415 let (_, mut o_prot) = test_objects();
2416 let expected = [24, 45, 68, 84, 251, 33, 9, 64];
2417
2418 let double = 3.141592653589793238462643;
2419 o_prot.write_double(double).unwrap();
2420
2421 assert_eq_written_bytes!(o_prot, expected);
2422
2423 }
2424
Allen George0e22c362017-01-30 07:15:00 -05002425 fn assert_no_write<F>(mut write_fn: F)
2426 where
Allen Georgeb0d14132020-03-29 11:48:55 -04002427 F: FnMut(&mut TCompactOutputProtocol<WriteHalf<TBufferChannel>>) -> crate::Result<()>,
Allen George0e22c362017-01-30 07:15:00 -05002428 {
2429 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002430 assert!(write_fn(&mut o_prot).is_ok());
Allen George0e22c362017-01-30 07:15:00 -05002431 assert_eq!(o_prot.transport.write_bytes().len(), 0);
Allen George8b96bfb2016-11-02 08:01:08 -04002432 }
2433}