blob: 353514d30d49d63dcd6691e16f02a71be9cc86be [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};
20use std::cell::RefCell;
21use std::convert::From;
22use std::rc::Rc;
23use std::io::{Read, Write};
24use try_from::TryFrom;
25
26use ::transport::TTransport;
27use super::{TFieldIdentifier, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType,
28 TInputProtocol, TInputProtocolFactory};
29use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
30
31const COMPACT_PROTOCOL_ID: u8 = 0x82;
32const COMPACT_VERSION: u8 = 0x01;
33const COMPACT_VERSION_MASK: u8 = 0x1F;
34
35/// Read messages encoded in the Thrift compact protocol.
36///
37/// # Examples
38///
39/// Create and use a `TCompactInputProtocol`.
40///
41/// ```no_run
42/// use std::cell::RefCell;
43/// use std::rc::Rc;
44/// use thrift::protocol::{TCompactInputProtocol, TInputProtocol};
45/// use thrift::transport::{TTcpTransport, TTransport};
46///
47/// let mut transport = TTcpTransport::new();
48/// transport.open("localhost:9090").unwrap();
49/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
50///
51/// let mut i_prot = TCompactInputProtocol::new(transport);
52///
53/// let recvd_bool = i_prot.read_bool().unwrap();
54/// let recvd_string = i_prot.read_string().unwrap();
55/// ```
Chao Sunc063b302017-03-12 12:21:05 -070056pub struct TCompactInputProtocol<'a> {
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.
Chao Sunc063b302017-03-12 12:21:05 -070066 transport: Rc<RefCell<Box<TTransport + 'a>>>,
Allen George8b96bfb2016-11-02 08:01:08 -040067}
68
Chao Sunc063b302017-03-12 12:21:05 -070069impl<'a> TCompactInputProtocol<'a> {
Allen George8b96bfb2016-11-02 08:01:08 -040070 /// Create a `TCompactInputProtocol` that reads bytes from `transport`.
Chao Sunc063b302017-03-12 12:21:05 -070071 pub fn new(transport: Rc<RefCell<Box<TTransport + 'a>>>) -> TCompactInputProtocol<'a> {
Allen George8b96bfb2016-11-02 08:01:08 -040072 TCompactInputProtocol {
73 last_read_field_id: 0,
74 read_field_id_stack: Vec::new(),
75 pending_read_bool_value: None,
76 transport: transport,
77 }
78 }
79
80 fn read_list_set_begin(&mut self) -> ::Result<(TType, i32)> {
81 let header = self.read_byte()?;
82 let element_type = collection_u8_to_type(header & 0x0F)?;
83
84 let element_count;
85 let possible_element_count = (header & 0xF0) >> 4;
86 if possible_element_count != 15 {
87 // high bits set high if count and type encoded separately
88 element_count = possible_element_count as i32;
89 } else {
90 element_count = self.transport.borrow_mut().read_varint::<u32>()? as i32;
91 }
92
93 Ok((element_type, element_count))
94 }
95}
96
Chao Sunc063b302017-03-12 12:21:05 -070097impl<'a> TInputProtocol for TCompactInputProtocol<'a> {
Allen George8b96bfb2016-11-02 08:01:08 -040098 fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
99 let compact_id = self.read_byte()?;
100 if compact_id != COMPACT_PROTOCOL_ID {
101 Err(::Error::Protocol(::ProtocolError {
102 kind: ::ProtocolErrorKind::BadVersion,
103 message: format!("invalid compact protocol header {:?}", compact_id),
104 }))
105 } else {
106 Ok(())
107 }?;
108
109 let type_and_byte = self.read_byte()?;
110 let received_version = type_and_byte & COMPACT_VERSION_MASK;
111 if received_version != COMPACT_VERSION {
112 Err(::Error::Protocol(::ProtocolError {
113 kind: ::ProtocolErrorKind::BadVersion,
114 message: format!("cannot process compact protocol version {:?}",
115 received_version),
116 }))
117 } else {
118 Ok(())
119 }?;
120
121 // NOTE: unsigned right shift will pad with 0s
122 let message_type: TMessageType = TMessageType::try_from(type_and_byte >> 5)?;
123 let sequence_number = self.read_i32()?;
124 let service_call_name = self.read_string()?;
125
126 self.last_read_field_id = 0;
127
128 Ok(TMessageIdentifier::new(service_call_name, message_type, sequence_number))
129 }
130
131 fn read_message_end(&mut self) -> ::Result<()> {
132 Ok(())
133 }
134
135 fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
136 self.read_field_id_stack.push(self.last_read_field_id);
137 self.last_read_field_id = 0;
138 Ok(None)
139 }
140
141 fn read_struct_end(&mut self) -> ::Result<()> {
142 self.last_read_field_id = self.read_field_id_stack
143 .pop()
144 .expect("should have previous field ids");
145 Ok(())
146 }
147
148 fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
149 // we can read at least one byte, which is:
150 // - the type
151 // - the field delta and the type
152 let field_type = self.read_byte()?;
153 let field_delta = (field_type & 0xF0) >> 4;
154 let field_type = match field_type & 0x0F {
155 0x01 => {
156 self.pending_read_bool_value = Some(true);
157 Ok(TType::Bool)
158 }
159 0x02 => {
160 self.pending_read_bool_value = Some(false);
161 Ok(TType::Bool)
162 }
163 ttu8 => u8_to_type(ttu8),
164 }?;
165
166 match field_type {
167 TType::Stop => {
168 Ok(TFieldIdentifier::new::<Option<String>, String, Option<i16>>(None,
169 TType::Stop,
170 None))
171 }
172 _ => {
173 if field_delta != 0 {
174 self.last_read_field_id += field_delta as i16;
175 } else {
176 self.last_read_field_id = self.read_i16()?;
177 };
178
179 Ok(TFieldIdentifier {
180 name: None,
181 field_type: field_type,
182 id: Some(self.last_read_field_id),
183 })
184 }
185 }
186 }
187
188 fn read_field_end(&mut self) -> ::Result<()> {
189 Ok(())
190 }
191
192 fn read_bool(&mut self) -> ::Result<bool> {
193 match self.pending_read_bool_value.take() {
194 Some(b) => Ok(b),
195 None => {
196 let b = self.read_byte()?;
197 match b {
198 0x01 => Ok(true),
199 0x02 => Ok(false),
200 unkn => {
201 Err(::Error::Protocol(::ProtocolError {
202 kind: ::ProtocolErrorKind::InvalidData,
203 message: format!("cannot convert {} into bool", unkn),
204 }))
205 }
206 }
207 }
208 }
209 }
210
211 fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
212 let len = self.transport.borrow_mut().read_varint::<u32>()?;
213 let mut buf = vec![0u8; len as usize];
214 self.transport.borrow_mut().read_exact(&mut buf).map_err(From::from).map(|_| buf)
215 }
216
217 fn read_i8(&mut self) -> ::Result<i8> {
218 self.read_byte().map(|i| i as i8)
219 }
220
221 fn read_i16(&mut self) -> ::Result<i16> {
222 self.transport.borrow_mut().read_varint::<i16>().map_err(From::from)
223 }
224
225 fn read_i32(&mut self) -> ::Result<i32> {
226 self.transport.borrow_mut().read_varint::<i32>().map_err(From::from)
227 }
228
229 fn read_i64(&mut self) -> ::Result<i64> {
230 self.transport.borrow_mut().read_varint::<i64>().map_err(From::from)
231 }
232
233 fn read_double(&mut self) -> ::Result<f64> {
234 self.transport.borrow_mut().read_f64::<BigEndian>().map_err(From::from)
235 }
236
237 fn read_string(&mut self) -> ::Result<String> {
238 let bytes = self.read_bytes()?;
239 String::from_utf8(bytes).map_err(From::from)
240 }
241
242 fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
243 let (element_type, element_count) = self.read_list_set_begin()?;
244 Ok(TListIdentifier::new(element_type, element_count))
245 }
246
247 fn read_list_end(&mut self) -> ::Result<()> {
248 Ok(())
249 }
250
251 fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
252 let (element_type, element_count) = self.read_list_set_begin()?;
253 Ok(TSetIdentifier::new(element_type, element_count))
254 }
255
256 fn read_set_end(&mut self) -> ::Result<()> {
257 Ok(())
258 }
259
260 fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
261 let element_count = self.transport.borrow_mut().read_varint::<u32>()? as i32;
262 if element_count == 0 {
263 Ok(TMapIdentifier::new(None, None, 0))
264 } else {
265 let type_header = self.read_byte()?;
266 let key_type = collection_u8_to_type((type_header & 0xF0) >> 4)?;
267 let val_type = collection_u8_to_type(type_header & 0x0F)?;
268 Ok(TMapIdentifier::new(key_type, val_type, element_count))
269 }
270 }
271
272 fn read_map_end(&mut self) -> ::Result<()> {
273 Ok(())
274 }
275
276 // utility
277 //
278
279 fn read_byte(&mut self) -> ::Result<u8> {
280 let mut buf = [0u8; 1];
281 self.transport.borrow_mut().read_exact(&mut buf).map_err(From::from).map(|_| buf[0])
282 }
283}
284
285/// Factory for creating instances of `TCompactInputProtocol`.
286#[derive(Default)]
287pub struct TCompactInputProtocolFactory;
288
289impl TCompactInputProtocolFactory {
290 /// Create a `TCompactInputProtocolFactory`.
291 pub fn new() -> TCompactInputProtocolFactory {
292 TCompactInputProtocolFactory {}
293 }
294}
295
296impl TInputProtocolFactory for TCompactInputProtocolFactory {
Chao Sunc063b302017-03-12 12:21:05 -0700297 fn create<'a>(&mut self, transport: Rc<RefCell<Box<TTransport + 'a>>>) -> Box<TInputProtocol + 'a> {
298 Box::new(TCompactInputProtocol::new(transport)) as Box<TInputProtocol + 'a>
Allen George8b96bfb2016-11-02 08:01:08 -0400299 }
300}
301
302/// Write messages using the Thrift compact protocol.
303///
304/// # Examples
305///
306/// Create and use a `TCompactOutputProtocol`.
307///
308/// ```no_run
309/// use std::cell::RefCell;
310/// use std::rc::Rc;
311/// use thrift::protocol::{TCompactOutputProtocol, TOutputProtocol};
312/// use thrift::transport::{TTcpTransport, TTransport};
313///
314/// let mut transport = TTcpTransport::new();
315/// transport.open("localhost:9090").unwrap();
316/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
317///
318/// let mut o_prot = TCompactOutputProtocol::new(transport);
319///
320/// o_prot.write_bool(true).unwrap();
321/// o_prot.write_string("test_string").unwrap();
322/// ```
Chao Sunc063b302017-03-12 12:21:05 -0700323pub struct TCompactOutputProtocol<'a> {
Allen George8b96bfb2016-11-02 08:01:08 -0400324 // Identifier of the last field serialized for a struct.
325 last_write_field_id: i16,
326 // Stack of the last written field ids (a new entry is added each time a nested struct is written).
327 write_field_id_stack: Vec<i16>,
328 // Field identifier of the boolean field to be written.
329 // Saved because boolean fields and their value are encoded in a single byte
330 pending_write_bool_field_identifier: Option<TFieldIdentifier>,
331 // Underlying transport used for byte-level operations.
Chao Sunc063b302017-03-12 12:21:05 -0700332 transport: Rc<RefCell<Box<TTransport + 'a>>>,
Allen George8b96bfb2016-11-02 08:01:08 -0400333}
334
Chao Sunc063b302017-03-12 12:21:05 -0700335impl<'a> TCompactOutputProtocol<'a> {
Allen George8b96bfb2016-11-02 08:01:08 -0400336 /// Create a `TCompactOutputProtocol` that writes bytes to `transport`.
Chao Sunc063b302017-03-12 12:21:05 -0700337 pub fn new(transport: Rc<RefCell<Box<TTransport + 'a>>>) -> TCompactOutputProtocol<'a> {
Allen George8b96bfb2016-11-02 08:01:08 -0400338 TCompactOutputProtocol {
339 last_write_field_id: 0,
340 write_field_id_stack: Vec::new(),
341 pending_write_bool_field_identifier: None,
342 transport: transport,
343 }
344 }
345
346 // FIXME: field_type as unconstrained u8 is bad
347 fn write_field_header(&mut self, field_type: u8, field_id: i16) -> ::Result<()> {
348 let field_delta = field_id - self.last_write_field_id;
349 if field_delta > 0 && field_delta < 15 {
350 self.write_byte(((field_delta as u8) << 4) | field_type)?;
351 } else {
352 self.write_byte(field_type)?;
353 self.write_i16(field_id)?;
354 }
355 self.last_write_field_id = field_id;
356 Ok(())
357 }
358
359 fn write_list_set_begin(&mut self, element_type: TType, element_count: i32) -> ::Result<()> {
360 let elem_identifier = collection_type_to_u8(element_type);
361 if element_count <= 14 {
362 let header = (element_count as u8) << 4 | elem_identifier;
363 self.write_byte(header)
364 } else {
365 let header = 0xF0 | elem_identifier;
366 self.write_byte(header)?;
367 self.transport
368 .borrow_mut()
369 .write_varint(element_count as u32)
370 .map_err(From::from)
371 .map(|_| ())
372 }
373 }
374
375 fn assert_no_pending_bool_write(&self) {
376 if let Some(ref f) = self.pending_write_bool_field_identifier {
377 panic!("pending bool field {:?} not written", f)
378 }
379 }
380}
381
Chao Sunc063b302017-03-12 12:21:05 -0700382impl<'a> TOutputProtocol for TCompactOutputProtocol<'a> {
Allen George8b96bfb2016-11-02 08:01:08 -0400383 fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
384 self.write_byte(COMPACT_PROTOCOL_ID)?;
385 self.write_byte((u8::from(identifier.message_type) << 5) | COMPACT_VERSION)?;
386 self.write_i32(identifier.sequence_number)?;
387 self.write_string(&identifier.name)?;
388 Ok(())
389 }
390
391 fn write_message_end(&mut self) -> ::Result<()> {
392 self.assert_no_pending_bool_write();
393 Ok(())
394 }
395
396 fn write_struct_begin(&mut self, _: &TStructIdentifier) -> ::Result<()> {
397 self.write_field_id_stack.push(self.last_write_field_id);
398 self.last_write_field_id = 0;
399 Ok(())
400 }
401
402 fn write_struct_end(&mut self) -> ::Result<()> {
403 self.assert_no_pending_bool_write();
404 self.last_write_field_id =
405 self.write_field_id_stack.pop().expect("should have previous field ids");
406 Ok(())
407 }
408
409 fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()> {
410 match identifier.field_type {
411 TType::Bool => {
412 if self.pending_write_bool_field_identifier.is_some() {
413 panic!("should not have a pending bool while writing another bool with id: \
414 {:?}",
415 identifier)
416 }
417 self.pending_write_bool_field_identifier = Some(identifier.clone());
418 Ok(())
419 }
420 _ => {
421 let field_type = type_to_u8(identifier.field_type);
422 let field_id = identifier.id.expect("non-stop field should have field id");
423 self.write_field_header(field_type, field_id)
424 }
425 }
426 }
427
428 fn write_field_end(&mut self) -> ::Result<()> {
429 self.assert_no_pending_bool_write();
430 Ok(())
431 }
432
433 fn write_field_stop(&mut self) -> ::Result<()> {
434 self.assert_no_pending_bool_write();
435 self.write_byte(type_to_u8(TType::Stop))
436 }
437
438 fn write_bool(&mut self, b: bool) -> ::Result<()> {
439 match self.pending_write_bool_field_identifier.take() {
440 Some(pending) => {
441 let field_id = pending.id.expect("bool field should have a field id");
442 let field_type_as_u8 = if b { 0x01 } else { 0x02 };
443 self.write_field_header(field_type_as_u8, field_id)
444 }
445 None => {
446 if b {
447 self.write_byte(0x01)
448 } else {
449 self.write_byte(0x02)
450 }
451 }
452 }
453 }
454
455 fn write_bytes(&mut self, b: &[u8]) -> ::Result<()> {
456 self.transport.borrow_mut().write_varint(b.len() as u32)?;
457 self.transport.borrow_mut().write_all(b).map_err(From::from)
458 }
459
460 fn write_i8(&mut self, i: i8) -> ::Result<()> {
461 self.write_byte(i as u8)
462 }
463
464 fn write_i16(&mut self, i: i16) -> ::Result<()> {
465 self.transport.borrow_mut().write_varint(i).map_err(From::from).map(|_| ())
466 }
467
468 fn write_i32(&mut self, i: i32) -> ::Result<()> {
469 self.transport.borrow_mut().write_varint(i).map_err(From::from).map(|_| ())
470 }
471
472 fn write_i64(&mut self, i: i64) -> ::Result<()> {
473 self.transport.borrow_mut().write_varint(i).map_err(From::from).map(|_| ())
474 }
475
476 fn write_double(&mut self, d: f64) -> ::Result<()> {
477 self.transport.borrow_mut().write_f64::<BigEndian>(d).map_err(From::from)
478 }
479
480 fn write_string(&mut self, s: &str) -> ::Result<()> {
481 self.write_bytes(s.as_bytes())
482 }
483
484 fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()> {
485 self.write_list_set_begin(identifier.element_type, identifier.size)
486 }
487
488 fn write_list_end(&mut self) -> ::Result<()> {
489 Ok(())
490 }
491
492 fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()> {
493 self.write_list_set_begin(identifier.element_type, identifier.size)
494 }
495
496 fn write_set_end(&mut self) -> ::Result<()> {
497 Ok(())
498 }
499
500 fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()> {
501 if identifier.size == 0 {
502 self.write_byte(0)
503 } else {
504 self.transport.borrow_mut().write_varint(identifier.size as u32)?;
505
506 let key_type = identifier.key_type
507 .expect("map identifier to write should contain key type");
508 let key_type_byte = collection_type_to_u8(key_type) << 4;
509
510 let val_type = identifier.value_type
511 .expect("map identifier to write should contain value type");
512 let val_type_byte = collection_type_to_u8(val_type);
513
514 let map_type_header = key_type_byte | val_type_byte;
515 self.write_byte(map_type_header)
516 }
517 }
518
519 fn write_map_end(&mut self) -> ::Result<()> {
520 Ok(())
521 }
522
523 fn flush(&mut self) -> ::Result<()> {
524 self.transport.borrow_mut().flush().map_err(From::from)
525 }
526
527 // utility
528 //
529
530 fn write_byte(&mut self, b: u8) -> ::Result<()> {
531 self.transport.borrow_mut().write(&[b]).map_err(From::from).map(|_| ())
532 }
533}
534
535/// Factory for creating instances of `TCompactOutputProtocol`.
536#[derive(Default)]
537pub struct TCompactOutputProtocolFactory;
538
539impl TCompactOutputProtocolFactory {
540 /// Create a `TCompactOutputProtocolFactory`.
541 pub fn new() -> TCompactOutputProtocolFactory {
542 TCompactOutputProtocolFactory {}
543 }
544}
545
546impl TOutputProtocolFactory for TCompactOutputProtocolFactory {
547 fn create(&mut self, transport: Rc<RefCell<Box<TTransport>>>) -> Box<TOutputProtocol> {
548 Box::new(TCompactOutputProtocol::new(transport)) as Box<TOutputProtocol>
549 }
550}
551
552fn collection_type_to_u8(field_type: TType) -> u8 {
553 match field_type {
554 TType::Bool => 0x01,
555 f => type_to_u8(f),
556 }
557}
558
559fn type_to_u8(field_type: TType) -> u8 {
560 match field_type {
561 TType::Stop => 0x00,
562 TType::I08 => 0x03, // equivalent to TType::Byte
563 TType::I16 => 0x04,
564 TType::I32 => 0x05,
565 TType::I64 => 0x06,
566 TType::Double => 0x07,
567 TType::String => 0x08,
568 TType::List => 0x09,
569 TType::Set => 0x0A,
570 TType::Map => 0x0B,
571 TType::Struct => 0x0C,
572 _ => panic!(format!("should not have attempted to convert {} to u8", field_type)),
573 }
574}
575
576fn collection_u8_to_type(b: u8) -> ::Result<TType> {
577 match b {
578 0x01 => Ok(TType::Bool),
579 o => u8_to_type(o),
580 }
581}
582
583fn u8_to_type(b: u8) -> ::Result<TType> {
584 match b {
585 0x00 => Ok(TType::Stop),
586 0x03 => Ok(TType::I08), // equivalent to TType::Byte
587 0x04 => Ok(TType::I16),
588 0x05 => Ok(TType::I32),
589 0x06 => Ok(TType::I64),
590 0x07 => Ok(TType::Double),
591 0x08 => Ok(TType::String),
592 0x09 => Ok(TType::List),
593 0x0A => Ok(TType::Set),
594 0x0B => Ok(TType::Map),
595 0x0C => Ok(TType::Struct),
596 unkn => {
597 Err(::Error::Protocol(::ProtocolError {
598 kind: ::ProtocolErrorKind::InvalidData,
599 message: format!("cannot convert {} into TType", unkn),
600 }))
601 }
602 }
603}
604
605#[cfg(test)]
606mod tests {
607
608 use std::rc::Rc;
609 use std::cell::RefCell;
610
611 use ::protocol::{TFieldIdentifier, TMessageIdentifier, TMessageType, TInputProtocol,
612 TListIdentifier, TMapIdentifier, TOutputProtocol, TSetIdentifier,
613 TStructIdentifier, TType};
614 use ::transport::{TPassThruTransport, TTransport};
615 use ::transport::mem::TBufferTransport;
616
617 use super::*;
618
619 #[test]
620 fn must_write_message_begin_0() {
621 let (trans, _, mut o_prot) = test_objects();
622
623 assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new("foo", TMessageType::Call, 431)));
624
625 let expected: [u8; 8] =
626 [0x82 /* protocol ID */, 0x21 /* message type | protocol version */, 0xDE,
627 0x06 /* zig-zag varint sequence number */, 0x03 /* message-name length */,
628 0x66, 0x6F, 0x6F /* "foo" */];
629
630 assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
631 }
632
633 #[test]
634 fn must_write_message_begin_1() {
635 let (trans, _, mut o_prot) = test_objects();
636
637 assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new("bar", TMessageType::Reply, 991828)));
638
639 let expected: [u8; 9] =
640 [0x82 /* protocol ID */, 0x41 /* message type | protocol version */, 0xA8,
641 0x89, 0x79 /* zig-zag varint sequence number */,
642 0x03 /* message-name length */, 0x62, 0x61, 0x72 /* "bar" */];
643
644 assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
645 }
646
647 #[test]
648 fn must_round_trip_message_begin() {
649 let (trans, mut i_prot, mut o_prot) = test_objects();
650
651 let ident = TMessageIdentifier::new("service_call", TMessageType::Call, 1283948);
652
653 assert_success!(o_prot.write_message_begin(&ident));
654
655 trans.borrow_mut().copy_write_buffer_to_read_buffer();
656
657 let res = assert_success!(i_prot.read_message_begin());
658 assert_eq!(&res, &ident);
659 }
660
661 #[test]
662 fn must_write_message_end() {
663 assert_no_write(|o| o.write_message_end());
664 }
665
666 // NOTE: structs and fields are tested together
667 //
668
669 #[test]
670 fn must_write_struct_with_delta_fields() {
671 let (trans, _, mut o_prot) = test_objects();
672
673 // no bytes should be written however
674 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
675
676 // write three fields with tiny field ids
677 // since they're small the field ids will be encoded as deltas
678
679 // since this is the first field (and it's zero) it gets the full varint write
680 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 0)));
681 assert_success!(o_prot.write_field_end());
682
683 // since this delta > 0 and < 15 it can be encoded as a delta
684 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I16, 4)));
685 assert_success!(o_prot.write_field_end());
686
687 // since this delta > 0 and < 15 it can be encoded as a delta
688 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::List, 9)));
689 assert_success!(o_prot.write_field_end());
690
691 // now, finish the struct off
692 assert_success!(o_prot.write_field_stop());
693 assert_success!(o_prot.write_struct_end());
694
695 // get bytes written
696 let buf = trans.borrow_mut().write_buffer_to_vec();
697
698 let expected: [u8; 5] = [0x03 /* field type */, 0x00 /* first field id */,
699 0x44 /* field delta (4) | field type */,
700 0x59 /* field delta (5) | field type */,
701 0x00 /* field stop */];
702
703 assert_eq!(&buf, &expected);
704 }
705
706 #[test]
707 fn must_round_trip_struct_with_delta_fields() {
708 let (trans, mut i_prot, mut o_prot) = test_objects();
709
710 // no bytes should be written however
711 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
712
713 // write three fields with tiny field ids
714 // since they're small the field ids will be encoded as deltas
715
716 // since this is the first field (and it's zero) it gets the full varint write
717 let field_ident_1 = TFieldIdentifier::new("foo", TType::I08, 0);
718 assert_success!(o_prot.write_field_begin(&field_ident_1));
719 assert_success!(o_prot.write_field_end());
720
721 // since this delta > 0 and < 15 it can be encoded as a delta
722 let field_ident_2 = TFieldIdentifier::new("foo", TType::I16, 4);
723 assert_success!(o_prot.write_field_begin(&field_ident_2));
724 assert_success!(o_prot.write_field_end());
725
726 // since this delta > 0 and < 15 it can be encoded as a delta
727 let field_ident_3 = TFieldIdentifier::new("foo", TType::List, 9);
728 assert_success!(o_prot.write_field_begin(&field_ident_3));
729 assert_success!(o_prot.write_field_end());
730
731 // now, finish the struct off
732 assert_success!(o_prot.write_field_stop());
733 assert_success!(o_prot.write_struct_end());
734
735 trans.borrow_mut().copy_write_buffer_to_read_buffer();
736
737 // read the struct back
738 assert_success!(i_prot.read_struct_begin());
739
740 let read_ident_1 = assert_success!(i_prot.read_field_begin());
741 assert_eq!(read_ident_1,
742 TFieldIdentifier { name: None, ..field_ident_1 });
743 assert_success!(i_prot.read_field_end());
744
745 let read_ident_2 = assert_success!(i_prot.read_field_begin());
746 assert_eq!(read_ident_2,
747 TFieldIdentifier { name: None, ..field_ident_2 });
748 assert_success!(i_prot.read_field_end());
749
750 let read_ident_3 = assert_success!(i_prot.read_field_begin());
751 assert_eq!(read_ident_3,
752 TFieldIdentifier { name: None, ..field_ident_3 });
753 assert_success!(i_prot.read_field_end());
754
755 let read_ident_4 = assert_success!(i_prot.read_field_begin());
756 assert_eq!(read_ident_4,
757 TFieldIdentifier {
758 name: None,
759 field_type: TType::Stop,
760 id: None,
761 });
762
763 assert_success!(i_prot.read_struct_end());
764 }
765
766 #[test]
767 fn must_write_struct_with_non_zero_initial_field_and_delta_fields() {
768 let (trans, _, mut o_prot) = test_objects();
769
770 // no bytes should be written however
771 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
772
773 // write three fields with tiny field ids
774 // since they're small the field ids will be encoded as deltas
775
776 // gets a delta write
777 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 1)));
778 assert_success!(o_prot.write_field_end());
779
780 // since this delta > 0 and < 15 it can be encoded as a delta
781 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2)));
782 assert_success!(o_prot.write_field_end());
783
784 // since this delta > 0 and < 15 it can be encoded as a delta
785 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 6)));
786 assert_success!(o_prot.write_field_end());
787
788 // now, finish the struct off
789 assert_success!(o_prot.write_field_stop());
790 assert_success!(o_prot.write_struct_end());
791
792 // get bytes written
793 let buf = trans.borrow_mut().write_buffer_to_vec();
794
795 let expected: [u8; 4] = [0x15 /* field delta (1) | field type */,
796 0x1A /* field delta (1) | field type */,
797 0x48 /* field delta (4) | field type */,
798 0x00 /* field stop */];
799
800 assert_eq!(&buf, &expected);
801 }
802
803 #[test]
804 fn must_round_trip_struct_with_non_zero_initial_field_and_delta_fields() {
805 let (trans, mut i_prot, mut o_prot) = test_objects();
806
807 // no bytes should be written however
808 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
809
810 // write three fields with tiny field ids
811 // since they're small the field ids will be encoded as deltas
812
813 // gets a delta write
814 let field_ident_1 = TFieldIdentifier::new("foo", TType::I32, 1);
815 assert_success!(o_prot.write_field_begin(&field_ident_1));
816 assert_success!(o_prot.write_field_end());
817
818 // since this delta > 0 and < 15 it can be encoded as a delta
819 let field_ident_2 = TFieldIdentifier::new("foo", TType::Set, 2);
820 assert_success!(o_prot.write_field_begin(&field_ident_2));
821 assert_success!(o_prot.write_field_end());
822
823 // since this delta > 0 and < 15 it can be encoded as a delta
824 let field_ident_3 = TFieldIdentifier::new("foo", TType::String, 6);
825 assert_success!(o_prot.write_field_begin(&field_ident_3));
826 assert_success!(o_prot.write_field_end());
827
828 // now, finish the struct off
829 assert_success!(o_prot.write_field_stop());
830 assert_success!(o_prot.write_struct_end());
831
832 trans.borrow_mut().copy_write_buffer_to_read_buffer();
833
834 // read the struct back
835 assert_success!(i_prot.read_struct_begin());
836
837 let read_ident_1 = assert_success!(i_prot.read_field_begin());
838 assert_eq!(read_ident_1,
839 TFieldIdentifier { name: None, ..field_ident_1 });
840 assert_success!(i_prot.read_field_end());
841
842 let read_ident_2 = assert_success!(i_prot.read_field_begin());
843 assert_eq!(read_ident_2,
844 TFieldIdentifier { name: None, ..field_ident_2 });
845 assert_success!(i_prot.read_field_end());
846
847 let read_ident_3 = assert_success!(i_prot.read_field_begin());
848 assert_eq!(read_ident_3,
849 TFieldIdentifier { name: None, ..field_ident_3 });
850 assert_success!(i_prot.read_field_end());
851
852 let read_ident_4 = assert_success!(i_prot.read_field_begin());
853 assert_eq!(read_ident_4,
854 TFieldIdentifier {
855 name: None,
856 field_type: TType::Stop,
857 id: None,
858 });
859
860 assert_success!(i_prot.read_struct_end());
861 }
862
863 #[test]
864 fn must_write_struct_with_long_fields() {
865 let (trans, _, mut o_prot) = test_objects();
866
867 // no bytes should be written however
868 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
869
870 // write three fields with field ids that cannot be encoded as deltas
871
872 // since this is the first field (and it's zero) it gets the full varint write
873 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 0)));
874 assert_success!(o_prot.write_field_end());
875
876 // since this delta is > 15 it is encoded as a zig-zag varint
877 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 16)));
878 assert_success!(o_prot.write_field_end());
879
880 // since this delta is > 15 it is encoded as a zig-zag varint
881 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 99)));
882 assert_success!(o_prot.write_field_end());
883
884 // now, finish the struct off
885 assert_success!(o_prot.write_field_stop());
886 assert_success!(o_prot.write_struct_end());
887
888 // get bytes written
889 let buf = trans.borrow_mut().write_buffer_to_vec();
890
891 let expected: [u8; 8] =
892 [0x05 /* field type */, 0x00 /* first field id */,
893 0x06 /* field type */, 0x20 /* zig-zag varint field id */,
894 0x0A /* field type */, 0xC6, 0x01 /* zig-zag varint field id */,
895 0x00 /* field stop */];
896
897 assert_eq!(&buf, &expected);
898 }
899
900 #[test]
901 fn must_round_trip_struct_with_long_fields() {
902 let (trans, mut i_prot, mut o_prot) = test_objects();
903
904 // no bytes should be written however
905 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
906
907 // write three fields with field ids that cannot be encoded as deltas
908
909 // since this is the first field (and it's zero) it gets the full varint write
910 let field_ident_1 = TFieldIdentifier::new("foo", TType::I32, 0);
911 assert_success!(o_prot.write_field_begin(&field_ident_1));
912 assert_success!(o_prot.write_field_end());
913
914 // since this delta is > 15 it is encoded as a zig-zag varint
915 let field_ident_2 = TFieldIdentifier::new("foo", TType::I64, 16);
916 assert_success!(o_prot.write_field_begin(&field_ident_2));
917 assert_success!(o_prot.write_field_end());
918
919 // since this delta is > 15 it is encoded as a zig-zag varint
920 let field_ident_3 = TFieldIdentifier::new("foo", TType::Set, 99);
921 assert_success!(o_prot.write_field_begin(&field_ident_3));
922 assert_success!(o_prot.write_field_end());
923
924 // now, finish the struct off
925 assert_success!(o_prot.write_field_stop());
926 assert_success!(o_prot.write_struct_end());
927
928 trans.borrow_mut().copy_write_buffer_to_read_buffer();
929
930 // read the struct back
931 assert_success!(i_prot.read_struct_begin());
932
933 let read_ident_1 = assert_success!(i_prot.read_field_begin());
934 assert_eq!(read_ident_1,
935 TFieldIdentifier { name: None, ..field_ident_1 });
936 assert_success!(i_prot.read_field_end());
937
938 let read_ident_2 = assert_success!(i_prot.read_field_begin());
939 assert_eq!(read_ident_2,
940 TFieldIdentifier { name: None, ..field_ident_2 });
941 assert_success!(i_prot.read_field_end());
942
943 let read_ident_3 = assert_success!(i_prot.read_field_begin());
944 assert_eq!(read_ident_3,
945 TFieldIdentifier { name: None, ..field_ident_3 });
946 assert_success!(i_prot.read_field_end());
947
948 let read_ident_4 = assert_success!(i_prot.read_field_begin());
949 assert_eq!(read_ident_4,
950 TFieldIdentifier {
951 name: None,
952 field_type: TType::Stop,
953 id: None,
954 });
955
956 assert_success!(i_prot.read_struct_end());
957 }
958
959 #[test]
960 fn must_write_struct_with_mix_of_long_and_delta_fields() {
961 let (trans, _, mut o_prot) = test_objects();
962
963 // no bytes should be written however
964 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
965
966 // write three fields with field ids that cannot be encoded as deltas
967
968 // since the delta is > 0 and < 15 it gets a delta write
969 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
970 assert_success!(o_prot.write_field_end());
971
972 // since this delta > 0 and < 15 it gets a delta write
973 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
974 assert_success!(o_prot.write_field_end());
975
976 // since this delta is > 15 it is encoded as a zig-zag varint
977 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 1000)));
978 assert_success!(o_prot.write_field_end());
979
980 // since this delta is > 15 it is encoded as a zig-zag varint
981 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2001)));
982 assert_success!(o_prot.write_field_end());
983
984 // since this is only 3 up from the previous it is recorded as a delta
985 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2004)));
986 assert_success!(o_prot.write_field_end());
987
988 // now, finish the struct off
989 assert_success!(o_prot.write_field_stop());
990 assert_success!(o_prot.write_struct_end());
991
992 // get bytes written
993 let buf = trans.borrow_mut().write_buffer_to_vec();
994
995 let expected: [u8; 10] =
996 [0x16 /* field delta (1) | field type */,
997 0x85 /* field delta (8) | field type */, 0x0A /* field type */, 0xD0,
998 0x0F /* zig-zag varint field id */, 0x0A /* field type */, 0xA2,
999 0x1F /* zig-zag varint field id */,
1000 0x3A /* field delta (3) | field type */, 0x00 /* field stop */];
1001
1002 assert_eq!(&buf, &expected);
1003 }
1004
1005 #[test]
1006 fn must_round_trip_struct_with_mix_of_long_and_delta_fields() {
1007 let (trans, mut i_prot, mut o_prot) = test_objects();
1008
1009 // no bytes should be written however
1010 let struct_ident = TStructIdentifier::new("foo");
1011 assert_success!(o_prot.write_struct_begin(&struct_ident));
1012
1013 // write three fields with field ids that cannot be encoded as deltas
1014
1015 // since the delta is > 0 and < 15 it gets a delta write
1016 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1017 assert_success!(o_prot.write_field_begin(&field_ident_1));
1018 assert_success!(o_prot.write_field_end());
1019
1020 // since this delta > 0 and < 15 it gets a delta write
1021 let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
1022 assert_success!(o_prot.write_field_begin(&field_ident_2));
1023 assert_success!(o_prot.write_field_end());
1024
1025 // since this delta is > 15 it is encoded as a zig-zag varint
1026 let field_ident_3 = TFieldIdentifier::new("foo", TType::Set, 1000);
1027 assert_success!(o_prot.write_field_begin(&field_ident_3));
1028 assert_success!(o_prot.write_field_end());
1029
1030 // since this delta is > 15 it is encoded as a zig-zag varint
1031 let field_ident_4 = TFieldIdentifier::new("foo", TType::Set, 2001);
1032 assert_success!(o_prot.write_field_begin(&field_ident_4));
1033 assert_success!(o_prot.write_field_end());
1034
1035 // since this is only 3 up from the previous it is recorded as a delta
1036 let field_ident_5 = TFieldIdentifier::new("foo", TType::Set, 2004);
1037 assert_success!(o_prot.write_field_begin(&field_ident_5));
1038 assert_success!(o_prot.write_field_end());
1039
1040 // now, finish the struct off
1041 assert_success!(o_prot.write_field_stop());
1042 assert_success!(o_prot.write_struct_end());
1043
1044 trans.borrow_mut().copy_write_buffer_to_read_buffer();
1045
1046 // read the struct back
1047 assert_success!(i_prot.read_struct_begin());
1048
1049 let read_ident_1 = assert_success!(i_prot.read_field_begin());
1050 assert_eq!(read_ident_1,
1051 TFieldIdentifier { name: None, ..field_ident_1 });
1052 assert_success!(i_prot.read_field_end());
1053
1054 let read_ident_2 = assert_success!(i_prot.read_field_begin());
1055 assert_eq!(read_ident_2,
1056 TFieldIdentifier { name: None, ..field_ident_2 });
1057 assert_success!(i_prot.read_field_end());
1058
1059 let read_ident_3 = assert_success!(i_prot.read_field_begin());
1060 assert_eq!(read_ident_3,
1061 TFieldIdentifier { name: None, ..field_ident_3 });
1062 assert_success!(i_prot.read_field_end());
1063
1064 let read_ident_4 = assert_success!(i_prot.read_field_begin());
1065 assert_eq!(read_ident_4,
1066 TFieldIdentifier { name: None, ..field_ident_4 });
1067 assert_success!(i_prot.read_field_end());
1068
1069 let read_ident_5 = assert_success!(i_prot.read_field_begin());
1070 assert_eq!(read_ident_5,
1071 TFieldIdentifier { name: None, ..field_ident_5 });
1072 assert_success!(i_prot.read_field_end());
1073
1074 let read_ident_6 = assert_success!(i_prot.read_field_begin());
1075 assert_eq!(read_ident_6,
1076 TFieldIdentifier {
1077 name: None,
1078 field_type: TType::Stop,
1079 id: None,
1080 });
1081
1082 assert_success!(i_prot.read_struct_end());
1083 }
1084
1085 #[test]
1086 fn must_write_nested_structs_0() {
1087 // last field of the containing struct is a delta
1088 // first field of the the contained struct is a delta
1089
1090 let (trans, _, mut o_prot) = test_objects();
1091
1092 // start containing struct
1093 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1094
1095 // containing struct
1096 // since the delta is > 0 and < 15 it gets a delta write
1097 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
1098 assert_success!(o_prot.write_field_end());
1099
1100 // containing struct
1101 // since this delta > 0 and < 15 it gets a delta write
1102 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
1103 assert_success!(o_prot.write_field_end());
1104
1105 // start contained struct
1106 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1107
1108 // contained struct
1109 // since the delta is > 0 and < 15 it gets a delta write
1110 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 7)));
1111 assert_success!(o_prot.write_field_end());
1112
1113 // contained struct
1114 // since this delta > 15 it gets a full write
1115 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 24)));
1116 assert_success!(o_prot.write_field_end());
1117
1118 // end contained struct
1119 assert_success!(o_prot.write_field_stop());
1120 assert_success!(o_prot.write_struct_end());
1121
1122 // end containing struct
1123 assert_success!(o_prot.write_field_stop());
1124 assert_success!(o_prot.write_struct_end());
1125
1126 // get bytes written
1127 let buf = trans.borrow_mut().write_buffer_to_vec();
1128
1129 let expected: [u8; 7] =
1130 [0x16 /* field delta (1) | field type */,
1131 0x85 /* field delta (8) | field type */,
1132 0x73 /* field delta (7) | field type */, 0x07 /* field type */,
1133 0x30 /* zig-zag varint field id */, 0x00 /* field stop - contained */,
1134 0x00 /* field stop - containing */];
1135
1136 assert_eq!(&buf, &expected);
1137 }
1138
1139 #[test]
1140 fn must_round_trip_nested_structs_0() {
1141 // last field of the containing struct is a delta
1142 // first field of the the contained struct is a delta
1143
1144 let (trans, mut i_prot, mut o_prot) = test_objects();
1145
1146 // start containing struct
1147 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1148
1149 // containing struct
1150 // since the delta is > 0 and < 15 it gets a delta write
1151 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1152 assert_success!(o_prot.write_field_begin(&field_ident_1));
1153 assert_success!(o_prot.write_field_end());
1154
1155 // containing struct
1156 // since this delta > 0 and < 15 it gets a delta write
1157 let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
1158 assert_success!(o_prot.write_field_begin(&field_ident_2));
1159 assert_success!(o_prot.write_field_end());
1160
1161 // start contained struct
1162 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1163
1164 // contained struct
1165 // since the delta is > 0 and < 15 it gets a delta write
1166 let field_ident_3 = TFieldIdentifier::new("foo", TType::I08, 7);
1167 assert_success!(o_prot.write_field_begin(&field_ident_3));
1168 assert_success!(o_prot.write_field_end());
1169
1170 // contained struct
1171 // since this delta > 15 it gets a full write
1172 let field_ident_4 = TFieldIdentifier::new("foo", TType::Double, 24);
1173 assert_success!(o_prot.write_field_begin(&field_ident_4));
1174 assert_success!(o_prot.write_field_end());
1175
1176 // end contained struct
1177 assert_success!(o_prot.write_field_stop());
1178 assert_success!(o_prot.write_struct_end());
1179
1180 // end containing struct
1181 assert_success!(o_prot.write_field_stop());
1182 assert_success!(o_prot.write_struct_end());
1183
1184 trans.borrow_mut().copy_write_buffer_to_read_buffer();
1185
1186 // read containing struct back
1187 assert_success!(i_prot.read_struct_begin());
1188
1189 let read_ident_1 = assert_success!(i_prot.read_field_begin());
1190 assert_eq!(read_ident_1,
1191 TFieldIdentifier { name: None, ..field_ident_1 });
1192 assert_success!(i_prot.read_field_end());
1193
1194 let read_ident_2 = assert_success!(i_prot.read_field_begin());
1195 assert_eq!(read_ident_2,
1196 TFieldIdentifier { name: None, ..field_ident_2 });
1197 assert_success!(i_prot.read_field_end());
1198
1199 // read contained struct back
1200 assert_success!(i_prot.read_struct_begin());
1201
1202 let read_ident_3 = assert_success!(i_prot.read_field_begin());
1203 assert_eq!(read_ident_3,
1204 TFieldIdentifier { name: None, ..field_ident_3 });
1205 assert_success!(i_prot.read_field_end());
1206
1207 let read_ident_4 = assert_success!(i_prot.read_field_begin());
1208 assert_eq!(read_ident_4,
1209 TFieldIdentifier { name: None, ..field_ident_4 });
1210 assert_success!(i_prot.read_field_end());
1211
1212 // end contained struct
1213 let read_ident_6 = assert_success!(i_prot.read_field_begin());
1214 assert_eq!(read_ident_6,
1215 TFieldIdentifier {
1216 name: None,
1217 field_type: TType::Stop,
1218 id: None,
1219 });
1220 assert_success!(i_prot.read_struct_end());
1221
1222 // end containing struct
1223 let read_ident_7 = assert_success!(i_prot.read_field_begin());
1224 assert_eq!(read_ident_7,
1225 TFieldIdentifier {
1226 name: None,
1227 field_type: TType::Stop,
1228 id: None,
1229 });
1230 assert_success!(i_prot.read_struct_end());
1231 }
1232
1233 #[test]
1234 fn must_write_nested_structs_1() {
1235 // last field of the containing struct is a delta
1236 // first field of the the contained struct is a full write
1237
1238 let (trans, _, mut o_prot) = test_objects();
1239
1240 // start containing struct
1241 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1242
1243 // containing struct
1244 // since the delta is > 0 and < 15 it gets a delta write
1245 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
1246 assert_success!(o_prot.write_field_end());
1247
1248 // containing struct
1249 // since this delta > 0 and < 15 it gets a delta write
1250 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
1251 assert_success!(o_prot.write_field_end());
1252
1253 // start contained struct
1254 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1255
1256 // contained struct
1257 // since this delta > 15 it gets a full write
1258 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 24)));
1259 assert_success!(o_prot.write_field_end());
1260
1261 // contained struct
1262 // since the delta is > 0 and < 15 it gets a delta write
1263 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 27)));
1264 assert_success!(o_prot.write_field_end());
1265
1266 // end contained struct
1267 assert_success!(o_prot.write_field_stop());
1268 assert_success!(o_prot.write_struct_end());
1269
1270 // end containing struct
1271 assert_success!(o_prot.write_field_stop());
1272 assert_success!(o_prot.write_struct_end());
1273
1274 // get bytes written
1275 let buf = trans.borrow_mut().write_buffer_to_vec();
1276
1277 let expected: [u8; 7] =
1278 [0x16 /* field delta (1) | field type */,
1279 0x85 /* field delta (8) | field type */, 0x07 /* field type */,
1280 0x30 /* zig-zag varint field id */,
1281 0x33 /* field delta (3) | field type */, 0x00 /* field stop - contained */,
1282 0x00 /* field stop - containing */];
1283
1284 assert_eq!(&buf, &expected);
1285 }
1286
1287 #[test]
1288 fn must_round_trip_nested_structs_1() {
1289 // last field of the containing struct is a delta
1290 // first field of the the contained struct is a full write
1291
1292 let (trans, mut i_prot, mut o_prot) = test_objects();
1293
1294 // start containing struct
1295 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1296
1297 // containing struct
1298 // since the delta is > 0 and < 15 it gets a delta write
1299 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1300 assert_success!(o_prot.write_field_begin(&field_ident_1));
1301 assert_success!(o_prot.write_field_end());
1302
1303 // containing struct
1304 // since this delta > 0 and < 15 it gets a delta write
1305 let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
1306 assert_success!(o_prot.write_field_begin(&field_ident_2));
1307 assert_success!(o_prot.write_field_end());
1308
1309 // start contained struct
1310 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1311
1312 // contained struct
1313 // since this delta > 15 it gets a full write
1314 let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 24);
1315 assert_success!(o_prot.write_field_begin(&field_ident_3));
1316 assert_success!(o_prot.write_field_end());
1317
1318 // contained struct
1319 // since the delta is > 0 and < 15 it gets a delta write
1320 let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 27);
1321 assert_success!(o_prot.write_field_begin(&field_ident_4));
1322 assert_success!(o_prot.write_field_end());
1323
1324 // end contained struct
1325 assert_success!(o_prot.write_field_stop());
1326 assert_success!(o_prot.write_struct_end());
1327
1328 // end containing struct
1329 assert_success!(o_prot.write_field_stop());
1330 assert_success!(o_prot.write_struct_end());
1331
1332 trans.borrow_mut().copy_write_buffer_to_read_buffer();
1333
1334 // read containing struct back
1335 assert_success!(i_prot.read_struct_begin());
1336
1337 let read_ident_1 = assert_success!(i_prot.read_field_begin());
1338 assert_eq!(read_ident_1,
1339 TFieldIdentifier { name: None, ..field_ident_1 });
1340 assert_success!(i_prot.read_field_end());
1341
1342 let read_ident_2 = assert_success!(i_prot.read_field_begin());
1343 assert_eq!(read_ident_2,
1344 TFieldIdentifier { name: None, ..field_ident_2 });
1345 assert_success!(i_prot.read_field_end());
1346
1347 // read contained struct back
1348 assert_success!(i_prot.read_struct_begin());
1349
1350 let read_ident_3 = assert_success!(i_prot.read_field_begin());
1351 assert_eq!(read_ident_3,
1352 TFieldIdentifier { name: None, ..field_ident_3 });
1353 assert_success!(i_prot.read_field_end());
1354
1355 let read_ident_4 = assert_success!(i_prot.read_field_begin());
1356 assert_eq!(read_ident_4,
1357 TFieldIdentifier { name: None, ..field_ident_4 });
1358 assert_success!(i_prot.read_field_end());
1359
1360 // end contained struct
1361 let read_ident_6 = assert_success!(i_prot.read_field_begin());
1362 assert_eq!(read_ident_6,
1363 TFieldIdentifier {
1364 name: None,
1365 field_type: TType::Stop,
1366 id: None,
1367 });
1368 assert_success!(i_prot.read_struct_end());
1369
1370 // end containing struct
1371 let read_ident_7 = assert_success!(i_prot.read_field_begin());
1372 assert_eq!(read_ident_7,
1373 TFieldIdentifier {
1374 name: None,
1375 field_type: TType::Stop,
1376 id: None,
1377 });
1378 assert_success!(i_prot.read_struct_end());
1379 }
1380
1381 #[test]
1382 fn must_write_nested_structs_2() {
1383 // last field of the containing struct is a full write
1384 // first field of the the contained struct is a delta write
1385
1386 let (trans, _, mut o_prot) = test_objects();
1387
1388 // start containing struct
1389 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1390
1391 // containing struct
1392 // since the delta is > 0 and < 15 it gets a delta write
1393 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
1394 assert_success!(o_prot.write_field_end());
1395
1396 // containing struct
1397 // since this delta > 15 it gets a full write
1398 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 21)));
1399 assert_success!(o_prot.write_field_end());
1400
1401 // start contained struct
1402 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1403
1404 // contained struct
1405 // since this delta > 0 and < 15 it gets a delta write
1406 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 7)));
1407 assert_success!(o_prot.write_field_end());
1408
1409 // contained struct
1410 // since the delta is > 0 and < 15 it gets a delta write
1411 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 10)));
1412 assert_success!(o_prot.write_field_end());
1413
1414 // end contained struct
1415 assert_success!(o_prot.write_field_stop());
1416 assert_success!(o_prot.write_struct_end());
1417
1418 // end containing struct
1419 assert_success!(o_prot.write_field_stop());
1420 assert_success!(o_prot.write_struct_end());
1421
1422 // get bytes written
1423 let buf = trans.borrow_mut().write_buffer_to_vec();
1424
1425 let expected: [u8; 7] =
1426 [0x16 /* field delta (1) | field type */, 0x08 /* field type */,
1427 0x2A /* zig-zag varint field id */, 0x77 /* field delta(7) | field type */,
1428 0x33 /* field delta (3) | field type */, 0x00 /* field stop - contained */,
1429 0x00 /* field stop - containing */];
1430
1431 assert_eq!(&buf, &expected);
1432 }
1433
1434 #[test]
1435 fn must_round_trip_nested_structs_2() {
1436 let (trans, mut i_prot, mut o_prot) = test_objects();
1437
1438 // start containing struct
1439 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1440
1441 // containing struct
1442 // since the delta is > 0 and < 15 it gets a delta write
1443 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1444 assert_success!(o_prot.write_field_begin(&field_ident_1));
1445 assert_success!(o_prot.write_field_end());
1446
1447 // containing struct
1448 // since this delta > 15 it gets a full write
1449 let field_ident_2 = TFieldIdentifier::new("foo", TType::String, 21);
1450 assert_success!(o_prot.write_field_begin(&field_ident_2));
1451 assert_success!(o_prot.write_field_end());
1452
1453 // start contained struct
1454 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1455
1456 // contained struct
1457 // since this delta > 0 and < 15 it gets a delta write
1458 let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 7);
1459 assert_success!(o_prot.write_field_begin(&field_ident_3));
1460 assert_success!(o_prot.write_field_end());
1461
1462 // contained struct
1463 // since the delta is > 0 and < 15 it gets a delta write
1464 let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 10);
1465 assert_success!(o_prot.write_field_begin(&field_ident_4));
1466 assert_success!(o_prot.write_field_end());
1467
1468 // end contained struct
1469 assert_success!(o_prot.write_field_stop());
1470 assert_success!(o_prot.write_struct_end());
1471
1472 // end containing struct
1473 assert_success!(o_prot.write_field_stop());
1474 assert_success!(o_prot.write_struct_end());
1475
1476 trans.borrow_mut().copy_write_buffer_to_read_buffer();
1477
1478 // read containing struct back
1479 assert_success!(i_prot.read_struct_begin());
1480
1481 let read_ident_1 = assert_success!(i_prot.read_field_begin());
1482 assert_eq!(read_ident_1,
1483 TFieldIdentifier { name: None, ..field_ident_1 });
1484 assert_success!(i_prot.read_field_end());
1485
1486 let read_ident_2 = assert_success!(i_prot.read_field_begin());
1487 assert_eq!(read_ident_2,
1488 TFieldIdentifier { name: None, ..field_ident_2 });
1489 assert_success!(i_prot.read_field_end());
1490
1491 // read contained struct back
1492 assert_success!(i_prot.read_struct_begin());
1493
1494 let read_ident_3 = assert_success!(i_prot.read_field_begin());
1495 assert_eq!(read_ident_3,
1496 TFieldIdentifier { name: None, ..field_ident_3 });
1497 assert_success!(i_prot.read_field_end());
1498
1499 let read_ident_4 = assert_success!(i_prot.read_field_begin());
1500 assert_eq!(read_ident_4,
1501 TFieldIdentifier { name: None, ..field_ident_4 });
1502 assert_success!(i_prot.read_field_end());
1503
1504 // end contained struct
1505 let read_ident_6 = assert_success!(i_prot.read_field_begin());
1506 assert_eq!(read_ident_6,
1507 TFieldIdentifier {
1508 name: None,
1509 field_type: TType::Stop,
1510 id: None,
1511 });
1512 assert_success!(i_prot.read_struct_end());
1513
1514 // end containing struct
1515 let read_ident_7 = assert_success!(i_prot.read_field_begin());
1516 assert_eq!(read_ident_7,
1517 TFieldIdentifier {
1518 name: None,
1519 field_type: TType::Stop,
1520 id: None,
1521 });
1522 assert_success!(i_prot.read_struct_end());
1523 }
1524
1525 #[test]
1526 fn must_write_nested_structs_3() {
1527 // last field of the containing struct is a full write
1528 // first field of the the contained struct is a full write
1529
1530 let (trans, _, mut o_prot) = test_objects();
1531
1532 // start containing struct
1533 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1534
1535 // containing struct
1536 // since the delta is > 0 and < 15 it gets a delta write
1537 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
1538 assert_success!(o_prot.write_field_end());
1539
1540 // containing struct
1541 // since this delta > 15 it gets a full write
1542 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 21)));
1543 assert_success!(o_prot.write_field_end());
1544
1545 // start contained struct
1546 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1547
1548 // contained struct
1549 // since this delta > 15 it gets a full write
1550 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 21)));
1551 assert_success!(o_prot.write_field_end());
1552
1553 // contained struct
1554 // since the delta is > 0 and < 15 it gets a delta write
1555 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 27)));
1556 assert_success!(o_prot.write_field_end());
1557
1558 // end contained struct
1559 assert_success!(o_prot.write_field_stop());
1560 assert_success!(o_prot.write_struct_end());
1561
1562 // end containing struct
1563 assert_success!(o_prot.write_field_stop());
1564 assert_success!(o_prot.write_struct_end());
1565
1566 // get bytes written
1567 let buf = trans.borrow_mut().write_buffer_to_vec();
1568
1569 let expected: [u8; 8] =
1570 [0x16 /* field delta (1) | field type */, 0x08 /* field type */,
1571 0x2A /* zig-zag varint field id */, 0x07 /* field type */,
1572 0x2A /* zig-zag varint field id */,
1573 0x63 /* field delta (6) | field type */, 0x00 /* field stop - contained */,
1574 0x00 /* field stop - containing */];
1575
1576 assert_eq!(&buf, &expected);
1577 }
1578
1579 #[test]
1580 fn must_round_trip_nested_structs_3() {
1581 // last field of the containing struct is a full write
1582 // first field of the the contained struct is a full write
1583
1584 let (trans, mut i_prot, mut o_prot) = test_objects();
1585
1586 // start containing struct
1587 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1588
1589 // containing struct
1590 // since the delta is > 0 and < 15 it gets a delta write
1591 let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
1592 assert_success!(o_prot.write_field_begin(&field_ident_1));
1593 assert_success!(o_prot.write_field_end());
1594
1595 // containing struct
1596 // since this delta > 15 it gets a full write
1597 let field_ident_2 = TFieldIdentifier::new("foo", TType::String, 21);
1598 assert_success!(o_prot.write_field_begin(&field_ident_2));
1599 assert_success!(o_prot.write_field_end());
1600
1601 // start contained struct
1602 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1603
1604 // contained struct
1605 // since this delta > 15 it gets a full write
1606 let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 21);
1607 assert_success!(o_prot.write_field_begin(&field_ident_3));
1608 assert_success!(o_prot.write_field_end());
1609
1610 // contained struct
1611 // since the delta is > 0 and < 15 it gets a delta write
1612 let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 27);
1613 assert_success!(o_prot.write_field_begin(&field_ident_4));
1614 assert_success!(o_prot.write_field_end());
1615
1616 // end contained struct
1617 assert_success!(o_prot.write_field_stop());
1618 assert_success!(o_prot.write_struct_end());
1619
1620 // end containing struct
1621 assert_success!(o_prot.write_field_stop());
1622 assert_success!(o_prot.write_struct_end());
1623
1624 trans.borrow_mut().copy_write_buffer_to_read_buffer();
1625
1626 // read containing struct back
1627 assert_success!(i_prot.read_struct_begin());
1628
1629 let read_ident_1 = assert_success!(i_prot.read_field_begin());
1630 assert_eq!(read_ident_1,
1631 TFieldIdentifier { name: None, ..field_ident_1 });
1632 assert_success!(i_prot.read_field_end());
1633
1634 let read_ident_2 = assert_success!(i_prot.read_field_begin());
1635 assert_eq!(read_ident_2,
1636 TFieldIdentifier { name: None, ..field_ident_2 });
1637 assert_success!(i_prot.read_field_end());
1638
1639 // read contained struct back
1640 assert_success!(i_prot.read_struct_begin());
1641
1642 let read_ident_3 = assert_success!(i_prot.read_field_begin());
1643 assert_eq!(read_ident_3,
1644 TFieldIdentifier { name: None, ..field_ident_3 });
1645 assert_success!(i_prot.read_field_end());
1646
1647 let read_ident_4 = assert_success!(i_prot.read_field_begin());
1648 assert_eq!(read_ident_4,
1649 TFieldIdentifier { name: None, ..field_ident_4 });
1650 assert_success!(i_prot.read_field_end());
1651
1652 // end contained struct
1653 let read_ident_6 = assert_success!(i_prot.read_field_begin());
1654 assert_eq!(read_ident_6,
1655 TFieldIdentifier {
1656 name: None,
1657 field_type: TType::Stop,
1658 id: None,
1659 });
1660 assert_success!(i_prot.read_struct_end());
1661
1662 // end containing struct
1663 let read_ident_7 = assert_success!(i_prot.read_field_begin());
1664 assert_eq!(read_ident_7,
1665 TFieldIdentifier {
1666 name: None,
1667 field_type: TType::Stop,
1668 id: None,
1669 });
1670 assert_success!(i_prot.read_struct_end());
1671 }
1672
1673 #[test]
1674 fn must_write_bool_field() {
1675 let (trans, _, mut o_prot) = test_objects();
1676
1677 // no bytes should be written however
1678 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1679
1680 // write three fields with field ids that cannot be encoded as deltas
1681
1682 // since the delta is > 0 and < 16 it gets a delta write
1683 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
1684 assert_success!(o_prot.write_bool(true));
1685 assert_success!(o_prot.write_field_end());
1686
1687 // since this delta > 0 and < 15 it gets a delta write
1688 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 9)));
1689 assert_success!(o_prot.write_bool(false));
1690 assert_success!(o_prot.write_field_end());
1691
1692 // since this delta > 15 it gets a full write
1693 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 26)));
1694 assert_success!(o_prot.write_bool(true));
1695 assert_success!(o_prot.write_field_end());
1696
1697 // since this delta > 15 it gets a full write
1698 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 45)));
1699 assert_success!(o_prot.write_bool(false));
1700 assert_success!(o_prot.write_field_end());
1701
1702 // now, finish the struct off
1703 assert_success!(o_prot.write_field_stop());
1704 assert_success!(o_prot.write_struct_end());
1705
1706 // get bytes written
1707 let buf = trans.borrow_mut().write_buffer_to_vec();
1708
1709 let expected: [u8; 7] = [0x11 /* field delta (1) | true */,
1710 0x82 /* field delta (8) | false */, 0x01 /* true */,
1711 0x34 /* field id */, 0x02 /* false */,
1712 0x5A /* field id */, 0x00 /* stop field */];
1713
1714 assert_eq!(&buf, &expected);
1715 }
1716
1717 #[test]
1718 fn must_round_trip_bool_field() {
1719 let (trans, mut i_prot, mut o_prot) = test_objects();
1720
1721 // no bytes should be written however
1722 let struct_ident = TStructIdentifier::new("foo");
1723 assert_success!(o_prot.write_struct_begin(&struct_ident));
1724
1725 // write two fields
1726
1727 // since the delta is > 0 and < 16 it gets a delta write
1728 let field_ident_1 = TFieldIdentifier::new("foo", TType::Bool, 1);
1729 assert_success!(o_prot.write_field_begin(&field_ident_1));
1730 assert_success!(o_prot.write_bool(true));
1731 assert_success!(o_prot.write_field_end());
1732
1733 // since this delta > 0 and < 15 it gets a delta write
1734 let field_ident_2 = TFieldIdentifier::new("foo", TType::Bool, 9);
1735 assert_success!(o_prot.write_field_begin(&field_ident_2));
1736 assert_success!(o_prot.write_bool(false));
1737 assert_success!(o_prot.write_field_end());
1738
1739 // since this delta > 15 it gets a full write
1740 let field_ident_3 = TFieldIdentifier::new("foo", TType::Bool, 26);
1741 assert_success!(o_prot.write_field_begin(&field_ident_3));
1742 assert_success!(o_prot.write_bool(true));
1743 assert_success!(o_prot.write_field_end());
1744
1745 // since this delta > 15 it gets a full write
1746 let field_ident_4 = TFieldIdentifier::new("foo", TType::Bool, 45);
1747 assert_success!(o_prot.write_field_begin(&field_ident_4));
1748 assert_success!(o_prot.write_bool(false));
1749 assert_success!(o_prot.write_field_end());
1750
1751 // now, finish the struct off
1752 assert_success!(o_prot.write_field_stop());
1753 assert_success!(o_prot.write_struct_end());
1754
1755 trans.borrow_mut().copy_write_buffer_to_read_buffer();
1756
1757 // read the struct back
1758 assert_success!(i_prot.read_struct_begin());
1759
1760 let read_ident_1 = assert_success!(i_prot.read_field_begin());
1761 assert_eq!(read_ident_1,
1762 TFieldIdentifier { name: None, ..field_ident_1 });
1763 let read_value_1 = assert_success!(i_prot.read_bool());
1764 assert_eq!(read_value_1, true);
1765 assert_success!(i_prot.read_field_end());
1766
1767 let read_ident_2 = assert_success!(i_prot.read_field_begin());
1768 assert_eq!(read_ident_2,
1769 TFieldIdentifier { name: None, ..field_ident_2 });
1770 let read_value_2 = assert_success!(i_prot.read_bool());
1771 assert_eq!(read_value_2, false);
1772 assert_success!(i_prot.read_field_end());
1773
1774 let read_ident_3 = assert_success!(i_prot.read_field_begin());
1775 assert_eq!(read_ident_3,
1776 TFieldIdentifier { name: None, ..field_ident_3 });
1777 let read_value_3 = assert_success!(i_prot.read_bool());
1778 assert_eq!(read_value_3, true);
1779 assert_success!(i_prot.read_field_end());
1780
1781 let read_ident_4 = assert_success!(i_prot.read_field_begin());
1782 assert_eq!(read_ident_4,
1783 TFieldIdentifier { name: None, ..field_ident_4 });
1784 let read_value_4 = assert_success!(i_prot.read_bool());
1785 assert_eq!(read_value_4, false);
1786 assert_success!(i_prot.read_field_end());
1787
1788 let read_ident_5 = assert_success!(i_prot.read_field_begin());
1789 assert_eq!(read_ident_5,
1790 TFieldIdentifier {
1791 name: None,
1792 field_type: TType::Stop,
1793 id: None,
1794 });
1795
1796 assert_success!(i_prot.read_struct_end());
1797 }
1798
1799 #[test]
1800 #[should_panic]
1801 fn must_fail_if_write_field_end_without_writing_bool_value() {
1802 let (_, _, mut o_prot) = test_objects();
1803 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1804 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
1805 o_prot.write_field_end().unwrap();
1806 }
1807
1808 #[test]
1809 #[should_panic]
1810 fn must_fail_if_write_stop_field_without_writing_bool_value() {
1811 let (_, _, mut o_prot) = test_objects();
1812 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1813 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
1814 o_prot.write_field_stop().unwrap();
1815 }
1816
1817 #[test]
1818 #[should_panic]
1819 fn must_fail_if_write_struct_end_without_writing_bool_value() {
1820 let (_, _, mut o_prot) = test_objects();
1821 assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
1822 assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
1823 o_prot.write_struct_end().unwrap();
1824 }
1825
1826 #[test]
1827 #[should_panic]
1828 fn must_fail_if_write_struct_end_without_any_fields() {
1829 let (_, _, mut o_prot) = test_objects();
1830 o_prot.write_struct_end().unwrap();
1831 }
1832
1833 #[test]
1834 fn must_write_field_end() {
1835 assert_no_write(|o| o.write_field_end());
1836 }
1837
1838 #[test]
1839 fn must_write_small_sized_list_begin() {
1840 let (trans, _, mut o_prot) = test_objects();
1841
1842 assert_success!(o_prot.write_list_begin(&TListIdentifier::new(TType::I64, 4)));
1843
1844 let expected: [u8; 1] = [0x46 /* size | elem_type */];
1845
1846 assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
1847 }
1848
1849 #[test]
1850 fn must_round_trip_small_sized_list_begin() {
1851 let (trans, mut i_prot, mut o_prot) = test_objects();
1852
1853 let ident = TListIdentifier::new(TType::I08, 10);
1854
1855 assert_success!(o_prot.write_list_begin(&ident));
1856
1857 trans.borrow_mut().copy_write_buffer_to_read_buffer();
1858
1859 let res = assert_success!(i_prot.read_list_begin());
1860 assert_eq!(&res, &ident);
1861 }
1862
1863 #[test]
1864 fn must_write_large_sized_list_begin() {
1865 let (trans, _, mut o_prot) = test_objects();
1866
1867 let res = o_prot.write_list_begin(&TListIdentifier::new(TType::List, 9999));
1868 assert!(res.is_ok());
1869
1870 let expected: [u8; 3] = [0xF9 /* 0xF0 | elem_type */, 0x8F,
1871 0x4E /* size as varint */];
1872
1873 assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
1874 }
1875
1876 #[test]
1877 fn must_round_trip_large_sized_list_begin() {
1878 let (trans, mut i_prot, mut o_prot) = test_objects();
1879
1880 let ident = TListIdentifier::new(TType::Set, 47381);
1881
1882 assert_success!(o_prot.write_list_begin(&ident));
1883
1884 trans.borrow_mut().copy_write_buffer_to_read_buffer();
1885
1886 let res = assert_success!(i_prot.read_list_begin());
1887 assert_eq!(&res, &ident);
1888 }
1889
1890 #[test]
1891 fn must_write_list_end() {
1892 assert_no_write(|o| o.write_list_end());
1893 }
1894
1895 #[test]
1896 fn must_write_small_sized_set_begin() {
1897 let (trans, _, mut o_prot) = test_objects();
1898
1899 assert_success!(o_prot.write_set_begin(&TSetIdentifier::new(TType::Struct, 2)));
1900
1901 let expected: [u8; 1] = [0x2C /* size | elem_type */];
1902
1903 assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
1904 }
1905
1906 #[test]
1907 fn must_round_trip_small_sized_set_begin() {
1908 let (trans, mut i_prot, mut o_prot) = test_objects();
1909
1910 let ident = TSetIdentifier::new(TType::I16, 7);
1911
1912 assert_success!(o_prot.write_set_begin(&ident));
1913
1914 trans.borrow_mut().copy_write_buffer_to_read_buffer();
1915
1916 let res = assert_success!(i_prot.read_set_begin());
1917 assert_eq!(&res, &ident);
1918 }
1919
1920 #[test]
1921 fn must_write_large_sized_set_begin() {
1922 let (trans, _, mut o_prot) = test_objects();
1923
1924 assert_success!(o_prot.write_set_begin(&TSetIdentifier::new(TType::Double, 23891)));
1925
1926 let expected: [u8; 4] = [0xF7 /* 0xF0 | elem_type */, 0xD3, 0xBA,
1927 0x01 /* size as varint */];
1928
1929 assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
1930 }
1931
1932 #[test]
1933 fn must_round_trip_large_sized_set_begin() {
1934 let (trans, mut i_prot, mut o_prot) = test_objects();
1935
1936 let ident = TSetIdentifier::new(TType::Map, 3928429);
1937
1938 assert_success!(o_prot.write_set_begin(&ident));
1939
1940 trans.borrow_mut().copy_write_buffer_to_read_buffer();
1941
1942 let res = assert_success!(i_prot.read_set_begin());
1943 assert_eq!(&res, &ident);
1944 }
1945
1946 #[test]
1947 fn must_write_set_end() {
1948 assert_no_write(|o| o.write_set_end());
1949 }
1950
1951 #[test]
1952 fn must_write_zero_sized_map_begin() {
1953 let (trans, _, mut o_prot) = test_objects();
1954
1955 assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::String, TType::I32, 0)));
1956
1957 let expected: [u8; 1] = [0x00]; // since size is zero we don't write anything
1958
1959 assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
1960 }
1961
1962 #[test]
1963 fn must_read_zero_sized_map_begin() {
1964 let (trans, mut i_prot, mut o_prot) = test_objects();
1965
1966 assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Double, TType::I32, 0)));
1967
1968 trans.borrow_mut().copy_write_buffer_to_read_buffer();
1969
1970 let res = assert_success!(i_prot.read_map_begin());
1971 assert_eq!(&res,
1972 &TMapIdentifier {
1973 key_type: None,
1974 value_type: None,
1975 size: 0,
1976 });
1977 }
1978
1979 #[test]
1980 fn must_write_map_begin() {
1981 let (trans, _, mut o_prot) = test_objects();
1982
1983 assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Double, TType::String, 238)));
1984
1985 let expected: [u8; 3] = [0xEE, 0x01 /* size as varint */,
1986 0x78 /* key type | val type */];
1987
1988 assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
1989 }
1990
1991 #[test]
1992 fn must_round_trip_map_begin() {
1993 let (trans, mut i_prot, mut o_prot) = test_objects();
1994
1995 let ident = TMapIdentifier::new(TType::Map, TType::List, 1928349);
1996
1997 assert_success!(o_prot.write_map_begin(&ident));
1998
1999 trans.borrow_mut().copy_write_buffer_to_read_buffer();
2000
2001 let res = assert_success!(i_prot.read_map_begin());
2002 assert_eq!(&res, &ident);
2003 }
2004
2005 #[test]
2006 fn must_write_map_end() {
2007 assert_no_write(|o| o.write_map_end());
2008 }
2009
2010 #[test]
2011 fn must_write_map_with_bool_key_and_value() {
2012 let (trans, _, mut o_prot) = test_objects();
2013
2014 assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Bool, TType::Bool, 1)));
2015 assert_success!(o_prot.write_bool(true));
2016 assert_success!(o_prot.write_bool(false));
2017 assert_success!(o_prot.write_map_end());
2018
2019 let expected: [u8; 4] = [0x01 /* size as varint */,
2020 0x11 /* key type | val type */, 0x01 /* key: true */,
2021 0x02 /* val: false */];
2022
2023 assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
2024 }
2025
2026 #[test]
2027 fn must_round_trip_map_with_bool_value() {
2028 let (trans, mut i_prot, mut o_prot) = test_objects();
2029
2030 let map_ident = TMapIdentifier::new(TType::Bool, TType::Bool, 2);
2031 assert_success!(o_prot.write_map_begin(&map_ident));
2032 assert_success!(o_prot.write_bool(true));
2033 assert_success!(o_prot.write_bool(false));
2034 assert_success!(o_prot.write_bool(false));
2035 assert_success!(o_prot.write_bool(true));
2036 assert_success!(o_prot.write_map_end());
2037
2038 trans.borrow_mut().copy_write_buffer_to_read_buffer();
2039
2040 // map header
2041 let rcvd_ident = assert_success!(i_prot.read_map_begin());
2042 assert_eq!(&rcvd_ident, &map_ident);
2043 // key 1
2044 let b = assert_success!(i_prot.read_bool());
2045 assert_eq!(b, true);
2046 // val 1
2047 let b = assert_success!(i_prot.read_bool());
2048 assert_eq!(b, false);
2049 // key 2
2050 let b = assert_success!(i_prot.read_bool());
2051 assert_eq!(b, false);
2052 // val 2
2053 let b = assert_success!(i_prot.read_bool());
2054 assert_eq!(b, true);
2055 // map end
2056 assert_success!(i_prot.read_map_end());
2057 }
2058
2059 #[test]
2060 fn must_read_map_end() {
2061 let (_, mut i_prot, _) = test_objects();
2062 assert!(i_prot.read_map_end().is_ok()); // will blow up if we try to read from empty buffer
2063 }
2064
Chao Sunc063b302017-03-12 12:21:05 -07002065 fn test_objects<'a>
Allen George8b96bfb2016-11-02 08:01:08 -04002066 ()
Chao Sunc063b302017-03-12 12:21:05 -07002067 -> (Rc<RefCell<Box<TBufferTransport>>>, TCompactInputProtocol<'a>, TCompactOutputProtocol<'a>)
Allen George8b96bfb2016-11-02 08:01:08 -04002068 {
2069 let mem = Rc::new(RefCell::new(Box::new(TBufferTransport::with_capacity(80, 80))));
2070
2071 let inner: Box<TTransport> = Box::new(TPassThruTransport { inner: mem.clone() });
2072 let inner = Rc::new(RefCell::new(inner));
2073
2074 let i_prot = TCompactInputProtocol::new(inner.clone());
2075 let o_prot = TCompactOutputProtocol::new(inner.clone());
2076
2077 (mem, i_prot, o_prot)
2078 }
2079
2080 fn assert_no_write<F: FnMut(&mut TCompactOutputProtocol) -> ::Result<()>>(mut write_fn: F) {
2081 let (trans, _, mut o_prot) = test_objects();
2082 assert!(write_fn(&mut o_prot).is_ok());
2083 assert_eq!(trans.borrow().write_buffer_as_ref().len(), 0);
2084 }
2085}