blob: 8509c34aeebf1d660ae3579fc051ecb68b3b03e1 [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};
Danny Browningddec4312019-03-08 14:20:41 -070019use std::convert::{From, TryFrom};
Allen George8b96bfb2016-11-02 08:01:08 -040020
Allen Georgeef7a1892018-12-16 18:01:37 -050021use super::{
22 TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier, TMapIdentifier,
23 TMessageIdentifier, TMessageType,
24};
Allen George8b96bfb2016-11-02 08:01:08 -040025use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
Allen Georgeb0d14132020-03-29 11:48:55 -040026use crate::transport::{TReadTransport, TWriteTransport};
27use crate::{ProtocolError, ProtocolErrorKind};
Allen George8b96bfb2016-11-02 08:01:08 -040028
Allen George7ddbcc02020-11-08 09:51:19 -050029const BINARY_PROTOCOL_VERSION_1: u32 = 0x8001_0000;
Allen George8b96bfb2016-11-02 08:01:08 -040030
31/// Read messages encoded in the Thrift simple binary encoding.
32///
33/// There are two available modes: `strict` and `non-strict`, where the
34/// `non-strict` version does not check for the protocol version in the
35/// received message header.
36///
37/// # Examples
38///
39/// Create and use a `TBinaryInputProtocol`.
40///
41/// ```no_run
Allen George8b96bfb2016-11-02 08:01:08 -040042/// use thrift::protocol::{TBinaryInputProtocol, TInputProtocol};
Allen George0e22c362017-01-30 07:15:00 -050043/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -040044///
Allen George0e22c362017-01-30 07:15:00 -050045/// let mut channel = TTcpChannel::new();
46/// channel.open("localhost:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -040047///
Allen George0e22c362017-01-30 07:15:00 -050048/// let mut protocol = TBinaryInputProtocol::new(channel, true);
Allen George8b96bfb2016-11-02 08:01:08 -040049///
Allen George0e22c362017-01-30 07:15:00 -050050/// let recvd_bool = protocol.read_bool().unwrap();
51/// let recvd_string = protocol.read_string().unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -040052/// ```
Allen George0e22c362017-01-30 07:15:00 -050053#[derive(Debug)]
54pub struct TBinaryInputProtocol<T>
55where
56 T: TReadTransport,
57{
Allen George8b96bfb2016-11-02 08:01:08 -040058 strict: bool,
Allen Georgebc1344d2017-04-28 10:22:03 -040059 pub transport: T, // FIXME: shouldn't be public
Allen George8b96bfb2016-11-02 08:01:08 -040060}
61
Allen George0e22c362017-01-30 07:15:00 -050062impl<'a, T> TBinaryInputProtocol<T>
63where
64 T: TReadTransport,
65{
Allen George8b96bfb2016-11-02 08:01:08 -040066 /// Create a `TBinaryInputProtocol` that reads bytes from `transport`.
67 ///
68 /// Set `strict` to `true` if all incoming messages contain the protocol
69 /// version number in the protocol header.
Allen George0e22c362017-01-30 07:15:00 -050070 pub fn new(transport: T, strict: bool) -> TBinaryInputProtocol<T> {
Allen George55c3e4c2021-03-01 23:19:52 -050071 TBinaryInputProtocol { strict, transport }
Allen George8b96bfb2016-11-02 08:01:08 -040072 }
73}
74
Allen George0e22c362017-01-30 07:15:00 -050075impl<T> TInputProtocol for TBinaryInputProtocol<T>
76where
77 T: TReadTransport,
78{
Allen George7ddbcc02020-11-08 09:51:19 -050079 #[allow(clippy::collapsible_if)]
Allen Georgeb0d14132020-03-29 11:48:55 -040080 fn read_message_begin(&mut self) -> crate::Result<TMessageIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -040081 let mut first_bytes = vec![0; 4];
Allen George0e22c362017-01-30 07:15:00 -050082 self.transport.read_exact(&mut first_bytes[..])?;
Allen George8b96bfb2016-11-02 08:01:08 -040083
84 // the thrift version header is intentionally negative
85 // so the first check we'll do is see if the sign bit is set
86 // and if so - assume it's the protocol-version header
87 if first_bytes[0] >= 8 {
88 // apparently we got a protocol-version header - check
89 // it, and if it matches, read the rest of the fields
90 if first_bytes[0..2] != [0x80, 0x01] {
Allen Georgeb0d14132020-03-29 11:48:55 -040091 Err(crate::Error::Protocol(ProtocolError {
Allen Georgeef7a1892018-12-16 18:01:37 -050092 kind: ProtocolErrorKind::BadVersion,
93 message: format!("received bad version: {:?}", &first_bytes[0..2]),
94 }))
Allen George8b96bfb2016-11-02 08:01:08 -040095 } else {
96 let message_type: TMessageType = TryFrom::try_from(first_bytes[3])?;
97 let name = self.read_string()?;
98 let sequence_number = self.read_i32()?;
99 Ok(TMessageIdentifier::new(name, message_type, sequence_number))
100 }
101 } else {
102 // apparently we didn't get a protocol-version header,
103 // which happens if the sender is not using the strict protocol
104 if self.strict {
105 // we're in strict mode however, and that always
106 // requires the protocol-version header to be written first
Allen Georgeb0d14132020-03-29 11:48:55 -0400107 Err(crate::Error::Protocol(ProtocolError {
Allen Georgeef7a1892018-12-16 18:01:37 -0500108 kind: ProtocolErrorKind::BadVersion,
109 message: format!("received bad version: {:?}", &first_bytes[0..2]),
110 }))
Allen George8b96bfb2016-11-02 08:01:08 -0400111 } else {
112 // in the non-strict version the first message field
113 // is the message name. strings (byte arrays) are length-prefixed,
114 // so we've just read the length in the first 4 bytes
115 let name_size = BigEndian::read_i32(&first_bytes) as usize;
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500116 let mut name_buf: Vec<u8> = vec![0; name_size];
Allen George0e22c362017-01-30 07:15:00 -0500117 self.transport.read_exact(&mut name_buf)?;
Allen George8b96bfb2016-11-02 08:01:08 -0400118 let name = String::from_utf8(name_buf)?;
119
120 // read the rest of the fields
121 let message_type: TMessageType = self.read_byte().and_then(TryFrom::try_from)?;
122 let sequence_number = self.read_i32()?;
123 Ok(TMessageIdentifier::new(name, message_type, sequence_number))
124 }
125 }
126 }
127
Allen Georgeb0d14132020-03-29 11:48:55 -0400128 fn read_message_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400129 Ok(())
130 }
131
Allen Georgeb0d14132020-03-29 11:48:55 -0400132 fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>> {
Allen George8b96bfb2016-11-02 08:01:08 -0400133 Ok(None)
134 }
135
Allen Georgeb0d14132020-03-29 11:48:55 -0400136 fn read_struct_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400137 Ok(())
138 }
139
Allen Georgeb0d14132020-03-29 11:48:55 -0400140 fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400141 let field_type_byte = self.read_byte()?;
142 let field_type = field_type_from_u8(field_type_byte)?;
143 let id = match field_type {
144 TType::Stop => Ok(0),
145 _ => self.read_i16(),
146 }?;
Allen Georgeef7a1892018-12-16 18:01:37 -0500147 Ok(TFieldIdentifier::new::<Option<String>, String, i16>(
148 None, field_type, id,
149 ))
Allen George8b96bfb2016-11-02 08:01:08 -0400150 }
151
Allen Georgeb0d14132020-03-29 11:48:55 -0400152 fn read_field_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400153 Ok(())
154 }
155
Allen Georgeb0d14132020-03-29 11:48:55 -0400156 fn read_bytes(&mut self) -> crate::Result<Vec<u8>> {
Allen George0e22c362017-01-30 07:15:00 -0500157 let num_bytes = self.transport.read_i32::<BigEndian>()? as usize;
Allen George8b96bfb2016-11-02 08:01:08 -0400158 let mut buf = vec![0u8; num_bytes];
Allen George0e22c362017-01-30 07:15:00 -0500159 self.transport
160 .read_exact(&mut buf)
161 .map(|_| buf)
162 .map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400163 }
164
Allen Georgeb0d14132020-03-29 11:48:55 -0400165 fn read_bool(&mut self) -> crate::Result<bool> {
Allen George8b96bfb2016-11-02 08:01:08 -0400166 let b = self.read_i8()?;
167 match b {
168 0 => Ok(false),
169 _ => Ok(true),
170 }
171 }
172
Allen Georgeb0d14132020-03-29 11:48:55 -0400173 fn read_i8(&mut self) -> crate::Result<i8> {
Allen George0e22c362017-01-30 07:15:00 -0500174 self.transport.read_i8().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400175 }
176
Allen Georgeb0d14132020-03-29 11:48:55 -0400177 fn read_i16(&mut self) -> crate::Result<i16> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500178 self.transport.read_i16::<BigEndian>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400179 }
180
Allen Georgeb0d14132020-03-29 11:48:55 -0400181 fn read_i32(&mut self) -> crate::Result<i32> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500182 self.transport.read_i32::<BigEndian>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400183 }
184
Allen Georgeb0d14132020-03-29 11:48:55 -0400185 fn read_i64(&mut self) -> crate::Result<i64> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500186 self.transport.read_i64::<BigEndian>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400187 }
188
Allen Georgeb0d14132020-03-29 11:48:55 -0400189 fn read_double(&mut self) -> crate::Result<f64> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500190 self.transport.read_f64::<BigEndian>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400191 }
192
Allen Georgeb0d14132020-03-29 11:48:55 -0400193 fn read_string(&mut self) -> crate::Result<String> {
Allen George8b96bfb2016-11-02 08:01:08 -0400194 let bytes = self.read_bytes()?;
195 String::from_utf8(bytes).map_err(From::from)
196 }
197
Allen Georgeb0d14132020-03-29 11:48:55 -0400198 fn read_list_begin(&mut self) -> crate::Result<TListIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400199 let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
200 let size = self.read_i32()?;
201 Ok(TListIdentifier::new(element_type, size))
202 }
203
Allen Georgeb0d14132020-03-29 11:48:55 -0400204 fn read_list_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400205 Ok(())
206 }
207
Allen Georgeb0d14132020-03-29 11:48:55 -0400208 fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400209 let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
210 let size = self.read_i32()?;
211 Ok(TSetIdentifier::new(element_type, size))
212 }
213
Allen Georgeb0d14132020-03-29 11:48:55 -0400214 fn read_set_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400215 Ok(())
216 }
217
Allen Georgeb0d14132020-03-29 11:48:55 -0400218 fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400219 let key_type: TType = self.read_byte().and_then(field_type_from_u8)?;
220 let value_type: TType = self.read_byte().and_then(field_type_from_u8)?;
221 let size = self.read_i32()?;
222 Ok(TMapIdentifier::new(key_type, value_type, size))
223 }
224
Allen Georgeb0d14132020-03-29 11:48:55 -0400225 fn read_map_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400226 Ok(())
227 }
228
229 // utility
230 //
231
Allen Georgeb0d14132020-03-29 11:48:55 -0400232 fn read_byte(&mut self) -> crate::Result<u8> {
Allen George0e22c362017-01-30 07:15:00 -0500233 self.transport.read_u8().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400234 }
235}
236
237/// Factory for creating instances of `TBinaryInputProtocol`.
238#[derive(Default)]
239pub struct TBinaryInputProtocolFactory;
240
241impl TBinaryInputProtocolFactory {
242 /// Create a `TBinaryInputProtocolFactory`.
243 pub fn new() -> TBinaryInputProtocolFactory {
244 TBinaryInputProtocolFactory {}
245 }
246}
247
248impl TInputProtocolFactory for TBinaryInputProtocolFactory {
Danny Browning77d96c12019-08-21 13:41:07 -0600249 fn create(&self, transport: Box<dyn TReadTransport + Send>) -> Box<dyn TInputProtocol + Send> {
Allen George0e22c362017-01-30 07:15:00 -0500250 Box::new(TBinaryInputProtocol::new(transport, true))
Allen George8b96bfb2016-11-02 08:01:08 -0400251 }
252}
253
254/// Write messages using the Thrift simple binary encoding.
255///
256/// There are two available modes: `strict` and `non-strict`, where the
257/// `strict` version writes the protocol version number in the outgoing message
258/// header and the `non-strict` version does not.
259///
260/// # Examples
261///
262/// Create and use a `TBinaryOutputProtocol`.
263///
264/// ```no_run
Allen George8b96bfb2016-11-02 08:01:08 -0400265/// use thrift::protocol::{TBinaryOutputProtocol, TOutputProtocol};
Allen George0e22c362017-01-30 07:15:00 -0500266/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -0400267///
Allen George0e22c362017-01-30 07:15:00 -0500268/// let mut channel = TTcpChannel::new();
269/// channel.open("localhost:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400270///
Allen George0e22c362017-01-30 07:15:00 -0500271/// let mut protocol = TBinaryOutputProtocol::new(channel, true);
Allen George8b96bfb2016-11-02 08:01:08 -0400272///
Allen George0e22c362017-01-30 07:15:00 -0500273/// protocol.write_bool(true).unwrap();
274/// protocol.write_string("test_string").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400275/// ```
Allen George0e22c362017-01-30 07:15:00 -0500276#[derive(Debug)]
277pub struct TBinaryOutputProtocol<T>
278where
279 T: TWriteTransport,
280{
Allen George8b96bfb2016-11-02 08:01:08 -0400281 strict: bool,
Allen George0e22c362017-01-30 07:15:00 -0500282 pub transport: T, // FIXME: do not make public; only public for testing!
Allen George8b96bfb2016-11-02 08:01:08 -0400283}
284
Allen George0e22c362017-01-30 07:15:00 -0500285impl<T> TBinaryOutputProtocol<T>
286where
287 T: TWriteTransport,
288{
Allen George8b96bfb2016-11-02 08:01:08 -0400289 /// Create a `TBinaryOutputProtocol` that writes bytes to `transport`.
290 ///
291 /// Set `strict` to `true` if all outgoing messages should contain the
292 /// protocol version number in the protocol header.
Allen George0e22c362017-01-30 07:15:00 -0500293 pub fn new(transport: T, strict: bool) -> TBinaryOutputProtocol<T> {
Allen George55c3e4c2021-03-01 23:19:52 -0500294 TBinaryOutputProtocol { strict, transport }
Allen George8b96bfb2016-11-02 08:01:08 -0400295 }
Allen George8b96bfb2016-11-02 08:01:08 -0400296}
297
Allen George0e22c362017-01-30 07:15:00 -0500298impl<T> TOutputProtocol for TBinaryOutputProtocol<T>
299where
300 T: TWriteTransport,
301{
Allen Georgeb0d14132020-03-29 11:48:55 -0400302 fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400303 if self.strict {
304 let message_type: u8 = identifier.message_type.into();
305 let header = BINARY_PROTOCOL_VERSION_1 | (message_type as u32);
Allen George0e22c362017-01-30 07:15:00 -0500306 self.transport.write_u32::<BigEndian>(header)?;
Allen George8b96bfb2016-11-02 08:01:08 -0400307 self.write_string(&identifier.name)?;
308 self.write_i32(identifier.sequence_number)
309 } else {
310 self.write_string(&identifier.name)?;
311 self.write_byte(identifier.message_type.into())?;
312 self.write_i32(identifier.sequence_number)
313 }
314 }
315
Allen Georgeb0d14132020-03-29 11:48:55 -0400316 fn write_message_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400317 Ok(())
318 }
319
Allen Georgeb0d14132020-03-29 11:48:55 -0400320 fn write_struct_begin(&mut self, _: &TStructIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400321 Ok(())
322 }
323
Allen Georgeb0d14132020-03-29 11:48:55 -0400324 fn write_struct_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400325 Ok(())
326 }
327
Allen Georgeb0d14132020-03-29 11:48:55 -0400328 fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400329 if identifier.id.is_none() && identifier.field_type != TType::Stop {
Allen Georgeb0d14132020-03-29 11:48:55 -0400330 return Err(crate::Error::Protocol(ProtocolError {
Allen Georgeef7a1892018-12-16 18:01:37 -0500331 kind: ProtocolErrorKind::Unknown,
332 message: format!(
333 "cannot write identifier {:?} without sequence number",
334 &identifier
Allen George0e22c362017-01-30 07:15:00 -0500335 ),
Allen Georgeef7a1892018-12-16 18:01:37 -0500336 }));
Allen George8b96bfb2016-11-02 08:01:08 -0400337 }
338
339 self.write_byte(field_type_to_u8(identifier.field_type))?;
340 if let Some(id) = identifier.id {
341 self.write_i16(id)
342 } else {
343 Ok(())
344 }
345 }
346
Allen Georgeb0d14132020-03-29 11:48:55 -0400347 fn write_field_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400348 Ok(())
349 }
350
Allen Georgeb0d14132020-03-29 11:48:55 -0400351 fn write_field_stop(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400352 self.write_byte(field_type_to_u8(TType::Stop))
353 }
354
Allen Georgeb0d14132020-03-29 11:48:55 -0400355 fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400356 self.write_i32(b.len() as i32)?;
Allen Georgecf7ba4c2017-12-11 11:44:11 -0500357 self.transport.write_all(b).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400358 }
359
Allen Georgeb0d14132020-03-29 11:48:55 -0400360 fn write_bool(&mut self, b: bool) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400361 if b {
362 self.write_i8(1)
363 } else {
364 self.write_i8(0)
365 }
366 }
367
Allen Georgeb0d14132020-03-29 11:48:55 -0400368 fn write_i8(&mut self, i: i8) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500369 self.transport.write_i8(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400370 }
371
Allen Georgeb0d14132020-03-29 11:48:55 -0400372 fn write_i16(&mut self, i: i16) -> crate::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500373 self.transport.write_i16::<BigEndian>(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400374 }
375
Allen Georgeb0d14132020-03-29 11:48:55 -0400376 fn write_i32(&mut self, i: i32) -> crate::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500377 self.transport.write_i32::<BigEndian>(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400378 }
379
Allen Georgeb0d14132020-03-29 11:48:55 -0400380 fn write_i64(&mut self, i: i64) -> crate::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500381 self.transport.write_i64::<BigEndian>(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400382 }
383
Allen Georgeb0d14132020-03-29 11:48:55 -0400384 fn write_double(&mut self, d: f64) -> crate::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500385 self.transport.write_f64::<BigEndian>(d).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400386 }
387
Allen Georgeb0d14132020-03-29 11:48:55 -0400388 fn write_string(&mut self, s: &str) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400389 self.write_bytes(s.as_bytes())
390 }
391
Allen Georgeb0d14132020-03-29 11:48:55 -0400392 fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400393 self.write_byte(field_type_to_u8(identifier.element_type))?;
394 self.write_i32(identifier.size)
395 }
396
Allen Georgeb0d14132020-03-29 11:48:55 -0400397 fn write_list_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400398 Ok(())
399 }
400
Allen Georgeb0d14132020-03-29 11:48:55 -0400401 fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400402 self.write_byte(field_type_to_u8(identifier.element_type))?;
403 self.write_i32(identifier.size)
404 }
405
Allen Georgeb0d14132020-03-29 11:48:55 -0400406 fn write_set_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400407 Ok(())
408 }
409
Allen Georgeb0d14132020-03-29 11:48:55 -0400410 fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500411 let key_type = identifier
412 .key_type
Allen George8b96bfb2016-11-02 08:01:08 -0400413 .expect("map identifier to write should contain key type");
414 self.write_byte(field_type_to_u8(key_type))?;
Allen George0e22c362017-01-30 07:15:00 -0500415 let val_type = identifier
416 .value_type
Allen George8b96bfb2016-11-02 08:01:08 -0400417 .expect("map identifier to write should contain value type");
418 self.write_byte(field_type_to_u8(val_type))?;
419 self.write_i32(identifier.size)
420 }
421
Allen Georgeb0d14132020-03-29 11:48:55 -0400422 fn write_map_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400423 Ok(())
424 }
425
Allen Georgeb0d14132020-03-29 11:48:55 -0400426 fn flush(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500427 self.transport.flush().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400428 }
429
430 // utility
431 //
432
Allen Georgeb0d14132020-03-29 11:48:55 -0400433 fn write_byte(&mut self, b: u8) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500434 self.transport.write_u8(b).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400435 }
436}
437
438/// Factory for creating instances of `TBinaryOutputProtocol`.
439#[derive(Default)]
440pub struct TBinaryOutputProtocolFactory;
441
442impl TBinaryOutputProtocolFactory {
443 /// Create a `TBinaryOutputProtocolFactory`.
444 pub fn new() -> TBinaryOutputProtocolFactory {
445 TBinaryOutputProtocolFactory {}
446 }
447}
448
449impl TOutputProtocolFactory for TBinaryOutputProtocolFactory {
Allen George55c3e4c2021-03-01 23:19:52 -0500450 fn create(
451 &self,
452 transport: Box<dyn TWriteTransport + Send>,
453 ) -> Box<dyn TOutputProtocol + Send> {
Allen George0e22c362017-01-30 07:15:00 -0500454 Box::new(TBinaryOutputProtocol::new(transport, true))
Allen George8b96bfb2016-11-02 08:01:08 -0400455 }
456}
457
458fn field_type_to_u8(field_type: TType) -> u8 {
459 match field_type {
460 TType::Stop => 0x00,
461 TType::Void => 0x01,
462 TType::Bool => 0x02,
463 TType::I08 => 0x03, // equivalent to TType::Byte
464 TType::Double => 0x04,
465 TType::I16 => 0x06,
466 TType::I32 => 0x08,
467 TType::I64 => 0x0A,
468 TType::String | TType::Utf7 => 0x0B,
469 TType::Struct => 0x0C,
470 TType::Map => 0x0D,
471 TType::Set => 0x0E,
472 TType::List => 0x0F,
473 TType::Utf8 => 0x10,
474 TType::Utf16 => 0x11,
475 }
476}
477
Allen Georgeb0d14132020-03-29 11:48:55 -0400478fn field_type_from_u8(b: u8) -> crate::Result<TType> {
Allen George8b96bfb2016-11-02 08:01:08 -0400479 match b {
480 0x00 => Ok(TType::Stop),
481 0x01 => Ok(TType::Void),
482 0x02 => Ok(TType::Bool),
483 0x03 => Ok(TType::I08), // Equivalent to TType::Byte
484 0x04 => Ok(TType::Double),
485 0x06 => Ok(TType::I16),
486 0x08 => Ok(TType::I32),
487 0x0A => Ok(TType::I64),
488 0x0B => Ok(TType::String), // technically, also a UTF7, but we'll treat it as string
489 0x0C => Ok(TType::Struct),
490 0x0D => Ok(TType::Map),
491 0x0E => Ok(TType::Set),
492 0x0F => Ok(TType::List),
493 0x10 => Ok(TType::Utf8),
494 0x11 => Ok(TType::Utf16),
Allen Georgeb0d14132020-03-29 11:48:55 -0400495 unkn => Err(crate::Error::Protocol(ProtocolError {
Allen Georgeef7a1892018-12-16 18:01:37 -0500496 kind: ProtocolErrorKind::InvalidData,
497 message: format!("cannot convert {} to TType", unkn),
498 })),
Allen George8b96bfb2016-11-02 08:01:08 -0400499 }
500}
501
502#[cfg(test)]
503mod tests {
504
Allen Georgeb0d14132020-03-29 11:48:55 -0400505 use crate::protocol::{
Allen Georgeef7a1892018-12-16 18:01:37 -0500506 TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
507 TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType,
508 };
Allen Georgeb0d14132020-03-29 11:48:55 -0400509 use crate::transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
Allen George8b96bfb2016-11-02 08:01:08 -0400510
511 use super::*;
512
513 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500514 fn must_write_strict_message_call_begin() {
515 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400516
517 let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
518 assert!(o_prot.write_message_begin(&ident).is_ok());
519
Allen George7ddbcc02020-11-08 09:51:19 -0500520 #[rustfmt::skip]
Allen George0e22c362017-01-30 07:15:00 -0500521 let expected: [u8; 16] = [
522 0x80,
523 0x01,
524 0x00,
525 0x01,
526 0x00,
527 0x00,
528 0x00,
529 0x04,
530 0x74,
531 0x65,
532 0x73,
533 0x74,
534 0x00,
535 0x00,
536 0x00,
537 0x01,
538 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400539
Allen George0e22c362017-01-30 07:15:00 -0500540 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400541 }
542
Allen George8b96bfb2016-11-02 08:01:08 -0400543 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500544 fn must_write_non_strict_message_call_begin() {
545 let (_, mut o_prot) = test_objects(false);
546
547 let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
548 assert!(o_prot.write_message_begin(&ident).is_ok());
549
Allen George7ddbcc02020-11-08 09:51:19 -0500550 #[rustfmt::skip]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500551 let expected: [u8; 13] = [
552 0x00,
553 0x00,
554 0x00,
555 0x04,
556 0x74,
557 0x65,
558 0x73,
559 0x74,
560 0x01,
561 0x00,
562 0x00,
563 0x00,
564 0x01,
565 ];
566
567 assert_eq_written_bytes!(o_prot, expected);
568 }
569
570 #[test]
571 fn must_write_strict_message_reply_begin() {
572 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400573
574 let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
575 assert!(o_prot.write_message_begin(&ident).is_ok());
576
Allen George7ddbcc02020-11-08 09:51:19 -0500577 #[rustfmt::skip]
Allen George0e22c362017-01-30 07:15:00 -0500578 let expected: [u8; 16] = [
579 0x80,
580 0x01,
581 0x00,
582 0x02,
583 0x00,
584 0x00,
585 0x00,
586 0x04,
587 0x74,
588 0x65,
589 0x73,
590 0x74,
591 0x00,
592 0x00,
593 0x00,
594 0x0A,
595 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400596
Allen George0e22c362017-01-30 07:15:00 -0500597 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400598 }
599
600 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500601 fn must_write_non_strict_message_reply_begin() {
602 let (_, mut o_prot) = test_objects(false);
603
604 let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
605 assert!(o_prot.write_message_begin(&ident).is_ok());
606
Allen George7ddbcc02020-11-08 09:51:19 -0500607 #[rustfmt::skip]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500608 let expected: [u8; 13] = [
609 0x00,
610 0x00,
611 0x00,
612 0x04,
613 0x74,
614 0x65,
615 0x73,
616 0x74,
617 0x02,
618 0x00,
619 0x00,
620 0x00,
621 0x0A,
622 ];
623
624 assert_eq_written_bytes!(o_prot, expected);
625 }
626
627 #[test]
Allen George8b96bfb2016-11-02 08:01:08 -0400628 fn must_round_trip_strict_message_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500629 let (mut i_prot, mut o_prot) = test_objects(true);
630
631 let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
632 assert!(o_prot.write_message_begin(&sent_ident).is_ok());
633
634 copy_write_buffer_to_read_buffer!(o_prot);
635
636 let received_ident = assert_success!(i_prot.read_message_begin());
637 assert_eq!(&received_ident, &sent_ident);
638 }
639
640 #[test]
641 fn must_round_trip_non_strict_message_begin() {
642 let (mut i_prot, mut o_prot) = test_objects(false);
Allen George8b96bfb2016-11-02 08:01:08 -0400643
644 let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
645 assert!(o_prot.write_message_begin(&sent_ident).is_ok());
646
Allen George0e22c362017-01-30 07:15:00 -0500647 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400648
649 let received_ident = assert_success!(i_prot.read_message_begin());
650 assert_eq!(&received_ident, &sent_ident);
651 }
652
653 #[test]
654 fn must_write_message_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500655 assert_no_write(|o| o.write_message_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400656 }
657
658 #[test]
659 fn must_write_struct_begin() {
Allen Georgeef7a1892018-12-16 18:01:37 -0500660 assert_no_write(
661 |o| o.write_struct_begin(&TStructIdentifier::new("foo")),
662 true,
663 );
Allen George8b96bfb2016-11-02 08:01:08 -0400664 }
665
666 #[test]
667 fn must_write_struct_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500668 assert_no_write(|o| o.write_struct_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400669 }
670
671 #[test]
672 fn must_write_field_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500673 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400674
Allen Georgeef7a1892018-12-16 18:01:37 -0500675 assert!(o_prot
676 .write_field_begin(&TFieldIdentifier::new("some_field", TType::String, 22))
677 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400678
679 let expected: [u8; 3] = [0x0B, 0x00, 0x16];
Allen George0e22c362017-01-30 07:15:00 -0500680 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400681 }
682
683 #[test]
684 fn must_round_trip_field_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500685 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400686
687 let sent_field_ident = TFieldIdentifier::new("foo", TType::I64, 20);
688 assert!(o_prot.write_field_begin(&sent_field_ident).is_ok());
689
Allen George0e22c362017-01-30 07:15:00 -0500690 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400691
692 let expected_ident = TFieldIdentifier {
693 name: None,
694 field_type: TType::I64,
695 id: Some(20),
696 }; // no name
697 let received_ident = assert_success!(i_prot.read_field_begin());
698 assert_eq!(&received_ident, &expected_ident);
699 }
700
701 #[test]
702 fn must_write_stop_field() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500703 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400704
705 assert!(o_prot.write_field_stop().is_ok());
706
707 let expected: [u8; 1] = [0x00];
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_stop() {
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 assert!(o_prot.write_field_stop().is_ok());
716
Allen George0e22c362017-01-30 07:15:00 -0500717 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400718
719 let expected_ident = TFieldIdentifier {
720 name: None,
721 field_type: TType::Stop,
722 id: Some(0),
723 }; // we get id 0
724
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_field_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500731 assert_no_write(|o| o.write_field_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400732 }
733
734 #[test]
735 fn must_write_list_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500736 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400737
Allen Georgeef7a1892018-12-16 18:01:37 -0500738 assert!(o_prot
739 .write_list_begin(&TListIdentifier::new(TType::Bool, 5))
740 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400741
742 let expected: [u8; 5] = [0x02, 0x00, 0x00, 0x00, 0x05];
Allen George0e22c362017-01-30 07:15:00 -0500743 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400744 }
745
746 #[test]
747 fn must_round_trip_list_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500748 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400749
750 let ident = TListIdentifier::new(TType::List, 900);
751 assert!(o_prot.write_list_begin(&ident).is_ok());
752
Allen George0e22c362017-01-30 07:15:00 -0500753 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400754
755 let received_ident = assert_success!(i_prot.read_list_begin());
756 assert_eq!(&received_ident, &ident);
757 }
758
759 #[test]
760 fn must_write_list_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500761 assert_no_write(|o| o.write_list_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400762 }
763
764 #[test]
765 fn must_write_set_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500766 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400767
Allen Georgeef7a1892018-12-16 18:01:37 -0500768 assert!(o_prot
769 .write_set_begin(&TSetIdentifier::new(TType::I16, 7))
770 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400771
772 let expected: [u8; 5] = [0x06, 0x00, 0x00, 0x00, 0x07];
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_set_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 = TSetIdentifier::new(TType::I64, 2000);
781 assert!(o_prot.write_set_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_result = i_prot.read_set_begin();
786 assert!(received_ident_result.is_ok());
787 assert_eq!(&received_ident_result.unwrap(), &ident);
788 }
789
790 #[test]
791 fn must_write_set_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500792 assert_no_write(|o| o.write_set_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400793 }
794
795 #[test]
796 fn must_write_map_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500797 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400798
Allen Georgeef7a1892018-12-16 18:01:37 -0500799 assert!(o_prot
800 .write_map_begin(&TMapIdentifier::new(TType::I64, TType::Struct, 32))
801 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400802
803 let expected: [u8; 6] = [0x0A, 0x0C, 0x00, 0x00, 0x00, 0x20];
Allen George0e22c362017-01-30 07:15:00 -0500804 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400805 }
806
807 #[test]
808 fn must_round_trip_map_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500809 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400810
811 let ident = TMapIdentifier::new(TType::Map, TType::Set, 100);
812 assert!(o_prot.write_map_begin(&ident).is_ok());
813
Allen George0e22c362017-01-30 07:15:00 -0500814 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400815
816 let received_ident = assert_success!(i_prot.read_map_begin());
817 assert_eq!(&received_ident, &ident);
818 }
819
820 #[test]
821 fn must_write_map_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500822 assert_no_write(|o| o.write_map_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400823 }
824
825 #[test]
826 fn must_write_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500827 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400828
829 assert!(o_prot.write_bool(true).is_ok());
830
831 let expected: [u8; 1] = [0x01];
Allen George0e22c362017-01-30 07:15:00 -0500832 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400833 }
834
835 #[test]
836 fn must_write_bool_false() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500837 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400838
839 assert!(o_prot.write_bool(false).is_ok());
840
841 let expected: [u8; 1] = [0x00];
Allen George0e22c362017-01-30 07:15:00 -0500842 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400843 }
844
845 #[test]
846 fn must_read_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500847 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400848
Allen George0e22c362017-01-30 07:15:00 -0500849 set_readable_bytes!(i_prot, &[0x01]);
Allen George8b96bfb2016-11-02 08:01:08 -0400850
851 let read_bool = assert_success!(i_prot.read_bool());
852 assert_eq!(read_bool, true);
853 }
854
855 #[test]
856 fn must_read_bool_false() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500857 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400858
Allen George0e22c362017-01-30 07:15:00 -0500859 set_readable_bytes!(i_prot, &[0x00]);
Allen George8b96bfb2016-11-02 08:01:08 -0400860
861 let read_bool = assert_success!(i_prot.read_bool());
862 assert_eq!(read_bool, false);
863 }
864
865 #[test]
866 fn must_allow_any_non_zero_value_to_be_interpreted_as_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500867 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400868
Allen George0e22c362017-01-30 07:15:00 -0500869 set_readable_bytes!(i_prot, &[0xAC]);
Allen George8b96bfb2016-11-02 08:01:08 -0400870
871 let read_bool = assert_success!(i_prot.read_bool());
872 assert_eq!(read_bool, true);
873 }
874
875 #[test]
876 fn must_write_bytes() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500877 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400878
879 let bytes: [u8; 10] = [0x0A, 0xCC, 0xD1, 0x84, 0x99, 0x12, 0xAB, 0xBB, 0x45, 0xDF];
880
881 assert!(o_prot.write_bytes(&bytes).is_ok());
882
Allen George0e22c362017-01-30 07:15:00 -0500883 let buf = o_prot.transport.write_bytes();
Allen George8b96bfb2016-11-02 08:01:08 -0400884 assert_eq!(&buf[0..4], [0x00, 0x00, 0x00, 0x0A]); // length
885 assert_eq!(&buf[4..], bytes); // actual bytes
886 }
887
888 #[test]
889 fn must_round_trip_bytes() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500890 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400891
Allen George7ddbcc02020-11-08 09:51:19 -0500892 #[rustfmt::skip]
Allen George0e22c362017-01-30 07:15:00 -0500893 let bytes: [u8; 25] = [
894 0x20,
895 0xFD,
896 0x18,
897 0x84,
898 0x99,
899 0x12,
900 0xAB,
901 0xBB,
902 0x45,
903 0xDF,
904 0x34,
905 0xDC,
906 0x98,
907 0xA4,
908 0x6D,
909 0xF3,
910 0x99,
911 0xB4,
912 0xB7,
913 0xD4,
914 0x9C,
915 0xA5,
916 0xB3,
917 0xC9,
918 0x88,
919 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400920
921 assert!(o_prot.write_bytes(&bytes).is_ok());
922
Allen George0e22c362017-01-30 07:15:00 -0500923 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400924
925 let received_bytes = assert_success!(i_prot.read_bytes());
926 assert_eq!(&received_bytes, &bytes);
927 }
928
Allen Georgeef7a1892018-12-16 18:01:37 -0500929 fn test_objects(
930 strict: bool,
931 ) -> (
932 TBinaryInputProtocol<ReadHalf<TBufferChannel>>,
933 TBinaryOutputProtocol<WriteHalf<TBufferChannel>>,
934 ) {
Allen George0e22c362017-01-30 07:15:00 -0500935 let mem = TBufferChannel::with_capacity(40, 40);
Chao Sunc063b302017-03-12 12:21:05 -0700936
Allen George0e22c362017-01-30 07:15:00 -0500937 let (r_mem, w_mem) = mem.split().unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400938
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500939 let i_prot = TBinaryInputProtocol::new(r_mem, strict);
940 let o_prot = TBinaryOutputProtocol::new(w_mem, strict);
Allen George8b96bfb2016-11-02 08:01:08 -0400941
Allen George0e22c362017-01-30 07:15:00 -0500942 (i_prot, o_prot)
Allen George8b96bfb2016-11-02 08:01:08 -0400943 }
944
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500945 fn assert_no_write<F>(mut write_fn: F, strict: bool)
Allen George0e22c362017-01-30 07:15:00 -0500946 where
Allen Georgeb0d14132020-03-29 11:48:55 -0400947 F: FnMut(&mut TBinaryOutputProtocol<WriteHalf<TBufferChannel>>) -> crate::Result<()>,
Allen George0e22c362017-01-30 07:15:00 -0500948 {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500949 let (_, mut o_prot) = test_objects(strict);
Allen George8b96bfb2016-11-02 08:01:08 -0400950 assert!(write_fn(&mut o_prot).is_ok());
Allen George0e22c362017-01-30 07:15:00 -0500951 assert_eq!(o_prot.transport.write_bytes().len(), 0);
Allen George8b96bfb2016-11-02 08:01:08 -0400952 }
953}