blob: 42c6c97511da80cf4c4213e9d4274610ecc943ba [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 George0e22c362017-01-30 07:15:00 -050022use {ProtocolError, ProtocolErrorKind};
23use transport::{TReadTransport, TWriteTransport};
Allen George8b96bfb2016-11-02 08:01:08 -040024use super::{TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier,
25 TMapIdentifier, TMessageIdentifier, TMessageType};
26use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
27
28const BINARY_PROTOCOL_VERSION_1: u32 = 0x80010000;
29
30/// Read messages encoded in the Thrift simple binary encoding.
31///
32/// There are two available modes: `strict` and `non-strict`, where the
33/// `non-strict` version does not check for the protocol version in the
34/// received message header.
35///
36/// # Examples
37///
38/// Create and use a `TBinaryInputProtocol`.
39///
40/// ```no_run
Allen George8b96bfb2016-11-02 08:01:08 -040041/// use thrift::protocol::{TBinaryInputProtocol, TInputProtocol};
Allen George0e22c362017-01-30 07:15:00 -050042/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -040043///
Allen George0e22c362017-01-30 07:15:00 -050044/// let mut channel = TTcpChannel::new();
45/// channel.open("localhost:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -040046///
Allen George0e22c362017-01-30 07:15:00 -050047/// let mut protocol = TBinaryInputProtocol::new(channel, true);
Allen George8b96bfb2016-11-02 08:01:08 -040048///
Allen George0e22c362017-01-30 07:15:00 -050049/// let recvd_bool = protocol.read_bool().unwrap();
50/// let recvd_string = protocol.read_string().unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -040051/// ```
Allen George0e22c362017-01-30 07:15:00 -050052#[derive(Debug)]
53pub struct TBinaryInputProtocol<T>
54where
55 T: TReadTransport,
56{
Allen George8b96bfb2016-11-02 08:01:08 -040057 strict: bool,
Allen Georgebc1344d2017-04-28 10:22:03 -040058 pub transport: T, // FIXME: shouldn't be public
Allen George8b96bfb2016-11-02 08:01:08 -040059}
60
Allen George0e22c362017-01-30 07:15:00 -050061impl<'a, T> TBinaryInputProtocol<T>
62where
63 T: TReadTransport,
64{
Allen George8b96bfb2016-11-02 08:01:08 -040065 /// Create a `TBinaryInputProtocol` that reads bytes from `transport`.
66 ///
67 /// Set `strict` to `true` if all incoming messages contain the protocol
68 /// version number in the protocol header.
Allen George0e22c362017-01-30 07:15:00 -050069 pub fn new(transport: T, strict: bool) -> TBinaryInputProtocol<T> {
Allen George8b96bfb2016-11-02 08:01:08 -040070 TBinaryInputProtocol {
71 strict: strict,
72 transport: transport,
73 }
74 }
75}
76
Allen George0e22c362017-01-30 07:15:00 -050077impl<T> TInputProtocol for TBinaryInputProtocol<T>
78where
79 T: TReadTransport,
80{
Allen George8b96bfb2016-11-02 08:01:08 -040081 #[cfg_attr(feature = "cargo-clippy", allow(collapsible_if))]
82 fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
83 let mut first_bytes = vec![0; 4];
Allen George0e22c362017-01-30 07:15:00 -050084 self.transport.read_exact(&mut first_bytes[..])?;
Allen George8b96bfb2016-11-02 08:01:08 -040085
86 // the thrift version header is intentionally negative
87 // so the first check we'll do is see if the sign bit is set
88 // and if so - assume it's the protocol-version header
89 if first_bytes[0] >= 8 {
90 // apparently we got a protocol-version header - check
91 // it, and if it matches, read the rest of the fields
92 if first_bytes[0..2] != [0x80, 0x01] {
Allen George0e22c362017-01-30 07:15:00 -050093 Err(
94 ::Error::Protocol(
95 ProtocolError {
96 kind: ProtocolErrorKind::BadVersion,
97 message: format!("received bad version: {:?}", &first_bytes[0..2]),
98 },
99 ),
100 )
Allen George8b96bfb2016-11-02 08:01:08 -0400101 } else {
102 let message_type: TMessageType = TryFrom::try_from(first_bytes[3])?;
103 let name = self.read_string()?;
104 let sequence_number = self.read_i32()?;
105 Ok(TMessageIdentifier::new(name, message_type, sequence_number))
106 }
107 } else {
108 // apparently we didn't get a protocol-version header,
109 // which happens if the sender is not using the strict protocol
110 if self.strict {
111 // we're in strict mode however, and that always
112 // requires the protocol-version header to be written first
Allen George0e22c362017-01-30 07:15:00 -0500113 Err(
114 ::Error::Protocol(
115 ProtocolError {
116 kind: ProtocolErrorKind::BadVersion,
117 message: format!("received bad version: {:?}", &first_bytes[0..2]),
118 },
119 ),
120 )
Allen George8b96bfb2016-11-02 08:01:08 -0400121 } else {
122 // in the non-strict version the first message field
123 // is the message name. strings (byte arrays) are length-prefixed,
124 // so we've just read the length in the first 4 bytes
125 let name_size = BigEndian::read_i32(&first_bytes) as usize;
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500126 let mut name_buf: Vec<u8> = vec![0; name_size];
Allen George0e22c362017-01-30 07:15:00 -0500127 self.transport.read_exact(&mut name_buf)?;
Allen George8b96bfb2016-11-02 08:01:08 -0400128 let name = String::from_utf8(name_buf)?;
129
130 // read the rest of the fields
131 let message_type: TMessageType = self.read_byte().and_then(TryFrom::try_from)?;
132 let sequence_number = self.read_i32()?;
133 Ok(TMessageIdentifier::new(name, message_type, sequence_number))
134 }
135 }
136 }
137
138 fn read_message_end(&mut self) -> ::Result<()> {
139 Ok(())
140 }
141
142 fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
143 Ok(None)
144 }
145
146 fn read_struct_end(&mut self) -> ::Result<()> {
147 Ok(())
148 }
149
150 fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
151 let field_type_byte = self.read_byte()?;
152 let field_type = field_type_from_u8(field_type_byte)?;
153 let id = match field_type {
154 TType::Stop => Ok(0),
155 _ => self.read_i16(),
156 }?;
Allen George0e22c362017-01-30 07:15:00 -0500157 Ok(TFieldIdentifier::new::<Option<String>, String, i16>(None, field_type, id),)
Allen George8b96bfb2016-11-02 08:01:08 -0400158 }
159
160 fn read_field_end(&mut self) -> ::Result<()> {
161 Ok(())
162 }
163
164 fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
Allen George0e22c362017-01-30 07:15:00 -0500165 let num_bytes = self.transport.read_i32::<BigEndian>()? as usize;
Allen George8b96bfb2016-11-02 08:01:08 -0400166 let mut buf = vec![0u8; num_bytes];
Allen George0e22c362017-01-30 07:15:00 -0500167 self.transport
168 .read_exact(&mut buf)
169 .map(|_| buf)
170 .map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400171 }
172
173 fn read_bool(&mut self) -> ::Result<bool> {
174 let b = self.read_i8()?;
175 match b {
176 0 => Ok(false),
177 _ => Ok(true),
178 }
179 }
180
181 fn read_i8(&mut self) -> ::Result<i8> {
Allen George0e22c362017-01-30 07:15:00 -0500182 self.transport.read_i8().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400183 }
184
185 fn read_i16(&mut self) -> ::Result<i16> {
Allen George0e22c362017-01-30 07:15:00 -0500186 self.transport
187 .read_i16::<BigEndian>()
188 .map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400189 }
190
191 fn read_i32(&mut self) -> ::Result<i32> {
Allen George0e22c362017-01-30 07:15:00 -0500192 self.transport
193 .read_i32::<BigEndian>()
194 .map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400195 }
196
197 fn read_i64(&mut self) -> ::Result<i64> {
Allen George0e22c362017-01-30 07:15:00 -0500198 self.transport
199 .read_i64::<BigEndian>()
200 .map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400201 }
202
203 fn read_double(&mut self) -> ::Result<f64> {
Allen George0e22c362017-01-30 07:15:00 -0500204 self.transport
205 .read_f64::<BigEndian>()
206 .map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400207 }
208
209 fn read_string(&mut self) -> ::Result<String> {
210 let bytes = self.read_bytes()?;
211 String::from_utf8(bytes).map_err(From::from)
212 }
213
214 fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
215 let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
216 let size = self.read_i32()?;
217 Ok(TListIdentifier::new(element_type, size))
218 }
219
220 fn read_list_end(&mut self) -> ::Result<()> {
221 Ok(())
222 }
223
224 fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
225 let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
226 let size = self.read_i32()?;
227 Ok(TSetIdentifier::new(element_type, size))
228 }
229
230 fn read_set_end(&mut self) -> ::Result<()> {
231 Ok(())
232 }
233
234 fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
235 let key_type: TType = self.read_byte().and_then(field_type_from_u8)?;
236 let value_type: TType = self.read_byte().and_then(field_type_from_u8)?;
237 let size = self.read_i32()?;
238 Ok(TMapIdentifier::new(key_type, value_type, size))
239 }
240
241 fn read_map_end(&mut self) -> ::Result<()> {
242 Ok(())
243 }
244
245 // utility
246 //
247
248 fn read_byte(&mut self) -> ::Result<u8> {
Allen George0e22c362017-01-30 07:15:00 -0500249 self.transport.read_u8().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400250 }
251}
252
253/// Factory for creating instances of `TBinaryInputProtocol`.
254#[derive(Default)]
255pub struct TBinaryInputProtocolFactory;
256
257impl TBinaryInputProtocolFactory {
258 /// Create a `TBinaryInputProtocolFactory`.
259 pub fn new() -> TBinaryInputProtocolFactory {
260 TBinaryInputProtocolFactory {}
261 }
262}
263
264impl TInputProtocolFactory for TBinaryInputProtocolFactory {
Allen George0e22c362017-01-30 07:15:00 -0500265 fn create(&self, transport: Box<TReadTransport + Send>) -> Box<TInputProtocol + Send> {
266 Box::new(TBinaryInputProtocol::new(transport, true))
Allen George8b96bfb2016-11-02 08:01:08 -0400267 }
268}
269
270/// Write messages using the Thrift simple binary encoding.
271///
272/// There are two available modes: `strict` and `non-strict`, where the
273/// `strict` version writes the protocol version number in the outgoing message
274/// header and the `non-strict` version does not.
275///
276/// # Examples
277///
278/// Create and use a `TBinaryOutputProtocol`.
279///
280/// ```no_run
Allen George8b96bfb2016-11-02 08:01:08 -0400281/// use thrift::protocol::{TBinaryOutputProtocol, TOutputProtocol};
Allen George0e22c362017-01-30 07:15:00 -0500282/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -0400283///
Allen George0e22c362017-01-30 07:15:00 -0500284/// let mut channel = TTcpChannel::new();
285/// channel.open("localhost:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400286///
Allen George0e22c362017-01-30 07:15:00 -0500287/// let mut protocol = TBinaryOutputProtocol::new(channel, true);
Allen George8b96bfb2016-11-02 08:01:08 -0400288///
Allen George0e22c362017-01-30 07:15:00 -0500289/// protocol.write_bool(true).unwrap();
290/// protocol.write_string("test_string").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400291/// ```
Allen George0e22c362017-01-30 07:15:00 -0500292#[derive(Debug)]
293pub struct TBinaryOutputProtocol<T>
294where
295 T: TWriteTransport,
296{
Allen George8b96bfb2016-11-02 08:01:08 -0400297 strict: bool,
Allen George0e22c362017-01-30 07:15:00 -0500298 pub transport: T, // FIXME: do not make public; only public for testing!
Allen George8b96bfb2016-11-02 08:01:08 -0400299}
300
Allen George0e22c362017-01-30 07:15:00 -0500301impl<T> TBinaryOutputProtocol<T>
302where
303 T: TWriteTransport,
304{
Allen George8b96bfb2016-11-02 08:01:08 -0400305 /// Create a `TBinaryOutputProtocol` that writes bytes to `transport`.
306 ///
307 /// Set `strict` to `true` if all outgoing messages should contain the
308 /// protocol version number in the protocol header.
Allen George0e22c362017-01-30 07:15:00 -0500309 pub fn new(transport: T, strict: bool) -> TBinaryOutputProtocol<T> {
Allen George8b96bfb2016-11-02 08:01:08 -0400310 TBinaryOutputProtocol {
311 strict: strict,
312 transport: transport,
313 }
314 }
Allen George8b96bfb2016-11-02 08:01:08 -0400315}
316
Allen George0e22c362017-01-30 07:15:00 -0500317impl<T> TOutputProtocol for TBinaryOutputProtocol<T>
318where
319 T: TWriteTransport,
320{
Allen George8b96bfb2016-11-02 08:01:08 -0400321 fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
322 if self.strict {
323 let message_type: u8 = identifier.message_type.into();
324 let header = BINARY_PROTOCOL_VERSION_1 | (message_type as u32);
Allen George0e22c362017-01-30 07:15:00 -0500325 self.transport.write_u32::<BigEndian>(header)?;
Allen George8b96bfb2016-11-02 08:01:08 -0400326 self.write_string(&identifier.name)?;
327 self.write_i32(identifier.sequence_number)
328 } else {
329 self.write_string(&identifier.name)?;
330 self.write_byte(identifier.message_type.into())?;
331 self.write_i32(identifier.sequence_number)
332 }
333 }
334
335 fn write_message_end(&mut self) -> ::Result<()> {
336 Ok(())
337 }
338
339 fn write_struct_begin(&mut self, _: &TStructIdentifier) -> ::Result<()> {
340 Ok(())
341 }
342
343 fn write_struct_end(&mut self) -> ::Result<()> {
344 Ok(())
345 }
346
347 fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()> {
348 if identifier.id.is_none() && identifier.field_type != TType::Stop {
Allen George0e22c362017-01-30 07:15:00 -0500349 return Err(
350 ::Error::Protocol(
351 ProtocolError {
352 kind: ProtocolErrorKind::Unknown,
353 message: format!(
354 "cannot write identifier {:?} without sequence number",
355 &identifier
356 ),
357 },
358 ),
359 );
Allen George8b96bfb2016-11-02 08:01:08 -0400360 }
361
362 self.write_byte(field_type_to_u8(identifier.field_type))?;
363 if let Some(id) = identifier.id {
364 self.write_i16(id)
365 } else {
366 Ok(())
367 }
368 }
369
370 fn write_field_end(&mut self) -> ::Result<()> {
371 Ok(())
372 }
373
374 fn write_field_stop(&mut self) -> ::Result<()> {
375 self.write_byte(field_type_to_u8(TType::Stop))
376 }
377
378 fn write_bytes(&mut self, b: &[u8]) -> ::Result<()> {
379 self.write_i32(b.len() as i32)?;
Allen Georgecf7ba4c2017-12-11 11:44:11 -0500380 self.transport.write_all(b).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400381 }
382
383 fn write_bool(&mut self, b: bool) -> ::Result<()> {
384 if b {
385 self.write_i8(1)
386 } else {
387 self.write_i8(0)
388 }
389 }
390
391 fn write_i8(&mut self, i: i8) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500392 self.transport.write_i8(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400393 }
394
395 fn write_i16(&mut self, i: i16) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500396 self.transport
397 .write_i16::<BigEndian>(i)
398 .map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400399 }
400
401 fn write_i32(&mut self, i: i32) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500402 self.transport
403 .write_i32::<BigEndian>(i)
404 .map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400405 }
406
407 fn write_i64(&mut self, i: i64) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500408 self.transport
409 .write_i64::<BigEndian>(i)
410 .map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400411 }
412
413 fn write_double(&mut self, d: f64) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500414 self.transport
415 .write_f64::<BigEndian>(d)
416 .map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400417 }
418
419 fn write_string(&mut self, s: &str) -> ::Result<()> {
420 self.write_bytes(s.as_bytes())
421 }
422
423 fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()> {
424 self.write_byte(field_type_to_u8(identifier.element_type))?;
425 self.write_i32(identifier.size)
426 }
427
428 fn write_list_end(&mut self) -> ::Result<()> {
429 Ok(())
430 }
431
432 fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()> {
433 self.write_byte(field_type_to_u8(identifier.element_type))?;
434 self.write_i32(identifier.size)
435 }
436
437 fn write_set_end(&mut self) -> ::Result<()> {
438 Ok(())
439 }
440
441 fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500442 let key_type = identifier
443 .key_type
Allen George8b96bfb2016-11-02 08:01:08 -0400444 .expect("map identifier to write should contain key type");
445 self.write_byte(field_type_to_u8(key_type))?;
Allen George0e22c362017-01-30 07:15:00 -0500446 let val_type = identifier
447 .value_type
Allen George8b96bfb2016-11-02 08:01:08 -0400448 .expect("map identifier to write should contain value type");
449 self.write_byte(field_type_to_u8(val_type))?;
450 self.write_i32(identifier.size)
451 }
452
453 fn write_map_end(&mut self) -> ::Result<()> {
454 Ok(())
455 }
456
457 fn flush(&mut self) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500458 self.transport.flush().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400459 }
460
461 // utility
462 //
463
464 fn write_byte(&mut self, b: u8) -> ::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500465 self.transport.write_u8(b).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400466 }
467}
468
469/// Factory for creating instances of `TBinaryOutputProtocol`.
470#[derive(Default)]
471pub struct TBinaryOutputProtocolFactory;
472
473impl TBinaryOutputProtocolFactory {
474 /// Create a `TBinaryOutputProtocolFactory`.
475 pub fn new() -> TBinaryOutputProtocolFactory {
476 TBinaryOutputProtocolFactory {}
477 }
478}
479
480impl TOutputProtocolFactory for TBinaryOutputProtocolFactory {
Allen George0e22c362017-01-30 07:15:00 -0500481 fn create(&self, transport: Box<TWriteTransport + Send>) -> Box<TOutputProtocol + Send> {
482 Box::new(TBinaryOutputProtocol::new(transport, true))
Allen George8b96bfb2016-11-02 08:01:08 -0400483 }
484}
485
486fn field_type_to_u8(field_type: TType) -> u8 {
487 match field_type {
488 TType::Stop => 0x00,
489 TType::Void => 0x01,
490 TType::Bool => 0x02,
491 TType::I08 => 0x03, // equivalent to TType::Byte
492 TType::Double => 0x04,
493 TType::I16 => 0x06,
494 TType::I32 => 0x08,
495 TType::I64 => 0x0A,
496 TType::String | TType::Utf7 => 0x0B,
497 TType::Struct => 0x0C,
498 TType::Map => 0x0D,
499 TType::Set => 0x0E,
500 TType::List => 0x0F,
501 TType::Utf8 => 0x10,
502 TType::Utf16 => 0x11,
503 }
504}
505
506fn field_type_from_u8(b: u8) -> ::Result<TType> {
507 match b {
508 0x00 => Ok(TType::Stop),
509 0x01 => Ok(TType::Void),
510 0x02 => Ok(TType::Bool),
511 0x03 => Ok(TType::I08), // Equivalent to TType::Byte
512 0x04 => Ok(TType::Double),
513 0x06 => Ok(TType::I16),
514 0x08 => Ok(TType::I32),
515 0x0A => Ok(TType::I64),
516 0x0B => Ok(TType::String), // technically, also a UTF7, but we'll treat it as string
517 0x0C => Ok(TType::Struct),
518 0x0D => Ok(TType::Map),
519 0x0E => Ok(TType::Set),
520 0x0F => Ok(TType::List),
521 0x10 => Ok(TType::Utf8),
522 0x11 => Ok(TType::Utf16),
523 unkn => {
Allen George0e22c362017-01-30 07:15:00 -0500524 Err(
525 ::Error::Protocol(
526 ProtocolError {
527 kind: ProtocolErrorKind::InvalidData,
528 message: format!("cannot convert {} to TType", unkn),
529 },
530 ),
531 )
Allen George8b96bfb2016-11-02 08:01:08 -0400532 }
533 }
534}
535
536#[cfg(test)]
537mod tests {
538
Allen George0e22c362017-01-30 07:15:00 -0500539 use protocol::{TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier,
540 TMessageIdentifier, TMessageType, TOutputProtocol, TSetIdentifier,
541 TStructIdentifier, TType};
542 use transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
Allen George8b96bfb2016-11-02 08:01:08 -0400543
544 use super::*;
545
546 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500547 fn must_write_strict_message_call_begin() {
548 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400549
550 let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
551 assert!(o_prot.write_message_begin(&ident).is_ok());
552
Allen George0e22c362017-01-30 07:15:00 -0500553 let expected: [u8; 16] = [
554 0x80,
555 0x01,
556 0x00,
557 0x01,
558 0x00,
559 0x00,
560 0x00,
561 0x04,
562 0x74,
563 0x65,
564 0x73,
565 0x74,
566 0x00,
567 0x00,
568 0x00,
569 0x01,
570 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400571
Allen George0e22c362017-01-30 07:15:00 -0500572 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400573 }
574
Allen George8b96bfb2016-11-02 08:01:08 -0400575 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500576 fn must_write_non_strict_message_call_begin() {
577 let (_, mut o_prot) = test_objects(false);
578
579 let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
580 assert!(o_prot.write_message_begin(&ident).is_ok());
581
582 let expected: [u8; 13] = [
583 0x00,
584 0x00,
585 0x00,
586 0x04,
587 0x74,
588 0x65,
589 0x73,
590 0x74,
591 0x01,
592 0x00,
593 0x00,
594 0x00,
595 0x01,
596 ];
597
598 assert_eq_written_bytes!(o_prot, expected);
599 }
600
601 #[test]
602 fn must_write_strict_message_reply_begin() {
603 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400604
605 let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
606 assert!(o_prot.write_message_begin(&ident).is_ok());
607
Allen George0e22c362017-01-30 07:15:00 -0500608 let expected: [u8; 16] = [
609 0x80,
610 0x01,
611 0x00,
612 0x02,
613 0x00,
614 0x00,
615 0x00,
616 0x04,
617 0x74,
618 0x65,
619 0x73,
620 0x74,
621 0x00,
622 0x00,
623 0x00,
624 0x0A,
625 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400626
Allen George0e22c362017-01-30 07:15:00 -0500627 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400628 }
629
630 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500631 fn must_write_non_strict_message_reply_begin() {
632 let (_, mut o_prot) = test_objects(false);
633
634 let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
635 assert!(o_prot.write_message_begin(&ident).is_ok());
636
637 let expected: [u8; 13] = [
638 0x00,
639 0x00,
640 0x00,
641 0x04,
642 0x74,
643 0x65,
644 0x73,
645 0x74,
646 0x02,
647 0x00,
648 0x00,
649 0x00,
650 0x0A,
651 ];
652
653 assert_eq_written_bytes!(o_prot, expected);
654 }
655
656 #[test]
Allen George8b96bfb2016-11-02 08:01:08 -0400657 fn must_round_trip_strict_message_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500658 let (mut i_prot, mut o_prot) = test_objects(true);
659
660 let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
661 assert!(o_prot.write_message_begin(&sent_ident).is_ok());
662
663 copy_write_buffer_to_read_buffer!(o_prot);
664
665 let received_ident = assert_success!(i_prot.read_message_begin());
666 assert_eq!(&received_ident, &sent_ident);
667 }
668
669 #[test]
670 fn must_round_trip_non_strict_message_begin() {
671 let (mut i_prot, mut o_prot) = test_objects(false);
Allen George8b96bfb2016-11-02 08:01:08 -0400672
673 let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
674 assert!(o_prot.write_message_begin(&sent_ident).is_ok());
675
Allen George0e22c362017-01-30 07:15:00 -0500676 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400677
678 let received_ident = assert_success!(i_prot.read_message_begin());
679 assert_eq!(&received_ident, &sent_ident);
680 }
681
682 #[test]
683 fn must_write_message_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500684 assert_no_write(|o| o.write_message_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400685 }
686
687 #[test]
688 fn must_write_struct_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500689 assert_no_write(|o| o.write_struct_begin(&TStructIdentifier::new("foo")), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400690 }
691
692 #[test]
693 fn must_write_struct_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500694 assert_no_write(|o| o.write_struct_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400695 }
696
697 #[test]
698 fn must_write_field_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500699 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400700
Allen George0e22c362017-01-30 07:15:00 -0500701 assert!(
702 o_prot
703 .write_field_begin(&TFieldIdentifier::new("some_field", TType::String, 22))
704 .is_ok()
705 );
Allen George8b96bfb2016-11-02 08:01:08 -0400706
707 let expected: [u8; 3] = [0x0B, 0x00, 0x16];
Allen George0e22c362017-01-30 07:15:00 -0500708 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400709 }
710
711 #[test]
712 fn must_round_trip_field_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500713 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400714
715 let sent_field_ident = TFieldIdentifier::new("foo", TType::I64, 20);
716 assert!(o_prot.write_field_begin(&sent_field_ident).is_ok());
717
Allen George0e22c362017-01-30 07:15:00 -0500718 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400719
720 let expected_ident = TFieldIdentifier {
721 name: None,
722 field_type: TType::I64,
723 id: Some(20),
724 }; // no name
725 let received_ident = assert_success!(i_prot.read_field_begin());
726 assert_eq!(&received_ident, &expected_ident);
727 }
728
729 #[test]
730 fn must_write_stop_field() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500731 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400732
733 assert!(o_prot.write_field_stop().is_ok());
734
735 let expected: [u8; 1] = [0x00];
Allen George0e22c362017-01-30 07:15:00 -0500736 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400737 }
738
739 #[test]
740 fn must_round_trip_field_stop() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500741 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400742
743 assert!(o_prot.write_field_stop().is_ok());
744
Allen George0e22c362017-01-30 07:15:00 -0500745 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400746
747 let expected_ident = TFieldIdentifier {
748 name: None,
749 field_type: TType::Stop,
750 id: Some(0),
751 }; // we get id 0
752
753 let received_ident = assert_success!(i_prot.read_field_begin());
754 assert_eq!(&received_ident, &expected_ident);
755 }
756
757 #[test]
758 fn must_write_field_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500759 assert_no_write(|o| o.write_field_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400760 }
761
762 #[test]
763 fn must_write_list_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500764 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400765
Allen George0e22c362017-01-30 07:15:00 -0500766 assert!(
767 o_prot
768 .write_list_begin(&TListIdentifier::new(TType::Bool, 5))
769 .is_ok()
770 );
Allen George8b96bfb2016-11-02 08:01:08 -0400771
772 let expected: [u8; 5] = [0x02, 0x00, 0x00, 0x00, 0x05];
Allen George0e22c362017-01-30 07:15:00 -0500773 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400774 }
775
776 #[test]
777 fn must_round_trip_list_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500778 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400779
780 let ident = TListIdentifier::new(TType::List, 900);
781 assert!(o_prot.write_list_begin(&ident).is_ok());
782
Allen George0e22c362017-01-30 07:15:00 -0500783 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400784
785 let received_ident = assert_success!(i_prot.read_list_begin());
786 assert_eq!(&received_ident, &ident);
787 }
788
789 #[test]
790 fn must_write_list_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500791 assert_no_write(|o| o.write_list_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400792 }
793
794 #[test]
795 fn must_write_set_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500796 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400797
Allen George0e22c362017-01-30 07:15:00 -0500798 assert!(
799 o_prot
800 .write_set_begin(&TSetIdentifier::new(TType::I16, 7))
801 .is_ok()
802 );
Allen George8b96bfb2016-11-02 08:01:08 -0400803
804 let expected: [u8; 5] = [0x06, 0x00, 0x00, 0x00, 0x07];
Allen George0e22c362017-01-30 07:15:00 -0500805 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400806 }
807
808 #[test]
809 fn must_round_trip_set_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500810 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400811
812 let ident = TSetIdentifier::new(TType::I64, 2000);
813 assert!(o_prot.write_set_begin(&ident).is_ok());
814
Allen George0e22c362017-01-30 07:15:00 -0500815 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400816
817 let received_ident_result = i_prot.read_set_begin();
818 assert!(received_ident_result.is_ok());
819 assert_eq!(&received_ident_result.unwrap(), &ident);
820 }
821
822 #[test]
823 fn must_write_set_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500824 assert_no_write(|o| o.write_set_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400825 }
826
827 #[test]
828 fn must_write_map_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500829 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400830
Allen George0e22c362017-01-30 07:15:00 -0500831 assert!(
832 o_prot
833 .write_map_begin(&TMapIdentifier::new(TType::I64, TType::Struct, 32))
834 .is_ok()
835 );
Allen George8b96bfb2016-11-02 08:01:08 -0400836
837 let expected: [u8; 6] = [0x0A, 0x0C, 0x00, 0x00, 0x00, 0x20];
Allen George0e22c362017-01-30 07:15:00 -0500838 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400839 }
840
841 #[test]
842 fn must_round_trip_map_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500843 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400844
845 let ident = TMapIdentifier::new(TType::Map, TType::Set, 100);
846 assert!(o_prot.write_map_begin(&ident).is_ok());
847
Allen George0e22c362017-01-30 07:15:00 -0500848 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400849
850 let received_ident = assert_success!(i_prot.read_map_begin());
851 assert_eq!(&received_ident, &ident);
852 }
853
854 #[test]
855 fn must_write_map_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500856 assert_no_write(|o| o.write_map_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400857 }
858
859 #[test]
860 fn must_write_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500861 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400862
863 assert!(o_prot.write_bool(true).is_ok());
864
865 let expected: [u8; 1] = [0x01];
Allen George0e22c362017-01-30 07:15:00 -0500866 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400867 }
868
869 #[test]
870 fn must_write_bool_false() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500871 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400872
873 assert!(o_prot.write_bool(false).is_ok());
874
875 let expected: [u8; 1] = [0x00];
Allen George0e22c362017-01-30 07:15:00 -0500876 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400877 }
878
879 #[test]
880 fn must_read_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500881 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400882
Allen George0e22c362017-01-30 07:15:00 -0500883 set_readable_bytes!(i_prot, &[0x01]);
Allen George8b96bfb2016-11-02 08:01:08 -0400884
885 let read_bool = assert_success!(i_prot.read_bool());
886 assert_eq!(read_bool, true);
887 }
888
889 #[test]
890 fn must_read_bool_false() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500891 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400892
Allen George0e22c362017-01-30 07:15:00 -0500893 set_readable_bytes!(i_prot, &[0x00]);
Allen George8b96bfb2016-11-02 08:01:08 -0400894
895 let read_bool = assert_success!(i_prot.read_bool());
896 assert_eq!(read_bool, false);
897 }
898
899 #[test]
900 fn must_allow_any_non_zero_value_to_be_interpreted_as_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500901 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400902
Allen George0e22c362017-01-30 07:15:00 -0500903 set_readable_bytes!(i_prot, &[0xAC]);
Allen George8b96bfb2016-11-02 08:01:08 -0400904
905 let read_bool = assert_success!(i_prot.read_bool());
906 assert_eq!(read_bool, true);
907 }
908
909 #[test]
910 fn must_write_bytes() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500911 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400912
913 let bytes: [u8; 10] = [0x0A, 0xCC, 0xD1, 0x84, 0x99, 0x12, 0xAB, 0xBB, 0x45, 0xDF];
914
915 assert!(o_prot.write_bytes(&bytes).is_ok());
916
Allen George0e22c362017-01-30 07:15:00 -0500917 let buf = o_prot.transport.write_bytes();
Allen George8b96bfb2016-11-02 08:01:08 -0400918 assert_eq!(&buf[0..4], [0x00, 0x00, 0x00, 0x0A]); // length
919 assert_eq!(&buf[4..], bytes); // actual bytes
920 }
921
922 #[test]
923 fn must_round_trip_bytes() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500924 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400925
Allen George0e22c362017-01-30 07:15:00 -0500926 let bytes: [u8; 25] = [
927 0x20,
928 0xFD,
929 0x18,
930 0x84,
931 0x99,
932 0x12,
933 0xAB,
934 0xBB,
935 0x45,
936 0xDF,
937 0x34,
938 0xDC,
939 0x98,
940 0xA4,
941 0x6D,
942 0xF3,
943 0x99,
944 0xB4,
945 0xB7,
946 0xD4,
947 0x9C,
948 0xA5,
949 0xB3,
950 0xC9,
951 0x88,
952 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400953
954 assert!(o_prot.write_bytes(&bytes).is_ok());
955
Allen George0e22c362017-01-30 07:15:00 -0500956 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400957
958 let received_bytes = assert_success!(i_prot.read_bytes());
959 assert_eq!(&received_bytes, &bytes);
960 }
961
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500962 fn test_objects(strict: bool)
Allen George0e22c362017-01-30 07:15:00 -0500963 -> (TBinaryInputProtocol<ReadHalf<TBufferChannel>>,
964 TBinaryOutputProtocol<WriteHalf<TBufferChannel>>)
Allen George8b96bfb2016-11-02 08:01:08 -0400965 {
Allen George0e22c362017-01-30 07:15:00 -0500966 let mem = TBufferChannel::with_capacity(40, 40);
Chao Sunc063b302017-03-12 12:21:05 -0700967
Allen George0e22c362017-01-30 07:15:00 -0500968 let (r_mem, w_mem) = mem.split().unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400969
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500970 let i_prot = TBinaryInputProtocol::new(r_mem, strict);
971 let o_prot = TBinaryOutputProtocol::new(w_mem, strict);
Allen George8b96bfb2016-11-02 08:01:08 -0400972
Allen George0e22c362017-01-30 07:15:00 -0500973 (i_prot, o_prot)
Allen George8b96bfb2016-11-02 08:01:08 -0400974 }
975
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500976 fn assert_no_write<F>(mut write_fn: F, strict: bool)
Allen George0e22c362017-01-30 07:15:00 -0500977 where
978 F: FnMut(&mut TBinaryOutputProtocol<WriteHalf<TBufferChannel>>) -> ::Result<()>,
979 {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500980 let (_, mut o_prot) = test_objects(strict);
Allen George8b96bfb2016-11-02 08:01:08 -0400981 assert!(write_fn(&mut o_prot).is_ok());
Allen George0e22c362017-01-30 07:15:00 -0500982 assert_eq!(o_prot.transport.write_bytes().len(), 0);
Allen George8b96bfb2016-11-02 08:01:08 -0400983 }
984}