blob: b4b51f682e00cf70f892f40321da5ac0e2da0502 [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
Jiayu Liufbfa52c2023-11-07 13:47:24 +080062impl<T> TBinaryInputProtocol<T>
Allen George0e22c362017-01-30 07:15:00 -050063where
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
Yuxuan 'fishy' Wangeadbd9c2022-01-27 13:17:37 -080087 if (first_bytes[0] & 0x80) != 0 {
Allen George8b96bfb2016-11-02 08:01:08 -040088 // 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
Jiayu Liub6b6dc72022-10-08 14:28:44 +0800193 fn read_uuid(&mut self) -> crate::Result<uuid::Uuid> {
194 let mut buf = [0u8; 16];
195 self.transport
196 .read_exact(&mut buf)
197 .map(|_| uuid::Uuid::from_bytes(buf))
198 .map_err(From::from)
199 }
200
Allen Georgeb0d14132020-03-29 11:48:55 -0400201 fn read_string(&mut self) -> crate::Result<String> {
Allen George8b96bfb2016-11-02 08:01:08 -0400202 let bytes = self.read_bytes()?;
203 String::from_utf8(bytes).map_err(From::from)
204 }
205
Allen Georgeb0d14132020-03-29 11:48:55 -0400206 fn read_list_begin(&mut self) -> crate::Result<TListIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400207 let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
208 let size = self.read_i32()?;
209 Ok(TListIdentifier::new(element_type, size))
210 }
211
Allen Georgeb0d14132020-03-29 11:48:55 -0400212 fn read_list_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400213 Ok(())
214 }
215
Allen Georgeb0d14132020-03-29 11:48:55 -0400216 fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400217 let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
218 let size = self.read_i32()?;
219 Ok(TSetIdentifier::new(element_type, size))
220 }
221
Allen Georgeb0d14132020-03-29 11:48:55 -0400222 fn read_set_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400223 Ok(())
224 }
225
Allen Georgeb0d14132020-03-29 11:48:55 -0400226 fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier> {
Allen George8b96bfb2016-11-02 08:01:08 -0400227 let key_type: TType = self.read_byte().and_then(field_type_from_u8)?;
228 let value_type: TType = self.read_byte().and_then(field_type_from_u8)?;
229 let size = self.read_i32()?;
230 Ok(TMapIdentifier::new(key_type, value_type, size))
231 }
232
Allen Georgeb0d14132020-03-29 11:48:55 -0400233 fn read_map_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400234 Ok(())
235 }
236
237 // utility
238 //
239
Allen Georgeb0d14132020-03-29 11:48:55 -0400240 fn read_byte(&mut self) -> crate::Result<u8> {
Allen George0e22c362017-01-30 07:15:00 -0500241 self.transport.read_u8().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400242 }
243}
244
245/// Factory for creating instances of `TBinaryInputProtocol`.
246#[derive(Default)]
247pub struct TBinaryInputProtocolFactory;
248
249impl TBinaryInputProtocolFactory {
250 /// Create a `TBinaryInputProtocolFactory`.
251 pub fn new() -> TBinaryInputProtocolFactory {
252 TBinaryInputProtocolFactory {}
253 }
254}
255
256impl TInputProtocolFactory for TBinaryInputProtocolFactory {
Danny Browning77d96c12019-08-21 13:41:07 -0600257 fn create(&self, transport: Box<dyn TReadTransport + Send>) -> Box<dyn TInputProtocol + Send> {
Allen George0e22c362017-01-30 07:15:00 -0500258 Box::new(TBinaryInputProtocol::new(transport, true))
Allen George8b96bfb2016-11-02 08:01:08 -0400259 }
260}
261
262/// Write messages using the Thrift simple binary encoding.
263///
264/// There are two available modes: `strict` and `non-strict`, where the
265/// `strict` version writes the protocol version number in the outgoing message
266/// header and the `non-strict` version does not.
267///
268/// # Examples
269///
270/// Create and use a `TBinaryOutputProtocol`.
271///
272/// ```no_run
Allen George8b96bfb2016-11-02 08:01:08 -0400273/// use thrift::protocol::{TBinaryOutputProtocol, TOutputProtocol};
Allen George0e22c362017-01-30 07:15:00 -0500274/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -0400275///
Allen George0e22c362017-01-30 07:15:00 -0500276/// let mut channel = TTcpChannel::new();
277/// channel.open("localhost:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400278///
Allen George0e22c362017-01-30 07:15:00 -0500279/// let mut protocol = TBinaryOutputProtocol::new(channel, true);
Allen George8b96bfb2016-11-02 08:01:08 -0400280///
Allen George0e22c362017-01-30 07:15:00 -0500281/// protocol.write_bool(true).unwrap();
282/// protocol.write_string("test_string").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400283/// ```
Allen George0e22c362017-01-30 07:15:00 -0500284#[derive(Debug)]
285pub struct TBinaryOutputProtocol<T>
286where
287 T: TWriteTransport,
288{
Allen George8b96bfb2016-11-02 08:01:08 -0400289 strict: bool,
Allen George0e22c362017-01-30 07:15:00 -0500290 pub transport: T, // FIXME: do not make public; only public for testing!
Allen George8b96bfb2016-11-02 08:01:08 -0400291}
292
Allen George0e22c362017-01-30 07:15:00 -0500293impl<T> TBinaryOutputProtocol<T>
294where
295 T: TWriteTransport,
296{
Allen George8b96bfb2016-11-02 08:01:08 -0400297 /// Create a `TBinaryOutputProtocol` that writes bytes to `transport`.
298 ///
299 /// Set `strict` to `true` if all outgoing messages should contain the
300 /// protocol version number in the protocol header.
Allen George0e22c362017-01-30 07:15:00 -0500301 pub fn new(transport: T, strict: bool) -> TBinaryOutputProtocol<T> {
Allen George55c3e4c2021-03-01 23:19:52 -0500302 TBinaryOutputProtocol { strict, transport }
Allen George8b96bfb2016-11-02 08:01:08 -0400303 }
Allen George8b96bfb2016-11-02 08:01:08 -0400304}
305
Allen George0e22c362017-01-30 07:15:00 -0500306impl<T> TOutputProtocol for TBinaryOutputProtocol<T>
307where
308 T: TWriteTransport,
309{
Allen Georgeb0d14132020-03-29 11:48:55 -0400310 fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400311 if self.strict {
312 let message_type: u8 = identifier.message_type.into();
313 let header = BINARY_PROTOCOL_VERSION_1 | (message_type as u32);
Allen George0e22c362017-01-30 07:15:00 -0500314 self.transport.write_u32::<BigEndian>(header)?;
Allen George8b96bfb2016-11-02 08:01:08 -0400315 self.write_string(&identifier.name)?;
316 self.write_i32(identifier.sequence_number)
317 } else {
318 self.write_string(&identifier.name)?;
319 self.write_byte(identifier.message_type.into())?;
320 self.write_i32(identifier.sequence_number)
321 }
322 }
323
Allen Georgeb0d14132020-03-29 11:48:55 -0400324 fn write_message_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_struct_begin(&mut self, _: &TStructIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400329 Ok(())
330 }
331
Allen Georgeb0d14132020-03-29 11:48:55 -0400332 fn write_struct_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400333 Ok(())
334 }
335
Allen Georgeb0d14132020-03-29 11:48:55 -0400336 fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400337 if identifier.id.is_none() && identifier.field_type != TType::Stop {
Allen Georgeb0d14132020-03-29 11:48:55 -0400338 return Err(crate::Error::Protocol(ProtocolError {
Allen Georgeef7a1892018-12-16 18:01:37 -0500339 kind: ProtocolErrorKind::Unknown,
340 message: format!(
341 "cannot write identifier {:?} without sequence number",
342 &identifier
Allen George0e22c362017-01-30 07:15:00 -0500343 ),
Allen Georgeef7a1892018-12-16 18:01:37 -0500344 }));
Allen George8b96bfb2016-11-02 08:01:08 -0400345 }
346
347 self.write_byte(field_type_to_u8(identifier.field_type))?;
348 if let Some(id) = identifier.id {
349 self.write_i16(id)
350 } else {
351 Ok(())
352 }
353 }
354
Allen Georgeb0d14132020-03-29 11:48:55 -0400355 fn write_field_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400356 Ok(())
357 }
358
Allen Georgeb0d14132020-03-29 11:48:55 -0400359 fn write_field_stop(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400360 self.write_byte(field_type_to_u8(TType::Stop))
361 }
362
Allen Georgeb0d14132020-03-29 11:48:55 -0400363 fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400364 self.write_i32(b.len() as i32)?;
Allen Georgecf7ba4c2017-12-11 11:44:11 -0500365 self.transport.write_all(b).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400366 }
367
Allen Georgeb0d14132020-03-29 11:48:55 -0400368 fn write_bool(&mut self, b: bool) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400369 if b {
370 self.write_i8(1)
371 } else {
372 self.write_i8(0)
373 }
374 }
375
Allen Georgeb0d14132020-03-29 11:48:55 -0400376 fn write_i8(&mut self, i: i8) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500377 self.transport.write_i8(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400378 }
379
Allen Georgeb0d14132020-03-29 11:48:55 -0400380 fn write_i16(&mut self, i: i16) -> crate::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500381 self.transport.write_i16::<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_i32(&mut self, i: i32) -> crate::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500385 self.transport.write_i32::<BigEndian>(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400386 }
387
Allen Georgeb0d14132020-03-29 11:48:55 -0400388 fn write_i64(&mut self, i: i64) -> crate::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500389 self.transport.write_i64::<BigEndian>(i).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400390 }
391
Allen Georgeb0d14132020-03-29 11:48:55 -0400392 fn write_double(&mut self, d: f64) -> crate::Result<()> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500393 self.transport.write_f64::<BigEndian>(d).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400394 }
395
Allen Georgeb0d14132020-03-29 11:48:55 -0400396 fn write_string(&mut self, s: &str) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400397 self.write_bytes(s.as_bytes())
398 }
399
Jiayu Liub6b6dc72022-10-08 14:28:44 +0800400 fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()> {
401 self.transport
402 .write_all(uuid.as_bytes())
403 .map_err(From::from)
404 }
405
Allen Georgeb0d14132020-03-29 11:48:55 -0400406 fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400407 self.write_byte(field_type_to_u8(identifier.element_type))?;
408 self.write_i32(identifier.size)
409 }
410
Allen Georgeb0d14132020-03-29 11:48:55 -0400411 fn write_list_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400412 Ok(())
413 }
414
Allen Georgeb0d14132020-03-29 11:48:55 -0400415 fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400416 self.write_byte(field_type_to_u8(identifier.element_type))?;
417 self.write_i32(identifier.size)
418 }
419
Allen Georgeb0d14132020-03-29 11:48:55 -0400420 fn write_set_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400421 Ok(())
422 }
423
Allen Georgeb0d14132020-03-29 11:48:55 -0400424 fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500425 let key_type = identifier
426 .key_type
Allen George8b96bfb2016-11-02 08:01:08 -0400427 .expect("map identifier to write should contain key type");
428 self.write_byte(field_type_to_u8(key_type))?;
Allen George0e22c362017-01-30 07:15:00 -0500429 let val_type = identifier
430 .value_type
Allen George8b96bfb2016-11-02 08:01:08 -0400431 .expect("map identifier to write should contain value type");
432 self.write_byte(field_type_to_u8(val_type))?;
433 self.write_i32(identifier.size)
434 }
435
Allen Georgeb0d14132020-03-29 11:48:55 -0400436 fn write_map_end(&mut self) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400437 Ok(())
438 }
439
Allen Georgeb0d14132020-03-29 11:48:55 -0400440 fn flush(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500441 self.transport.flush().map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400442 }
443
444 // utility
445 //
446
Allen Georgeb0d14132020-03-29 11:48:55 -0400447 fn write_byte(&mut self, b: u8) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500448 self.transport.write_u8(b).map_err(From::from)
Allen George8b96bfb2016-11-02 08:01:08 -0400449 }
450}
451
452/// Factory for creating instances of `TBinaryOutputProtocol`.
453#[derive(Default)]
454pub struct TBinaryOutputProtocolFactory;
455
456impl TBinaryOutputProtocolFactory {
457 /// Create a `TBinaryOutputProtocolFactory`.
458 pub fn new() -> TBinaryOutputProtocolFactory {
459 TBinaryOutputProtocolFactory {}
460 }
461}
462
463impl TOutputProtocolFactory for TBinaryOutputProtocolFactory {
Allen George55c3e4c2021-03-01 23:19:52 -0500464 fn create(
465 &self,
466 transport: Box<dyn TWriteTransport + Send>,
467 ) -> Box<dyn TOutputProtocol + Send> {
Allen George0e22c362017-01-30 07:15:00 -0500468 Box::new(TBinaryOutputProtocol::new(transport, true))
Allen George8b96bfb2016-11-02 08:01:08 -0400469 }
470}
471
472fn field_type_to_u8(field_type: TType) -> u8 {
473 match field_type {
474 TType::Stop => 0x00,
475 TType::Void => 0x01,
476 TType::Bool => 0x02,
477 TType::I08 => 0x03, // equivalent to TType::Byte
478 TType::Double => 0x04,
479 TType::I16 => 0x06,
480 TType::I32 => 0x08,
481 TType::I64 => 0x0A,
482 TType::String | TType::Utf7 => 0x0B,
483 TType::Struct => 0x0C,
484 TType::Map => 0x0D,
485 TType::Set => 0x0E,
486 TType::List => 0x0F,
Jiayu Liub6b6dc72022-10-08 14:28:44 +0800487 TType::Uuid => 0x10,
Allen George8b96bfb2016-11-02 08:01:08 -0400488 }
489}
490
Allen Georgeb0d14132020-03-29 11:48:55 -0400491fn field_type_from_u8(b: u8) -> crate::Result<TType> {
Allen George8b96bfb2016-11-02 08:01:08 -0400492 match b {
493 0x00 => Ok(TType::Stop),
494 0x01 => Ok(TType::Void),
495 0x02 => Ok(TType::Bool),
496 0x03 => Ok(TType::I08), // Equivalent to TType::Byte
497 0x04 => Ok(TType::Double),
498 0x06 => Ok(TType::I16),
499 0x08 => Ok(TType::I32),
500 0x0A => Ok(TType::I64),
501 0x0B => Ok(TType::String), // technically, also a UTF7, but we'll treat it as string
502 0x0C => Ok(TType::Struct),
503 0x0D => Ok(TType::Map),
504 0x0E => Ok(TType::Set),
505 0x0F => Ok(TType::List),
Jiayu Liub6b6dc72022-10-08 14:28:44 +0800506 0x10 => Ok(TType::Uuid),
Allen Georgeb0d14132020-03-29 11:48:55 -0400507 unkn => Err(crate::Error::Protocol(ProtocolError {
Allen Georgeef7a1892018-12-16 18:01:37 -0500508 kind: ProtocolErrorKind::InvalidData,
509 message: format!("cannot convert {} to TType", unkn),
510 })),
Allen George8b96bfb2016-11-02 08:01:08 -0400511 }
512}
513
514#[cfg(test)]
515mod tests {
516
Allen Georgeb0d14132020-03-29 11:48:55 -0400517 use crate::protocol::{
Allen Georgeef7a1892018-12-16 18:01:37 -0500518 TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
519 TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType,
520 };
Allen Georgeb0d14132020-03-29 11:48:55 -0400521 use crate::transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
Allen George8b96bfb2016-11-02 08:01:08 -0400522
523 use super::*;
524
525 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500526 fn must_write_strict_message_call_begin() {
527 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400528
529 let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
530 assert!(o_prot.write_message_begin(&ident).is_ok());
531
Allen George7ddbcc02020-11-08 09:51:19 -0500532 #[rustfmt::skip]
Allen George0e22c362017-01-30 07:15:00 -0500533 let expected: [u8; 16] = [
534 0x80,
535 0x01,
536 0x00,
537 0x01,
538 0x00,
539 0x00,
540 0x00,
541 0x04,
542 0x74,
543 0x65,
544 0x73,
545 0x74,
546 0x00,
547 0x00,
548 0x00,
549 0x01,
550 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400551
Allen George0e22c362017-01-30 07:15:00 -0500552 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400553 }
554
Allen George8b96bfb2016-11-02 08:01:08 -0400555 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500556 fn must_write_non_strict_message_call_begin() {
557 let (_, mut o_prot) = test_objects(false);
558
559 let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
560 assert!(o_prot.write_message_begin(&ident).is_ok());
561
Allen George7ddbcc02020-11-08 09:51:19 -0500562 #[rustfmt::skip]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500563 let expected: [u8; 13] = [
564 0x00,
565 0x00,
566 0x00,
567 0x04,
568 0x74,
569 0x65,
570 0x73,
571 0x74,
572 0x01,
573 0x00,
574 0x00,
575 0x00,
576 0x01,
577 ];
578
579 assert_eq_written_bytes!(o_prot, expected);
580 }
581
582 #[test]
583 fn must_write_strict_message_reply_begin() {
584 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400585
586 let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
587 assert!(o_prot.write_message_begin(&ident).is_ok());
588
Allen George7ddbcc02020-11-08 09:51:19 -0500589 #[rustfmt::skip]
Allen George0e22c362017-01-30 07:15:00 -0500590 let expected: [u8; 16] = [
591 0x80,
592 0x01,
593 0x00,
594 0x02,
595 0x00,
596 0x00,
597 0x00,
598 0x04,
599 0x74,
600 0x65,
601 0x73,
602 0x74,
603 0x00,
604 0x00,
605 0x00,
606 0x0A,
607 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400608
Allen George0e22c362017-01-30 07:15:00 -0500609 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400610 }
611
612 #[test]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500613 fn must_write_non_strict_message_reply_begin() {
614 let (_, mut o_prot) = test_objects(false);
615
616 let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
617 assert!(o_prot.write_message_begin(&ident).is_ok());
618
Allen George7ddbcc02020-11-08 09:51:19 -0500619 #[rustfmt::skip]
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500620 let expected: [u8; 13] = [
621 0x00,
622 0x00,
623 0x00,
624 0x04,
625 0x74,
626 0x65,
627 0x73,
628 0x74,
629 0x02,
630 0x00,
631 0x00,
632 0x00,
633 0x0A,
634 ];
635
636 assert_eq_written_bytes!(o_prot, expected);
637 }
638
639 #[test]
Allen George8b96bfb2016-11-02 08:01:08 -0400640 fn must_round_trip_strict_message_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500641 let (mut i_prot, mut o_prot) = test_objects(true);
642
643 let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
644 assert!(o_prot.write_message_begin(&sent_ident).is_ok());
645
646 copy_write_buffer_to_read_buffer!(o_prot);
647
648 let received_ident = assert_success!(i_prot.read_message_begin());
649 assert_eq!(&received_ident, &sent_ident);
650 }
651
652 #[test]
653 fn must_round_trip_non_strict_message_begin() {
654 let (mut i_prot, mut o_prot) = test_objects(false);
Allen George8b96bfb2016-11-02 08:01:08 -0400655
656 let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
657 assert!(o_prot.write_message_begin(&sent_ident).is_ok());
658
Allen George0e22c362017-01-30 07:15:00 -0500659 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400660
661 let received_ident = assert_success!(i_prot.read_message_begin());
662 assert_eq!(&received_ident, &sent_ident);
663 }
664
665 #[test]
666 fn must_write_message_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500667 assert_no_write(|o| o.write_message_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400668 }
669
670 #[test]
671 fn must_write_struct_begin() {
Allen Georgeef7a1892018-12-16 18:01:37 -0500672 assert_no_write(
673 |o| o.write_struct_begin(&TStructIdentifier::new("foo")),
674 true,
675 );
Allen George8b96bfb2016-11-02 08:01:08 -0400676 }
677
678 #[test]
679 fn must_write_struct_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500680 assert_no_write(|o| o.write_struct_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400681 }
682
683 #[test]
684 fn must_write_field_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500685 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400686
Allen Georgeef7a1892018-12-16 18:01:37 -0500687 assert!(o_prot
688 .write_field_begin(&TFieldIdentifier::new("some_field", TType::String, 22))
689 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400690
691 let expected: [u8; 3] = [0x0B, 0x00, 0x16];
Allen George0e22c362017-01-30 07:15:00 -0500692 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400693 }
694
695 #[test]
696 fn must_round_trip_field_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500697 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400698
699 let sent_field_ident = TFieldIdentifier::new("foo", TType::I64, 20);
700 assert!(o_prot.write_field_begin(&sent_field_ident).is_ok());
701
Allen George0e22c362017-01-30 07:15:00 -0500702 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400703
704 let expected_ident = TFieldIdentifier {
705 name: None,
706 field_type: TType::I64,
707 id: Some(20),
708 }; // no name
709 let received_ident = assert_success!(i_prot.read_field_begin());
710 assert_eq!(&received_ident, &expected_ident);
711 }
712
713 #[test]
714 fn must_write_stop_field() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500715 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400716
717 assert!(o_prot.write_field_stop().is_ok());
718
719 let expected: [u8; 1] = [0x00];
Allen George0e22c362017-01-30 07:15:00 -0500720 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400721 }
722
723 #[test]
724 fn must_round_trip_field_stop() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500725 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400726
727 assert!(o_prot.write_field_stop().is_ok());
728
Allen George0e22c362017-01-30 07:15:00 -0500729 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400730
731 let expected_ident = TFieldIdentifier {
732 name: None,
733 field_type: TType::Stop,
734 id: Some(0),
735 }; // we get id 0
736
737 let received_ident = assert_success!(i_prot.read_field_begin());
738 assert_eq!(&received_ident, &expected_ident);
739 }
740
741 #[test]
742 fn must_write_field_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500743 assert_no_write(|o| o.write_field_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400744 }
745
746 #[test]
747 fn must_write_list_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500748 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400749
Allen Georgeef7a1892018-12-16 18:01:37 -0500750 assert!(o_prot
751 .write_list_begin(&TListIdentifier::new(TType::Bool, 5))
752 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400753
754 let expected: [u8; 5] = [0x02, 0x00, 0x00, 0x00, 0x05];
Allen George0e22c362017-01-30 07:15:00 -0500755 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400756 }
757
758 #[test]
759 fn must_round_trip_list_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500760 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400761
762 let ident = TListIdentifier::new(TType::List, 900);
763 assert!(o_prot.write_list_begin(&ident).is_ok());
764
Allen George0e22c362017-01-30 07:15:00 -0500765 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400766
767 let received_ident = assert_success!(i_prot.read_list_begin());
768 assert_eq!(&received_ident, &ident);
769 }
770
771 #[test]
772 fn must_write_list_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500773 assert_no_write(|o| o.write_list_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400774 }
775
776 #[test]
777 fn must_write_set_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500778 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400779
Allen Georgeef7a1892018-12-16 18:01:37 -0500780 assert!(o_prot
781 .write_set_begin(&TSetIdentifier::new(TType::I16, 7))
782 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400783
784 let expected: [u8; 5] = [0x06, 0x00, 0x00, 0x00, 0x07];
Allen George0e22c362017-01-30 07:15:00 -0500785 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400786 }
787
788 #[test]
789 fn must_round_trip_set_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500790 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400791
792 let ident = TSetIdentifier::new(TType::I64, 2000);
793 assert!(o_prot.write_set_begin(&ident).is_ok());
794
Allen George0e22c362017-01-30 07:15:00 -0500795 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400796
797 let received_ident_result = i_prot.read_set_begin();
798 assert!(received_ident_result.is_ok());
799 assert_eq!(&received_ident_result.unwrap(), &ident);
800 }
801
802 #[test]
803 fn must_write_set_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500804 assert_no_write(|o| o.write_set_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400805 }
806
807 #[test]
808 fn must_write_map_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500809 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400810
Allen Georgeef7a1892018-12-16 18:01:37 -0500811 assert!(o_prot
812 .write_map_begin(&TMapIdentifier::new(TType::I64, TType::Struct, 32))
813 .is_ok());
Allen George8b96bfb2016-11-02 08:01:08 -0400814
815 let expected: [u8; 6] = [0x0A, 0x0C, 0x00, 0x00, 0x00, 0x20];
Allen George0e22c362017-01-30 07:15:00 -0500816 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400817 }
818
819 #[test]
820 fn must_round_trip_map_begin() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500821 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400822
823 let ident = TMapIdentifier::new(TType::Map, TType::Set, 100);
824 assert!(o_prot.write_map_begin(&ident).is_ok());
825
Allen George0e22c362017-01-30 07:15:00 -0500826 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400827
828 let received_ident = assert_success!(i_prot.read_map_begin());
829 assert_eq!(&received_ident, &ident);
830 }
831
832 #[test]
833 fn must_write_map_end() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500834 assert_no_write(|o| o.write_map_end(), true);
Allen George8b96bfb2016-11-02 08:01:08 -0400835 }
836
837 #[test]
838 fn must_write_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500839 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400840
841 assert!(o_prot.write_bool(true).is_ok());
842
843 let expected: [u8; 1] = [0x01];
Allen George0e22c362017-01-30 07:15:00 -0500844 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400845 }
846
847 #[test]
848 fn must_write_bool_false() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500849 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400850
851 assert!(o_prot.write_bool(false).is_ok());
852
853 let expected: [u8; 1] = [0x00];
Allen George0e22c362017-01-30 07:15:00 -0500854 assert_eq_written_bytes!(o_prot, expected);
Allen George8b96bfb2016-11-02 08:01:08 -0400855 }
856
857 #[test]
858 fn must_read_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500859 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400860
Allen George0e22c362017-01-30 07:15:00 -0500861 set_readable_bytes!(i_prot, &[0x01]);
Allen George8b96bfb2016-11-02 08:01:08 -0400862
863 let read_bool = assert_success!(i_prot.read_bool());
Jiayu Liufbfa52c2023-11-07 13:47:24 +0800864 assert!(read_bool);
Allen George8b96bfb2016-11-02 08:01:08 -0400865 }
866
867 #[test]
868 fn must_read_bool_false() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500869 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400870
Allen George0e22c362017-01-30 07:15:00 -0500871 set_readable_bytes!(i_prot, &[0x00]);
Allen George8b96bfb2016-11-02 08:01:08 -0400872
873 let read_bool = assert_success!(i_prot.read_bool());
Jiayu Liufbfa52c2023-11-07 13:47:24 +0800874 assert!(!read_bool);
Allen George8b96bfb2016-11-02 08:01:08 -0400875 }
876
877 #[test]
878 fn must_allow_any_non_zero_value_to_be_interpreted_as_bool_true() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500879 let (mut i_prot, _) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400880
Allen George0e22c362017-01-30 07:15:00 -0500881 set_readable_bytes!(i_prot, &[0xAC]);
Allen George8b96bfb2016-11-02 08:01:08 -0400882
883 let read_bool = assert_success!(i_prot.read_bool());
Jiayu Liufbfa52c2023-11-07 13:47:24 +0800884 assert!(read_bool);
Allen George8b96bfb2016-11-02 08:01:08 -0400885 }
886
887 #[test]
888 fn must_write_bytes() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500889 let (_, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400890
891 let bytes: [u8; 10] = [0x0A, 0xCC, 0xD1, 0x84, 0x99, 0x12, 0xAB, 0xBB, 0x45, 0xDF];
892
893 assert!(o_prot.write_bytes(&bytes).is_ok());
894
Allen George0e22c362017-01-30 07:15:00 -0500895 let buf = o_prot.transport.write_bytes();
Allen George8b96bfb2016-11-02 08:01:08 -0400896 assert_eq!(&buf[0..4], [0x00, 0x00, 0x00, 0x0A]); // length
897 assert_eq!(&buf[4..], bytes); // actual bytes
898 }
899
900 #[test]
Jiayu Liub6b6dc72022-10-08 14:28:44 +0800901 fn must_write_uuid() {
902 let (_, mut o_prot) = test_objects(true);
903 let uuid = uuid::Uuid::new_v4();
904 assert!(o_prot.write_uuid(&uuid).is_ok());
905 let buf = o_prot.transport.write_bytes();
906 assert_eq!(&buf, uuid.as_bytes());
907 }
908
909 #[test]
910 fn must_round_trip_uuid() {
911 let (mut i_prot, mut o_prot) = test_objects(true);
912 let uuid = uuid::uuid!("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4");
913 assert!(o_prot.write_uuid(&uuid).is_ok());
914 copy_write_buffer_to_read_buffer!(o_prot);
915 let received_uuid = assert_success!(i_prot.read_uuid());
916 assert_eq!(&received_uuid, &uuid);
917 }
918
919 #[test]
Allen George8b96bfb2016-11-02 08:01:08 -0400920 fn must_round_trip_bytes() {
GREATEST Wiggler EvaR!718a63c2018-11-04 20:28:57 -0500921 let (mut i_prot, mut o_prot) = test_objects(true);
Allen George8b96bfb2016-11-02 08:01:08 -0400922
Allen George7ddbcc02020-11-08 09:51:19 -0500923 #[rustfmt::skip]
Allen George0e22c362017-01-30 07:15:00 -0500924 let bytes: [u8; 25] = [
925 0x20,
926 0xFD,
927 0x18,
928 0x84,
929 0x99,
930 0x12,
931 0xAB,
932 0xBB,
933 0x45,
934 0xDF,
935 0x34,
936 0xDC,
937 0x98,
938 0xA4,
939 0x6D,
940 0xF3,
941 0x99,
942 0xB4,
943 0xB7,
944 0xD4,
945 0x9C,
946 0xA5,
947 0xB3,
948 0xC9,
949 0x88,
950 ];
Allen George8b96bfb2016-11-02 08:01:08 -0400951
952 assert!(o_prot.write_bytes(&bytes).is_ok());
953
Allen George0e22c362017-01-30 07:15:00 -0500954 copy_write_buffer_to_read_buffer!(o_prot);
Allen George8b96bfb2016-11-02 08:01:08 -0400955
956 let received_bytes = assert_success!(i_prot.read_bytes());
957 assert_eq!(&received_bytes, &bytes);
958 }
959
Allen Georgeef7a1892018-12-16 18:01:37 -0500960 fn test_objects(
961 strict: bool,
962 ) -> (
963 TBinaryInputProtocol<ReadHalf<TBufferChannel>>,
964 TBinaryOutputProtocol<WriteHalf<TBufferChannel>>,
965 ) {
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
Allen Georgeb0d14132020-03-29 11:48:55 -0400978 F: FnMut(&mut TBinaryOutputProtocol<WriteHalf<TBufferChannel>>) -> crate::Result<()>,
Allen George0e22c362017-01-30 07:15:00 -0500979 {
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}