blob: 19aff3d6cf1a7894f059513c3cb04c3f4dfd94ac [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, ByteOrder, ReadBytesExt, WriteBytesExt};
Allen George8b96bfb2016-11-02 08:01:08 -040019use std::convert::From;
Allen George8b96bfb2016-11-02 08:01:08 -040020use try_from::TryFrom;
21
Allen Georgeef7a1892018-12-16 18:01:37 -050022use super::{
23 TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier, TMapIdentifier,
24 TMessageIdentifier, TMessageType,
25};
Allen George8b96bfb2016-11-02 08:01:08 -040026use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
Allen Georgeef7a1892018-12-16 18:01:37 -050027use transport::{TReadTransport, TWriteTransport};
28use {ProtocolError, ProtocolErrorKind};
Allen George8b96bfb2016-11-02 08:01:08 -040029
30const BINARY_PROTOCOL_VERSION_1: u32 = 0x80010000;
31
32/// Read messages encoded in the Thrift simple binary encoding.
33///
34/// There are two available modes: `strict` and `non-strict`, where the
35/// `non-strict` version does not check for the protocol version in the
36/// received message header.
37///
38/// # Examples
39///
40/// Create and use a `TBinaryInputProtocol`.
41///
42/// ```no_run
Allen George8b96bfb2016-11-02 08:01:08 -040043/// use thrift::protocol::{TBinaryInputProtocol, TInputProtocol};
Allen George0e22c362017-01-30 07:15:00 -050044/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -040045///
Allen George0e22c362017-01-30 07:15:00 -050046/// let mut channel = TTcpChannel::new();
47/// channel.open("localhost:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -040048///
Allen George0e22c362017-01-30 07:15:00 -050049/// let mut protocol = TBinaryInputProtocol::new(channel, true);
Allen George8b96bfb2016-11-02 08:01:08 -040050///
Allen George0e22c362017-01-30 07:15:00 -050051/// let recvd_bool = protocol.read_bool().unwrap();
52/// let recvd_string = protocol.read_string().unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -040053/// ```
Allen George0e22c362017-01-30 07:15:00 -050054#[derive(Debug)]
55pub struct TBinaryInputProtocol<T>
56where
57 T: TReadTransport,
58{
Allen George8b96bfb2016-11-02 08:01:08 -040059 strict: bool,
Allen Georgebc1344d2017-04-28 10:22:03 -040060 pub transport: T, // FIXME: shouldn't be public
Allen George8b96bfb2016-11-02 08:01:08 -040061}
62
Allen George0e22c362017-01-30 07:15:00 -050063impl<'a, T> TBinaryInputProtocol<T>
64where
65 T: TReadTransport,
66{
Allen George8b96bfb2016-11-02 08:01:08 -040067 /// Create a `TBinaryInputProtocol` that reads bytes from `transport`.
68 ///
69 /// Set `strict` to `true` if all incoming messages contain the protocol
70 /// version number in the protocol header.
Allen George0e22c362017-01-30 07:15:00 -050071 pub fn new(transport: T, strict: bool) -> TBinaryInputProtocol<T> {
Allen George8b96bfb2016-11-02 08:01:08 -040072 TBinaryInputProtocol {
73 strict: strict,
74 transport: transport,
75 }
76 }
77}
78
Allen George0e22c362017-01-30 07:15:00 -050079impl<T> TInputProtocol for TBinaryInputProtocol<T>
80where
81 T: TReadTransport,
82{
Allen George8b96bfb2016-11-02 08:01:08 -040083 #[cfg_attr(feature = "cargo-clippy", allow(collapsible_if))]
84 fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
85 let mut first_bytes = vec![0; 4];
Allen George0e22c362017-01-30 07:15:00 -050086 self.transport.read_exact(&mut first_bytes[..])?;
Allen George8b96bfb2016-11-02 08:01:08 -040087
88 // the thrift version header is intentionally negative
89 // so the first check we'll do is see if the sign bit is set
90 // and if so - assume it's the protocol-version header
91 if first_bytes[0] >= 8 {
92 // apparently we got a protocol-version header - check
93 // it, and if it matches, read the rest of the fields
94 if first_bytes[0..2] != [0x80, 0x01] {
Allen Georgeef7a1892018-12-16 18:01:37 -050095 Err(::Error::Protocol(ProtocolError {
96 kind: ProtocolErrorKind::BadVersion,
97 message: format!("received bad version: {:?}", &first_bytes[0..2]),
98 }))
Allen George8b96bfb2016-11-02 08:01:08 -040099 } else {
100 let message_type: TMessageType = TryFrom::try_from(first_bytes[3])?;
101 let name = self.read_string()?;
102 let sequence_number = self.read_i32()?;
103 Ok(TMessageIdentifier::new(name, message_type, sequence_number))
104 }
105 } else {
106 // apparently we didn't get a protocol-version header,
107 // which happens if the sender is not using the strict protocol
108 if self.strict {
109 // we're in strict mode however, and that always
110 // requires the protocol-version header to be written first
Allen Georgeef7a1892018-12-16 18:01:37 -0500111 Err(::Error::Protocol(ProtocolError {
112 kind: ProtocolErrorKind::BadVersion,
113 message: format!("received bad version: {:?}", &first_bytes[0..2]),
114 }))
Allen George8b96bfb2016-11-02 08:01:08 -0400115 } else {
116 // in the non-strict version the first message field
117 // is the message name. strings (byte arrays) are length-prefixed,
118 // so we've just read the length in the first 4 bytes
119 let name_size = BigEndian::read_i32(&first_bytes) as usize;
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500120 let mut name_buf: Vec<u8> = vec![0; name_size];
Allen George0e22c362017-01-30 07:15:00 -0500121 self.transport.read_exact(&mut name_buf)?;
Allen George8b96bfb2016-11-02 08:01:08 -0400122 let name = String::from_utf8(name_buf)?;
123
124 // read the rest of the fields
125 let message_type: TMessageType = self.read_byte().and_then(TryFrom::try_from)?;
126 let sequence_number = self.read_i32()?;
127 Ok(TMessageIdentifier::new(name, message_type, sequence_number))
128 }
129 }
130 }
131
132 fn read_message_end(&mut self) -> ::Result<()> {
133 Ok(())
134 }
135
136 fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
137 Ok(None)
138 }
139
140 fn read_struct_end(&mut self) -> ::Result<()> {
141 Ok(())
142 }
143
144 fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
145 let field_type_byte = self.read_byte()?;
146 let field_type = field_type_from_u8(field_type_byte)?;
147 let id = match field_type {
148 TType::Stop => Ok(0),
149 _ => self.read_i16(),
150 }?;
Allen Georgeef7a1892018-12-16 18:01:37 -0500151 Ok(TFieldIdentifier::new::<Option<String>, String, i16>(
152 None, field_type, id,
153 ))
Allen George8b96bfb2016-11-02 08:01:08 -0400154 }
155
156 fn read_field_end(&mut self) -> ::Result<()> {
157 Ok(())
158 }
159
160 fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
Allen George0e22c362017-01-30 07:15:00 -0500161 let num_bytes = self.transport.read_i32::<BigEndian>()? as usize;
Allen George8b96bfb2016-11-02 08:01:08 -0400162 let mut buf = vec![0u8; num_bytes];
Allen George0e22c362017-01-30 07:15:00 -0500163 self.transport
164 .read_exact(&mut buf)
165 .map(|_| buf)
166 .map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400167 }
168
169 fn read_bool(&mut self) -> ::Result<bool> {
170 let b = self.read_i8()?;
171 match b {
172 0 => Ok(false),
173 _ => Ok(true),
174 }
175 }
176
177 fn read_i8(&mut self) -> ::Result<i8> {
Allen George0e22c362017-01-30 07:15:00 -0500178 self.transport.read_i8().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400179 }
180
181 fn read_i16(&mut self) -> ::Result<i16> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500182 self.transport.read_i16::<BigEndian>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400183 }
184
185 fn read_i32(&mut self) -> ::Result<i32> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500186 self.transport.read_i32::<BigEndian>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400187 }
188
189 fn read_i64(&mut self) -> ::Result<i64> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500190 self.transport.read_i64::<BigEndian>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400191 }
192
193 fn read_double(&mut self) -> ::Result<f64> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500194 self.transport.read_f64::<BigEndian>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400195 }
196
197 fn read_string(&mut self) -> ::Result<String> {
198 let bytes = self.read_bytes()?;
199 String::from_utf8(bytes).map_err(From::from)
200 }
201
202 fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
203 let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
204 let size = self.read_i32()?;
205 Ok(TListIdentifier::new(element_type, size))
206 }
207
208 fn read_list_end(&mut self) -> ::Result<()> {
209 Ok(())
210 }
211
212 fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
213 let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
214 let size = self.read_i32()?;
215 Ok(TSetIdentifier::new(element_type, size))
216 }
217
218 fn read_set_end(&mut self) -> ::Result<()> {
219 Ok(())
220 }
221
222 fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
223 let key_type: TType = self.read_byte().and_then(field_type_from_u8)?;
224 let value_type: TType = self.read_byte().and_then(field_type_from_u8)?;
225 let size = self.read_i32()?;
226 Ok(TMapIdentifier::new(key_type, value_type, size))
227 }
228
229 fn read_map_end(&mut self) -> ::Result<()> {
230 Ok(())
231 }
232
233 // utility
234 //
235
236 fn read_byte(&mut self) -> ::Result<u8> {
Allen George0e22c362017-01-30 07:15:00 -0500237 self.transport.read_u8().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400238 }
239}
240
241/// Factory for creating instances of `TBinaryInputProtocol`.
242#[derive(Default)]
243pub struct TBinaryInputProtocolFactory;
244
245impl TBinaryInputProtocolFactory {
246 /// Create a `TBinaryInputProtocolFactory`.
247 pub fn new() -> TBinaryInputProtocolFactory {
248 TBinaryInputProtocolFactory {}
249 }
250}
251
252impl TInputProtocolFactory for TBinaryInputProtocolFactory {
Allen George0e22c362017-01-30 07:15:00 -0500253 fn create(&self, transport: Box<TReadTransport + Send>) -> Box<TInputProtocol + Send> {
254 Box::new(TBinaryInputProtocol::new(transport, true))
Allen George8b96bfb2016-11-02 08:01:08 -0400255 }
256}
257
258/// Write messages using the Thrift simple binary encoding.
259///
260/// There are two available modes: `strict` and `non-strict`, where the
261/// `strict` version writes the protocol version number in the outgoing message
262/// header and the `non-strict` version does not.
263///
264/// # Examples
265///
266/// Create and use a `TBinaryOutputProtocol`.
267///
268/// ```no_run
Allen George8b96bfb2016-11-02 08:01:08 -0400269/// use thrift::protocol::{TBinaryOutputProtocol, TOutputProtocol};
Allen George0e22c362017-01-30 07:15:00 -0500270/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -0400271///
Allen George0e22c362017-01-30 07:15:00 -0500272/// let mut channel = TTcpChannel::new();
273/// channel.open("localhost:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400274///
Allen George0e22c362017-01-30 07:15:00 -0500275/// let mut protocol = TBinaryOutputProtocol::new(channel, true);
Allen George8b96bfb2016-11-02 08:01:08 -0400276///
Allen George0e22c362017-01-30 07:15:00 -0500277/// protocol.write_bool(true).unwrap();
278/// protocol.write_string("test_string").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400279/// ```
Allen George0e22c362017-01-30 07:15:00 -0500280#[derive(Debug)]
281pub struct TBinaryOutputProtocol<T>
282where
283 T: TWriteTransport,
284{
Allen George8b96bfb2016-11-02 08:01:08 -0400285 strict: bool,
Allen George0e22c362017-01-30 07:15:00 -0500286 pub transport: T, // FIXME: do not make public; only public for testing!
Allen George8b96bfb2016-11-02 08:01:08 -0400287}
288
Allen George0e22c362017-01-30 07:15:00 -0500289impl<T> TBinaryOutputProtocol<T>
290where
291 T: TWriteTransport,
292{
Allen George8b96bfb2016-11-02 08:01:08 -0400293 /// Create a `TBinaryOutputProtocol` that writes bytes to `transport`.
294 ///
295 /// Set `strict` to `true` if all outgoing messages should contain the
296 /// protocol version number in the protocol header.
Allen George0e22c362017-01-30 07:15:00 -0500297 pub fn new(transport: T, strict: bool) -> TBinaryOutputProtocol<T> {
Allen George8b96bfb2016-11-02 08:01:08 -0400298 TBinaryOutputProtocol {
299 strict: strict,
300 transport: transport,
301 }
302 }
Allen George8b96bfb2016-11-02 08:01:08 -0400303}
304
Allen George0e22c362017-01-30 07:15:00 -0500305impl<T> TOutputProtocol for TBinaryOutputProtocol<T>
306where
307 T: TWriteTransport,
308{
Allen George8b96bfb2016-11-02 08:01:08 -0400309 fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
310 if self.strict {
311 let message_type: u8 = identifier.message_type.into();
312 let header = BINARY_PROTOCOL_VERSION_1 | (message_type as u32);
Allen George0e22c362017-01-30 07:15:00 -0500313 self.transport.write_u32::<BigEndian>(header)?;
Allen George8b96bfb2016-11-02 08:01:08 -0400314 self.write_string(&identifier.name)?;
315 self.write_i32(identifier.sequence_number)
316 } else {
317 self.write_string(&identifier.name)?;
318 self.write_byte(identifier.message_type.into())?;
319 self.write_i32(identifier.sequence_number)
320 }
321 }
322
323 fn write_message_end(&mut self) -> ::Result<()> {
324 Ok(())
325 }
326
327 fn write_struct_begin(&mut self, _: &TStructIdentifier) -> ::Result<()> {
328 Ok(())
329 }
330
331 fn write_struct_end(&mut self) -> ::Result<()> {
332 Ok(())
333 }
334
335 fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()> {
336 if identifier.id.is_none() && identifier.field_type != TType::Stop {
Allen Georgeef7a1892018-12-16 18:01:37 -0500337 return Err(::Error::Protocol(ProtocolError {
338 kind: ProtocolErrorKind::Unknown,
339 message: format!(
340 "cannot write identifier {:?} without sequence number",
341 &identifier
Allen George0e22c362017-01-30 07:15:00 -0500342 ),
Allen Georgeef7a1892018-12-16 18:01:37 -0500343 }));
Allen George8b96bfb2016-11-02 08:01:08 -0400344 }
345
346 self.write_byte(field_type_to_u8(identifier.field_type))?;
347 if let Some(id) = identifier.id {
348 self.write_i16(id)
349 } else {
350 Ok(())
351 }
352 }
353
354 fn write_field_end(&mut self) -> ::Result<()> {
355 Ok(())
356 }
357
358 fn write_field_stop(&mut self) -> ::Result<()> {
359 self.write_byte(field_type_to_u8(TType::Stop))
360 }
361
362 fn write_bytes(&mut self, b: &[u8]) -> ::Result<()> {
363 self.write_i32(b.len() as i32)?;
Allen Georgecf7ba4c2017-12-11 11:44:11 -0500364 self.transport.write_all(b).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400365 }
366
367 fn write_bool(&mut self, b: bool) -> ::Result<()> {
368 if b {
369 self.write_i8(1)
370 } else {
371 self.write_i8(0)
372 }
373 }
374
375 fn write_i8(&mut self, i: i8) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500376 self.transport.write_i8(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400377 }
378
379 fn write_i16(&mut self, i: i16) -> ::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500380 self.transport.write_i16::<BigEndian>(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400381 }
382
383 fn write_i32(&mut self, i: i32) -> ::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500384 self.transport.write_i32::<BigEndian>(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400385 }
386
387 fn write_i64(&mut self, i: i64) -> ::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500388 self.transport.write_i64::<BigEndian>(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400389 }
390
391 fn write_double(&mut self, d: f64) -> ::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500392 self.transport.write_f64::<BigEndian>(d).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400393 }
394
395 fn write_string(&mut self, s: &str) -> ::Result<()> {
396 self.write_bytes(s.as_bytes())
397 }
398
399 fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()> {
400 self.write_byte(field_type_to_u8(identifier.element_type))?;
401 self.write_i32(identifier.size)
402 }
403
404 fn write_list_end(&mut self) -> ::Result<()> {
405 Ok(())
406 }
407
408 fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()> {
409 self.write_byte(field_type_to_u8(identifier.element_type))?;
410 self.write_i32(identifier.size)
411 }
412
413 fn write_set_end(&mut self) -> ::Result<()> {
414 Ok(())
415 }
416
417 fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500418 let key_type = identifier
419 .key_type
Allen George8b96bfb2016-11-02 08:01:08 -0400420 .expect("map identifier to write should contain key type");
421 self.write_byte(field_type_to_u8(key_type))?;
Allen George0e22c362017-01-30 07:15:00 -0500422 let val_type = identifier
423 .value_type
Allen George8b96bfb2016-11-02 08:01:08 -0400424 .expect("map identifier to write should contain value type");
425 self.write_byte(field_type_to_u8(val_type))?;
426 self.write_i32(identifier.size)
427 }
428
429 fn write_map_end(&mut self) -> ::Result<()> {
430 Ok(())
431 }
432
433 fn flush(&mut self) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500434 self.transport.flush().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400435 }
436
437 // utility
438 //
439
440 fn write_byte(&mut self, b: u8) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500441 self.transport.write_u8(b).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400442 }
443}
444
445/// Factory for creating instances of `TBinaryOutputProtocol`.
446#[derive(Default)]
447pub struct TBinaryOutputProtocolFactory;
448
449impl TBinaryOutputProtocolFactory {
450 /// Create a `TBinaryOutputProtocolFactory`.
451 pub fn new() -> TBinaryOutputProtocolFactory {
452 TBinaryOutputProtocolFactory {}
453 }
454}
455
456impl TOutputProtocolFactory for TBinaryOutputProtocolFactory {
Allen George0e22c362017-01-30 07:15:00 -0500457 fn create(&self, transport: Box<TWriteTransport + Send>) -> Box<TOutputProtocol + Send> {
458 Box::new(TBinaryOutputProtocol::new(transport, true))
Allen George8b96bfb2016-11-02 08:01:08 -0400459 }
460}
461
462fn field_type_to_u8(field_type: TType) -> u8 {
463 match field_type {
464 TType::Stop => 0x00,
465 TType::Void => 0x01,
466 TType::Bool => 0x02,
467 TType::I08 => 0x03, // equivalent to TType::Byte
468 TType::Double => 0x04,
469 TType::I16 => 0x06,
470 TType::I32 => 0x08,
471 TType::I64 => 0x0A,
472 TType::String | TType::Utf7 => 0x0B,
473 TType::Struct => 0x0C,
474 TType::Map => 0x0D,
475 TType::Set => 0x0E,
476 TType::List => 0x0F,
477 TType::Utf8 => 0x10,
478 TType::Utf16 => 0x11,
479 }
480}
481
482fn field_type_from_u8(b: u8) -> ::Result<TType> {
483 match b {
484 0x00 => Ok(TType::Stop),
485 0x01 => Ok(TType::Void),
486 0x02 => Ok(TType::Bool),
487 0x03 => Ok(TType::I08), // Equivalent to TType::Byte
488 0x04 => Ok(TType::Double),
489 0x06 => Ok(TType::I16),
490 0x08 => Ok(TType::I32),
491 0x0A => Ok(TType::I64),
492 0x0B => Ok(TType::String), // technically, also a UTF7, but we'll treat it as string
493 0x0C => Ok(TType::Struct),
494 0x0D => Ok(TType::Map),
495 0x0E => Ok(TType::Set),
496 0x0F => Ok(TType::List),
497 0x10 => Ok(TType::Utf8),
498 0x11 => Ok(TType::Utf16),
Allen Georgeef7a1892018-12-16 18:01:37 -0500499 unkn => Err(::Error::Protocol(ProtocolError {
500 kind: ProtocolErrorKind::InvalidData,
501 message: format!("cannot convert {} to TType", unkn),
502 })),
Allen George8b96bfb2016-11-02 08:01:08 -0400503 }
504}
505
506#[cfg(test)]
507mod tests {
508
Allen Georgeef7a1892018-12-16 18:01:37 -0500509 use protocol::{
510 TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
511 TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType,
512 };
Allen George0e22c362017-01-30 07:15:00 -0500513 use transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
Allen George8b96bfb2016-11-02 08:01:08 -0400514
515 use super::*;
516
517 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500518 fn must_write_strict_message_call_begin() {
519 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400520
521 let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
522 assert!(o_prot.write_message_begin(&ident).is_ok());
523
Allen Georgeef7a1892018-12-16 18:01:37 -0500524 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -0500525 let expected: [u8; 16] = [
526 0x80,
527 0x01,
528 0x00,
529 0x01,
530 0x00,
531 0x00,
532 0x00,
533 0x04,
534 0x74,
535 0x65,
536 0x73,
537 0x74,
538 0x00,
539 0x00,
540 0x00,
541 0x01,
542 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400543
Allen George0e22c362017-01-30 07:15:00 -0500544 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400545 }
546
Allen George8b96bfb2016-11-02 08:01:08 -0400547 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500548 fn must_write_non_strict_message_call_begin() {
549 let (_, mut o_prot) = test_objects(false);
550
551 let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
552 assert!(o_prot.write_message_begin(&ident).is_ok());
553
Allen Georgeef7a1892018-12-16 18:01:37 -0500554 #[cfg_attr(rustfmt, rustfmt::skip)]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500555 let expected: [u8; 13] = [
556 0x00,
557 0x00,
558 0x00,
559 0x04,
560 0x74,
561 0x65,
562 0x73,
563 0x74,
564 0x01,
565 0x00,
566 0x00,
567 0x00,
568 0x01,
569 ];
570
571 assert_eq_written_bytes!(o_prot, expected);
572 }
573
574 #[test]
575 fn must_write_strict_message_reply_begin() {
576 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400577
578 let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
579 assert!(o_prot.write_message_begin(&ident).is_ok());
580
Allen Georgeef7a1892018-12-16 18:01:37 -0500581 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -0500582 let expected: [u8; 16] = [
583 0x80,
584 0x01,
585 0x00,
586 0x02,
587 0x00,
588 0x00,
589 0x00,
590 0x04,
591 0x74,
592 0x65,
593 0x73,
594 0x74,
595 0x00,
596 0x00,
597 0x00,
598 0x0A,
599 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400600
Allen George0e22c362017-01-30 07:15:00 -0500601 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400602 }
603
604 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500605 fn must_write_non_strict_message_reply_begin() {
606 let (_, mut o_prot) = test_objects(false);
607
608 let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
609 assert!(o_prot.write_message_begin(&ident).is_ok());
610
Allen Georgeef7a1892018-12-16 18:01:37 -0500611 #[cfg_attr(rustfmt, rustfmt::skip)]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500612 let expected: [u8; 13] = [
613 0x00,
614 0x00,
615 0x00,
616 0x04,
617 0x74,
618 0x65,
619 0x73,
620 0x74,
621 0x02,
622 0x00,
623 0x00,
624 0x00,
625 0x0A,
626 ];
627
628 assert_eq_written_bytes!(o_prot, expected);
629 }
630
631 #[test]
Allen George8b96bfb2016-11-02 08:01:08 -0400632 fn must_round_trip_strict_message_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500633 let (mut i_prot, mut o_prot) = test_objects(true);
634
635 let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
636 assert!(o_prot.write_message_begin(&sent_ident).is_ok());
637
638 copy_write_buffer_to_read_buffer!(o_prot);
639
640 let received_ident = assert_success!(i_prot.read_message_begin());
641 assert_eq!(&received_ident, &sent_ident);
642 }
643
644 #[test]
645 fn must_round_trip_non_strict_message_begin() {
646 let (mut i_prot, mut o_prot) = test_objects(false);
Allen George8b96bfb2016-11-02 08:01:08 -0400647
648 let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
649 assert!(o_prot.write_message_begin(&sent_ident).is_ok());
650
Allen George0e22c362017-01-30 07:15:00 -0500651 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400652
653 let received_ident = assert_success!(i_prot.read_message_begin());
654 assert_eq!(&received_ident, &sent_ident);
655 }
656
657 #[test]
658 fn must_write_message_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500659 assert_no_write(|o| o.write_message_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400660 }
661
662 #[test]
663 fn must_write_struct_begin() {
Allen Georgeef7a1892018-12-16 18:01:37 -0500664 assert_no_write(
665 |o| o.write_struct_begin(&TStructIdentifier::new("foo")),
666 true,
667 );
Allen George8b96bfb2016-11-02 08:01:08 -0400668 }
669
670 #[test]
671 fn must_write_struct_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500672 assert_no_write(|o| o.write_struct_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400673 }
674
675 #[test]
676 fn must_write_field_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500677 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400678
Allen Georgeef7a1892018-12-16 18:01:37 -0500679 assert!(o_prot
680 .write_field_begin(&TFieldIdentifier::new("some_field", TType::String, 22))
681 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400682
683 let expected: [u8; 3] = [0x0B, 0x00, 0x16];
Allen George0e22c362017-01-30 07:15:00 -0500684 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400685 }
686
687 #[test]
688 fn must_round_trip_field_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500689 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400690
691 let sent_field_ident = TFieldIdentifier::new("foo", TType::I64, 20);
692 assert!(o_prot.write_field_begin(&sent_field_ident).is_ok());
693
Allen George0e22c362017-01-30 07:15:00 -0500694 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400695
696 let expected_ident = TFieldIdentifier {
697 name: None,
698 field_type: TType::I64,
699 id: Some(20),
700 }; // no name
701 let received_ident = assert_success!(i_prot.read_field_begin());
702 assert_eq!(&received_ident, &expected_ident);
703 }
704
705 #[test]
706 fn must_write_stop_field() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500707 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400708
709 assert!(o_prot.write_field_stop().is_ok());
710
711 let expected: [u8; 1] = [0x00];
Allen George0e22c362017-01-30 07:15:00 -0500712 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400713 }
714
715 #[test]
716 fn must_round_trip_field_stop() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500717 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400718
719 assert!(o_prot.write_field_stop().is_ok());
720
Allen George0e22c362017-01-30 07:15:00 -0500721 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400722
723 let expected_ident = TFieldIdentifier {
724 name: None,
725 field_type: TType::Stop,
726 id: Some(0),
727 }; // we get id 0
728
729 let received_ident = assert_success!(i_prot.read_field_begin());
730 assert_eq!(&received_ident, &expected_ident);
731 }
732
733 #[test]
734 fn must_write_field_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500735 assert_no_write(|o| o.write_field_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400736 }
737
738 #[test]
739 fn must_write_list_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500740 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400741
Allen Georgeef7a1892018-12-16 18:01:37 -0500742 assert!(o_prot
743 .write_list_begin(&TListIdentifier::new(TType::Bool, 5))
744 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400745
746 let expected: [u8; 5] = [0x02, 0x00, 0x00, 0x00, 0x05];
Allen George0e22c362017-01-30 07:15:00 -0500747 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400748 }
749
750 #[test]
751 fn must_round_trip_list_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500752 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400753
754 let ident = TListIdentifier::new(TType::List, 900);
755 assert!(o_prot.write_list_begin(&ident).is_ok());
756
Allen George0e22c362017-01-30 07:15:00 -0500757 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400758
759 let received_ident = assert_success!(i_prot.read_list_begin());
760 assert_eq!(&received_ident, &ident);
761 }
762
763 #[test]
764 fn must_write_list_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500765 assert_no_write(|o| o.write_list_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400766 }
767
768 #[test]
769 fn must_write_set_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500770 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400771
Allen Georgeef7a1892018-12-16 18:01:37 -0500772 assert!(o_prot
773 .write_set_begin(&TSetIdentifier::new(TType::I16, 7))
774 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400775
776 let expected: [u8; 5] = [0x06, 0x00, 0x00, 0x00, 0x07];
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_set_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500782 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400783
784 let ident = TSetIdentifier::new(TType::I64, 2000);
785 assert!(o_prot.write_set_begin(&ident).is_ok());
786
Allen George0e22c362017-01-30 07:15:00 -0500787 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400788
789 let received_ident_result = i_prot.read_set_begin();
790 assert!(received_ident_result.is_ok());
791 assert_eq!(&received_ident_result.unwrap(), &ident);
792 }
793
794 #[test]
795 fn must_write_set_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500796 assert_no_write(|o| o.write_set_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400797 }
798
799 #[test]
800 fn must_write_map_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500801 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400802
Allen Georgeef7a1892018-12-16 18:01:37 -0500803 assert!(o_prot
804 .write_map_begin(&TMapIdentifier::new(TType::I64, TType::Struct, 32))
805 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400806
807 let expected: [u8; 6] = [0x0A, 0x0C, 0x00, 0x00, 0x00, 0x20];
Allen George0e22c362017-01-30 07:15:00 -0500808 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400809 }
810
811 #[test]
812 fn must_round_trip_map_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500813 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400814
815 let ident = TMapIdentifier::new(TType::Map, TType::Set, 100);
816 assert!(o_prot.write_map_begin(&ident).is_ok());
817
Allen George0e22c362017-01-30 07:15:00 -0500818 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400819
820 let received_ident = assert_success!(i_prot.read_map_begin());
821 assert_eq!(&received_ident, &ident);
822 }
823
824 #[test]
825 fn must_write_map_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500826 assert_no_write(|o| o.write_map_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400827 }
828
829 #[test]
830 fn must_write_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500831 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400832
833 assert!(o_prot.write_bool(true).is_ok());
834
835 let expected: [u8; 1] = [0x01];
Allen George0e22c362017-01-30 07:15:00 -0500836 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400837 }
838
839 #[test]
840 fn must_write_bool_false() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500841 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400842
843 assert!(o_prot.write_bool(false).is_ok());
844
845 let expected: [u8; 1] = [0x00];
Allen George0e22c362017-01-30 07:15:00 -0500846 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400847 }
848
849 #[test]
850 fn must_read_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500851 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400852
Allen George0e22c362017-01-30 07:15:00 -0500853 set_readable_bytes!(i_prot, &[0x01]);
Allen George8b96bfb2016-11-02 08:01:08 -0400854
855 let read_bool = assert_success!(i_prot.read_bool());
856 assert_eq!(read_bool, true);
857 }
858
859 #[test]
860 fn must_read_bool_false() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500861 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400862
Allen George0e22c362017-01-30 07:15:00 -0500863 set_readable_bytes!(i_prot, &[0x00]);
Allen George8b96bfb2016-11-02 08:01:08 -0400864
865 let read_bool = assert_success!(i_prot.read_bool());
866 assert_eq!(read_bool, false);
867 }
868
869 #[test]
870 fn must_allow_any_non_zero_value_to_be_interpreted_as_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500871 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400872
Allen George0e22c362017-01-30 07:15:00 -0500873 set_readable_bytes!(i_prot, &[0xAC]);
Allen George8b96bfb2016-11-02 08:01:08 -0400874
875 let read_bool = assert_success!(i_prot.read_bool());
876 assert_eq!(read_bool, true);
877 }
878
879 #[test]
880 fn must_write_bytes() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500881 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400882
883 let bytes: [u8; 10] = [0x0A, 0xCC, 0xD1, 0x84, 0x99, 0x12, 0xAB, 0xBB, 0x45, 0xDF];
884
885 assert!(o_prot.write_bytes(&bytes).is_ok());
886
Allen George0e22c362017-01-30 07:15:00 -0500887 let buf = o_prot.transport.write_bytes();
Allen George8b96bfb2016-11-02 08:01:08 -0400888 assert_eq!(&buf[0..4], [0x00, 0x00, 0x00, 0x0A]); // length
889 assert_eq!(&buf[4..], bytes); // actual bytes
890 }
891
892 #[test]
893 fn must_round_trip_bytes() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500894 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400895
Allen Georgeef7a1892018-12-16 18:01:37 -0500896 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -0500897 let bytes: [u8; 25] = [
898 0x20,
899 0xFD,
900 0x18,
901 0x84,
902 0x99,
903 0x12,
904 0xAB,
905 0xBB,
906 0x45,
907 0xDF,
908 0x34,
909 0xDC,
910 0x98,
911 0xA4,
912 0x6D,
913 0xF3,
914 0x99,
915 0xB4,
916 0xB7,
917 0xD4,
918 0x9C,
919 0xA5,
920 0xB3,
921 0xC9,
922 0x88,
923 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400924
925 assert!(o_prot.write_bytes(&bytes).is_ok());
926
Allen George0e22c362017-01-30 07:15:00 -0500927 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400928
929 let received_bytes = assert_success!(i_prot.read_bytes());
930 assert_eq!(&received_bytes, &bytes);
931 }
932
Allen Georgeef7a1892018-12-16 18:01:37 -0500933 fn test_objects(
934 strict: bool,
935 ) -> (
936 TBinaryInputProtocol<ReadHalf<TBufferChannel>>,
937 TBinaryOutputProtocol<WriteHalf<TBufferChannel>>,
938 ) {
Allen George0e22c362017-01-30 07:15:00 -0500939 let mem = TBufferChannel::with_capacity(40, 40);
Chao Sunc063b302017-03-12 12:21:05 -0700940
Allen George0e22c362017-01-30 07:15:00 -0500941 let (r_mem, w_mem) = mem.split().unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400942
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500943 let i_prot = TBinaryInputProtocol::new(r_mem, strict);
944 let o_prot = TBinaryOutputProtocol::new(w_mem, strict);
Allen George8b96bfb2016-11-02 08:01:08 -0400945
Allen George0e22c362017-01-30 07:15:00 -0500946 (i_prot, o_prot)
Allen George8b96bfb2016-11-02 08:01:08 -0400947 }
948
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500949 fn assert_no_write<F>(mut write_fn: F, strict: bool)
Allen George0e22c362017-01-30 07:15:00 -0500950 where
951 F: FnMut(&mut TBinaryOutputProtocol<WriteHalf<TBufferChannel>>) -> ::Result<()>,
952 {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500953 let (_, mut o_prot) = test_objects(strict);
Allen George8b96bfb2016-11-02 08:01:08 -0400954 assert!(write_fn(&mut o_prot).is_ok());
Allen George0e22c362017-01-30 07:15:00 -0500955 assert_eq!(o_prot.transport.write_bytes().len(), 0);
Allen George8b96bfb2016-11-02 08:01:08 -0400956 }
957}