blob: 0ef65e54ba5ef0061b338cfc9a36708fff38870d [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
29const BINARY_PROTOCOL_VERSION_1: u32 = 0x80010000;
30
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 George8b96bfb2016-11-02 08:01:08 -040071 TBinaryInputProtocol {
72 strict: strict,
73 transport: transport,
74 }
75 }
76}
77
Allen George0e22c362017-01-30 07:15:00 -050078impl<T> TInputProtocol for TBinaryInputProtocol<T>
79where
80 T: TReadTransport,
81{
Allen George8b96bfb2016-11-02 08:01:08 -040082 #[cfg_attr(feature = "cargo-clippy", allow(collapsible_if))]
Allen Georgeb0d14132020-03-29 11:48:55 -040083 fn read_message_begin(&mut self) -> crate::Result<TMessageIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -040084 let mut first_bytes = vec![0; 4];
Allen George0e22c362017-01-30 07:15:00 -050085 self.transport.read_exact(&mut first_bytes[..])?;
Allen George8b96bfb2016-11-02 08:01:08 -040086
87 // the thrift version header is intentionally negative
88 // so the first check we'll do is see if the sign bit is set
89 // and if so - assume it's the protocol-version header
90 if first_bytes[0] >= 8 {
91 // apparently we got a protocol-version header - check
92 // it, and if it matches, read the rest of the fields
93 if first_bytes[0..2] != [0x80, 0x01] {
Allen Georgeb0d14132020-03-29 11:48:55 -040094 Err(crate::Error::Protocol(ProtocolError {
Allen Georgeef7a1892018-12-16 18:01:37 -050095 kind: ProtocolErrorKind::BadVersion,
96 message: format!("received bad version: {:?}", &first_bytes[0..2]),
97 }))
Allen George8b96bfb2016-11-02 08:01:08 -040098 } else {
99 let message_type: TMessageType = TryFrom::try_from(first_bytes[3])?;
100 let name = self.read_string()?;
101 let sequence_number = self.read_i32()?;
102 Ok(TMessageIdentifier::new(name, message_type, sequence_number))
103 }
104 } else {
105 // apparently we didn't get a protocol-version header,
106 // which happens if the sender is not using the strict protocol
107 if self.strict {
108 // we're in strict mode however, and that always
109 // requires the protocol-version header to be written first
Allen Georgeb0d14132020-03-29 11:48:55 -0400110 Err(crate::Error::Protocol(ProtocolError {
Allen Georgeef7a1892018-12-16 18:01:37 -0500111 kind: ProtocolErrorKind::BadVersion,
112 message: format!("received bad version: {:?}", &first_bytes[0..2]),
113 }))
Allen George8b96bfb2016-11-02 08:01:08 -0400114 } else {
115 // in the non-strict version the first message field
116 // is the message name. strings (byte arrays) are length-prefixed,
117 // so we've just read the length in the first 4 bytes
118 let name_size = BigEndian::read_i32(&first_bytes) as usize;
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500119 let mut name_buf: Vec<u8> = vec![0; name_size];
Allen George0e22c362017-01-30 07:15:00 -0500120 self.transport.read_exact(&mut name_buf)?;
Allen George8b96bfb2016-11-02 08:01:08 -0400121 let name = String::from_utf8(name_buf)?;
122
123 // read the rest of the fields
124 let message_type: TMessageType = self.read_byte().and_then(TryFrom::try_from)?;
125 let sequence_number = self.read_i32()?;
126 Ok(TMessageIdentifier::new(name, message_type, sequence_number))
127 }
128 }
129 }
130
Allen Georgeb0d14132020-03-29 11:48:55 -0400131 fn read_message_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400132 Ok(())
133 }
134
Allen Georgeb0d14132020-03-29 11:48:55 -0400135 fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>> {
Allen George8b96bfb2016-11-02 08:01:08 -0400136 Ok(None)
137 }
138
Allen Georgeb0d14132020-03-29 11:48:55 -0400139 fn read_struct_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400140 Ok(())
141 }
142
Allen Georgeb0d14132020-03-29 11:48:55 -0400143 fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400144 let field_type_byte = self.read_byte()?;
145 let field_type = field_type_from_u8(field_type_byte)?;
146 let id = match field_type {
147 TType::Stop => Ok(0),
148 _ => self.read_i16(),
149 }?;
Allen Georgeef7a1892018-12-16 18:01:37 -0500150 Ok(TFieldIdentifier::new::<Option<String>, String, i16>(
151 None, field_type, id,
152 ))
Allen George8b96bfb2016-11-02 08:01:08 -0400153 }
154
Allen Georgeb0d14132020-03-29 11:48:55 -0400155 fn read_field_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400156 Ok(())
157 }
158
Allen Georgeb0d14132020-03-29 11:48:55 -0400159 fn read_bytes(&mut self) -> crate::Result<Vec<u8>> {
Allen George0e22c362017-01-30 07:15:00 -0500160 let num_bytes = self.transport.read_i32::<BigEndian>()? as usize;
Allen George8b96bfb2016-11-02 08:01:08 -0400161 let mut buf = vec![0u8; num_bytes];
Allen George0e22c362017-01-30 07:15:00 -0500162 self.transport
163 .read_exact(&mut buf)
164 .map(|_| buf)
165 .map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400166 }
167
Allen Georgeb0d14132020-03-29 11:48:55 -0400168 fn read_bool(&mut self) -> crate::Result<bool> {
Allen George8b96bfb2016-11-02 08:01:08 -0400169 let b = self.read_i8()?;
170 match b {
171 0 => Ok(false),
172 _ => Ok(true),
173 }
174 }
175
Allen Georgeb0d14132020-03-29 11:48:55 -0400176 fn read_i8(&mut self) -> crate::Result<i8> {
Allen George0e22c362017-01-30 07:15:00 -0500177 self.transport.read_i8().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400178 }
179
Allen Georgeb0d14132020-03-29 11:48:55 -0400180 fn read_i16(&mut self) -> crate::Result<i16> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500181 self.transport.read_i16::<BigEndian>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400182 }
183
Allen Georgeb0d14132020-03-29 11:48:55 -0400184 fn read_i32(&mut self) -> crate::Result<i32> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500185 self.transport.read_i32::<BigEndian>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400186 }
187
Allen Georgeb0d14132020-03-29 11:48:55 -0400188 fn read_i64(&mut self) -> crate::Result<i64> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500189 self.transport.read_i64::<BigEndian>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400190 }
191
Allen Georgeb0d14132020-03-29 11:48:55 -0400192 fn read_double(&mut self) -> crate::Result<f64> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500193 self.transport.read_f64::<BigEndian>().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400194 }
195
Allen Georgeb0d14132020-03-29 11:48:55 -0400196 fn read_string(&mut self) -> crate::Result<String> {
Allen George8b96bfb2016-11-02 08:01:08 -0400197 let bytes = self.read_bytes()?;
198 String::from_utf8(bytes).map_err(From::from)
199 }
200
Allen Georgeb0d14132020-03-29 11:48:55 -0400201 fn read_list_begin(&mut self) -> crate::Result<TListIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400202 let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
203 let size = self.read_i32()?;
204 Ok(TListIdentifier::new(element_type, size))
205 }
206
Allen Georgeb0d14132020-03-29 11:48:55 -0400207 fn read_list_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400208 Ok(())
209 }
210
Allen Georgeb0d14132020-03-29 11:48:55 -0400211 fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400212 let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
213 let size = self.read_i32()?;
214 Ok(TSetIdentifier::new(element_type, size))
215 }
216
Allen Georgeb0d14132020-03-29 11:48:55 -0400217 fn read_set_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400218 Ok(())
219 }
220
Allen Georgeb0d14132020-03-29 11:48:55 -0400221 fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400222 let key_type: TType = self.read_byte().and_then(field_type_from_u8)?;
223 let value_type: TType = self.read_byte().and_then(field_type_from_u8)?;
224 let size = self.read_i32()?;
225 Ok(TMapIdentifier::new(key_type, value_type, size))
226 }
227
Allen Georgeb0d14132020-03-29 11:48:55 -0400228 fn read_map_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400229 Ok(())
230 }
231
232 // utility
233 //
234
Allen Georgeb0d14132020-03-29 11:48:55 -0400235 fn read_byte(&mut self) -> crate::Result<u8> {
Allen George0e22c362017-01-30 07:15:00 -0500236 self.transport.read_u8().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400237 }
238}
239
240/// Factory for creating instances of `TBinaryInputProtocol`.
241#[derive(Default)]
242pub struct TBinaryInputProtocolFactory;
243
244impl TBinaryInputProtocolFactory {
245 /// Create a `TBinaryInputProtocolFactory`.
246 pub fn new() -> TBinaryInputProtocolFactory {
247 TBinaryInputProtocolFactory {}
248 }
249}
250
251impl TInputProtocolFactory for TBinaryInputProtocolFactory {
Danny Browning77d96c12019-08-21 13:41:07 -0600252 fn create(&self, transport: Box<dyn TReadTransport + Send>) -> Box<dyn TInputProtocol + Send> {
Allen George0e22c362017-01-30 07:15:00 -0500253 Box::new(TBinaryInputProtocol::new(transport, true))
Allen George8b96bfb2016-11-02 08:01:08 -0400254 }
255}
256
257/// Write messages using the Thrift simple binary encoding.
258///
259/// There are two available modes: `strict` and `non-strict`, where the
260/// `strict` version writes the protocol version number in the outgoing message
261/// header and the `non-strict` version does not.
262///
263/// # Examples
264///
265/// Create and use a `TBinaryOutputProtocol`.
266///
267/// ```no_run
Allen George8b96bfb2016-11-02 08:01:08 -0400268/// use thrift::protocol::{TBinaryOutputProtocol, TOutputProtocol};
Allen George0e22c362017-01-30 07:15:00 -0500269/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -0400270///
Allen George0e22c362017-01-30 07:15:00 -0500271/// let mut channel = TTcpChannel::new();
272/// channel.open("localhost:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400273///
Allen George0e22c362017-01-30 07:15:00 -0500274/// let mut protocol = TBinaryOutputProtocol::new(channel, true);
Allen George8b96bfb2016-11-02 08:01:08 -0400275///
Allen George0e22c362017-01-30 07:15:00 -0500276/// protocol.write_bool(true).unwrap();
277/// protocol.write_string("test_string").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400278/// ```
Allen George0e22c362017-01-30 07:15:00 -0500279#[derive(Debug)]
280pub struct TBinaryOutputProtocol<T>
281where
282 T: TWriteTransport,
283{
Allen George8b96bfb2016-11-02 08:01:08 -0400284 strict: bool,
Allen George0e22c362017-01-30 07:15:00 -0500285 pub transport: T, // FIXME: do not make public; only public for testing!
Allen George8b96bfb2016-11-02 08:01:08 -0400286}
287
Allen George0e22c362017-01-30 07:15:00 -0500288impl<T> TBinaryOutputProtocol<T>
289where
290 T: TWriteTransport,
291{
Allen George8b96bfb2016-11-02 08:01:08 -0400292 /// Create a `TBinaryOutputProtocol` that writes bytes to `transport`.
293 ///
294 /// Set `strict` to `true` if all outgoing messages should contain the
295 /// protocol version number in the protocol header.
Allen George0e22c362017-01-30 07:15:00 -0500296 pub fn new(transport: T, strict: bool) -> TBinaryOutputProtocol<T> {
Allen George8b96bfb2016-11-02 08:01:08 -0400297 TBinaryOutputProtocol {
298 strict: strict,
299 transport: transport,
300 }
301 }
Allen George8b96bfb2016-11-02 08:01:08 -0400302}
303
Allen George0e22c362017-01-30 07:15:00 -0500304impl<T> TOutputProtocol for TBinaryOutputProtocol<T>
305where
306 T: TWriteTransport,
307{
Allen Georgeb0d14132020-03-29 11:48:55 -0400308 fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400309 if self.strict {
310 let message_type: u8 = identifier.message_type.into();
311 let header = BINARY_PROTOCOL_VERSION_1 | (message_type as u32);
Allen George0e22c362017-01-30 07:15:00 -0500312 self.transport.write_u32::<BigEndian>(header)?;
Allen George8b96bfb2016-11-02 08:01:08 -0400313 self.write_string(&identifier.name)?;
314 self.write_i32(identifier.sequence_number)
315 } else {
316 self.write_string(&identifier.name)?;
317 self.write_byte(identifier.message_type.into())?;
318 self.write_i32(identifier.sequence_number)
319 }
320 }
321
Allen Georgeb0d14132020-03-29 11:48:55 -0400322 fn write_message_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400323 Ok(())
324 }
325
Allen Georgeb0d14132020-03-29 11:48:55 -0400326 fn write_struct_begin(&mut self, _: &TStructIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400327 Ok(())
328 }
329
Allen Georgeb0d14132020-03-29 11:48:55 -0400330 fn write_struct_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400331 Ok(())
332 }
333
Allen Georgeb0d14132020-03-29 11:48:55 -0400334 fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400335 if identifier.id.is_none() && identifier.field_type != TType::Stop {
Allen Georgeb0d14132020-03-29 11:48:55 -0400336 return Err(crate::Error::Protocol(ProtocolError {
Allen Georgeef7a1892018-12-16 18:01:37 -0500337 kind: ProtocolErrorKind::Unknown,
338 message: format!(
339 "cannot write identifier {:?} without sequence number",
340 &identifier
Allen George0e22c362017-01-30 07:15:00 -0500341 ),
Allen Georgeef7a1892018-12-16 18:01:37 -0500342 }));
Allen George8b96bfb2016-11-02 08:01:08 -0400343 }
344
345 self.write_byte(field_type_to_u8(identifier.field_type))?;
346 if let Some(id) = identifier.id {
347 self.write_i16(id)
348 } else {
349 Ok(())
350 }
351 }
352
Allen Georgeb0d14132020-03-29 11:48:55 -0400353 fn write_field_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400354 Ok(())
355 }
356
Allen Georgeb0d14132020-03-29 11:48:55 -0400357 fn write_field_stop(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400358 self.write_byte(field_type_to_u8(TType::Stop))
359 }
360
Allen Georgeb0d14132020-03-29 11:48:55 -0400361 fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400362 self.write_i32(b.len() as i32)?;
Allen Georgecf7ba4c2017-12-11 11:44:11 -0500363 self.transport.write_all(b).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400364 }
365
Allen Georgeb0d14132020-03-29 11:48:55 -0400366 fn write_bool(&mut self, b: bool) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400367 if b {
368 self.write_i8(1)
369 } else {
370 self.write_i8(0)
371 }
372 }
373
Allen Georgeb0d14132020-03-29 11:48:55 -0400374 fn write_i8(&mut self, i: i8) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500375 self.transport.write_i8(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400376 }
377
Allen Georgeb0d14132020-03-29 11:48:55 -0400378 fn write_i16(&mut self, i: i16) -> crate::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500379 self.transport.write_i16::<BigEndian>(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400380 }
381
Allen Georgeb0d14132020-03-29 11:48:55 -0400382 fn write_i32(&mut self, i: i32) -> crate::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500383 self.transport.write_i32::<BigEndian>(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400384 }
385
Allen Georgeb0d14132020-03-29 11:48:55 -0400386 fn write_i64(&mut self, i: i64) -> crate::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500387 self.transport.write_i64::<BigEndian>(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400388 }
389
Allen Georgeb0d14132020-03-29 11:48:55 -0400390 fn write_double(&mut self, d: f64) -> crate::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500391 self.transport.write_f64::<BigEndian>(d).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400392 }
393
Allen Georgeb0d14132020-03-29 11:48:55 -0400394 fn write_string(&mut self, s: &str) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400395 self.write_bytes(s.as_bytes())
396 }
397
Allen Georgeb0d14132020-03-29 11:48:55 -0400398 fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400399 self.write_byte(field_type_to_u8(identifier.element_type))?;
400 self.write_i32(identifier.size)
401 }
402
Allen Georgeb0d14132020-03-29 11:48:55 -0400403 fn write_list_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400404 Ok(())
405 }
406
Allen Georgeb0d14132020-03-29 11:48:55 -0400407 fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400408 self.write_byte(field_type_to_u8(identifier.element_type))?;
409 self.write_i32(identifier.size)
410 }
411
Allen Georgeb0d14132020-03-29 11:48:55 -0400412 fn write_set_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400413 Ok(())
414 }
415
Allen Georgeb0d14132020-03-29 11:48:55 -0400416 fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500417 let key_type = identifier
418 .key_type
Allen George8b96bfb2016-11-02 08:01:08 -0400419 .expect("map identifier to write should contain key type");
420 self.write_byte(field_type_to_u8(key_type))?;
Allen George0e22c362017-01-30 07:15:00 -0500421 let val_type = identifier
422 .value_type
Allen George8b96bfb2016-11-02 08:01:08 -0400423 .expect("map identifier to write should contain value type");
424 self.write_byte(field_type_to_u8(val_type))?;
425 self.write_i32(identifier.size)
426 }
427
Allen Georgeb0d14132020-03-29 11:48:55 -0400428 fn write_map_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400429 Ok(())
430 }
431
Allen Georgeb0d14132020-03-29 11:48:55 -0400432 fn flush(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500433 self.transport.flush().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400434 }
435
436 // utility
437 //
438
Allen Georgeb0d14132020-03-29 11:48:55 -0400439 fn write_byte(&mut self, b: u8) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500440 self.transport.write_u8(b).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400441 }
442}
443
444/// Factory for creating instances of `TBinaryOutputProtocol`.
445#[derive(Default)]
446pub struct TBinaryOutputProtocolFactory;
447
448impl TBinaryOutputProtocolFactory {
449 /// Create a `TBinaryOutputProtocolFactory`.
450 pub fn new() -> TBinaryOutputProtocolFactory {
451 TBinaryOutputProtocolFactory {}
452 }
453}
454
455impl TOutputProtocolFactory for TBinaryOutputProtocolFactory {
Danny Browning77d96c12019-08-21 13:41:07 -0600456 fn create(&self, transport: Box<dyn TWriteTransport + Send>) -> Box<dyn TOutputProtocol + Send> {
Allen George0e22c362017-01-30 07:15:00 -0500457 Box::new(TBinaryOutputProtocol::new(transport, true))
Allen George8b96bfb2016-11-02 08:01:08 -0400458 }
459}
460
461fn field_type_to_u8(field_type: TType) -> u8 {
462 match field_type {
463 TType::Stop => 0x00,
464 TType::Void => 0x01,
465 TType::Bool => 0x02,
466 TType::I08 => 0x03, // equivalent to TType::Byte
467 TType::Double => 0x04,
468 TType::I16 => 0x06,
469 TType::I32 => 0x08,
470 TType::I64 => 0x0A,
471 TType::String | TType::Utf7 => 0x0B,
472 TType::Struct => 0x0C,
473 TType::Map => 0x0D,
474 TType::Set => 0x0E,
475 TType::List => 0x0F,
476 TType::Utf8 => 0x10,
477 TType::Utf16 => 0x11,
478 }
479}
480
Allen Georgeb0d14132020-03-29 11:48:55 -0400481fn field_type_from_u8(b: u8) -> crate::Result<TType> {
Allen George8b96bfb2016-11-02 08:01:08 -0400482 match b {
483 0x00 => Ok(TType::Stop),
484 0x01 => Ok(TType::Void),
485 0x02 => Ok(TType::Bool),
486 0x03 => Ok(TType::I08), // Equivalent to TType::Byte
487 0x04 => Ok(TType::Double),
488 0x06 => Ok(TType::I16),
489 0x08 => Ok(TType::I32),
490 0x0A => Ok(TType::I64),
491 0x0B => Ok(TType::String), // technically, also a UTF7, but we'll treat it as string
492 0x0C => Ok(TType::Struct),
493 0x0D => Ok(TType::Map),
494 0x0E => Ok(TType::Set),
495 0x0F => Ok(TType::List),
496 0x10 => Ok(TType::Utf8),
497 0x11 => Ok(TType::Utf16),
Allen Georgeb0d14132020-03-29 11:48:55 -0400498 unkn => Err(crate::Error::Protocol(ProtocolError {
Allen Georgeef7a1892018-12-16 18:01:37 -0500499 kind: ProtocolErrorKind::InvalidData,
500 message: format!("cannot convert {} to TType", unkn),
501 })),
Allen George8b96bfb2016-11-02 08:01:08 -0400502 }
503}
504
505#[cfg(test)]
506mod tests {
507
Allen Georgeb0d14132020-03-29 11:48:55 -0400508 use crate::protocol::{
Allen Georgeef7a1892018-12-16 18:01:37 -0500509 TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
510 TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType,
511 };
Allen Georgeb0d14132020-03-29 11:48:55 -0400512 use crate::transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
Allen George8b96bfb2016-11-02 08:01:08 -0400513
514 use super::*;
515
516 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500517 fn must_write_strict_message_call_begin() {
518 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400519
520 let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
521 assert!(o_prot.write_message_begin(&ident).is_ok());
522
Allen Georgeef7a1892018-12-16 18:01:37 -0500523 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -0500524 let expected: [u8; 16] = [
525 0x80,
526 0x01,
527 0x00,
528 0x01,
529 0x00,
530 0x00,
531 0x00,
532 0x04,
533 0x74,
534 0x65,
535 0x73,
536 0x74,
537 0x00,
538 0x00,
539 0x00,
540 0x01,
541 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400542
Allen George0e22c362017-01-30 07:15:00 -0500543 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400544 }
545
Allen George8b96bfb2016-11-02 08:01:08 -0400546 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500547 fn must_write_non_strict_message_call_begin() {
548 let (_, mut o_prot) = test_objects(false);
549
550 let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
551 assert!(o_prot.write_message_begin(&ident).is_ok());
552
Allen Georgeef7a1892018-12-16 18:01:37 -0500553 #[cfg_attr(rustfmt, rustfmt::skip)]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500554 let expected: [u8; 13] = [
555 0x00,
556 0x00,
557 0x00,
558 0x04,
559 0x74,
560 0x65,
561 0x73,
562 0x74,
563 0x01,
564 0x00,
565 0x00,
566 0x00,
567 0x01,
568 ];
569
570 assert_eq_written_bytes!(o_prot, expected);
571 }
572
573 #[test]
574 fn must_write_strict_message_reply_begin() {
575 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400576
577 let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
578 assert!(o_prot.write_message_begin(&ident).is_ok());
579
Allen Georgeef7a1892018-12-16 18:01:37 -0500580 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -0500581 let expected: [u8; 16] = [
582 0x80,
583 0x01,
584 0x00,
585 0x02,
586 0x00,
587 0x00,
588 0x00,
589 0x04,
590 0x74,
591 0x65,
592 0x73,
593 0x74,
594 0x00,
595 0x00,
596 0x00,
597 0x0A,
598 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400599
Allen George0e22c362017-01-30 07:15:00 -0500600 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400601 }
602
603 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500604 fn must_write_non_strict_message_reply_begin() {
605 let (_, mut o_prot) = test_objects(false);
606
607 let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
608 assert!(o_prot.write_message_begin(&ident).is_ok());
609
Allen Georgeef7a1892018-12-16 18:01:37 -0500610 #[cfg_attr(rustfmt, rustfmt::skip)]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500611 let expected: [u8; 13] = [
612 0x00,
613 0x00,
614 0x00,
615 0x04,
616 0x74,
617 0x65,
618 0x73,
619 0x74,
620 0x02,
621 0x00,
622 0x00,
623 0x00,
624 0x0A,
625 ];
626
627 assert_eq_written_bytes!(o_prot, expected);
628 }
629
630 #[test]
Allen George8b96bfb2016-11-02 08:01:08 -0400631 fn must_round_trip_strict_message_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500632 let (mut i_prot, mut o_prot) = test_objects(true);
633
634 let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
635 assert!(o_prot.write_message_begin(&sent_ident).is_ok());
636
637 copy_write_buffer_to_read_buffer!(o_prot);
638
639 let received_ident = assert_success!(i_prot.read_message_begin());
640 assert_eq!(&received_ident, &sent_ident);
641 }
642
643 #[test]
644 fn must_round_trip_non_strict_message_begin() {
645 let (mut i_prot, mut o_prot) = test_objects(false);
Allen George8b96bfb2016-11-02 08:01:08 -0400646
647 let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
648 assert!(o_prot.write_message_begin(&sent_ident).is_ok());
649
Allen George0e22c362017-01-30 07:15:00 -0500650 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400651
652 let received_ident = assert_success!(i_prot.read_message_begin());
653 assert_eq!(&received_ident, &sent_ident);
654 }
655
656 #[test]
657 fn must_write_message_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500658 assert_no_write(|o| o.write_message_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400659 }
660
661 #[test]
662 fn must_write_struct_begin() {
Allen Georgeef7a1892018-12-16 18:01:37 -0500663 assert_no_write(
664 |o| o.write_struct_begin(&TStructIdentifier::new("foo")),
665 true,
666 );
Allen George8b96bfb2016-11-02 08:01:08 -0400667 }
668
669 #[test]
670 fn must_write_struct_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500671 assert_no_write(|o| o.write_struct_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400672 }
673
674 #[test]
675 fn must_write_field_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500676 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400677
Allen Georgeef7a1892018-12-16 18:01:37 -0500678 assert!(o_prot
679 .write_field_begin(&TFieldIdentifier::new("some_field", TType::String, 22))
680 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400681
682 let expected: [u8; 3] = [0x0B, 0x00, 0x16];
Allen George0e22c362017-01-30 07:15:00 -0500683 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400684 }
685
686 #[test]
687 fn must_round_trip_field_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500688 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400689
690 let sent_field_ident = TFieldIdentifier::new("foo", TType::I64, 20);
691 assert!(o_prot.write_field_begin(&sent_field_ident).is_ok());
692
Allen George0e22c362017-01-30 07:15:00 -0500693 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400694
695 let expected_ident = TFieldIdentifier {
696 name: None,
697 field_type: TType::I64,
698 id: Some(20),
699 }; // no name
700 let received_ident = assert_success!(i_prot.read_field_begin());
701 assert_eq!(&received_ident, &expected_ident);
702 }
703
704 #[test]
705 fn must_write_stop_field() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500706 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400707
708 assert!(o_prot.write_field_stop().is_ok());
709
710 let expected: [u8; 1] = [0x00];
Allen George0e22c362017-01-30 07:15:00 -0500711 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400712 }
713
714 #[test]
715 fn must_round_trip_field_stop() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500716 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400717
718 assert!(o_prot.write_field_stop().is_ok());
719
Allen George0e22c362017-01-30 07:15:00 -0500720 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400721
722 let expected_ident = TFieldIdentifier {
723 name: None,
724 field_type: TType::Stop,
725 id: Some(0),
726 }; // we get id 0
727
728 let received_ident = assert_success!(i_prot.read_field_begin());
729 assert_eq!(&received_ident, &expected_ident);
730 }
731
732 #[test]
733 fn must_write_field_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500734 assert_no_write(|o| o.write_field_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400735 }
736
737 #[test]
738 fn must_write_list_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500739 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400740
Allen Georgeef7a1892018-12-16 18:01:37 -0500741 assert!(o_prot
742 .write_list_begin(&TListIdentifier::new(TType::Bool, 5))
743 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400744
745 let expected: [u8; 5] = [0x02, 0x00, 0x00, 0x00, 0x05];
Allen George0e22c362017-01-30 07:15:00 -0500746 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400747 }
748
749 #[test]
750 fn must_round_trip_list_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500751 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400752
753 let ident = TListIdentifier::new(TType::List, 900);
754 assert!(o_prot.write_list_begin(&ident).is_ok());
755
Allen George0e22c362017-01-30 07:15:00 -0500756 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400757
758 let received_ident = assert_success!(i_prot.read_list_begin());
759 assert_eq!(&received_ident, &ident);
760 }
761
762 #[test]
763 fn must_write_list_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500764 assert_no_write(|o| o.write_list_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400765 }
766
767 #[test]
768 fn must_write_set_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500769 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400770
Allen Georgeef7a1892018-12-16 18:01:37 -0500771 assert!(o_prot
772 .write_set_begin(&TSetIdentifier::new(TType::I16, 7))
773 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400774
775 let expected: [u8; 5] = [0x06, 0x00, 0x00, 0x00, 0x07];
Allen George0e22c362017-01-30 07:15:00 -0500776 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400777 }
778
779 #[test]
780 fn must_round_trip_set_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500781 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400782
783 let ident = TSetIdentifier::new(TType::I64, 2000);
784 assert!(o_prot.write_set_begin(&ident).is_ok());
785
Allen George0e22c362017-01-30 07:15:00 -0500786 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400787
788 let received_ident_result = i_prot.read_set_begin();
789 assert!(received_ident_result.is_ok());
790 assert_eq!(&received_ident_result.unwrap(), &ident);
791 }
792
793 #[test]
794 fn must_write_set_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500795 assert_no_write(|o| o.write_set_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400796 }
797
798 #[test]
799 fn must_write_map_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500800 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400801
Allen Georgeef7a1892018-12-16 18:01:37 -0500802 assert!(o_prot
803 .write_map_begin(&TMapIdentifier::new(TType::I64, TType::Struct, 32))
804 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400805
806 let expected: [u8; 6] = [0x0A, 0x0C, 0x00, 0x00, 0x00, 0x20];
Allen George0e22c362017-01-30 07:15:00 -0500807 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400808 }
809
810 #[test]
811 fn must_round_trip_map_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500812 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400813
814 let ident = TMapIdentifier::new(TType::Map, TType::Set, 100);
815 assert!(o_prot.write_map_begin(&ident).is_ok());
816
Allen George0e22c362017-01-30 07:15:00 -0500817 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400818
819 let received_ident = assert_success!(i_prot.read_map_begin());
820 assert_eq!(&received_ident, &ident);
821 }
822
823 #[test]
824 fn must_write_map_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500825 assert_no_write(|o| o.write_map_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400826 }
827
828 #[test]
829 fn must_write_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500830 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400831
832 assert!(o_prot.write_bool(true).is_ok());
833
834 let expected: [u8; 1] = [0x01];
Allen George0e22c362017-01-30 07:15:00 -0500835 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400836 }
837
838 #[test]
839 fn must_write_bool_false() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500840 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400841
842 assert!(o_prot.write_bool(false).is_ok());
843
844 let expected: [u8; 1] = [0x00];
Allen George0e22c362017-01-30 07:15:00 -0500845 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400846 }
847
848 #[test]
849 fn must_read_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500850 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400851
Allen George0e22c362017-01-30 07:15:00 -0500852 set_readable_bytes!(i_prot, &[0x01]);
Allen George8b96bfb2016-11-02 08:01:08 -0400853
854 let read_bool = assert_success!(i_prot.read_bool());
855 assert_eq!(read_bool, true);
856 }
857
858 #[test]
859 fn must_read_bool_false() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500860 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400861
Allen George0e22c362017-01-30 07:15:00 -0500862 set_readable_bytes!(i_prot, &[0x00]);
Allen George8b96bfb2016-11-02 08:01:08 -0400863
864 let read_bool = assert_success!(i_prot.read_bool());
865 assert_eq!(read_bool, false);
866 }
867
868 #[test]
869 fn must_allow_any_non_zero_value_to_be_interpreted_as_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500870 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400871
Allen George0e22c362017-01-30 07:15:00 -0500872 set_readable_bytes!(i_prot, &[0xAC]);
Allen George8b96bfb2016-11-02 08:01:08 -0400873
874 let read_bool = assert_success!(i_prot.read_bool());
875 assert_eq!(read_bool, true);
876 }
877
878 #[test]
879 fn must_write_bytes() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500880 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400881
882 let bytes: [u8; 10] = [0x0A, 0xCC, 0xD1, 0x84, 0x99, 0x12, 0xAB, 0xBB, 0x45, 0xDF];
883
884 assert!(o_prot.write_bytes(&bytes).is_ok());
885
Allen George0e22c362017-01-30 07:15:00 -0500886 let buf = o_prot.transport.write_bytes();
Allen George8b96bfb2016-11-02 08:01:08 -0400887 assert_eq!(&buf[0..4], [0x00, 0x00, 0x00, 0x0A]); // length
888 assert_eq!(&buf[4..], bytes); // actual bytes
889 }
890
891 #[test]
892 fn must_round_trip_bytes() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500893 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400894
Allen Georgeef7a1892018-12-16 18:01:37 -0500895 #[cfg_attr(rustfmt, rustfmt::skip)]
Allen George0e22c362017-01-30 07:15:00 -0500896 let bytes: [u8; 25] = [
897 0x20,
898 0xFD,
899 0x18,
900 0x84,
901 0x99,
902 0x12,
903 0xAB,
904 0xBB,
905 0x45,
906 0xDF,
907 0x34,
908 0xDC,
909 0x98,
910 0xA4,
911 0x6D,
912 0xF3,
913 0x99,
914 0xB4,
915 0xB7,
916 0xD4,
917 0x9C,
918 0xA5,
919 0xB3,
920 0xC9,
921 0x88,
922 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400923
924 assert!(o_prot.write_bytes(&bytes).is_ok());
925
Allen George0e22c362017-01-30 07:15:00 -0500926 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400927
928 let received_bytes = assert_success!(i_prot.read_bytes());
929 assert_eq!(&received_bytes, &bytes);
930 }
931
Allen Georgeef7a1892018-12-16 18:01:37 -0500932 fn test_objects(
933 strict: bool,
934 ) -> (
935 TBinaryInputProtocol<ReadHalf<TBufferChannel>>,
936 TBinaryOutputProtocol<WriteHalf<TBufferChannel>>,
937 ) {
Allen George0e22c362017-01-30 07:15:00 -0500938 let mem = TBufferChannel::with_capacity(40, 40);
Chao Sunc063b302017-03-12 12:21:05 -0700939
Allen George0e22c362017-01-30 07:15:00 -0500940 let (r_mem, w_mem) = mem.split().unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400941
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500942 let i_prot = TBinaryInputProtocol::new(r_mem, strict);
943 let o_prot = TBinaryOutputProtocol::new(w_mem, strict);
Allen George8b96bfb2016-11-02 08:01:08 -0400944
Allen George0e22c362017-01-30 07:15:00 -0500945 (i_prot, o_prot)
Allen George8b96bfb2016-11-02 08:01:08 -0400946 }
947
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500948 fn assert_no_write<F>(mut write_fn: F, strict: bool)
Allen George0e22c362017-01-30 07:15:00 -0500949 where
Allen Georgeb0d14132020-03-29 11:48:55 -0400950 F: FnMut(&mut TBinaryOutputProtocol<WriteHalf<TBufferChannel>>) -> crate::Result<()>,
Allen George0e22c362017-01-30 07:15:00 -0500951 {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500952 let (_, mut o_prot) = test_objects(strict);
Allen George8b96bfb2016-11-02 08:01:08 -0400953 assert!(write_fn(&mut o_prot).is_ok());
Allen George0e22c362017-01-30 07:15:00 -0500954 assert_eq!(o_prot.transport.write_bytes().len(), 0);
Allen George8b96bfb2016-11-02 08:01:08 -0400955 }
956}