blob: dfe11f8523960a2c1a05af030d385d2ceacb209e [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
18use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
19use integer_encoding::{VarIntReader, VarIntWriter};
Allen George8b96bfb2016-11-02 08:01:08 -040020use std::convert::From;
Allen George8b96bfb2016-11-02 08:01:08 -040021use try_from::TryFrom;
22
Allen George0e22c362017-01-30 07:15:00 -050023use transport::{TReadTransport, TWriteTransport};
24use super::{TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier,
25 TMapIdentifier, TMessageIdentifier, TMessageType};
Allen George8b96bfb2016-11-02 08:01:08 -040026use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
27
28const COMPACT_PROTOCOL_ID: u8 = 0x82;
29const COMPACT_VERSION: u8 = 0x01;
30const COMPACT_VERSION_MASK: u8 = 0x1F;
31
32/// Read messages encoded in the Thrift compact protocol.
33///
34/// # Examples
35///
36/// Create and use a `TCompactInputProtocol`.
37///
38/// ```no_run
Allen George8b96bfb2016-11-02 08:01:08 -040039/// use thrift::protocol::{TCompactInputProtocol, TInputProtocol};
Allen George0e22c362017-01-30 07:15:00 -050040/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -040041///
Allen George0e22c362017-01-30 07:15:00 -050042/// let mut channel = TTcpChannel::new();
43/// channel.open("localhost:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -040044///
Allen George0e22c362017-01-30 07:15:00 -050045/// let mut protocol = TCompactInputProtocol::new(channel);
Allen George8b96bfb2016-11-02 08:01:08 -040046///
Allen George0e22c362017-01-30 07:15:00 -050047/// let recvd_bool = protocol.read_bool().unwrap();
48/// let recvd_string = protocol.read_string().unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -040049/// ```
Allen George0e22c362017-01-30 07:15:00 -050050#[derive(Debug)]
51pub struct TCompactInputProtocol<T>
52where
53 T: TReadTransport,
54{
Allen George8b96bfb2016-11-02 08:01:08 -040055 // Identifier of the last field deserialized for a struct.
56 last_read_field_id: i16,
57 // Stack of the last read field ids (a new entry is added each time a nested struct is read).
58 read_field_id_stack: Vec<i16>,
59 // Boolean value for a field.
60 // Saved because boolean fields and their value are encoded in a single byte,
61 // and reading the field only occurs after the field id is read.
62 pending_read_bool_value: Option<bool>,
63 // Underlying transport used for byte-level operations.
Allen George0e22c362017-01-30 07:15:00 -050064 transport: T,
Allen George8b96bfb2016-11-02 08:01:08 -040065}
66
Allen George0e22c362017-01-30 07:15:00 -050067impl<T> TCompactInputProtocol<T>
68where
69 T: TReadTransport,
70{
Allen George8b96bfb2016-11-02 08:01:08 -040071 /// Create a `TCompactInputProtocol` that reads bytes from `transport`.
Allen George0e22c362017-01-30 07:15:00 -050072 pub fn new(transport: T) -> TCompactInputProtocol<T> {
Allen George8b96bfb2016-11-02 08:01:08 -040073 TCompactInputProtocol {
74 last_read_field_id: 0,
75 read_field_id_stack: Vec::new(),
76 pending_read_bool_value: None,
77 transport: transport,
78 }
79 }
80
81 fn read_list_set_begin(&mut self) -> ::Result<(TType, i32)> {
82 let header = self.read_byte()?;
83 let element_type = collection_u8_to_type(header & 0x0F)?;
84
85 let element_count;
86 let possible_element_count = (header & 0xF0) >> 4;
87 if possible_element_count != 15 {
88 // high bits set high if count and type encoded separately
89 element_count = possible_element_count as i32;
90 } else {
Allen George0e22c362017-01-30 07:15:00 -050091 element_count = self.transport.read_varint::<u32>()? as i32;
Allen George8b96bfb2016-11-02 08:01:08 -040092 }
93
94 Ok((element_type, element_count))
95 }
96}
97
Allen George0e22c362017-01-30 07:15:00 -050098impl<T> TInputProtocol for TCompactInputProtocol<T>
99where
100 T: TReadTransport,
101{
Allen George8b96bfb2016-11-02 08:01:08 -0400102 fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
103 let compact_id = self.read_byte()?;
104 if compact_id != COMPACT_PROTOCOL_ID {
Allen George0e22c362017-01-30 07:15:00 -0500105 Err(
106 ::Error::Protocol(
107 ::ProtocolError {
108 kind: ::ProtocolErrorKind::BadVersion,
109 message: format!("invalid compact protocol header {:?}", compact_id),
110 },
111 ),
112 )
Allen George8b96bfb2016-11-02 08:01:08 -0400113 } else {
114 Ok(())
115 }?;
116
117 let type_and_byte = self.read_byte()?;
118 let received_version = type_and_byte & COMPACT_VERSION_MASK;
119 if received_version != COMPACT_VERSION {
Allen George0e22c362017-01-30 07:15:00 -0500120 Err(
121 ::Error::Protocol(
122 ::ProtocolError {
123 kind: ::ProtocolErrorKind::BadVersion,
124 message: format!(
125 "cannot process compact protocol version {:?}",
126 received_version
127 ),
128 },
129 ),
130 )
Allen George8b96bfb2016-11-02 08:01:08 -0400131 } else {
132 Ok(())
133 }?;
134
135 // NOTE: unsigned right shift will pad with 0s
136 let message_type: TMessageType = TMessageType::try_from(type_and_byte >> 5)?;
137 let sequence_number = self.read_i32()?;
138 let service_call_name = self.read_string()?;
139
140 self.last_read_field_id = 0;
141
Allen George0e22c362017-01-30 07:15:00 -0500142 Ok(TMessageIdentifier::new(service_call_name, message_type, sequence_number),)
Allen George8b96bfb2016-11-02 08:01:08 -0400143 }
144
145 fn read_message_end(&mut self) -> ::Result<()> {
146 Ok(())
147 }
148
149 fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
150 self.read_field_id_stack.push(self.last_read_field_id);
151 self.last_read_field_id = 0;
152 Ok(None)
153 }
154
155 fn read_struct_end(&mut self) -> ::Result<()> {
156 self.last_read_field_id = self.read_field_id_stack
157 .pop()
158 .expect("should have previous field ids");
159 Ok(())
160 }
161
162 fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
163 // we can read at least one byte, which is:
164 // - the type
165 // - the field delta and the type
166 let field_type = self.read_byte()?;
167 let field_delta = (field_type & 0xF0) >> 4;
168 let field_type = match field_type & 0x0F {
169 0x01 => {
170 self.pending_read_bool_value = Some(true);
171 Ok(TType::Bool)
172 }
173 0x02 => {
174 self.pending_read_bool_value = Some(false);
175 Ok(TType::Bool)
176 }
177 ttu8 => u8_to_type(ttu8),
178 }?;
179
180 match field_type {
181 TType::Stop => {
Allen George0e22c362017-01-30 07:15:00 -0500182 Ok(
183 TFieldIdentifier::new::<Option<String>, String, Option<i16>>(
184 None,
185 TType::Stop,
186 None,
187 ),
188 )
Allen George8b96bfb2016-11-02 08:01:08 -0400189 }
190 _ => {
191 if field_delta != 0 {
192 self.last_read_field_id += field_delta as i16;
193 } else {
194 self.last_read_field_id = self.read_i16()?;
195 };
196
Allen George0e22c362017-01-30 07:15:00 -0500197 Ok(
198 TFieldIdentifier {
199 name: None,
200 field_type: field_type,
201 id: Some(self.last_read_field_id),
202 },
203 )
Allen George8b96bfb2016-11-02 08:01:08 -0400204 }
205 }
206 }
207
208 fn read_field_end(&mut self) -> ::Result<()> {
209 Ok(())
210 }
211
212 fn read_bool(&mut self) -> ::Result<bool> {
213 match self.pending_read_bool_value.take() {
214 Some(b) => Ok(b),
215 None => {
216 let b = self.read_byte()?;
217 match b {
218 0x01 => Ok(true),
219 0x02 => Ok(false),
220 unkn => {
Allen George0e22c362017-01-30 07:15:00 -0500221 Err(
222 ::Error::Protocol(
223 ::ProtocolError {
224 kind: ::ProtocolErrorKind::InvalidData,
225 message: format!("cannot convert {} into bool", unkn),
226 },
227 ),
228 )
Allen George8b96bfb2016-11-02 08:01:08 -0400229 }
230 }
231 }
232 }
233 }
234
235 fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
Allen George0e22c362017-01-30 07:15:00 -0500236 let len = self.transport.read_varint::<u32>()?;
Allen George8b96bfb2016-11-02 08:01:08 -0400237 let mut buf = vec![0u8; len as usize];
Allen George0e22c362017-01-30 07:15:00 -0500238 self.transport
239 .read_exact(&mut buf)
240 .map_err(From::from)
241 .map(|_| buf)
Allen George8b96bfb2016-11-02 08:01:08 -0400242 }
243
244 fn read_i8(&mut self) -> ::Result<i8> {
245 self.read_byte().map(|i| i as i8)
246 }
247
248 fn read_i16(&mut self) -> ::Result<i16> {
Allen George0e22c362017-01-30 07:15:00 -0500249 self.transport.read_varint::<i16>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400250 }
251
252 fn read_i32(&mut self) -> ::Result<i32> {
Allen George0e22c362017-01-30 07:15:00 -0500253 self.transport.read_varint::<i32>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400254 }
255
256 fn read_i64(&mut self) -> ::Result<i64> {
Allen George0e22c362017-01-30 07:15:00 -0500257 self.transport.read_varint::<i64>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400258 }
259
260 fn read_double(&mut self) -> ::Result<f64> {
Allen George0e22c362017-01-30 07:15:00 -0500261 self.transport
262 .read_f64::<BigEndian>()
263 .map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400264 }
265
266 fn read_string(&mut self) -> ::Result<String> {
267 let bytes = self.read_bytes()?;
268 String::from_utf8(bytes).map_err(From::from)
269 }
270
271 fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
272 let (element_type, element_count) = self.read_list_set_begin()?;
273 Ok(TListIdentifier::new(element_type, element_count))
274 }
275
276 fn read_list_end(&mut self) -> ::Result<()> {
277 Ok(())
278 }
279
280 fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
281 let (element_type, element_count) = self.read_list_set_begin()?;
282 Ok(TSetIdentifier::new(element_type, element_count))
283 }
284
285 fn read_set_end(&mut self) -> ::Result<()> {
286 Ok(())
287 }
288
289 fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
Allen George0e22c362017-01-30 07:15:00 -0500290 let element_count = self.transport.read_varint::<u32>()? as i32;
Allen George8b96bfb2016-11-02 08:01:08 -0400291 if element_count == 0 {
292 Ok(TMapIdentifier::new(None, None, 0))
293 } else {
294 let type_header = self.read_byte()?;
295 let key_type = collection_u8_to_type((type_header & 0xF0) >> 4)?;
296 let val_type = collection_u8_to_type(type_header & 0x0F)?;
297 Ok(TMapIdentifier::new(key_type, val_type, element_count))
298 }
299 }
300
301 fn read_map_end(&mut self) -> ::Result<()> {
302 Ok(())
303 }
304
305 // utility
306 //
307
308 fn read_byte(&mut self) -> ::Result<u8> {
309 let mut buf = [0u8; 1];
Allen George0e22c362017-01-30 07:15:00 -0500310 self.transport
311 .read_exact(&mut buf)
312 .map_err(From::from)
313 .map(|_| buf[0])
Allen George8b96bfb2016-11-02 08:01:08 -0400314 }
315}
316
317/// Factory for creating instances of `TCompactInputProtocol`.
318#[derive(Default)]
319pub struct TCompactInputProtocolFactory;
320
321impl TCompactInputProtocolFactory {
322 /// Create a `TCompactInputProtocolFactory`.
323 pub fn new() -> TCompactInputProtocolFactory {
324 TCompactInputProtocolFactory {}
325 }
326}
327
328impl TInputProtocolFactory for TCompactInputProtocolFactory {
Allen George0e22c362017-01-30 07:15:00 -0500329 fn create(&self, transport: Box<TReadTransport + Send>) -> Box<TInputProtocol + Send> {
330 Box::new(TCompactInputProtocol::new(transport))
Allen George8b96bfb2016-11-02 08:01:08 -0400331 }
332}
333
334/// Write messages using the Thrift compact protocol.
335///
336/// # Examples
337///
338/// Create and use a `TCompactOutputProtocol`.
339///
340/// ```no_run
Allen George8b96bfb2016-11-02 08:01:08 -0400341/// use thrift::protocol::{TCompactOutputProtocol, TOutputProtocol};
Allen George0e22c362017-01-30 07:15:00 -0500342/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -0400343///
Allen George0e22c362017-01-30 07:15:00 -0500344/// let mut channel = TTcpChannel::new();
345/// channel.open("localhost:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400346///
Allen George0e22c362017-01-30 07:15:00 -0500347/// let mut protocol = TCompactOutputProtocol::new(channel);
Allen George8b96bfb2016-11-02 08:01:08 -0400348///
Allen George0e22c362017-01-30 07:15:00 -0500349/// protocol.write_bool(true).unwrap();
350/// protocol.write_string("test_string").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400351/// ```
Allen George0e22c362017-01-30 07:15:00 -0500352#[derive(Debug)]
353pub struct TCompactOutputProtocol<T>
354where
355 T: TWriteTransport,
356{
Allen George8b96bfb2016-11-02 08:01:08 -0400357 // Identifier of the last field serialized for a struct.
358 last_write_field_id: i16,
Allen George0e22c362017-01-30 07:15:00 -0500359 // Stack of the last written field ids (new entry added each time a nested struct is written).
Allen George8b96bfb2016-11-02 08:01:08 -0400360 write_field_id_stack: Vec<i16>,
361 // Field identifier of the boolean field to be written.
362 // Saved because boolean fields and their value are encoded in a single byte
363 pending_write_bool_field_identifier: Option<TFieldIdentifier>,
364 // Underlying transport used for byte-level operations.
Allen George0e22c362017-01-30 07:15:00 -0500365 transport: T,
Allen George8b96bfb2016-11-02 08:01:08 -0400366}
367
Allen George0e22c362017-01-30 07:15:00 -0500368impl<T> TCompactOutputProtocol<T>
369where
370 T: TWriteTransport,
371{
Allen George8b96bfb2016-11-02 08:01:08 -0400372 /// Create a `TCompactOutputProtocol` that writes bytes to `transport`.
Allen George0e22c362017-01-30 07:15:00 -0500373 pub fn new(transport: T) -> TCompactOutputProtocol<T> {
Allen George8b96bfb2016-11-02 08:01:08 -0400374 TCompactOutputProtocol {
375 last_write_field_id: 0,
376 write_field_id_stack: Vec::new(),
377 pending_write_bool_field_identifier: None,
378 transport: transport,
379 }
380 }
381
382 // FIXME: field_type as unconstrained u8 is bad
383 fn write_field_header(&mut self, field_type: u8, field_id: i16) -> ::Result<()> {
384 let field_delta = field_id - self.last_write_field_id;
385 if field_delta > 0 && field_delta < 15 {
386 self.write_byte(((field_delta as u8) << 4) | field_type)?;
387 } else {
388 self.write_byte(field_type)?;
389 self.write_i16(field_id)?;
390 }
391 self.last_write_field_id = field_id;
392 Ok(())
393 }
394
395 fn write_list_set_begin(&mut self, element_type: TType, element_count: i32) -> ::Result<()> {
396 let elem_identifier = collection_type_to_u8(element_type);
397 if element_count <= 14 {
398 let header = (element_count as u8) << 4 | elem_identifier;
399 self.write_byte(header)
400 } else {
401 let header = 0xF0 | elem_identifier;
402 self.write_byte(header)?;
403 self.transport
Allen George8b96bfb2016-11-02 08:01:08 -0400404 .write_varint(element_count as u32)
405 .map_err(From::from)
406 .map(|_| ())
407 }
408 }
409
410 fn assert_no_pending_bool_write(&self) {
411 if let Some(ref f) = self.pending_write_bool_field_identifier {
412 panic!("pending bool field {:?} not written", f)
413 }
414 }
415}
416
Allen George0e22c362017-01-30 07:15:00 -0500417impl<T> TOutputProtocol for TCompactOutputProtocol<T>
418where
419 T: TWriteTransport,
420{
Allen George8b96bfb2016-11-02 08:01:08 -0400421 fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
422 self.write_byte(COMPACT_PROTOCOL_ID)?;
423 self.write_byte((u8::from(identifier.message_type) << 5) | COMPACT_VERSION)?;
424 self.write_i32(identifier.sequence_number)?;
425 self.write_string(&identifier.name)?;
426 Ok(())
427 }
428
429 fn write_message_end(&mut self) -> ::Result<()> {
430 self.assert_no_pending_bool_write();
431 Ok(())
432 }
433
434 fn write_struct_begin(&mut self, _: &TStructIdentifier) -> ::Result<()> {
435 self.write_field_id_stack.push(self.last_write_field_id);
436 self.last_write_field_id = 0;
437 Ok(())
438 }
439
440 fn write_struct_end(&mut self) -> ::Result<()> {
441 self.assert_no_pending_bool_write();
Allen George0e22c362017-01-30 07:15:00 -0500442 self.last_write_field_id = self.write_field_id_stack
443 .pop()
444 .expect("should have previous field ids");
Allen George8b96bfb2016-11-02 08:01:08 -0400445 Ok(())
446 }
447
448 fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()> {
449 match identifier.field_type {
450 TType::Bool => {
451 if self.pending_write_bool_field_identifier.is_some() {
Allen George0e22c362017-01-30 07:15:00 -0500452 panic!(
453 "should not have a pending bool while writing another bool with id: \
Allen George8b96bfb2016-11-02 08:01:08 -0400454 {:?}",
Allen George0e22c362017-01-30 07:15:00 -0500455 identifier
456 )
Allen George8b96bfb2016-11-02 08:01:08 -0400457 }
458 self.pending_write_bool_field_identifier = Some(identifier.clone());
459 Ok(())
460 }
461 _ => {
462 let field_type = type_to_u8(identifier.field_type);
Allen George0e22c362017-01-30 07:15:00 -0500463 let field_id = identifier
464 .id
465 .expect("non-stop field should have field id");
Allen George8b96bfb2016-11-02 08:01:08 -0400466 self.write_field_header(field_type, field_id)
467 }
468 }
469 }
470
471 fn write_field_end(&mut self) -> ::Result<()> {
472 self.assert_no_pending_bool_write();
473 Ok(())
474 }
475
476 fn write_field_stop(&mut self) -> ::Result<()> {
477 self.assert_no_pending_bool_write();
478 self.write_byte(type_to_u8(TType::Stop))
479 }
480
481 fn write_bool(&mut self, b: bool) -> ::Result<()> {
482 match self.pending_write_bool_field_identifier.take() {
483 Some(pending) => {
484 let field_id = pending.id.expect("bool field should have a field id");
485 let field_type_as_u8 = if b { 0x01 } else { 0x02 };
486 self.write_field_header(field_type_as_u8, field_id)
487 }
488 None => {
489 if b {
490 self.write_byte(0x01)
491 } else {
492 self.write_byte(0x02)
493 }
494 }
495 }
496 }
497
498 fn write_bytes(&mut self, b: &[u8]) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500499 self.transport.write_varint(b.len() as u32)?;
500 self.transport.write_all(b).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400501 }
502
503 fn write_i8(&mut self, i: i8) -> ::Result<()> {
504 self.write_byte(i as u8)
505 }
506
507 fn write_i16(&mut self, i: i16) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500508 self.transport
509 .write_varint(i)
510 .map_err(From::from)
511 .map(|_| ())
Allen George8b96bfb2016-11-02 08:01:08 -0400512 }
513
514 fn write_i32(&mut self, i: i32) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500515 self.transport
516 .write_varint(i)
517 .map_err(From::from)
518 .map(|_| ())
Allen George8b96bfb2016-11-02 08:01:08 -0400519 }
520
521 fn write_i64(&mut self, i: i64) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500522 self.transport
523 .write_varint(i)
524 .map_err(From::from)
525 .map(|_| ())
Allen George8b96bfb2016-11-02 08:01:08 -0400526 }
527
528 fn write_double(&mut self, d: f64) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500529 self.transport
530 .write_f64::<BigEndian>(d)
531 .map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400532 }
533
534 fn write_string(&mut self, s: &str) -> ::Result<()> {
535 self.write_bytes(s.as_bytes())
536 }
537
538 fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()> {
539 self.write_list_set_begin(identifier.element_type, identifier.size)
540 }
541
542 fn write_list_end(&mut self) -> ::Result<()> {
543 Ok(())
544 }
545
546 fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()> {
547 self.write_list_set_begin(identifier.element_type, identifier.size)
548 }
549
550 fn write_set_end(&mut self) -> ::Result<()> {
551 Ok(())
552 }
553
554 fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()> {
555 if identifier.size == 0 {
556 self.write_byte(0)
557 } else {
Allen George0e22c362017-01-30 07:15:00 -0500558 self.transport.write_varint(identifier.size as u32)?;
Allen George8b96bfb2016-11-02 08:01:08 -0400559
Allen George0e22c362017-01-30 07:15:00 -0500560 let key_type = identifier
561 .key_type
Allen George8b96bfb2016-11-02 08:01:08 -0400562 .expect("map identifier to write should contain key type");
563 let key_type_byte = collection_type_to_u8(key_type) << 4;
564
Allen George0e22c362017-01-30 07:15:00 -0500565 let val_type = identifier
566 .value_type
Allen George8b96bfb2016-11-02 08:01:08 -0400567 .expect("map identifier to write should contain value type");
568 let val_type_byte = collection_type_to_u8(val_type);
569
570 let map_type_header = key_type_byte | val_type_byte;
571 self.write_byte(map_type_header)
572 }
573 }
574
575 fn write_map_end(&mut self) -> ::Result<()> {
576 Ok(())
577 }
578
579 fn flush(&mut self) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500580 self.transport.flush().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400581 }
582
583 // utility
584 //
585
586 fn write_byte(&mut self, b: u8) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500587 self.transport
588 .write(&[b])
589 .map_err(From::from)
590 .map(|_| ())
Allen George8b96bfb2016-11-02 08:01:08 -0400591 }
592}
593
594/// Factory for creating instances of `TCompactOutputProtocol`.
595#[derive(Default)]
596pub struct TCompactOutputProtocolFactory;
597
598impl TCompactOutputProtocolFactory {
599 /// Create a `TCompactOutputProtocolFactory`.
600 pub fn new() -> TCompactOutputProtocolFactory {
601 TCompactOutputProtocolFactory {}
602 }
603}
604
605impl TOutputProtocolFactory for TCompactOutputProtocolFactory {
Allen George0e22c362017-01-30 07:15:00 -0500606 fn create(&self, transport: Box<TWriteTransport + Send>) -> Box<TOutputProtocol + Send> {
607 Box::new(TCompactOutputProtocol::new(transport))
Allen George8b96bfb2016-11-02 08:01:08 -0400608 }
609}
610
611fn collection_type_to_u8(field_type: TType) -> u8 {
612 match field_type {
613 TType::Bool => 0x01,
614 f => type_to_u8(f),
615 }
616}
617
618fn type_to_u8(field_type: TType) -> u8 {
619 match field_type {
620 TType::Stop => 0x00,
621 TType::I08 => 0x03, // equivalent to TType::Byte
622 TType::I16 => 0x04,
623 TType::I32 => 0x05,
624 TType::I64 => 0x06,
625 TType::Double => 0x07,
626 TType::String => 0x08,
627 TType::List => 0x09,
628 TType::Set => 0x0A,
629 TType::Map => 0x0B,
630 TType::Struct => 0x0C,
631 _ => panic!(format!("should not have attempted to convert {} to u8", field_type)),
632 }
633}
634
635fn collection_u8_to_type(b: u8) -> ::Result<TType> {
636 match b {
637 0x01 => Ok(TType::Bool),
638 o => u8_to_type(o),
639 }
640}
641
642fn u8_to_type(b: u8) -> ::Result<TType> {
643 match b {
644 0x00 => Ok(TType::Stop),
645 0x03 => Ok(TType::I08), // equivalent to TType::Byte
646 0x04 => Ok(TType::I16),
647 0x05 => Ok(TType::I32),
648 0x06 => Ok(TType::I64),
649 0x07 => Ok(TType::Double),
650 0x08 => Ok(TType::String),
651 0x09 => Ok(TType::List),
652 0x0A => Ok(TType::Set),
653 0x0B => Ok(TType::Map),
654 0x0C => Ok(TType::Struct),
655 unkn => {
Allen George0e22c362017-01-30 07:15:00 -0500656 Err(
657 ::Error::Protocol(
658 ::ProtocolError {
659 kind: ::ProtocolErrorKind::InvalidData,
660 message: format!("cannot convert {} into TType", unkn),
661 },
662 ),
663 )
Allen George8b96bfb2016-11-02 08:01:08 -0400664 }
665 }
666}
667
668#[cfg(test)]
669mod tests {
670
Allen George0e22c362017-01-30 07:15:00 -0500671 use protocol::{TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier,
672 TMessageIdentifier, TMessageType, TOutputProtocol, TSetIdentifier,
673 TStructIdentifier, TType};
674 use transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
Allen George8b96bfb2016-11-02 08:01:08 -0400675
676 use super::*;
677
678 #[test]
679 fn must_write_message_begin_0() {
Allen George0e22c362017-01-30 07:15:00 -0500680 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400681
682 assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new("foo", TMessageType::Call, 431)));
683
Allen George0e22c362017-01-30 07:15:00 -0500684 let expected: [u8; 8] = [
685 0x82, /* protocol ID */
686 0x21, /* message type | protocol version */
687 0xDE,
688 0x06, /* zig-zag varint sequence number */
689 0x03, /* message-name length */
690 0x66,
691 0x6F,
692 0x6F /* "foo" */,
693 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400694
Allen George0e22c362017-01-30 07:15:00 -0500695 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400696 }
697
698 #[test]
699 fn must_write_message_begin_1() {
Allen George0e22c362017-01-30 07:15:00 -0500700 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400701
Allen George0e22c362017-01-30 07:15:00 -0500702 assert_success!(
703 o_prot.write_message_begin(&TMessageIdentifier::new("bar", TMessageType::Reply, 991828))
704 );
Allen George8b96bfb2016-11-02 08:01:08 -0400705
Allen George0e22c362017-01-30 07:15:00 -0500706 let expected: [u8; 9] = [
707 0x82, /* protocol ID */
708 0x41, /* message type | protocol version */
709 0xA8,
710 0x89,
711 0x79, /* zig-zag varint sequence number */
712 0x03, /* message-name length */
713 0x62,
714 0x61,
715 0x72 /* "bar" */,
716 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400717
Allen George0e22c362017-01-30 07:15:00 -0500718 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400719 }
720
721 #[test]
722 fn must_round_trip_message_begin() {
Allen George0e22c362017-01-30 07:15:00 -0500723 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400724
725 let ident = TMessageIdentifier::new("service_call", TMessageType::Call, 1283948);
726
727 assert_success!(o_prot.write_message_begin(&ident));
728
Allen George0e22c362017-01-30 07:15:00 -0500729 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400730
731 let res = assert_success!(i_prot.read_message_begin());
732 assert_eq!(&res, &ident);
733 }
734
735 #[test]
736 fn must_write_message_end() {
737 assert_no_write(|o| o.write_message_end());
738 }
739
740 // NOTE: structs and fields are tested together
741 //
742
743 #[test]
744 fn must_write_struct_with_delta_fields() {
Allen George0e22c362017-01-30 07:15:00 -0500745 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400746
747 // no bytes should be written however
748 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
749
750 // write three fields with tiny field ids
751 // since they're small the field ids will be encoded as deltas
752
753 // since this is the first field (and it's zero) it gets the full varint write
754 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 0)));
755 assert_success!(o_prot.write_field_end());
756
757 // since this delta > 0 and < 15 it can be encoded as a delta
758 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I16, 4)));
759 assert_success!(o_prot.write_field_end());
760
761 // since this delta > 0 and < 15 it can be encoded as a delta
762 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::List, 9)));
763 assert_success!(o_prot.write_field_end());
764
765 // now, finish the struct off
766 assert_success!(o_prot.write_field_stop());
767 assert_success!(o_prot.write_struct_end());
768
Allen George0e22c362017-01-30 07:15:00 -0500769 let expected: [u8; 5] = [
770 0x03, /* field type */
771 0x00, /* first field id */
772 0x44, /* field delta (4) | field type */
773 0x59, /* field delta (5) | field type */
774 0x00 /* field stop */,
775 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400776
Allen George0e22c362017-01-30 07:15:00 -0500777 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400778 }
779
780 #[test]
781 fn must_round_trip_struct_with_delta_fields() {
Allen George0e22c362017-01-30 07:15:00 -0500782 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400783
784 // no bytes should be written however
785 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
786
787 // write three fields with tiny field ids
788 // since they're small the field ids will be encoded as deltas
789
790 // since this is the first field (and it's zero) it gets the full varint write
791 let field_ident_1 = TFieldIdentifier::new("foo", TType::I08, 0);
792 assert_success!(o_prot.write_field_begin(&field_ident_1));
793 assert_success!(o_prot.write_field_end());
794
795 // since this delta > 0 and < 15 it can be encoded as a delta
796 let field_ident_2 = TFieldIdentifier::new("foo", TType::I16, 4);
797 assert_success!(o_prot.write_field_begin(&field_ident_2));
798 assert_success!(o_prot.write_field_end());
799
800 // since this delta > 0 and < 15 it can be encoded as a delta
801 let field_ident_3 = TFieldIdentifier::new("foo", TType::List, 9);
802 assert_success!(o_prot.write_field_begin(&field_ident_3));
803 assert_success!(o_prot.write_field_end());
804
805 // now, finish the struct off
806 assert_success!(o_prot.write_field_stop());
807 assert_success!(o_prot.write_struct_end());
808
Allen George0e22c362017-01-30 07:15:00 -0500809 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400810
811 // read the struct back
812 assert_success!(i_prot.read_struct_begin());
813
814 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500815 assert_eq!(
816 read_ident_1,
817 TFieldIdentifier {
818 name: None,
819 ..field_ident_1
820 }
821 );
Allen George8b96bfb2016-11-02 08:01:08 -0400822 assert_success!(i_prot.read_field_end());
823
824 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500825 assert_eq!(
826 read_ident_2,
827 TFieldIdentifier {
828 name: None,
829 ..field_ident_2
830 }
831 );
Allen George8b96bfb2016-11-02 08:01:08 -0400832 assert_success!(i_prot.read_field_end());
833
834 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500835 assert_eq!(
836 read_ident_3,
837 TFieldIdentifier {
838 name: None,
839 ..field_ident_3
840 }
841 );
Allen George8b96bfb2016-11-02 08:01:08 -0400842 assert_success!(i_prot.read_field_end());
843
844 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500845 assert_eq!(
846 read_ident_4,
847 TFieldIdentifier {
848 name: None,
849 field_type: TType::Stop,
850 id: None,
851 }
852 );
Allen George8b96bfb2016-11-02 08:01:08 -0400853
854 assert_success!(i_prot.read_struct_end());
855 }
856
857 #[test]
858 fn must_write_struct_with_non_zero_initial_field_and_delta_fields() {
Allen George0e22c362017-01-30 07:15:00 -0500859 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400860
861 // no bytes should be written however
862 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
863
864 // write three fields with tiny field ids
865 // since they're small the field ids will be encoded as deltas
866
867 // gets a delta write
868 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 1)));
869 assert_success!(o_prot.write_field_end());
870
871 // since this delta > 0 and < 15 it can be encoded as a delta
872 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2)));
873 assert_success!(o_prot.write_field_end());
874
875 // since this delta > 0 and < 15 it can be encoded as a delta
876 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 6)));
877 assert_success!(o_prot.write_field_end());
878
879 // now, finish the struct off
880 assert_success!(o_prot.write_field_stop());
881 assert_success!(o_prot.write_struct_end());
882
Allen George0e22c362017-01-30 07:15:00 -0500883 let expected: [u8; 4] = [
884 0x15, /* field delta (1) | field type */
885 0x1A, /* field delta (1) | field type */
886 0x48, /* field delta (4) | field type */
887 0x00 /* field stop */,
888 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400889
Allen George0e22c362017-01-30 07:15:00 -0500890 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400891 }
892
893 #[test]
894 fn must_round_trip_struct_with_non_zero_initial_field_and_delta_fields() {
Allen George0e22c362017-01-30 07:15:00 -0500895 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400896
897 // no bytes should be written however
898 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
899
900 // write three fields with tiny field ids
901 // since they're small the field ids will be encoded as deltas
902
903 // gets a delta write
904 let field_ident_1 = TFieldIdentifier::new("foo", TType::I32, 1);
905 assert_success!(o_prot.write_field_begin(&field_ident_1));
906 assert_success!(o_prot.write_field_end());
907
908 // since this delta > 0 and < 15 it can be encoded as a delta
909 let field_ident_2 = TFieldIdentifier::new("foo", TType::Set, 2);
910 assert_success!(o_prot.write_field_begin(&field_ident_2));
911 assert_success!(o_prot.write_field_end());
912
913 // since this delta > 0 and < 15 it can be encoded as a delta
914 let field_ident_3 = TFieldIdentifier::new("foo", TType::String, 6);
915 assert_success!(o_prot.write_field_begin(&field_ident_3));
916 assert_success!(o_prot.write_field_end());
917
918 // now, finish the struct off
919 assert_success!(o_prot.write_field_stop());
920 assert_success!(o_prot.write_struct_end());
921
Allen George0e22c362017-01-30 07:15:00 -0500922 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400923
924 // read the struct back
925 assert_success!(i_prot.read_struct_begin());
926
927 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500928 assert_eq!(
929 read_ident_1,
930 TFieldIdentifier {
931 name: None,
932 ..field_ident_1
933 }
934 );
Allen George8b96bfb2016-11-02 08:01:08 -0400935 assert_success!(i_prot.read_field_end());
936
937 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500938 assert_eq!(
939 read_ident_2,
940 TFieldIdentifier {
941 name: None,
942 ..field_ident_2
943 }
944 );
Allen George8b96bfb2016-11-02 08:01:08 -0400945 assert_success!(i_prot.read_field_end());
946
947 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500948 assert_eq!(
949 read_ident_3,
950 TFieldIdentifier {
951 name: None,
952 ..field_ident_3
953 }
954 );
Allen George8b96bfb2016-11-02 08:01:08 -0400955 assert_success!(i_prot.read_field_end());
956
957 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -0500958 assert_eq!(
959 read_ident_4,
960 TFieldIdentifier {
961 name: None,
962 field_type: TType::Stop,
963 id: None,
964 }
965 );
Allen George8b96bfb2016-11-02 08:01:08 -0400966
967 assert_success!(i_prot.read_struct_end());
968 }
969
970 #[test]
971 fn must_write_struct_with_long_fields() {
Allen George0e22c362017-01-30 07:15:00 -0500972 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -0400973
974 // no bytes should be written however
975 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
976
977 // write three fields with field ids that cannot be encoded as deltas
978
979 // since this is the first field (and it's zero) it gets the full varint write
980 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 0)));
981 assert_success!(o_prot.write_field_end());
982
983 // since this delta is > 15 it is encoded as a zig-zag varint
984 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 16)));
985 assert_success!(o_prot.write_field_end());
986
987 // since this delta is > 15 it is encoded as a zig-zag varint
988 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 99)));
989 assert_success!(o_prot.write_field_end());
990
991 // now, finish the struct off
992 assert_success!(o_prot.write_field_stop());
993 assert_success!(o_prot.write_struct_end());
994
Allen George0e22c362017-01-30 07:15:00 -0500995 let expected: [u8; 8] = [
996 0x05, /* field type */
997 0x00, /* first field id */
998 0x06, /* field type */
999 0x20, /* zig-zag varint field id */
1000 0x0A, /* field type */
1001 0xC6,
1002 0x01, /* zig-zag varint field id */
1003 0x00 /* field stop */,
1004 ];
Allen George8b96bfb2016-11-02 08:01:08 -04001005
Allen George0e22c362017-01-30 07:15:00 -05001006 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04001007 }
1008
1009 #[test]
1010 fn must_round_trip_struct_with_long_fields() {
Allen George0e22c362017-01-30 07:15:00 -05001011 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001012
1013 // no bytes should be written however
1014 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1015
1016 // write three fields with field ids that cannot be encoded as deltas
1017
1018 // since this is the first field (and it's zero) it gets the full varint write
1019 let field_ident_1 = TFieldIdentifier::new("foo", TType::I32, 0);
1020 assert_success!(o_prot.write_field_begin(&field_ident_1));
1021 assert_success!(o_prot.write_field_end());
1022
1023 // since this delta is > 15 it is encoded as a zig-zag varint
1024 let field_ident_2 = TFieldIdentifier::new("foo", TType::I64, 16);
1025 assert_success!(o_prot.write_field_begin(&field_ident_2));
1026 assert_success!(o_prot.write_field_end());
1027
1028 // since this delta is > 15 it is encoded as a zig-zag varint
1029 let field_ident_3 = TFieldIdentifier::new("foo", TType::Set, 99);
1030 assert_success!(o_prot.write_field_begin(&field_ident_3));
1031 assert_success!(o_prot.write_field_end());
1032
1033 // now, finish the struct off
1034 assert_success!(o_prot.write_field_stop());
1035 assert_success!(o_prot.write_struct_end());
1036
Allen George0e22c362017-01-30 07:15:00 -05001037 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04001038
1039 // read the struct back
1040 assert_success!(i_prot.read_struct_begin());
1041
1042 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001043 assert_eq!(
1044 read_ident_1,
1045 TFieldIdentifier {
1046 name: None,
1047 ..field_ident_1
1048 }
1049 );
Allen George8b96bfb2016-11-02 08:01:08 -04001050 assert_success!(i_prot.read_field_end());
1051
1052 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001053 assert_eq!(
1054 read_ident_2,
1055 TFieldIdentifier {
1056 name: None,
1057 ..field_ident_2
1058 }
1059 );
Allen George8b96bfb2016-11-02 08:01:08 -04001060 assert_success!(i_prot.read_field_end());
1061
1062 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001063 assert_eq!(
1064 read_ident_3,
1065 TFieldIdentifier {
1066 name: None,
1067 ..field_ident_3
1068 }
1069 );
Allen George8b96bfb2016-11-02 08:01:08 -04001070 assert_success!(i_prot.read_field_end());
1071
1072 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001073 assert_eq!(
1074 read_ident_4,
1075 TFieldIdentifier {
1076 name: None,
1077 field_type: TType::Stop,
1078 id: None,
1079 }
1080 );
Allen George8b96bfb2016-11-02 08:01:08 -04001081
1082 assert_success!(i_prot.read_struct_end());
1083 }
1084
1085 #[test]
1086 fn must_write_struct_with_mix_of_long_and_delta_fields() {
Allen George0e22c362017-01-30 07:15:00 -05001087 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001088
1089 // no bytes should be written however
1090 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1091
1092 // write three fields with field ids that cannot be encoded as deltas
1093
1094 // since the delta is > 0 and < 15 it gets a delta write
1095 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
1096 assert_success!(o_prot.write_field_end());
1097
1098 // since this delta > 0 and < 15 it gets a delta write
1099 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
1100 assert_success!(o_prot.write_field_end());
1101
1102 // since this delta is > 15 it is encoded as a zig-zag varint
1103 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 1000)));
1104 assert_success!(o_prot.write_field_end());
1105
1106 // since this delta is > 15 it is encoded as a zig-zag varint
1107 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2001)));
1108 assert_success!(o_prot.write_field_end());
1109
1110 // since this is only 3 up from the previous it is recorded as a delta
1111 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2004)));
1112 assert_success!(o_prot.write_field_end());
1113
1114 // now, finish the struct off
1115 assert_success!(o_prot.write_field_stop());
1116 assert_success!(o_prot.write_struct_end());
1117
Allen George0e22c362017-01-30 07:15:00 -05001118 let expected: [u8; 10] = [
1119 0x16, /* field delta (1) | field type */
1120 0x85, /* field delta (8) | field type */
1121 0x0A, /* field type */
1122 0xD0,
1123 0x0F, /* zig-zag varint field id */
1124 0x0A, /* field type */
1125 0xA2,
1126 0x1F, /* zig-zag varint field id */
1127 0x3A, /* field delta (3) | field type */
1128 0x00 /* field stop */,
1129 ];
Allen George8b96bfb2016-11-02 08:01:08 -04001130
Allen George0e22c362017-01-30 07:15:00 -05001131 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04001132 }
1133
1134 #[test]
1135 fn must_round_trip_struct_with_mix_of_long_and_delta_fields() {
Allen George0e22c362017-01-30 07:15:00 -05001136 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001137
1138 // no bytes should be written however
1139 let struct_ident = TStructIdentifier::new("foo");
1140 assert_success!(o_prot.write_struct_begin(&struct_ident));
1141
1142 // write three fields with field ids that cannot be encoded as deltas
1143
1144 // since the delta is > 0 and < 15 it gets a delta write
1145 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1146 assert_success!(o_prot.write_field_begin(&field_ident_1));
1147 assert_success!(o_prot.write_field_end());
1148
1149 // since this delta > 0 and < 15 it gets a delta write
1150 let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
1151 assert_success!(o_prot.write_field_begin(&field_ident_2));
1152 assert_success!(o_prot.write_field_end());
1153
1154 // since this delta is > 15 it is encoded as a zig-zag varint
1155 let field_ident_3 = TFieldIdentifier::new("foo", TType::Set, 1000);
1156 assert_success!(o_prot.write_field_begin(&field_ident_3));
1157 assert_success!(o_prot.write_field_end());
1158
1159 // since this delta is > 15 it is encoded as a zig-zag varint
1160 let field_ident_4 = TFieldIdentifier::new("foo", TType::Set, 2001);
1161 assert_success!(o_prot.write_field_begin(&field_ident_4));
1162 assert_success!(o_prot.write_field_end());
1163
1164 // since this is only 3 up from the previous it is recorded as a delta
1165 let field_ident_5 = TFieldIdentifier::new("foo", TType::Set, 2004);
1166 assert_success!(o_prot.write_field_begin(&field_ident_5));
1167 assert_success!(o_prot.write_field_end());
1168
1169 // now, finish the struct off
1170 assert_success!(o_prot.write_field_stop());
1171 assert_success!(o_prot.write_struct_end());
1172
Allen George0e22c362017-01-30 07:15:00 -05001173 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04001174
1175 // read the struct back
1176 assert_success!(i_prot.read_struct_begin());
1177
1178 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001179 assert_eq!(
1180 read_ident_1,
1181 TFieldIdentifier {
1182 name: None,
1183 ..field_ident_1
1184 }
1185 );
Allen George8b96bfb2016-11-02 08:01:08 -04001186 assert_success!(i_prot.read_field_end());
1187
1188 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001189 assert_eq!(
1190 read_ident_2,
1191 TFieldIdentifier {
1192 name: None,
1193 ..field_ident_2
1194 }
1195 );
Allen George8b96bfb2016-11-02 08:01:08 -04001196 assert_success!(i_prot.read_field_end());
1197
1198 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001199 assert_eq!(
1200 read_ident_3,
1201 TFieldIdentifier {
1202 name: None,
1203 ..field_ident_3
1204 }
1205 );
Allen George8b96bfb2016-11-02 08:01:08 -04001206 assert_success!(i_prot.read_field_end());
1207
1208 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001209 assert_eq!(
1210 read_ident_4,
1211 TFieldIdentifier {
1212 name: None,
1213 ..field_ident_4
1214 }
1215 );
Allen George8b96bfb2016-11-02 08:01:08 -04001216 assert_success!(i_prot.read_field_end());
1217
1218 let read_ident_5 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001219 assert_eq!(
1220 read_ident_5,
1221 TFieldIdentifier {
1222 name: None,
1223 ..field_ident_5
1224 }
1225 );
Allen George8b96bfb2016-11-02 08:01:08 -04001226 assert_success!(i_prot.read_field_end());
1227
1228 let read_ident_6 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001229 assert_eq!(
1230 read_ident_6,
1231 TFieldIdentifier {
1232 name: None,
1233 field_type: TType::Stop,
1234 id: None,
1235 }
1236 );
Allen George8b96bfb2016-11-02 08:01:08 -04001237
1238 assert_success!(i_prot.read_struct_end());
1239 }
1240
1241 #[test]
1242 fn must_write_nested_structs_0() {
1243 // last field of the containing struct is a delta
1244 // first field of the the contained struct is a delta
1245
Allen George0e22c362017-01-30 07:15:00 -05001246 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001247
1248 // start containing struct
1249 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1250
1251 // containing struct
1252 // since the delta is > 0 and < 15 it gets a delta write
1253 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
1254 assert_success!(o_prot.write_field_end());
1255
1256 // containing struct
1257 // since this delta > 0 and < 15 it gets a delta write
1258 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
1259 assert_success!(o_prot.write_field_end());
1260
1261 // start contained struct
1262 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1263
1264 // contained struct
1265 // since the delta is > 0 and < 15 it gets a delta write
1266 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 7)));
1267 assert_success!(o_prot.write_field_end());
1268
1269 // contained struct
1270 // since this delta > 15 it gets a full write
1271 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 24)));
1272 assert_success!(o_prot.write_field_end());
1273
1274 // end contained struct
1275 assert_success!(o_prot.write_field_stop());
1276 assert_success!(o_prot.write_struct_end());
1277
1278 // end containing struct
1279 assert_success!(o_prot.write_field_stop());
1280 assert_success!(o_prot.write_struct_end());
1281
Allen George0e22c362017-01-30 07:15:00 -05001282 let expected: [u8; 7] = [
1283 0x16, /* field delta (1) | field type */
1284 0x85, /* field delta (8) | field type */
1285 0x73, /* field delta (7) | field type */
1286 0x07, /* field type */
1287 0x30, /* zig-zag varint field id */
1288 0x00, /* field stop - contained */
1289 0x00 /* field stop - containing */,
1290 ];
Allen George8b96bfb2016-11-02 08:01:08 -04001291
Allen George0e22c362017-01-30 07:15:00 -05001292 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04001293 }
1294
1295 #[test]
1296 fn must_round_trip_nested_structs_0() {
1297 // last field of the containing struct is a delta
1298 // first field of the the contained struct is a delta
1299
Allen George0e22c362017-01-30 07:15:00 -05001300 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001301
1302 // start containing struct
1303 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1304
1305 // containing struct
1306 // since the delta is > 0 and < 15 it gets a delta write
1307 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1308 assert_success!(o_prot.write_field_begin(&field_ident_1));
1309 assert_success!(o_prot.write_field_end());
1310
1311 // containing struct
1312 // since this delta > 0 and < 15 it gets a delta write
1313 let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
1314 assert_success!(o_prot.write_field_begin(&field_ident_2));
1315 assert_success!(o_prot.write_field_end());
1316
1317 // start contained struct
1318 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1319
1320 // contained struct
1321 // since the delta is > 0 and < 15 it gets a delta write
1322 let field_ident_3 = TFieldIdentifier::new("foo", TType::I08, 7);
1323 assert_success!(o_prot.write_field_begin(&field_ident_3));
1324 assert_success!(o_prot.write_field_end());
1325
1326 // contained struct
1327 // since this delta > 15 it gets a full write
1328 let field_ident_4 = TFieldIdentifier::new("foo", TType::Double, 24);
1329 assert_success!(o_prot.write_field_begin(&field_ident_4));
1330 assert_success!(o_prot.write_field_end());
1331
1332 // end contained struct
1333 assert_success!(o_prot.write_field_stop());
1334 assert_success!(o_prot.write_struct_end());
1335
1336 // end containing struct
1337 assert_success!(o_prot.write_field_stop());
1338 assert_success!(o_prot.write_struct_end());
1339
Allen George0e22c362017-01-30 07:15:00 -05001340 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04001341
1342 // read containing struct back
1343 assert_success!(i_prot.read_struct_begin());
1344
1345 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001346 assert_eq!(
1347 read_ident_1,
1348 TFieldIdentifier {
1349 name: None,
1350 ..field_ident_1
1351 }
1352 );
Allen George8b96bfb2016-11-02 08:01:08 -04001353 assert_success!(i_prot.read_field_end());
1354
1355 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001356 assert_eq!(
1357 read_ident_2,
1358 TFieldIdentifier {
1359 name: None,
1360 ..field_ident_2
1361 }
1362 );
Allen George8b96bfb2016-11-02 08:01:08 -04001363 assert_success!(i_prot.read_field_end());
1364
1365 // read contained struct back
1366 assert_success!(i_prot.read_struct_begin());
1367
1368 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001369 assert_eq!(
1370 read_ident_3,
1371 TFieldIdentifier {
1372 name: None,
1373 ..field_ident_3
1374 }
1375 );
Allen George8b96bfb2016-11-02 08:01:08 -04001376 assert_success!(i_prot.read_field_end());
1377
1378 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001379 assert_eq!(
1380 read_ident_4,
1381 TFieldIdentifier {
1382 name: None,
1383 ..field_ident_4
1384 }
1385 );
Allen George8b96bfb2016-11-02 08:01:08 -04001386 assert_success!(i_prot.read_field_end());
1387
1388 // end contained struct
1389 let read_ident_6 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001390 assert_eq!(
1391 read_ident_6,
1392 TFieldIdentifier {
1393 name: None,
1394 field_type: TType::Stop,
1395 id: None,
1396 }
1397 );
Allen George8b96bfb2016-11-02 08:01:08 -04001398 assert_success!(i_prot.read_struct_end());
1399
1400 // end containing struct
1401 let read_ident_7 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001402 assert_eq!(
1403 read_ident_7,
1404 TFieldIdentifier {
1405 name: None,
1406 field_type: TType::Stop,
1407 id: None,
1408 }
1409 );
Allen George8b96bfb2016-11-02 08:01:08 -04001410 assert_success!(i_prot.read_struct_end());
1411 }
1412
1413 #[test]
1414 fn must_write_nested_structs_1() {
1415 // last field of the containing struct is a delta
1416 // first field of the the contained struct is a full write
1417
Allen George0e22c362017-01-30 07:15:00 -05001418 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001419
1420 // start containing struct
1421 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1422
1423 // containing struct
1424 // since the delta is > 0 and < 15 it gets a delta write
1425 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
1426 assert_success!(o_prot.write_field_end());
1427
1428 // containing struct
1429 // since this delta > 0 and < 15 it gets a delta write
1430 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
1431 assert_success!(o_prot.write_field_end());
1432
1433 // start contained struct
1434 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1435
1436 // contained struct
1437 // since this delta > 15 it gets a full write
1438 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 24)));
1439 assert_success!(o_prot.write_field_end());
1440
1441 // contained struct
1442 // since the delta is > 0 and < 15 it gets a delta write
1443 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 27)));
1444 assert_success!(o_prot.write_field_end());
1445
1446 // end contained struct
1447 assert_success!(o_prot.write_field_stop());
1448 assert_success!(o_prot.write_struct_end());
1449
1450 // end containing struct
1451 assert_success!(o_prot.write_field_stop());
1452 assert_success!(o_prot.write_struct_end());
1453
Allen George0e22c362017-01-30 07:15:00 -05001454 let expected: [u8; 7] = [
1455 0x16, /* field delta (1) | field type */
1456 0x85, /* field delta (8) | field type */
1457 0x07, /* field type */
1458 0x30, /* zig-zag varint field id */
1459 0x33, /* field delta (3) | field type */
1460 0x00, /* field stop - contained */
1461 0x00 /* field stop - containing */,
1462 ];
Allen George8b96bfb2016-11-02 08:01:08 -04001463
Allen George0e22c362017-01-30 07:15:00 -05001464 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04001465 }
1466
1467 #[test]
1468 fn must_round_trip_nested_structs_1() {
1469 // last field of the containing struct is a delta
1470 // first field of the the contained struct is a full write
1471
Allen George0e22c362017-01-30 07:15:00 -05001472 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001473
1474 // start containing struct
1475 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1476
1477 // containing struct
1478 // since the delta is > 0 and < 15 it gets a delta write
1479 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1480 assert_success!(o_prot.write_field_begin(&field_ident_1));
1481 assert_success!(o_prot.write_field_end());
1482
1483 // containing struct
1484 // since this delta > 0 and < 15 it gets a delta write
1485 let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
1486 assert_success!(o_prot.write_field_begin(&field_ident_2));
1487 assert_success!(o_prot.write_field_end());
1488
1489 // start contained struct
1490 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1491
1492 // contained struct
1493 // since this delta > 15 it gets a full write
1494 let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 24);
1495 assert_success!(o_prot.write_field_begin(&field_ident_3));
1496 assert_success!(o_prot.write_field_end());
1497
1498 // contained struct
1499 // since the delta is > 0 and < 15 it gets a delta write
1500 let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 27);
1501 assert_success!(o_prot.write_field_begin(&field_ident_4));
1502 assert_success!(o_prot.write_field_end());
1503
1504 // end contained struct
1505 assert_success!(o_prot.write_field_stop());
1506 assert_success!(o_prot.write_struct_end());
1507
1508 // end containing struct
1509 assert_success!(o_prot.write_field_stop());
1510 assert_success!(o_prot.write_struct_end());
1511
Allen George0e22c362017-01-30 07:15:00 -05001512 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04001513
1514 // read containing struct back
1515 assert_success!(i_prot.read_struct_begin());
1516
1517 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001518 assert_eq!(
1519 read_ident_1,
1520 TFieldIdentifier {
1521 name: None,
1522 ..field_ident_1
1523 }
1524 );
Allen George8b96bfb2016-11-02 08:01:08 -04001525 assert_success!(i_prot.read_field_end());
1526
1527 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001528 assert_eq!(
1529 read_ident_2,
1530 TFieldIdentifier {
1531 name: None,
1532 ..field_ident_2
1533 }
1534 );
Allen George8b96bfb2016-11-02 08:01:08 -04001535 assert_success!(i_prot.read_field_end());
1536
1537 // read contained struct back
1538 assert_success!(i_prot.read_struct_begin());
1539
1540 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001541 assert_eq!(
1542 read_ident_3,
1543 TFieldIdentifier {
1544 name: None,
1545 ..field_ident_3
1546 }
1547 );
Allen George8b96bfb2016-11-02 08:01:08 -04001548 assert_success!(i_prot.read_field_end());
1549
1550 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001551 assert_eq!(
1552 read_ident_4,
1553 TFieldIdentifier {
1554 name: None,
1555 ..field_ident_4
1556 }
1557 );
Allen George8b96bfb2016-11-02 08:01:08 -04001558 assert_success!(i_prot.read_field_end());
1559
1560 // end contained struct
1561 let read_ident_6 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001562 assert_eq!(
1563 read_ident_6,
1564 TFieldIdentifier {
1565 name: None,
1566 field_type: TType::Stop,
1567 id: None,
1568 }
1569 );
Allen George8b96bfb2016-11-02 08:01:08 -04001570 assert_success!(i_prot.read_struct_end());
1571
1572 // end containing struct
1573 let read_ident_7 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001574 assert_eq!(
1575 read_ident_7,
1576 TFieldIdentifier {
1577 name: None,
1578 field_type: TType::Stop,
1579 id: None,
1580 }
1581 );
Allen George8b96bfb2016-11-02 08:01:08 -04001582 assert_success!(i_prot.read_struct_end());
1583 }
1584
1585 #[test]
1586 fn must_write_nested_structs_2() {
1587 // last field of the containing struct is a full write
1588 // first field of the the contained struct is a delta write
1589
Allen George0e22c362017-01-30 07:15:00 -05001590 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001591
1592 // start containing struct
1593 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1594
1595 // containing struct
1596 // since the delta is > 0 and < 15 it gets a delta write
1597 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
1598 assert_success!(o_prot.write_field_end());
1599
1600 // containing struct
1601 // since this delta > 15 it gets a full write
1602 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 21)));
1603 assert_success!(o_prot.write_field_end());
1604
1605 // start contained struct
1606 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1607
1608 // contained struct
1609 // since this delta > 0 and < 15 it gets a delta write
1610 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 7)));
1611 assert_success!(o_prot.write_field_end());
1612
1613 // contained struct
1614 // since the delta is > 0 and < 15 it gets a delta write
1615 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 10)));
1616 assert_success!(o_prot.write_field_end());
1617
1618 // end contained struct
1619 assert_success!(o_prot.write_field_stop());
1620 assert_success!(o_prot.write_struct_end());
1621
1622 // end containing struct
1623 assert_success!(o_prot.write_field_stop());
1624 assert_success!(o_prot.write_struct_end());
1625
Allen George0e22c362017-01-30 07:15:00 -05001626 let expected: [u8; 7] = [
1627 0x16, /* field delta (1) | field type */
1628 0x08, /* field type */
1629 0x2A, /* zig-zag varint field id */
1630 0x77, /* field delta(7) | field type */
1631 0x33, /* field delta (3) | field type */
1632 0x00, /* field stop - contained */
1633 0x00 /* field stop - containing */,
1634 ];
Allen George8b96bfb2016-11-02 08:01:08 -04001635
Allen George0e22c362017-01-30 07:15:00 -05001636 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04001637 }
1638
1639 #[test]
1640 fn must_round_trip_nested_structs_2() {
Allen George0e22c362017-01-30 07:15:00 -05001641 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001642
1643 // start containing struct
1644 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1645
1646 // containing struct
1647 // since the delta is > 0 and < 15 it gets a delta write
1648 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1649 assert_success!(o_prot.write_field_begin(&field_ident_1));
1650 assert_success!(o_prot.write_field_end());
1651
1652 // containing struct
1653 // since this delta > 15 it gets a full write
1654 let field_ident_2 = TFieldIdentifier::new("foo", TType::String, 21);
1655 assert_success!(o_prot.write_field_begin(&field_ident_2));
1656 assert_success!(o_prot.write_field_end());
1657
1658 // start contained struct
1659 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1660
1661 // contained struct
1662 // since this delta > 0 and < 15 it gets a delta write
1663 let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 7);
1664 assert_success!(o_prot.write_field_begin(&field_ident_3));
1665 assert_success!(o_prot.write_field_end());
1666
1667 // contained struct
1668 // since the delta is > 0 and < 15 it gets a delta write
1669 let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 10);
1670 assert_success!(o_prot.write_field_begin(&field_ident_4));
1671 assert_success!(o_prot.write_field_end());
1672
1673 // end contained struct
1674 assert_success!(o_prot.write_field_stop());
1675 assert_success!(o_prot.write_struct_end());
1676
1677 // end containing struct
1678 assert_success!(o_prot.write_field_stop());
1679 assert_success!(o_prot.write_struct_end());
1680
Allen George0e22c362017-01-30 07:15:00 -05001681 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04001682
1683 // read containing struct back
1684 assert_success!(i_prot.read_struct_begin());
1685
1686 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001687 assert_eq!(
1688 read_ident_1,
1689 TFieldIdentifier {
1690 name: None,
1691 ..field_ident_1
1692 }
1693 );
Allen George8b96bfb2016-11-02 08:01:08 -04001694 assert_success!(i_prot.read_field_end());
1695
1696 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001697 assert_eq!(
1698 read_ident_2,
1699 TFieldIdentifier {
1700 name: None,
1701 ..field_ident_2
1702 }
1703 );
Allen George8b96bfb2016-11-02 08:01:08 -04001704 assert_success!(i_prot.read_field_end());
1705
1706 // read contained struct back
1707 assert_success!(i_prot.read_struct_begin());
1708
1709 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001710 assert_eq!(
1711 read_ident_3,
1712 TFieldIdentifier {
1713 name: None,
1714 ..field_ident_3
1715 }
1716 );
Allen George8b96bfb2016-11-02 08:01:08 -04001717 assert_success!(i_prot.read_field_end());
1718
1719 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001720 assert_eq!(
1721 read_ident_4,
1722 TFieldIdentifier {
1723 name: None,
1724 ..field_ident_4
1725 }
1726 );
Allen George8b96bfb2016-11-02 08:01:08 -04001727 assert_success!(i_prot.read_field_end());
1728
1729 // end contained struct
1730 let read_ident_6 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001731 assert_eq!(
1732 read_ident_6,
1733 TFieldIdentifier {
1734 name: None,
1735 field_type: TType::Stop,
1736 id: None,
1737 }
1738 );
Allen George8b96bfb2016-11-02 08:01:08 -04001739 assert_success!(i_prot.read_struct_end());
1740
1741 // end containing struct
1742 let read_ident_7 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001743 assert_eq!(
1744 read_ident_7,
1745 TFieldIdentifier {
1746 name: None,
1747 field_type: TType::Stop,
1748 id: None,
1749 }
1750 );
Allen George8b96bfb2016-11-02 08:01:08 -04001751 assert_success!(i_prot.read_struct_end());
1752 }
1753
1754 #[test]
1755 fn must_write_nested_structs_3() {
1756 // last field of the containing struct is a full write
1757 // first field of the the contained struct is a full write
1758
Allen George0e22c362017-01-30 07:15:00 -05001759 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001760
1761 // start containing struct
1762 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1763
1764 // containing struct
1765 // since the delta is > 0 and < 15 it gets a delta write
1766 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
1767 assert_success!(o_prot.write_field_end());
1768
1769 // containing struct
1770 // since this delta > 15 it gets a full write
1771 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 21)));
1772 assert_success!(o_prot.write_field_end());
1773
1774 // start contained struct
1775 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1776
1777 // contained struct
1778 // since this delta > 15 it gets a full write
1779 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 21)));
1780 assert_success!(o_prot.write_field_end());
1781
1782 // contained struct
1783 // since the delta is > 0 and < 15 it gets a delta write
1784 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 27)));
1785 assert_success!(o_prot.write_field_end());
1786
1787 // end contained struct
1788 assert_success!(o_prot.write_field_stop());
1789 assert_success!(o_prot.write_struct_end());
1790
1791 // end containing struct
1792 assert_success!(o_prot.write_field_stop());
1793 assert_success!(o_prot.write_struct_end());
1794
Allen George0e22c362017-01-30 07:15:00 -05001795 let expected: [u8; 8] = [
1796 0x16, /* field delta (1) | field type */
1797 0x08, /* field type */
1798 0x2A, /* zig-zag varint field id */
1799 0x07, /* field type */
1800 0x2A, /* zig-zag varint field id */
1801 0x63, /* field delta (6) | field type */
1802 0x00, /* field stop - contained */
1803 0x00 /* field stop - containing */,
1804 ];
Allen George8b96bfb2016-11-02 08:01:08 -04001805
Allen George0e22c362017-01-30 07:15:00 -05001806 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04001807 }
1808
1809 #[test]
1810 fn must_round_trip_nested_structs_3() {
1811 // last field of the containing struct is a full write
1812 // first field of the the contained struct is a full write
1813
Allen George0e22c362017-01-30 07:15:00 -05001814 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001815
1816 // start containing struct
1817 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1818
1819 // containing struct
1820 // since the delta is > 0 and < 15 it gets a delta write
1821 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1822 assert_success!(o_prot.write_field_begin(&field_ident_1));
1823 assert_success!(o_prot.write_field_end());
1824
1825 // containing struct
1826 // since this delta > 15 it gets a full write
1827 let field_ident_2 = TFieldIdentifier::new("foo", TType::String, 21);
1828 assert_success!(o_prot.write_field_begin(&field_ident_2));
1829 assert_success!(o_prot.write_field_end());
1830
1831 // start contained struct
1832 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1833
1834 // contained struct
1835 // since this delta > 15 it gets a full write
1836 let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 21);
1837 assert_success!(o_prot.write_field_begin(&field_ident_3));
1838 assert_success!(o_prot.write_field_end());
1839
1840 // contained struct
1841 // since the delta is > 0 and < 15 it gets a delta write
1842 let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 27);
1843 assert_success!(o_prot.write_field_begin(&field_ident_4));
1844 assert_success!(o_prot.write_field_end());
1845
1846 // end contained struct
1847 assert_success!(o_prot.write_field_stop());
1848 assert_success!(o_prot.write_struct_end());
1849
1850 // end containing struct
1851 assert_success!(o_prot.write_field_stop());
1852 assert_success!(o_prot.write_struct_end());
1853
Allen George0e22c362017-01-30 07:15:00 -05001854 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04001855
1856 // read containing struct back
1857 assert_success!(i_prot.read_struct_begin());
1858
1859 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001860 assert_eq!(
1861 read_ident_1,
1862 TFieldIdentifier {
1863 name: None,
1864 ..field_ident_1
1865 }
1866 );
Allen George8b96bfb2016-11-02 08:01:08 -04001867 assert_success!(i_prot.read_field_end());
1868
1869 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001870 assert_eq!(
1871 read_ident_2,
1872 TFieldIdentifier {
1873 name: None,
1874 ..field_ident_2
1875 }
1876 );
Allen George8b96bfb2016-11-02 08:01:08 -04001877 assert_success!(i_prot.read_field_end());
1878
1879 // read contained struct back
1880 assert_success!(i_prot.read_struct_begin());
1881
1882 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001883 assert_eq!(
1884 read_ident_3,
1885 TFieldIdentifier {
1886 name: None,
1887 ..field_ident_3
1888 }
1889 );
Allen George8b96bfb2016-11-02 08:01:08 -04001890 assert_success!(i_prot.read_field_end());
1891
1892 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001893 assert_eq!(
1894 read_ident_4,
1895 TFieldIdentifier {
1896 name: None,
1897 ..field_ident_4
1898 }
1899 );
Allen George8b96bfb2016-11-02 08:01:08 -04001900 assert_success!(i_prot.read_field_end());
1901
1902 // end contained struct
1903 let read_ident_6 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001904 assert_eq!(
1905 read_ident_6,
1906 TFieldIdentifier {
1907 name: None,
1908 field_type: TType::Stop,
1909 id: None,
1910 }
1911 );
Allen George8b96bfb2016-11-02 08:01:08 -04001912 assert_success!(i_prot.read_struct_end());
1913
1914 // end containing struct
1915 let read_ident_7 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05001916 assert_eq!(
1917 read_ident_7,
1918 TFieldIdentifier {
1919 name: None,
1920 field_type: TType::Stop,
1921 id: None,
1922 }
1923 );
Allen George8b96bfb2016-11-02 08:01:08 -04001924 assert_success!(i_prot.read_struct_end());
1925 }
1926
1927 #[test]
1928 fn must_write_bool_field() {
Allen George0e22c362017-01-30 07:15:00 -05001929 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001930
1931 // no bytes should be written however
1932 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1933
1934 // write three fields with field ids that cannot be encoded as deltas
1935
1936 // since the delta is > 0 and < 16 it gets a delta write
1937 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
1938 assert_success!(o_prot.write_bool(true));
1939 assert_success!(o_prot.write_field_end());
1940
1941 // since this delta > 0 and < 15 it gets a delta write
1942 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 9)));
1943 assert_success!(o_prot.write_bool(false));
1944 assert_success!(o_prot.write_field_end());
1945
1946 // since this delta > 15 it gets a full write
1947 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 26)));
1948 assert_success!(o_prot.write_bool(true));
1949 assert_success!(o_prot.write_field_end());
1950
1951 // since this delta > 15 it gets a full write
1952 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 45)));
1953 assert_success!(o_prot.write_bool(false));
1954 assert_success!(o_prot.write_field_end());
1955
1956 // now, finish the struct off
1957 assert_success!(o_prot.write_field_stop());
1958 assert_success!(o_prot.write_struct_end());
1959
Allen George0e22c362017-01-30 07:15:00 -05001960 let expected: [u8; 7] = [
1961 0x11, /* field delta (1) | true */
1962 0x82, /* field delta (8) | false */
1963 0x01, /* true */
1964 0x34, /* field id */
1965 0x02, /* false */
1966 0x5A, /* field id */
1967 0x00 /* stop field */,
1968 ];
Allen George8b96bfb2016-11-02 08:01:08 -04001969
Allen George0e22c362017-01-30 07:15:00 -05001970 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04001971 }
1972
1973 #[test]
1974 fn must_round_trip_bool_field() {
Allen George0e22c362017-01-30 07:15:00 -05001975 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04001976
1977 // no bytes should be written however
1978 let struct_ident = TStructIdentifier::new("foo");
1979 assert_success!(o_prot.write_struct_begin(&struct_ident));
1980
1981 // write two fields
1982
1983 // since the delta is > 0 and < 16 it gets a delta write
1984 let field_ident_1 = TFieldIdentifier::new("foo", TType::Bool, 1);
1985 assert_success!(o_prot.write_field_begin(&field_ident_1));
1986 assert_success!(o_prot.write_bool(true));
1987 assert_success!(o_prot.write_field_end());
1988
1989 // since this delta > 0 and < 15 it gets a delta write
1990 let field_ident_2 = TFieldIdentifier::new("foo", TType::Bool, 9);
1991 assert_success!(o_prot.write_field_begin(&field_ident_2));
1992 assert_success!(o_prot.write_bool(false));
1993 assert_success!(o_prot.write_field_end());
1994
1995 // since this delta > 15 it gets a full write
1996 let field_ident_3 = TFieldIdentifier::new("foo", TType::Bool, 26);
1997 assert_success!(o_prot.write_field_begin(&field_ident_3));
1998 assert_success!(o_prot.write_bool(true));
1999 assert_success!(o_prot.write_field_end());
2000
2001 // since this delta > 15 it gets a full write
2002 let field_ident_4 = TFieldIdentifier::new("foo", TType::Bool, 45);
2003 assert_success!(o_prot.write_field_begin(&field_ident_4));
2004 assert_success!(o_prot.write_bool(false));
2005 assert_success!(o_prot.write_field_end());
2006
2007 // now, finish the struct off
2008 assert_success!(o_prot.write_field_stop());
2009 assert_success!(o_prot.write_struct_end());
2010
Allen George0e22c362017-01-30 07:15:00 -05002011 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002012
2013 // read the struct back
2014 assert_success!(i_prot.read_struct_begin());
2015
2016 let read_ident_1 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05002017 assert_eq!(
2018 read_ident_1,
2019 TFieldIdentifier {
2020 name: None,
2021 ..field_ident_1
2022 }
2023 );
Allen George8b96bfb2016-11-02 08:01:08 -04002024 let read_value_1 = assert_success!(i_prot.read_bool());
2025 assert_eq!(read_value_1, true);
2026 assert_success!(i_prot.read_field_end());
2027
2028 let read_ident_2 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05002029 assert_eq!(
2030 read_ident_2,
2031 TFieldIdentifier {
2032 name: None,
2033 ..field_ident_2
2034 }
2035 );
Allen George8b96bfb2016-11-02 08:01:08 -04002036 let read_value_2 = assert_success!(i_prot.read_bool());
2037 assert_eq!(read_value_2, false);
2038 assert_success!(i_prot.read_field_end());
2039
2040 let read_ident_3 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05002041 assert_eq!(
2042 read_ident_3,
2043 TFieldIdentifier {
2044 name: None,
2045 ..field_ident_3
2046 }
2047 );
Allen George8b96bfb2016-11-02 08:01:08 -04002048 let read_value_3 = assert_success!(i_prot.read_bool());
2049 assert_eq!(read_value_3, true);
2050 assert_success!(i_prot.read_field_end());
2051
2052 let read_ident_4 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05002053 assert_eq!(
2054 read_ident_4,
2055 TFieldIdentifier {
2056 name: None,
2057 ..field_ident_4
2058 }
2059 );
Allen George8b96bfb2016-11-02 08:01:08 -04002060 let read_value_4 = assert_success!(i_prot.read_bool());
2061 assert_eq!(read_value_4, false);
2062 assert_success!(i_prot.read_field_end());
2063
2064 let read_ident_5 = assert_success!(i_prot.read_field_begin());
Allen George0e22c362017-01-30 07:15:00 -05002065 assert_eq!(
2066 read_ident_5,
2067 TFieldIdentifier {
2068 name: None,
2069 field_type: TType::Stop,
2070 id: None,
2071 }
2072 );
Allen George8b96bfb2016-11-02 08:01:08 -04002073
2074 assert_success!(i_prot.read_struct_end());
2075 }
2076
2077 #[test]
2078 #[should_panic]
2079 fn must_fail_if_write_field_end_without_writing_bool_value() {
Allen George0e22c362017-01-30 07:15:00 -05002080 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002081 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
2082 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
2083 o_prot.write_field_end().unwrap();
2084 }
2085
2086 #[test]
2087 #[should_panic]
2088 fn must_fail_if_write_stop_field_without_writing_bool_value() {
Allen George0e22c362017-01-30 07:15:00 -05002089 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002090 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
2091 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
2092 o_prot.write_field_stop().unwrap();
2093 }
2094
2095 #[test]
2096 #[should_panic]
2097 fn must_fail_if_write_struct_end_without_writing_bool_value() {
Allen George0e22c362017-01-30 07:15:00 -05002098 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002099 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
2100 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
2101 o_prot.write_struct_end().unwrap();
2102 }
2103
2104 #[test]
2105 #[should_panic]
2106 fn must_fail_if_write_struct_end_without_any_fields() {
Allen George0e22c362017-01-30 07:15:00 -05002107 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002108 o_prot.write_struct_end().unwrap();
2109 }
2110
2111 #[test]
2112 fn must_write_field_end() {
2113 assert_no_write(|o| o.write_field_end());
2114 }
2115
2116 #[test]
2117 fn must_write_small_sized_list_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002118 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002119
2120 assert_success!(o_prot.write_list_begin(&TListIdentifier::new(TType::I64, 4)));
2121
2122 let expected: [u8; 1] = [0x46 /* size | elem_type */];
2123
Allen George0e22c362017-01-30 07:15:00 -05002124 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04002125 }
2126
2127 #[test]
2128 fn must_round_trip_small_sized_list_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002129 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002130
2131 let ident = TListIdentifier::new(TType::I08, 10);
2132
2133 assert_success!(o_prot.write_list_begin(&ident));
2134
Allen George0e22c362017-01-30 07:15:00 -05002135 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002136
2137 let res = assert_success!(i_prot.read_list_begin());
2138 assert_eq!(&res, &ident);
2139 }
2140
2141 #[test]
2142 fn must_write_large_sized_list_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002143 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002144
2145 let res = o_prot.write_list_begin(&TListIdentifier::new(TType::List, 9999));
2146 assert!(res.is_ok());
2147
Allen George0e22c362017-01-30 07:15:00 -05002148 let expected: [u8; 3] = [
2149 0xF9, /* 0xF0 | elem_type */
2150 0x8F,
2151 0x4E /* size as varint */,
2152 ];
Allen George8b96bfb2016-11-02 08:01:08 -04002153
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_large_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::Set, 47381);
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_list_end() {
2173 assert_no_write(|o| o.write_list_end());
2174 }
2175
2176 #[test]
2177 fn must_write_small_sized_set_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002178 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002179
2180 assert_success!(o_prot.write_set_begin(&TSetIdentifier::new(TType::Struct, 2)));
2181
2182 let expected: [u8; 1] = [0x2C /* size | elem_type */];
2183
Allen George0e22c362017-01-30 07:15:00 -05002184 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04002185 }
2186
2187 #[test]
2188 fn must_round_trip_small_sized_set_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002189 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002190
2191 let ident = TSetIdentifier::new(TType::I16, 7);
2192
2193 assert_success!(o_prot.write_set_begin(&ident));
2194
Allen George0e22c362017-01-30 07:15:00 -05002195 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002196
2197 let res = assert_success!(i_prot.read_set_begin());
2198 assert_eq!(&res, &ident);
2199 }
2200
2201 #[test]
2202 fn must_write_large_sized_set_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002203 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002204
2205 assert_success!(o_prot.write_set_begin(&TSetIdentifier::new(TType::Double, 23891)));
2206
Allen George0e22c362017-01-30 07:15:00 -05002207 let expected: [u8; 4] = [
2208 0xF7, /* 0xF0 | elem_type */
2209 0xD3,
2210 0xBA,
2211 0x01 /* size as varint */,
2212 ];
Allen George8b96bfb2016-11-02 08:01:08 -04002213
Allen George0e22c362017-01-30 07:15:00 -05002214 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04002215 }
2216
2217 #[test]
2218 fn must_round_trip_large_sized_set_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002219 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002220
2221 let ident = TSetIdentifier::new(TType::Map, 3928429);
2222
2223 assert_success!(o_prot.write_set_begin(&ident));
2224
Allen George0e22c362017-01-30 07:15:00 -05002225 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002226
2227 let res = assert_success!(i_prot.read_set_begin());
2228 assert_eq!(&res, &ident);
2229 }
2230
2231 #[test]
2232 fn must_write_set_end() {
2233 assert_no_write(|o| o.write_set_end());
2234 }
2235
2236 #[test]
2237 fn must_write_zero_sized_map_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002238 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002239
2240 assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::String, TType::I32, 0)));
2241
2242 let expected: [u8; 1] = [0x00]; // since size is zero we don't write anything
2243
Allen George0e22c362017-01-30 07:15:00 -05002244 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04002245 }
2246
2247 #[test]
2248 fn must_read_zero_sized_map_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002249 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002250
2251 assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Double, TType::I32, 0)));
2252
Allen George0e22c362017-01-30 07:15:00 -05002253 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002254
2255 let res = assert_success!(i_prot.read_map_begin());
Allen George0e22c362017-01-30 07:15:00 -05002256 assert_eq!(
2257 &res,
2258 &TMapIdentifier {
2259 key_type: None,
2260 value_type: None,
2261 size: 0,
2262 }
2263 );
Allen George8b96bfb2016-11-02 08:01:08 -04002264 }
2265
2266 #[test]
2267 fn must_write_map_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002268 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002269
2270 assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Double, TType::String, 238)));
2271
Allen George0e22c362017-01-30 07:15:00 -05002272 let expected: [u8; 3] = [
2273 0xEE,
2274 0x01, /* size as varint */
2275 0x78 /* key type | val type */,
2276 ];
Allen George8b96bfb2016-11-02 08:01:08 -04002277
Allen George0e22c362017-01-30 07:15:00 -05002278 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04002279 }
2280
2281 #[test]
2282 fn must_round_trip_map_begin() {
Allen George0e22c362017-01-30 07:15:00 -05002283 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002284
2285 let ident = TMapIdentifier::new(TType::Map, TType::List, 1928349);
2286
2287 assert_success!(o_prot.write_map_begin(&ident));
2288
Allen George0e22c362017-01-30 07:15:00 -05002289 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002290
2291 let res = assert_success!(i_prot.read_map_begin());
2292 assert_eq!(&res, &ident);
2293 }
2294
2295 #[test]
2296 fn must_write_map_end() {
2297 assert_no_write(|o| o.write_map_end());
2298 }
2299
2300 #[test]
2301 fn must_write_map_with_bool_key_and_value() {
Allen George0e22c362017-01-30 07:15:00 -05002302 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002303
2304 assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Bool, TType::Bool, 1)));
2305 assert_success!(o_prot.write_bool(true));
2306 assert_success!(o_prot.write_bool(false));
2307 assert_success!(o_prot.write_map_end());
2308
Allen George0e22c362017-01-30 07:15:00 -05002309 let expected: [u8; 4] = [
2310 0x01, /* size as varint */
2311 0x11, /* key type | val type */
2312 0x01, /* key: true */
2313 0x02 /* val: false */,
2314 ];
Allen George8b96bfb2016-11-02 08:01:08 -04002315
Allen George0e22c362017-01-30 07:15:00 -05002316 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -04002317 }
2318
2319 #[test]
2320 fn must_round_trip_map_with_bool_value() {
Allen George0e22c362017-01-30 07:15:00 -05002321 let (mut i_prot, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002322
2323 let map_ident = TMapIdentifier::new(TType::Bool, TType::Bool, 2);
2324 assert_success!(o_prot.write_map_begin(&map_ident));
2325 assert_success!(o_prot.write_bool(true));
2326 assert_success!(o_prot.write_bool(false));
2327 assert_success!(o_prot.write_bool(false));
2328 assert_success!(o_prot.write_bool(true));
2329 assert_success!(o_prot.write_map_end());
2330
Allen George0e22c362017-01-30 07:15:00 -05002331 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -04002332
2333 // map header
2334 let rcvd_ident = assert_success!(i_prot.read_map_begin());
2335 assert_eq!(&rcvd_ident, &map_ident);
2336 // key 1
2337 let b = assert_success!(i_prot.read_bool());
2338 assert_eq!(b, true);
2339 // val 1
2340 let b = assert_success!(i_prot.read_bool());
2341 assert_eq!(b, false);
2342 // key 2
2343 let b = assert_success!(i_prot.read_bool());
2344 assert_eq!(b, false);
2345 // val 2
2346 let b = assert_success!(i_prot.read_bool());
2347 assert_eq!(b, true);
2348 // map end
2349 assert_success!(i_prot.read_map_end());
2350 }
2351
2352 #[test]
2353 fn must_read_map_end() {
Allen George0e22c362017-01-30 07:15:00 -05002354 let (mut i_prot, _) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002355 assert!(i_prot.read_map_end().is_ok()); // will blow up if we try to read from empty buffer
2356 }
2357
Allen George0e22c362017-01-30 07:15:00 -05002358 fn test_objects()
2359 -> (TCompactInputProtocol<ReadHalf<TBufferChannel>>,
2360 TCompactOutputProtocol<WriteHalf<TBufferChannel>>)
Allen George8b96bfb2016-11-02 08:01:08 -04002361 {
Allen George0e22c362017-01-30 07:15:00 -05002362 let mem = TBufferChannel::with_capacity(80, 80);
Allen George8b96bfb2016-11-02 08:01:08 -04002363
Allen George0e22c362017-01-30 07:15:00 -05002364 let (r_mem, w_mem) = mem.split().unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -04002365
Allen George0e22c362017-01-30 07:15:00 -05002366 let i_prot = TCompactInputProtocol::new(r_mem);
2367 let o_prot = TCompactOutputProtocol::new(w_mem);
Allen George8b96bfb2016-11-02 08:01:08 -04002368
Allen George0e22c362017-01-30 07:15:00 -05002369 (i_prot, o_prot)
Allen George8b96bfb2016-11-02 08:01:08 -04002370 }
2371
Allen George0e22c362017-01-30 07:15:00 -05002372 fn assert_no_write<F>(mut write_fn: F)
2373 where
2374 F: FnMut(&mut TCompactOutputProtocol<WriteHalf<TBufferChannel>>) -> ::Result<()>,
2375 {
2376 let (_, mut o_prot) = test_objects();
Allen George8b96bfb2016-11-02 08:01:08 -04002377 assert!(write_fn(&mut o_prot).is_ok());
Allen George0e22c362017-01-30 07:15:00 -05002378 assert_eq!(o_prot.transport.write_bytes().len(), 0);
Allen George8b96bfb2016-11-02 08:01:08 -04002379 }
2380}