Coverage Report

Created: 2026-08-13 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/thrift/lib/rs/src/protocol/binary.rs
Line
Count
Source
1
// 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
18
use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
19
use std::convert::{From, TryFrom};
20
21
use super::{
22
    TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier, TMapIdentifier,
23
    TMessageIdentifier, TMessageType,
24
};
25
use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
26
use crate::transport::{TReadTransport, TWriteTransport};
27
use crate::{ProtocolError, ProtocolErrorKind, TConfiguration};
28
29
const BINARY_PROTOCOL_VERSION_1: u32 = 0x8001_0000;
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
42
/// use thrift::protocol::{TBinaryInputProtocol, TInputProtocol};
43
/// use thrift::transport::TTcpChannel;
44
///
45
/// let mut channel = TTcpChannel::new();
46
/// channel.open("localhost:9090").unwrap();
47
///
48
/// let mut protocol = TBinaryInputProtocol::new(channel, true);
49
///
50
/// let recvd_bool = protocol.read_bool().unwrap();
51
/// let recvd_string = protocol.read_string().unwrap();
52
/// ```
53
#[derive(Debug)]
54
pub struct TBinaryInputProtocol<T>
55
where
56
    T: TReadTransport,
57
{
58
    strict: bool,
59
    pub transport: T, // FIXME: shouldn't be public
60
    config: TConfiguration,
61
    recursion_depth: usize,
62
}
63
64
impl<T> TBinaryInputProtocol<T>
65
where
66
    T: TReadTransport,
67
{
68
    /// Create a `TBinaryInputProtocol` that reads bytes from `transport`.
69
    ///
70
    /// Set `strict` to `true` if all incoming messages contain the protocol
71
    /// version number in the protocol header.
72
0
    pub fn new(transport: T, strict: bool) -> Self {
73
0
        Self::with_config(transport, strict, TConfiguration::default())
74
0
    }
75
76
14.2k
    pub fn with_config(transport: T, strict: bool, config: TConfiguration) -> Self {
77
14.2k
        TBinaryInputProtocol {
78
14.2k
            strict,
79
14.2k
            transport,
80
14.2k
            config,
81
14.2k
            recursion_depth: 0,
82
14.2k
        }
83
14.2k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel>>::with_config
Line
Count
Source
76
6.24k
    pub fn with_config(transport: T, strict: bool, config: TConfiguration) -> Self {
77
6.24k
        TBinaryInputProtocol {
78
6.24k
            strict,
79
6.24k
            transport,
80
6.24k
            config,
81
6.24k
            recursion_depth: 0,
82
6.24k
        }
83
6.24k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>>>::with_config
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel>>::with_config
Line
Count
Source
76
8.00k
    pub fn with_config(transport: T, strict: bool, config: TConfiguration) -> Self {
77
8.00k
        TBinaryInputProtocol {
78
8.00k
            strict,
79
8.00k
            transport,
80
8.00k
            config,
81
8.00k
            recursion_depth: 0,
82
8.00k
        }
83
8.00k
    }
84
85
343k
    fn check_recursion_depth(&self) -> crate::Result<()> {
86
343k
        if let Some(limit) = self.config.max_recursion_depth() {
87
343k
            if self.recursion_depth >= limit {
88
10
                return Err(crate::Error::Protocol(ProtocolError::new(
89
10
                    ProtocolErrorKind::DepthLimit,
90
10
                    format!("Maximum recursion depth {} exceeded", limit),
91
10
                )));
92
343k
            }
93
0
        }
94
343k
        Ok(())
95
343k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel>>::check_recursion_depth
Line
Count
Source
85
123k
    fn check_recursion_depth(&self) -> crate::Result<()> {
86
123k
        if let Some(limit) = self.config.max_recursion_depth() {
87
123k
            if self.recursion_depth >= limit {
88
6
                return Err(crate::Error::Protocol(ProtocolError::new(
89
6
                    ProtocolErrorKind::DepthLimit,
90
6
                    format!("Maximum recursion depth {} exceeded", limit),
91
6
                )));
92
123k
            }
93
0
        }
94
123k
        Ok(())
95
123k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>>>::check_recursion_depth
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel>>::check_recursion_depth
Line
Count
Source
85
219k
    fn check_recursion_depth(&self) -> crate::Result<()> {
86
219k
        if let Some(limit) = self.config.max_recursion_depth() {
87
219k
            if self.recursion_depth >= limit {
88
4
                return Err(crate::Error::Protocol(ProtocolError::new(
89
4
                    ProtocolErrorKind::DepthLimit,
90
4
                    format!("Maximum recursion depth {} exceeded", limit),
91
4
                )));
92
219k
            }
93
0
        }
94
219k
        Ok(())
95
219k
    }
96
}
97
98
impl<T> TInputProtocol for TBinaryInputProtocol<T>
99
where
100
    T: TReadTransport,
101
{
102
    #[allow(clippy::collapsible_if)]
103
0
    fn read_message_begin(&mut self) -> crate::Result<TMessageIdentifier> {
104
        // TODO: Once specialization is stable, call the message size tracking here
105
0
        let mut first_bytes = vec![0; 4];
106
0
        self.transport.read_exact(&mut first_bytes[..])?;
107
108
        // the thrift version header is intentionally negative
109
        // so the first check we'll do is see if the sign bit is set
110
        // and if so - assume it's the protocol-version header
111
0
        if (first_bytes[0] & 0x80) != 0 {
112
            // apparently we got a protocol-version header - check
113
            // it, and if it matches, read the rest of the fields
114
0
            if first_bytes[0..2] != [0x80, 0x01] {
115
0
                Err(crate::Error::Protocol(ProtocolError {
116
0
                    kind: ProtocolErrorKind::BadVersion,
117
0
                    message: format!("received bad version: {:?}", &first_bytes[0..2]),
118
0
                }))
119
            } else {
120
0
                let message_type: TMessageType = TryFrom::try_from(first_bytes[3])?;
121
0
                let name = self.read_string()?;
122
0
                let sequence_number = self.read_i32()?;
123
0
                Ok(TMessageIdentifier::new(name, message_type, sequence_number))
124
            }
125
        } else {
126
            // apparently we didn't get a protocol-version header,
127
            // which happens if the sender is not using the strict protocol
128
0
            if self.strict {
129
                // we're in strict mode however, and that always
130
                // requires the protocol-version header to be written first
131
0
                Err(crate::Error::Protocol(ProtocolError {
132
0
                    kind: ProtocolErrorKind::BadVersion,
133
0
                    message: format!("received bad version: {:?}", &first_bytes[0..2]),
134
0
                }))
135
            } else {
136
                // in the non-strict version the first message field
137
                // is the message name. strings (byte arrays) are length-prefixed,
138
                // so we've just read the length in the first 4 bytes
139
0
                let name_size = BigEndian::read_i32(&first_bytes) as usize;
140
0
                if let Some(max_size) = self.config.max_string_size() {
141
0
                    if name_size > max_size {
142
0
                        return Err(crate::Error::Protocol(ProtocolError::new(
143
0
                            ProtocolErrorKind::SizeLimit,
144
0
                            format!(
145
0
                                "Message name size {} exceeds maximum allowed size of {}",
146
0
                                name_size, max_size
147
0
                            ),
148
0
                        )));
149
0
                    }
150
0
                }
151
0
                let mut name_buf: Vec<u8> = vec![0; name_size];
152
0
                self.transport.read_exact(&mut name_buf)?;
153
0
                let name = String::from_utf8(name_buf)?;
154
155
                // read the rest of the fields
156
0
                let message_type: TMessageType = self.read_byte().and_then(TryFrom::try_from)?;
157
0
                let sequence_number = self.read_i32()?;
158
0
                Ok(TMessageIdentifier::new(name, message_type, sequence_number))
159
            }
160
        }
161
0
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_message_begin
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_message_begin
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_message_begin
162
163
0
    fn read_message_end(&mut self) -> crate::Result<()> {
164
0
        Ok(())
165
0
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_message_end
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_message_end
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_message_end
166
167
343k
    fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>> {
168
343k
        self.check_recursion_depth()?;
169
343k
        self.recursion_depth += 1;
170
343k
        Ok(None)
171
343k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_struct_begin
Line
Count
Source
167
123k
    fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>> {
168
123k
        self.check_recursion_depth()?;
169
123k
        self.recursion_depth += 1;
170
123k
        Ok(None)
171
123k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_struct_begin
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_struct_begin
Line
Count
Source
167
219k
    fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>> {
168
219k
        self.check_recursion_depth()?;
169
219k
        self.recursion_depth += 1;
170
219k
        Ok(None)
171
219k
    }
172
173
321k
    fn read_struct_end(&mut self) -> crate::Result<()> {
174
321k
        self.recursion_depth -= 1;
175
321k
        Ok(())
176
321k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_struct_end
Line
Count
Source
173
111k
    fn read_struct_end(&mut self) -> crate::Result<()> {
174
111k
        self.recursion_depth -= 1;
175
111k
        Ok(())
176
111k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_struct_end
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_struct_end
Line
Count
Source
173
209k
    fn read_struct_end(&mut self) -> crate::Result<()> {
174
209k
        self.recursion_depth -= 1;
175
209k
        Ok(())
176
209k
    }
177
178
889k
    fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier> {
179
889k
        let field_type_byte = self.read_byte()?;
180
884k
        let field_type = field_type_from_u8(field_type_byte)?;
181
884k
        let id = match field_type {
182
321k
            TType::Stop => Ok(0),
183
563k
            _ => self.read_i16(),
184
317
        }?;
185
884k
        Ok(TFieldIdentifier::new::<Option<String>, String, i16>(
186
884k
            None, field_type, id,
187
884k
        ))
188
889k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_field_begin
Line
Count
Source
178
372k
    fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier> {
179
372k
        let field_type_byte = self.read_byte()?;
180
369k
        let field_type = field_type_from_u8(field_type_byte)?;
181
369k
        let id = match field_type {
182
111k
            TType::Stop => Ok(0),
183
257k
            _ => self.read_i16(),
184
160
        }?;
185
369k
        Ok(TFieldIdentifier::new::<Option<String>, String, i16>(
186
369k
            None, field_type, id,
187
369k
        ))
188
372k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_field_begin
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_field_begin
Line
Count
Source
178
517k
    fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier> {
179
517k
        let field_type_byte = self.read_byte()?;
180
515k
        let field_type = field_type_from_u8(field_type_byte)?;
181
514k
        let id = match field_type {
182
209k
            TType::Stop => Ok(0),
183
305k
            _ => self.read_i16(),
184
157
        }?;
185
514k
        Ok(TFieldIdentifier::new::<Option<String>, String, i16>(
186
514k
            None, field_type, id,
187
514k
        ))
188
517k
    }
189
190
532k
    fn read_field_end(&mut self) -> crate::Result<()> {
191
532k
        Ok(())
192
532k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_field_end
Line
Count
Source
190
239k
    fn read_field_end(&mut self) -> crate::Result<()> {
191
239k
        Ok(())
192
239k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_field_end
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_field_end
Line
Count
Source
190
292k
    fn read_field_end(&mut self) -> crate::Result<()> {
191
292k
        Ok(())
192
292k
    }
193
194
2.55M
    fn read_bytes(&mut self) -> crate::Result<Vec<u8>> {
195
2.55M
        let num_bytes = self.transport.read_i32::<BigEndian>()?;
196
197
2.55M
        if num_bytes < 0 {
198
120
            return Err(crate::Error::Protocol(ProtocolError::new(
199
120
                ProtocolErrorKind::NegativeSize,
200
120
                format!("Negative byte array size: {}", num_bytes),
201
120
            )));
202
2.55M
        }
203
204
2.55M
        if let Some(max_size) = self.config.max_string_size() {
205
2.55M
            if num_bytes as usize > max_size {
206
396
                return Err(crate::Error::Protocol(ProtocolError::new(
207
396
                    ProtocolErrorKind::SizeLimit,
208
396
                    format!(
209
396
                        "Byte array size {} exceeds maximum allowed size of {}",
210
396
                        num_bytes, max_size
211
396
                    ),
212
396
                )));
213
2.55M
            }
214
0
        }
215
216
2.55M
        let mut buf = vec![0u8; num_bytes as usize];
217
2.55M
        self.transport
218
2.55M
            .read_exact(&mut buf)
219
2.55M
            .map(|_| buf)
220
2.55M
            .map_err(From::from)
221
2.55M
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_bytes
Line
Count
Source
194
1.36M
    fn read_bytes(&mut self) -> crate::Result<Vec<u8>> {
195
1.36M
        let num_bytes = self.transport.read_i32::<BigEndian>()?;
196
197
1.36M
        if num_bytes < 0 {
198
57
            return Err(crate::Error::Protocol(ProtocolError::new(
199
57
                ProtocolErrorKind::NegativeSize,
200
57
                format!("Negative byte array size: {}", num_bytes),
201
57
            )));
202
1.36M
        }
203
204
1.36M
        if let Some(max_size) = self.config.max_string_size() {
205
1.36M
            if num_bytes as usize > max_size {
206
226
                return Err(crate::Error::Protocol(ProtocolError::new(
207
226
                    ProtocolErrorKind::SizeLimit,
208
226
                    format!(
209
226
                        "Byte array size {} exceeds maximum allowed size of {}",
210
226
                        num_bytes, max_size
211
226
                    ),
212
226
                )));
213
1.36M
            }
214
0
        }
215
216
1.36M
        let mut buf = vec![0u8; num_bytes as usize];
217
1.36M
        self.transport
218
1.36M
            .read_exact(&mut buf)
219
1.36M
            .map(|_| buf)
220
1.36M
            .map_err(From::from)
221
1.36M
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_bytes
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_bytes
Line
Count
Source
194
1.19M
    fn read_bytes(&mut self) -> crate::Result<Vec<u8>> {
195
1.19M
        let num_bytes = self.transport.read_i32::<BigEndian>()?;
196
197
1.18M
        if num_bytes < 0 {
198
63
            return Err(crate::Error::Protocol(ProtocolError::new(
199
63
                ProtocolErrorKind::NegativeSize,
200
63
                format!("Negative byte array size: {}", num_bytes),
201
63
            )));
202
1.18M
        }
203
204
1.18M
        if let Some(max_size) = self.config.max_string_size() {
205
1.18M
            if num_bytes as usize > max_size {
206
170
                return Err(crate::Error::Protocol(ProtocolError::new(
207
170
                    ProtocolErrorKind::SizeLimit,
208
170
                    format!(
209
170
                        "Byte array size {} exceeds maximum allowed size of {}",
210
170
                        num_bytes, max_size
211
170
                    ),
212
170
                )));
213
1.18M
            }
214
0
        }
215
216
1.18M
        let mut buf = vec![0u8; num_bytes as usize];
217
1.18M
        self.transport
218
1.18M
            .read_exact(&mut buf)
219
1.18M
            .map(|_| buf)
220
1.18M
            .map_err(From::from)
221
1.19M
    }
222
223
90.3k
    fn read_bool(&mut self) -> crate::Result<bool> {
224
90.3k
        let b = self.read_i8()?;
225
90.1k
        match b {
226
22.8k
            0 => Ok(false),
227
67.3k
            _ => Ok(true),
228
        }
229
90.3k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_bool
Line
Count
Source
223
60.5k
    fn read_bool(&mut self) -> crate::Result<bool> {
224
60.5k
        let b = self.read_i8()?;
225
60.5k
        match b {
226
11.3k
            0 => Ok(false),
227
49.1k
            _ => Ok(true),
228
        }
229
60.5k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_bool
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_bool
Line
Count
Source
223
29.7k
    fn read_bool(&mut self) -> crate::Result<bool> {
224
29.7k
        let b = self.read_i8()?;
225
29.6k
        match b {
226
11.4k
            0 => Ok(false),
227
18.2k
            _ => Ok(true),
228
        }
229
29.7k
    }
230
231
132k
    fn read_i8(&mut self) -> crate::Result<i8> {
232
132k
        self.transport.read_i8().map_err(From::from)
233
132k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_i8
Line
Count
Source
231
81.0k
    fn read_i8(&mut self) -> crate::Result<i8> {
232
81.0k
        self.transport.read_i8().map_err(From::from)
233
81.0k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_i8
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_i8
Line
Count
Source
231
51.5k
    fn read_i8(&mut self) -> crate::Result<i8> {
232
51.5k
        self.transport.read_i8().map_err(From::from)
233
51.5k
    }
234
235
575k
    fn read_i16(&mut self) -> crate::Result<i16> {
236
575k
        self.transport.read_i16::<BigEndian>().map_err(From::from)
237
575k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_i16
Line
Count
Source
235
261k
    fn read_i16(&mut self) -> crate::Result<i16> {
236
261k
        self.transport.read_i16::<BigEndian>().map_err(From::from)
237
261k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_i16
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_i16
Line
Count
Source
235
313k
    fn read_i16(&mut self) -> crate::Result<i16> {
236
313k
        self.transport.read_i16::<BigEndian>().map_err(From::from)
237
313k
    }
238
239
2.32M
    fn read_i32(&mut self) -> crate::Result<i32> {
240
2.32M
        self.transport.read_i32::<BigEndian>().map_err(From::from)
241
2.32M
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_i32
Line
Count
Source
239
1.07M
    fn read_i32(&mut self) -> crate::Result<i32> {
240
1.07M
        self.transport.read_i32::<BigEndian>().map_err(From::from)
241
1.07M
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_i32
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_i32
Line
Count
Source
239
1.25M
    fn read_i32(&mut self) -> crate::Result<i32> {
240
1.25M
        self.transport.read_i32::<BigEndian>().map_err(From::from)
241
1.25M
    }
242
243
1.61M
    fn read_i64(&mut self) -> crate::Result<i64> {
244
1.61M
        self.transport.read_i64::<BigEndian>().map_err(From::from)
245
1.61M
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_i64
Line
Count
Source
243
768k
    fn read_i64(&mut self) -> crate::Result<i64> {
244
768k
        self.transport.read_i64::<BigEndian>().map_err(From::from)
245
768k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_i64
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_i64
Line
Count
Source
243
843k
    fn read_i64(&mut self) -> crate::Result<i64> {
244
843k
        self.transport.read_i64::<BigEndian>().map_err(From::from)
245
843k
    }
246
247
12.6k
    fn read_double(&mut self) -> crate::Result<f64> {
248
12.6k
        self.transport.read_f64::<BigEndian>().map_err(From::from)
249
12.6k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_double
Line
Count
Source
247
1.65k
    fn read_double(&mut self) -> crate::Result<f64> {
248
1.65k
        self.transport.read_f64::<BigEndian>().map_err(From::from)
249
1.65k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_double
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_double
Line
Count
Source
247
10.9k
    fn read_double(&mut self) -> crate::Result<f64> {
248
10.9k
        self.transport.read_f64::<BigEndian>().map_err(From::from)
249
10.9k
    }
250
251
9.99k
    fn read_uuid(&mut self) -> crate::Result<uuid::Uuid> {
252
9.99k
        let mut buf = [0u8; 16];
253
9.99k
        self.transport
254
9.99k
            .read_exact(&mut buf)
255
9.99k
            .map(|_| uuid::Uuid::from_bytes(buf))
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_uuid::{closure#0}
Line
Count
Source
255
2.73k
            .map(|_| uuid::Uuid::from_bytes(buf))
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_uuid::{closure#0}
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_uuid::{closure#0}
Line
Count
Source
255
7.21k
            .map(|_| uuid::Uuid::from_bytes(buf))
256
9.99k
            .map_err(From::from)
257
9.99k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_uuid
Line
Count
Source
251
2.76k
    fn read_uuid(&mut self) -> crate::Result<uuid::Uuid> {
252
2.76k
        let mut buf = [0u8; 16];
253
2.76k
        self.transport
254
2.76k
            .read_exact(&mut buf)
255
2.76k
            .map(|_| uuid::Uuid::from_bytes(buf))
256
2.76k
            .map_err(From::from)
257
2.76k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_uuid
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_uuid
Line
Count
Source
251
7.23k
    fn read_uuid(&mut self) -> crate::Result<uuid::Uuid> {
252
7.23k
        let mut buf = [0u8; 16];
253
7.23k
        self.transport
254
7.23k
            .read_exact(&mut buf)
255
7.23k
            .map(|_| uuid::Uuid::from_bytes(buf))
256
7.23k
            .map_err(From::from)
257
7.23k
    }
258
259
2.52M
    fn read_string(&mut self) -> crate::Result<String> {
260
2.52M
        let bytes = self.read_bytes()?;
261
2.52M
        String::from_utf8(bytes).map_err(From::from)
262
2.52M
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_string
Line
Count
Source
259
1.35M
    fn read_string(&mut self) -> crate::Result<String> {
260
1.35M
        let bytes = self.read_bytes()?;
261
1.35M
        String::from_utf8(bytes).map_err(From::from)
262
1.35M
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_string
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_string
Line
Count
Source
259
1.17M
    fn read_string(&mut self) -> crate::Result<String> {
260
1.17M
        let bytes = self.read_bytes()?;
261
1.17M
        String::from_utf8(bytes).map_err(From::from)
262
1.17M
    }
263
264
173k
    fn read_list_begin(&mut self) -> crate::Result<TListIdentifier> {
265
173k
        let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
266
173k
        let size = self.read_i32()?;
267
173k
        let min_element_size = self.min_serialized_size(element_type);
268
173k
        super::check_container_size(&self.config, size, min_element_size)?;
269
173k
        Ok(TListIdentifier::new(element_type, size))
270
173k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_list_begin
Line
Count
Source
264
81.2k
    fn read_list_begin(&mut self) -> crate::Result<TListIdentifier> {
265
81.2k
        let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
266
81.1k
        let size = self.read_i32()?;
267
81.1k
        let min_element_size = self.min_serialized_size(element_type);
268
81.1k
        super::check_container_size(&self.config, size, min_element_size)?;
269
81.0k
        Ok(TListIdentifier::new(element_type, size))
270
81.2k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_list_begin
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_list_begin
Line
Count
Source
264
92.2k
    fn read_list_begin(&mut self) -> crate::Result<TListIdentifier> {
265
92.2k
        let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
266
92.2k
        let size = self.read_i32()?;
267
92.1k
        let min_element_size = self.min_serialized_size(element_type);
268
92.1k
        super::check_container_size(&self.config, size, min_element_size)?;
269
92.1k
        Ok(TListIdentifier::new(element_type, size))
270
92.2k
    }
271
272
171k
    fn read_list_end(&mut self) -> crate::Result<()> {
273
171k
        Ok(())
274
171k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_list_end
Line
Count
Source
272
80.4k
    fn read_list_end(&mut self) -> crate::Result<()> {
273
80.4k
        Ok(())
274
80.4k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_list_end
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_list_end
Line
Count
Source
272
91.5k
    fn read_list_end(&mut self) -> crate::Result<()> {
273
91.5k
        Ok(())
274
91.5k
    }
275
276
29.3k
    fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier> {
277
29.3k
        let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
278
29.2k
        let size = self.read_i32()?;
279
29.2k
        let min_element_size = self.min_serialized_size(element_type);
280
29.2k
        super::check_container_size(&self.config, size, min_element_size)?;
281
29.1k
        Ok(TSetIdentifier::new(element_type, size))
282
29.3k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_set_begin
Line
Count
Source
276
15.9k
    fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier> {
277
15.9k
        let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
278
15.8k
        let size = self.read_i32()?;
279
15.8k
        let min_element_size = self.min_serialized_size(element_type);
280
15.8k
        super::check_container_size(&self.config, size, min_element_size)?;
281
15.7k
        Ok(TSetIdentifier::new(element_type, size))
282
15.9k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_set_begin
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_set_begin
Line
Count
Source
276
13.4k
    fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier> {
277
13.4k
        let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
278
13.4k
        let size = self.read_i32()?;
279
13.4k
        let min_element_size = self.min_serialized_size(element_type);
280
13.4k
        super::check_container_size(&self.config, size, min_element_size)?;
281
13.4k
        Ok(TSetIdentifier::new(element_type, size))
282
13.4k
    }
283
284
27.4k
    fn read_set_end(&mut self) -> crate::Result<()> {
285
27.4k
        Ok(())
286
27.4k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_set_end
Line
Count
Source
284
14.7k
    fn read_set_end(&mut self) -> crate::Result<()> {
285
14.7k
        Ok(())
286
14.7k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_set_end
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_set_end
Line
Count
Source
284
12.6k
    fn read_set_end(&mut self) -> crate::Result<()> {
285
12.6k
        Ok(())
286
12.6k
    }
287
288
40.6k
    fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier> {
289
40.6k
        let key_type: TType = self.read_byte().and_then(field_type_from_u8)?;
290
40.4k
        let value_type: TType = self.read_byte().and_then(field_type_from_u8)?;
291
40.4k
        let size = self.read_i32()?;
292
293
40.3k
        let key_min_size = self.min_serialized_size(key_type);
294
40.3k
        let value_min_size = self.min_serialized_size(value_type);
295
40.3k
        let element_size = key_min_size + value_min_size;
296
40.3k
        super::check_container_size(&self.config, size, element_size)?;
297
298
40.3k
        Ok(TMapIdentifier::new(key_type, value_type, size))
299
40.6k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_map_begin
Line
Count
Source
288
17.6k
    fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier> {
289
17.6k
        let key_type: TType = self.read_byte().and_then(field_type_from_u8)?;
290
17.5k
        let value_type: TType = self.read_byte().and_then(field_type_from_u8)?;
291
17.5k
        let size = self.read_i32()?;
292
293
17.5k
        let key_min_size = self.min_serialized_size(key_type);
294
17.5k
        let value_min_size = self.min_serialized_size(value_type);
295
17.5k
        let element_size = key_min_size + value_min_size;
296
17.5k
        super::check_container_size(&self.config, size, element_size)?;
297
298
17.5k
        Ok(TMapIdentifier::new(key_type, value_type, size))
299
17.6k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_map_begin
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_map_begin
Line
Count
Source
288
22.9k
    fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier> {
289
22.9k
        let key_type: TType = self.read_byte().and_then(field_type_from_u8)?;
290
22.8k
        let value_type: TType = self.read_byte().and_then(field_type_from_u8)?;
291
22.8k
        let size = self.read_i32()?;
292
293
22.8k
        let key_min_size = self.min_serialized_size(key_type);
294
22.8k
        let value_min_size = self.min_serialized_size(value_type);
295
22.8k
        let element_size = key_min_size + value_min_size;
296
22.8k
        super::check_container_size(&self.config, size, element_size)?;
297
298
22.8k
        Ok(TMapIdentifier::new(key_type, value_type, size))
299
22.9k
    }
300
301
37.7k
    fn read_map_end(&mut self) -> crate::Result<()> {
302
37.7k
        Ok(())
303
37.7k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_map_end
Line
Count
Source
301
16.2k
    fn read_map_end(&mut self) -> crate::Result<()> {
302
16.2k
        Ok(())
303
16.2k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_map_end
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_map_end
Line
Count
Source
301
21.5k
    fn read_map_end(&mut self) -> crate::Result<()> {
302
21.5k
        Ok(())
303
21.5k
    }
304
305
    // utility
306
    //
307
308
1.17M
    fn read_byte(&mut self) -> crate::Result<u8> {
309
1.17M
        self.transport.read_u8().map_err(From::from)
310
1.17M
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_byte
Line
Count
Source
308
504k
    fn read_byte(&mut self) -> crate::Result<u8> {
309
504k
        self.transport.read_u8().map_err(From::from)
310
504k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::read_byte
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::read_byte
Line
Count
Source
308
668k
    fn read_byte(&mut self) -> crate::Result<u8> {
309
668k
        self.transport.read_u8().map_err(From::from)
310
668k
    }
311
312
283k
    fn min_serialized_size(&self, field_type: TType) -> usize {
313
283k
        match field_type {
314
166k
            TType::Stop => 1,   // 1 byte minimum
315
11.3k
            TType::Void => 1,   // 1 byte minimum
316
1.42k
            TType::Bool => 1,   // 1 byte
317
948
            TType::I08 => 1,    // 1 byte
318
2.51k
            TType::Double => 8, // 8 bytes
319
363
            TType::I16 => 2,    // 2 bytes
320
26.3k
            TType::I32 => 4,    // 4 bytes
321
11.3k
            TType::I64 => 8,    // 8 bytes
322
31.4k
            TType::String => 4, // 4 bytes for length prefix
323
20.6k
            TType::Struct => 1, // 1 byte minimum (stop field)
324
1.62k
            TType::Map => 4,    // 4 bytes size
325
928
            TType::Set => 4,    // 4 bytes size
326
7.82k
            TType::List => 4,   // 4 bytes size
327
83
            TType::Uuid => 16,  // 16 bytes
328
0
            TType::Utf7 => 1,   // 1 byte
329
        }
330
283k
    }
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::min_serialized_size
Line
Count
Source
312
132k
    fn min_serialized_size(&self, field_type: TType) -> usize {
313
132k
        match field_type {
314
84.5k
            TType::Stop => 1,   // 1 byte minimum
315
4.47k
            TType::Void => 1,   // 1 byte minimum
316
883
            TType::Bool => 1,   // 1 byte
317
376
            TType::I08 => 1,    // 1 byte
318
836
            TType::Double => 8, // 8 bytes
319
166
            TType::I16 => 2,    // 2 bytes
320
7.44k
            TType::I32 => 4,    // 4 bytes
321
7.74k
            TType::I64 => 8,    // 8 bytes
322
12.2k
            TType::String => 4, // 4 bytes for length prefix
323
9.19k
            TType::Struct => 1, // 1 byte minimum (stop field)
324
639
            TType::Map => 4,    // 4 bytes size
325
575
            TType::Set => 4,    // 4 bytes size
326
2.83k
            TType::List => 4,   // 4 bytes size
327
52
            TType::Uuid => 16,  // 16 bytes
328
0
            TType::Utf7 => 1,   // 1 byte
329
        }
330
132k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::min_serialized_size
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::min_serialized_size
Line
Count
Source
312
151k
    fn min_serialized_size(&self, field_type: TType) -> usize {
313
151k
        match field_type {
314
81.8k
            TType::Stop => 1,   // 1 byte minimum
315
6.92k
            TType::Void => 1,   // 1 byte minimum
316
540
            TType::Bool => 1,   // 1 byte
317
572
            TType::I08 => 1,    // 1 byte
318
1.67k
            TType::Double => 8, // 8 bytes
319
197
            TType::I16 => 2,    // 2 bytes
320
18.9k
            TType::I32 => 4,    // 4 bytes
321
3.61k
            TType::I64 => 8,    // 8 bytes
322
19.1k
            TType::String => 4, // 4 bytes for length prefix
323
11.4k
            TType::Struct => 1, // 1 byte minimum (stop field)
324
985
            TType::Map => 4,    // 4 bytes size
325
353
            TType::Set => 4,    // 4 bytes size
326
4.98k
            TType::List => 4,   // 4 bytes size
327
31
            TType::Uuid => 16,  // 16 bytes
328
0
            TType::Utf7 => 1,   // 1 byte
329
        }
330
151k
    }
331
}
332
333
/// Factory for creating instances of `TBinaryInputProtocol`.
334
#[derive(Default)]
335
pub struct TBinaryInputProtocolFactory;
336
337
impl TBinaryInputProtocolFactory {
338
    /// Create a `TBinaryInputProtocolFactory`.
339
0
    pub fn new() -> TBinaryInputProtocolFactory {
340
0
        TBinaryInputProtocolFactory {}
341
0
    }
342
}
343
344
impl TInputProtocolFactory for TBinaryInputProtocolFactory {
345
0
    fn create(&self, transport: Box<dyn TReadTransport + Send>) -> Box<dyn TInputProtocol + Send> {
346
0
        Box::new(TBinaryInputProtocol::new(transport, true))
347
0
    }
348
}
349
350
/// Write messages using the Thrift simple binary encoding.
351
///
352
/// There are two available modes: `strict` and `non-strict`, where the
353
/// `strict` version writes the protocol version number in the outgoing message
354
/// header and the `non-strict` version does not.
355
///
356
/// # Examples
357
///
358
/// Create and use a `TBinaryOutputProtocol`.
359
///
360
/// ```no_run
361
/// use thrift::protocol::{TBinaryOutputProtocol, TOutputProtocol};
362
/// use thrift::transport::TTcpChannel;
363
///
364
/// let mut channel = TTcpChannel::new();
365
/// channel.open("localhost:9090").unwrap();
366
///
367
/// let mut protocol = TBinaryOutputProtocol::new(channel, true);
368
///
369
/// protocol.write_bool(true).unwrap();
370
/// protocol.write_string("test_string").unwrap();
371
/// ```
372
#[derive(Debug)]
373
pub struct TBinaryOutputProtocol<T>
374
where
375
    T: TWriteTransport,
376
{
377
    strict: bool,
378
    pub transport: T, // FIXME: do not make public; only public for testing!
379
    config: TConfiguration,
380
    recursion_depth: usize,
381
}
382
383
impl<T> TBinaryOutputProtocol<T>
384
where
385
    T: TWriteTransport,
386
{
387
    /// Create a `TBinaryOutputProtocol` that writes bytes to `transport`.
388
    ///
389
    /// Set `strict` to `true` if all outgoing messages should contain the
390
    /// protocol version number in the protocol header.
391
2.06k
    pub fn new(transport: T, strict: bool) -> TBinaryOutputProtocol<T> {
392
2.06k
        Self::with_config(transport, strict, TConfiguration::default())
393
2.06k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>>>::new
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel>>::new
Line
Count
Source
391
2.06k
    pub fn new(transport: T, strict: bool) -> TBinaryOutputProtocol<T> {
392
2.06k
        Self::with_config(transport, strict, TConfiguration::default())
393
2.06k
    }
394
395
2.06k
    pub fn with_config(
396
2.06k
        transport: T,
397
2.06k
        strict: bool,
398
2.06k
        config: TConfiguration,
399
2.06k
    ) -> TBinaryOutputProtocol<T> {
400
2.06k
        TBinaryOutputProtocol {
401
2.06k
            strict,
402
2.06k
            transport,
403
2.06k
            config,
404
2.06k
            recursion_depth: 0,
405
2.06k
        }
406
2.06k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>>>::with_config
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel>>::with_config
Line
Count
Source
395
2.06k
    pub fn with_config(
396
2.06k
        transport: T,
397
2.06k
        strict: bool,
398
2.06k
        config: TConfiguration,
399
2.06k
    ) -> TBinaryOutputProtocol<T> {
400
2.06k
        TBinaryOutputProtocol {
401
2.06k
            strict,
402
2.06k
            transport,
403
2.06k
            config,
404
2.06k
            recursion_depth: 0,
405
2.06k
        }
406
2.06k
    }
407
408
51.5k
    fn check_recursion_depth(&self) -> crate::Result<()> {
409
51.5k
        if let Some(limit) = self.config.max_recursion_depth() {
410
51.5k
            if self.recursion_depth >= limit {
411
0
                return Err(crate::Error::Protocol(ProtocolError::new(
412
0
                    ProtocolErrorKind::DepthLimit,
413
0
                    format!("Maximum recursion depth {} exceeded", limit),
414
0
                )));
415
51.5k
            }
416
0
        }
417
51.5k
        Ok(())
418
51.5k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>>>::check_recursion_depth
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel>>::check_recursion_depth
Line
Count
Source
408
51.5k
    fn check_recursion_depth(&self) -> crate::Result<()> {
409
51.5k
        if let Some(limit) = self.config.max_recursion_depth() {
410
51.5k
            if self.recursion_depth >= limit {
411
0
                return Err(crate::Error::Protocol(ProtocolError::new(
412
0
                    ProtocolErrorKind::DepthLimit,
413
0
                    format!("Maximum recursion depth {} exceeded", limit),
414
0
                )));
415
51.5k
            }
416
0
        }
417
51.5k
        Ok(())
418
51.5k
    }
419
}
420
421
impl<T> TOutputProtocol for TBinaryOutputProtocol<T>
422
where
423
    T: TWriteTransport,
424
{
425
0
    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> {
426
0
        if self.strict {
427
0
            let message_type: u8 = identifier.message_type.into();
428
0
            let header = BINARY_PROTOCOL_VERSION_1 | (message_type as u32);
429
0
            self.transport.write_u32::<BigEndian>(header)?;
430
0
            self.write_string(&identifier.name)?;
431
0
            self.write_i32(identifier.sequence_number)
432
        } else {
433
0
            self.write_string(&identifier.name)?;
434
0
            self.write_byte(identifier.message_type.into())?;
435
0
            self.write_i32(identifier.sequence_number)
436
        }
437
0
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_message_begin
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_message_begin
438
439
0
    fn write_message_end(&mut self) -> crate::Result<()> {
440
0
        Ok(())
441
0
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_message_end
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_message_end
442
443
51.5k
    fn write_struct_begin(&mut self, _: &TStructIdentifier) -> crate::Result<()> {
444
51.5k
        self.check_recursion_depth()?;
445
51.5k
        self.recursion_depth += 1;
446
51.5k
        Ok(())
447
51.5k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_struct_begin
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_struct_begin
Line
Count
Source
443
51.5k
    fn write_struct_begin(&mut self, _: &TStructIdentifier) -> crate::Result<()> {
444
51.5k
        self.check_recursion_depth()?;
445
51.5k
        self.recursion_depth += 1;
446
51.5k
        Ok(())
447
51.5k
    }
448
449
46.6k
    fn write_struct_end(&mut self) -> crate::Result<()> {
450
46.6k
        self.recursion_depth -= 1;
451
46.6k
        Ok(())
452
46.6k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_struct_end
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_struct_end
Line
Count
Source
449
46.6k
    fn write_struct_end(&mut self) -> crate::Result<()> {
450
46.6k
        self.recursion_depth -= 1;
451
46.6k
        Ok(())
452
46.6k
    }
453
454
188k
    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> {
455
188k
        if identifier.id.is_none() && identifier.field_type != TType::Stop {
456
0
            return Err(crate::Error::Protocol(ProtocolError {
457
0
                kind: ProtocolErrorKind::Unknown,
458
0
                message: format!(
459
0
                    "cannot write identifier {:?} without sequence number",
460
0
                    &identifier
461
0
                ),
462
0
            }));
463
188k
        }
464
465
188k
        self.write_byte(field_type_to_u8(identifier.field_type))?;
466
188k
        if let Some(id) = identifier.id {
467
188k
            self.write_i16(id)
468
        } else {
469
0
            Ok(())
470
        }
471
188k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_field_begin
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_field_begin
Line
Count
Source
454
188k
    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> {
455
188k
        if identifier.id.is_none() && identifier.field_type != TType::Stop {
456
0
            return Err(crate::Error::Protocol(ProtocolError {
457
0
                kind: ProtocolErrorKind::Unknown,
458
0
                message: format!(
459
0
                    "cannot write identifier {:?} without sequence number",
460
0
                    &identifier
461
0
                ),
462
0
            }));
463
188k
        }
464
465
188k
        self.write_byte(field_type_to_u8(identifier.field_type))?;
466
188k
        if let Some(id) = identifier.id {
467
188k
            self.write_i16(id)
468
        } else {
469
0
            Ok(())
470
        }
471
188k
    }
472
473
183k
    fn write_field_end(&mut self) -> crate::Result<()> {
474
183k
        Ok(())
475
183k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_field_end
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_field_end
Line
Count
Source
473
183k
    fn write_field_end(&mut self) -> crate::Result<()> {
474
183k
        Ok(())
475
183k
    }
476
477
46.7k
    fn write_field_stop(&mut self) -> crate::Result<()> {
478
46.7k
        self.write_byte(field_type_to_u8(TType::Stop))
479
46.7k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_field_stop
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_field_stop
Line
Count
Source
477
46.7k
    fn write_field_stop(&mut self) -> crate::Result<()> {
478
46.7k
        self.write_byte(field_type_to_u8(TType::Stop))
479
46.7k
    }
480
481
49.9k
    fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> {
482
49.9k
        self.write_i32(b.len() as i32)?;
483
49.8k
        self.transport.write_all(b).map_err(From::from)
484
49.9k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_bytes
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_bytes
Line
Count
Source
481
49.9k
    fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> {
482
49.9k
        self.write_i32(b.len() as i32)?;
483
49.8k
        self.transport.write_all(b).map_err(From::from)
484
49.9k
    }
485
486
16.0k
    fn write_bool(&mut self, b: bool) -> crate::Result<()> {
487
16.0k
        if b {
488
1.65k
            self.write_i8(1)
489
        } else {
490
14.4k
            self.write_i8(0)
491
        }
492
16.0k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_bool
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_bool
Line
Count
Source
486
16.0k
    fn write_bool(&mut self, b: bool) -> crate::Result<()> {
487
16.0k
        if b {
488
1.65k
            self.write_i8(1)
489
        } else {
490
14.4k
            self.write_i8(0)
491
        }
492
16.0k
    }
493
494
30.4k
    fn write_i8(&mut self, i: i8) -> crate::Result<()> {
495
30.4k
        self.transport.write_i8(i).map_err(From::from)
496
30.4k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_i8
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_i8
Line
Count
Source
494
30.4k
    fn write_i8(&mut self, i: i8) -> crate::Result<()> {
495
30.4k
        self.transport.write_i8(i).map_err(From::from)
496
30.4k
    }
497
498
202k
    fn write_i16(&mut self, i: i16) -> crate::Result<()> {
499
202k
        self.transport.write_i16::<BigEndian>(i).map_err(From::from)
500
202k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_i16
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_i16
Line
Count
Source
498
202k
    fn write_i16(&mut self, i: i16) -> crate::Result<()> {
499
202k
        self.transport.write_i16::<BigEndian>(i).map_err(From::from)
500
202k
    }
501
502
137k
    fn write_i32(&mut self, i: i32) -> crate::Result<()> {
503
137k
        self.transport.write_i32::<BigEndian>(i).map_err(From::from)
504
137k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_i32
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_i32
Line
Count
Source
502
137k
    fn write_i32(&mut self, i: i32) -> crate::Result<()> {
503
137k
        self.transport.write_i32::<BigEndian>(i).map_err(From::from)
504
137k
    }
505
506
55.7k
    fn write_i64(&mut self, i: i64) -> crate::Result<()> {
507
55.7k
        self.transport.write_i64::<BigEndian>(i).map_err(From::from)
508
55.7k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_i64
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_i64
Line
Count
Source
506
55.7k
    fn write_i64(&mut self, i: i64) -> crate::Result<()> {
507
55.7k
        self.transport.write_i64::<BigEndian>(i).map_err(From::from)
508
55.7k
    }
509
510
14.2k
    fn write_double(&mut self, d: f64) -> crate::Result<()> {
511
14.2k
        self.transport.write_f64::<BigEndian>(d).map_err(From::from)
512
14.2k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_double
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_double
Line
Count
Source
510
14.2k
    fn write_double(&mut self, d: f64) -> crate::Result<()> {
511
14.2k
        self.transport.write_f64::<BigEndian>(d).map_err(From::from)
512
14.2k
    }
513
514
35.1k
    fn write_string(&mut self, s: &str) -> crate::Result<()> {
515
35.1k
        self.write_bytes(s.as_bytes())
516
35.1k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_string
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_string
Line
Count
Source
514
35.1k
    fn write_string(&mut self, s: &str) -> crate::Result<()> {
515
35.1k
        self.write_bytes(s.as_bytes())
516
35.1k
    }
517
518
13.9k
    fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()> {
519
13.9k
        self.transport
520
13.9k
            .write_all(uuid.as_bytes())
521
13.9k
            .map_err(From::from)
522
13.9k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_uuid
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_uuid
Line
Count
Source
518
13.9k
    fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()> {
519
13.9k
        self.transport
520
13.9k
            .write_all(uuid.as_bytes())
521
13.9k
            .map_err(From::from)
522
13.9k
    }
523
524
7.38k
    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> {
525
7.38k
        self.write_byte(field_type_to_u8(identifier.element_type))?;
526
7.33k
        self.write_i32(identifier.size)
527
7.38k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_list_begin
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_list_begin
Line
Count
Source
524
7.38k
    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> {
525
7.38k
        self.write_byte(field_type_to_u8(identifier.element_type))?;
526
7.33k
        self.write_i32(identifier.size)
527
7.38k
    }
528
529
6.61k
    fn write_list_end(&mut self) -> crate::Result<()> {
530
6.61k
        Ok(())
531
6.61k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_list_end
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_list_end
Line
Count
Source
529
6.61k
    fn write_list_end(&mut self) -> crate::Result<()> {
530
6.61k
        Ok(())
531
6.61k
    }
532
533
2.79k
    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> {
534
2.79k
        self.write_byte(field_type_to_u8(identifier.element_type))?;
535
2.78k
        self.write_i32(identifier.size)
536
2.79k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_set_begin
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_set_begin
Line
Count
Source
533
2.79k
    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> {
534
2.79k
        self.write_byte(field_type_to_u8(identifier.element_type))?;
535
2.78k
        self.write_i32(identifier.size)
536
2.79k
    }
537
538
2.70k
    fn write_set_end(&mut self) -> crate::Result<()> {
539
2.70k
        Ok(())
540
2.70k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_set_end
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_set_end
Line
Count
Source
538
2.70k
    fn write_set_end(&mut self) -> crate::Result<()> {
539
2.70k
        Ok(())
540
2.70k
    }
541
542
3.02k
    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> {
543
3.02k
        let key_type = identifier
544
3.02k
            .key_type
545
3.02k
            .expect("map identifier to write should contain key type");
546
3.02k
        self.write_byte(field_type_to_u8(key_type))?;
547
3.01k
        let val_type = identifier
548
3.01k
            .value_type
549
3.01k
            .expect("map identifier to write should contain value type");
550
3.01k
        self.write_byte(field_type_to_u8(val_type))?;
551
3.00k
        self.write_i32(identifier.size)
552
3.02k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_map_begin
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_map_begin
Line
Count
Source
542
3.02k
    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> {
543
3.02k
        let key_type = identifier
544
3.02k
            .key_type
545
3.02k
            .expect("map identifier to write should contain key type");
546
3.02k
        self.write_byte(field_type_to_u8(key_type))?;
547
3.01k
        let val_type = identifier
548
3.01k
            .value_type
549
3.01k
            .expect("map identifier to write should contain value type");
550
3.01k
        self.write_byte(field_type_to_u8(val_type))?;
551
3.00k
        self.write_i32(identifier.size)
552
3.02k
    }
553
554
2.85k
    fn write_map_end(&mut self) -> crate::Result<()> {
555
2.85k
        Ok(())
556
2.85k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_map_end
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_map_end
Line
Count
Source
554
2.85k
    fn write_map_end(&mut self) -> crate::Result<()> {
555
2.85k
        Ok(())
556
2.85k
    }
557
558
652
    fn flush(&mut self) -> crate::Result<()> {
559
652
        self.transport.flush().map_err(From::from)
560
652
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::flush
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::flush
Line
Count
Source
558
652
    fn flush(&mut self) -> crate::Result<()> {
559
652
        self.transport.flush().map_err(From::from)
560
652
    }
561
562
    // utility
563
    //
564
565
251k
    fn write_byte(&mut self, b: u8) -> crate::Result<()> {
566
251k
        self.transport.write_u8(b).map_err(From::from)
567
251k
    }
Unexecuted instantiation: <thrift::protocol::binary::TBinaryOutputProtocol<alloc::boxed::Box<dyn thrift::transport::TWriteTransport + core::marker::Send>> as thrift::protocol::TOutputProtocol>::write_byte
<thrift::protocol::binary::TBinaryOutputProtocol<&mut thrift::transport::mem::TBufferChannel> as thrift::protocol::TOutputProtocol>::write_byte
Line
Count
Source
565
251k
    fn write_byte(&mut self, b: u8) -> crate::Result<()> {
566
251k
        self.transport.write_u8(b).map_err(From::from)
567
251k
    }
568
}
569
570
/// Factory for creating instances of `TBinaryOutputProtocol`.
571
#[derive(Default)]
572
pub struct TBinaryOutputProtocolFactory;
573
574
impl TBinaryOutputProtocolFactory {
575
    /// Create a `TBinaryOutputProtocolFactory`.
576
0
    pub fn new() -> TBinaryOutputProtocolFactory {
577
0
        TBinaryOutputProtocolFactory {}
578
0
    }
579
}
580
581
impl TOutputProtocolFactory for TBinaryOutputProtocolFactory {
582
0
    fn create(
583
0
        &self,
584
0
        transport: Box<dyn TWriteTransport + Send>,
585
0
    ) -> Box<dyn TOutputProtocol + Send> {
586
0
        Box::new(TBinaryOutputProtocol::new(transport, true))
587
0
    }
588
}
589
590
251k
fn field_type_to_u8(field_type: TType) -> u8 {
591
251k
    match field_type {
592
46.7k
        TType::Stop => 0x00,
593
0
        TType::Void => 0x01,
594
16.1k
        TType::Bool => 0x02,
595
14.3k
        TType::I08 => 0x03, // equivalent to TType::Byte
596
14.2k
        TType::Double => 0x04,
597
14.3k
        TType::I16 => 0x06,
598
53.4k
        TType::I32 => 0x08,
599
16.1k
        TType::I64 => 0x0A,
600
34.4k
        TType::String | TType::Utf7 => 0x0B,
601
14.6k
        TType::Struct => 0x0C,
602
3.04k
        TType::Map => 0x0D,
603
2.81k
        TType::Set => 0x0E,
604
6.95k
        TType::List => 0x0F,
605
13.9k
        TType::Uuid => 0x10,
606
    }
607
251k
}
608
609
1.16M
fn field_type_from_u8(b: u8) -> crate::Result<TType> {
610
1.16M
    match b {
611
487k
        0x00 => Ok(TType::Stop),
612
19.9k
        0x01 => Ok(TType::Void),
613
92.3k
        0x02 => Ok(TType::Bool),
614
47.1k
        0x03 => Ok(TType::I08), // Equivalent to TType::Byte
615
17.7k
        0x04 => Ok(TType::Double),
616
13.8k
        0x06 => Ok(TType::I16),
617
112k
        0x08 => Ok(TType::I32),
618
25.4k
        0x0A => Ok(TType::I64),
619
82.1k
        0x0B => Ok(TType::String), // technically, also a UTF7, but we'll treat it as string
620
166k
        0x0C => Ok(TType::Struct),
621
27.7k
        0x0D => Ok(TType::Map),
622
26.4k
        0x0E => Ok(TType::Set),
623
37.9k
        0x0F => Ok(TType::List),
624
10.5k
        0x10 => Ok(TType::Uuid),
625
471
        unkn => Err(crate::Error::Protocol(ProtocolError {
626
471
            kind: ProtocolErrorKind::InvalidData,
627
471
            message: format!("cannot convert {} to TType", unkn),
628
471
        })),
629
    }
630
1.16M
}
631
632
#[cfg(test)]
633
mod tests {
634
635
    use super::*;
636
    use crate::protocol::{
637
        TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
638
        TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType,
639
    };
640
    use crate::transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
641
642
    #[test]
643
    fn must_write_strict_message_call_begin() {
644
        let (_, mut o_prot) = test_objects(true);
645
646
        let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
647
        assert!(o_prot.write_message_begin(&ident).is_ok());
648
649
        #[rustfmt::skip]
650
        let expected: [u8; 16] = [
651
            0x80,
652
            0x01,
653
            0x00,
654
            0x01,
655
            0x00,
656
            0x00,
657
            0x00,
658
            0x04,
659
            0x74,
660
            0x65,
661
            0x73,
662
            0x74,
663
            0x00,
664
            0x00,
665
            0x00,
666
            0x01,
667
        ];
668
669
        assert_eq_written_bytes!(o_prot, expected);
670
    }
671
672
    #[test]
673
    fn must_write_non_strict_message_call_begin() {
674
        let (_, mut o_prot) = test_objects(false);
675
676
        let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
677
        assert!(o_prot.write_message_begin(&ident).is_ok());
678
679
        #[rustfmt::skip]
680
        let expected: [u8; 13] = [
681
            0x00,
682
            0x00,
683
            0x00,
684
            0x04,
685
            0x74,
686
            0x65,
687
            0x73,
688
            0x74,
689
            0x01,
690
            0x00,
691
            0x00,
692
            0x00,
693
            0x01,
694
        ];
695
696
        assert_eq_written_bytes!(o_prot, expected);
697
    }
698
699
    #[test]
700
    fn must_write_strict_message_reply_begin() {
701
        let (_, mut o_prot) = test_objects(true);
702
703
        let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
704
        assert!(o_prot.write_message_begin(&ident).is_ok());
705
706
        #[rustfmt::skip]
707
        let expected: [u8; 16] = [
708
            0x80,
709
            0x01,
710
            0x00,
711
            0x02,
712
            0x00,
713
            0x00,
714
            0x00,
715
            0x04,
716
            0x74,
717
            0x65,
718
            0x73,
719
            0x74,
720
            0x00,
721
            0x00,
722
            0x00,
723
            0x0A,
724
        ];
725
726
        assert_eq_written_bytes!(o_prot, expected);
727
    }
728
729
    #[test]
730
    fn must_write_non_strict_message_reply_begin() {
731
        let (_, mut o_prot) = test_objects(false);
732
733
        let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
734
        assert!(o_prot.write_message_begin(&ident).is_ok());
735
736
        #[rustfmt::skip]
737
        let expected: [u8; 13] = [
738
            0x00,
739
            0x00,
740
            0x00,
741
            0x04,
742
            0x74,
743
            0x65,
744
            0x73,
745
            0x74,
746
            0x02,
747
            0x00,
748
            0x00,
749
            0x00,
750
            0x0A,
751
        ];
752
753
        assert_eq_written_bytes!(o_prot, expected);
754
    }
755
756
    #[test]
757
    fn must_round_trip_strict_message_begin() {
758
        let (mut i_prot, mut o_prot) = test_objects(true);
759
760
        let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
761
        assert!(o_prot.write_message_begin(&sent_ident).is_ok());
762
763
        copy_write_buffer_to_read_buffer!(o_prot);
764
765
        let received_ident = assert_success!(i_prot.read_message_begin());
766
        assert_eq!(&received_ident, &sent_ident);
767
    }
768
769
    #[test]
770
    fn must_round_trip_non_strict_message_begin() {
771
        let (mut i_prot, mut o_prot) = test_objects(false);
772
773
        let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
774
        assert!(o_prot.write_message_begin(&sent_ident).is_ok());
775
776
        copy_write_buffer_to_read_buffer!(o_prot);
777
778
        let received_ident = assert_success!(i_prot.read_message_begin());
779
        assert_eq!(&received_ident, &sent_ident);
780
    }
781
782
    #[test]
783
    fn must_write_message_end() {
784
        assert_no_write(|o| o.write_message_end(), true);
785
    }
786
787
    #[test]
788
    fn must_write_struct_begin() {
789
        assert_no_write(
790
            |o| o.write_struct_begin(&TStructIdentifier::new("foo")),
791
            true,
792
        );
793
    }
794
795
    #[test]
796
    fn must_write_struct_end() {
797
        // write_struct_end now balances the recursion-depth counter against
798
        // write_struct_begin, so pair them (both still emit no bytes).
799
        assert_no_write(
800
            |o| {
801
                o.write_struct_begin(&TStructIdentifier::new("foo"))?;
802
                o.write_struct_end()
803
            },
804
            true,
805
        );
806
    }
807
808
    #[test]
809
    fn must_write_field_begin() {
810
        let (_, mut o_prot) = test_objects(true);
811
812
        assert!(o_prot
813
            .write_field_begin(&TFieldIdentifier::new("some_field", TType::String, 22))
814
            .is_ok());
815
816
        let expected: [u8; 3] = [0x0B, 0x00, 0x16];
817
        assert_eq_written_bytes!(o_prot, expected);
818
    }
819
820
    #[test]
821
    fn must_round_trip_field_begin() {
822
        let (mut i_prot, mut o_prot) = test_objects(true);
823
824
        let sent_field_ident = TFieldIdentifier::new("foo", TType::I64, 20);
825
        assert!(o_prot.write_field_begin(&sent_field_ident).is_ok());
826
827
        copy_write_buffer_to_read_buffer!(o_prot);
828
829
        let expected_ident = TFieldIdentifier {
830
            name: None,
831
            field_type: TType::I64,
832
            id: Some(20),
833
        }; // no name
834
        let received_ident = assert_success!(i_prot.read_field_begin());
835
        assert_eq!(&received_ident, &expected_ident);
836
    }
837
838
    #[test]
839
    fn must_write_stop_field() {
840
        let (_, mut o_prot) = test_objects(true);
841
842
        assert!(o_prot.write_field_stop().is_ok());
843
844
        let expected: [u8; 1] = [0x00];
845
        assert_eq_written_bytes!(o_prot, expected);
846
    }
847
848
    #[test]
849
    fn must_round_trip_field_stop() {
850
        let (mut i_prot, mut o_prot) = test_objects(true);
851
852
        assert!(o_prot.write_field_stop().is_ok());
853
854
        copy_write_buffer_to_read_buffer!(o_prot);
855
856
        let expected_ident = TFieldIdentifier {
857
            name: None,
858
            field_type: TType::Stop,
859
            id: Some(0),
860
        }; // we get id 0
861
862
        let received_ident = assert_success!(i_prot.read_field_begin());
863
        assert_eq!(&received_ident, &expected_ident);
864
    }
865
866
    #[test]
867
    fn must_write_field_end() {
868
        assert_no_write(|o| o.write_field_end(), true);
869
    }
870
871
    #[test]
872
    fn must_write_list_begin() {
873
        let (_, mut o_prot) = test_objects(true);
874
875
        assert!(o_prot
876
            .write_list_begin(&TListIdentifier::new(TType::Bool, 5))
877
            .is_ok());
878
879
        let expected: [u8; 5] = [0x02, 0x00, 0x00, 0x00, 0x05];
880
        assert_eq_written_bytes!(o_prot, expected);
881
    }
882
883
    #[test]
884
    fn must_round_trip_list_begin() {
885
        let (mut i_prot, mut o_prot) = test_objects(true);
886
887
        let ident = TListIdentifier::new(TType::I32, 4);
888
        assert!(o_prot.write_list_begin(&ident).is_ok());
889
        assert!(o_prot.write_i32(10).is_ok());
890
        assert!(o_prot.write_i32(20).is_ok());
891
        assert!(o_prot.write_i32(30).is_ok());
892
        assert!(o_prot.write_i32(40).is_ok());
893
894
        assert!(o_prot.write_list_end().is_ok());
895
896
        copy_write_buffer_to_read_buffer!(o_prot);
897
898
        let received_ident = assert_success!(i_prot.read_list_begin());
899
        assert_eq!(&received_ident, &ident);
900
901
        assert_eq!(i_prot.read_i32().unwrap(), 10);
902
        assert_eq!(i_prot.read_i32().unwrap(), 20);
903
        assert_eq!(i_prot.read_i32().unwrap(), 30);
904
        assert_eq!(i_prot.read_i32().unwrap(), 40);
905
906
        assert!(i_prot.read_list_end().is_ok());
907
    }
908
909
    #[test]
910
    fn must_write_list_end() {
911
        assert_no_write(|o| o.write_list_end(), true);
912
    }
913
914
    #[test]
915
    fn must_write_set_begin() {
916
        let (_, mut o_prot) = test_objects(true);
917
918
        assert!(o_prot
919
            .write_set_begin(&TSetIdentifier::new(TType::I16, 7))
920
            .is_ok());
921
922
        let expected: [u8; 5] = [0x06, 0x00, 0x00, 0x00, 0x07];
923
        assert_eq_written_bytes!(o_prot, expected);
924
    }
925
926
    #[test]
927
    fn must_round_trip_set_begin() {
928
        let (mut i_prot, mut o_prot) = test_objects(true);
929
930
        let ident = TSetIdentifier::new(TType::I64, 3);
931
        assert!(o_prot.write_set_begin(&ident).is_ok());
932
        assert!(o_prot.write_i64(123).is_ok());
933
        assert!(o_prot.write_i64(456).is_ok());
934
        assert!(o_prot.write_i64(789).is_ok());
935
936
        assert!(o_prot.write_set_end().is_ok());
937
938
        copy_write_buffer_to_read_buffer!(o_prot);
939
940
        let received_ident_result = i_prot.read_set_begin();
941
        assert!(received_ident_result.is_ok());
942
        assert_eq!(&received_ident_result.unwrap(), &ident);
943
944
        assert_eq!(i_prot.read_i64().unwrap(), 123);
945
        assert_eq!(i_prot.read_i64().unwrap(), 456);
946
        assert_eq!(i_prot.read_i64().unwrap(), 789);
947
948
        assert!(i_prot.read_set_end().is_ok());
949
    }
950
951
    #[test]
952
    fn must_write_set_end() {
953
        assert_no_write(|o| o.write_set_end(), true);
954
    }
955
956
    #[test]
957
    fn must_write_map_begin() {
958
        let (_, mut o_prot) = test_objects(true);
959
960
        assert!(o_prot
961
            .write_map_begin(&TMapIdentifier::new(TType::I64, TType::Struct, 32))
962
            .is_ok());
963
964
        let expected: [u8; 6] = [0x0A, 0x0C, 0x00, 0x00, 0x00, 0x20];
965
        assert_eq_written_bytes!(o_prot, expected);
966
    }
967
968
    #[test]
969
    fn must_round_trip_map_begin() {
970
        let (mut i_prot, mut o_prot) = test_objects(true);
971
972
        let ident = TMapIdentifier::new(TType::String, TType::I32, 2);
973
        assert!(o_prot.write_map_begin(&ident).is_ok());
974
        assert!(o_prot.write_string("key1").is_ok());
975
        assert!(o_prot.write_i32(100).is_ok());
976
        assert!(o_prot.write_string("key2").is_ok());
977
        assert!(o_prot.write_i32(200).is_ok());
978
979
        assert!(o_prot.write_map_end().is_ok());
980
981
        copy_write_buffer_to_read_buffer!(o_prot);
982
983
        let received_ident = assert_success!(i_prot.read_map_begin());
984
        assert_eq!(&received_ident, &ident);
985
986
        assert_eq!(i_prot.read_string().unwrap(), "key1");
987
        assert_eq!(i_prot.read_i32().unwrap(), 100);
988
        assert_eq!(i_prot.read_string().unwrap(), "key2");
989
        assert_eq!(i_prot.read_i32().unwrap(), 200);
990
991
        assert!(i_prot.read_map_end().is_ok());
992
    }
993
994
    #[test]
995
    fn must_write_map_end() {
996
        assert_no_write(|o| o.write_map_end(), true);
997
    }
998
999
    #[test]
1000
    fn must_write_bool_true() {
1001
        let (_, mut o_prot) = test_objects(true);
1002
1003
        assert!(o_prot.write_bool(true).is_ok());
1004
1005
        let expected: [u8; 1] = [0x01];
1006
        assert_eq_written_bytes!(o_prot, expected);
1007
    }
1008
1009
    #[test]
1010
    fn must_write_bool_false() {
1011
        let (_, mut o_prot) = test_objects(true);
1012
1013
        assert!(o_prot.write_bool(false).is_ok());
1014
1015
        let expected: [u8; 1] = [0x00];
1016
        assert_eq_written_bytes!(o_prot, expected);
1017
    }
1018
1019
    #[test]
1020
    fn must_read_bool_true() {
1021
        let (mut i_prot, _) = test_objects(true);
1022
1023
        set_readable_bytes!(i_prot, &[0x01]);
1024
1025
        let read_bool = assert_success!(i_prot.read_bool());
1026
        assert!(read_bool);
1027
    }
1028
1029
    #[test]
1030
    fn must_read_bool_false() {
1031
        let (mut i_prot, _) = test_objects(true);
1032
1033
        set_readable_bytes!(i_prot, &[0x00]);
1034
1035
        let read_bool = assert_success!(i_prot.read_bool());
1036
        assert!(!read_bool);
1037
    }
1038
1039
    #[test]
1040
    fn must_allow_any_non_zero_value_to_be_interpreted_as_bool_true() {
1041
        let (mut i_prot, _) = test_objects(true);
1042
1043
        set_readable_bytes!(i_prot, &[0xAC]);
1044
1045
        let read_bool = assert_success!(i_prot.read_bool());
1046
        assert!(read_bool);
1047
    }
1048
1049
    #[test]
1050
    fn must_write_bytes() {
1051
        let (_, mut o_prot) = test_objects(true);
1052
1053
        let bytes: [u8; 10] = [0x0A, 0xCC, 0xD1, 0x84, 0x99, 0x12, 0xAB, 0xBB, 0x45, 0xDF];
1054
1055
        assert!(o_prot.write_bytes(&bytes).is_ok());
1056
1057
        let buf = o_prot.transport.write_bytes();
1058
        assert_eq!(&buf[0..4], [0x00, 0x00, 0x00, 0x0A]); // length
1059
        assert_eq!(&buf[4..], bytes); // actual bytes
1060
    }
1061
1062
    #[test]
1063
    fn must_write_uuid() {
1064
        let (_, mut o_prot) = test_objects(true);
1065
        let uuid = uuid::Uuid::new_v4();
1066
        assert!(o_prot.write_uuid(&uuid).is_ok());
1067
        let buf = o_prot.transport.write_bytes();
1068
        assert_eq!(&buf, uuid.as_bytes());
1069
    }
1070
1071
    #[test]
1072
    fn must_round_trip_uuid() {
1073
        let (mut i_prot, mut o_prot) = test_objects(true);
1074
        let uuid = uuid::uuid!("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4");
1075
        assert!(o_prot.write_uuid(&uuid).is_ok());
1076
        copy_write_buffer_to_read_buffer!(o_prot);
1077
        let received_uuid = assert_success!(i_prot.read_uuid());
1078
        assert_eq!(&received_uuid, &uuid);
1079
    }
1080
1081
    #[test]
1082
    fn must_round_trip_bytes() {
1083
        let (mut i_prot, mut o_prot) = test_objects(true);
1084
1085
        #[rustfmt::skip]
1086
        let bytes: [u8; 25] = [
1087
            0x20,
1088
            0xFD,
1089
            0x18,
1090
            0x84,
1091
            0x99,
1092
            0x12,
1093
            0xAB,
1094
            0xBB,
1095
            0x45,
1096
            0xDF,
1097
            0x34,
1098
            0xDC,
1099
            0x98,
1100
            0xA4,
1101
            0x6D,
1102
            0xF3,
1103
            0x99,
1104
            0xB4,
1105
            0xB7,
1106
            0xD4,
1107
            0x9C,
1108
            0xA5,
1109
            0xB3,
1110
            0xC9,
1111
            0x88,
1112
        ];
1113
1114
        assert!(o_prot.write_bytes(&bytes).is_ok());
1115
1116
        copy_write_buffer_to_read_buffer!(o_prot);
1117
1118
        let received_bytes = assert_success!(i_prot.read_bytes());
1119
        assert_eq!(&received_bytes, &bytes);
1120
    }
1121
1122
    fn test_objects(
1123
        strict: bool,
1124
    ) -> (
1125
        TBinaryInputProtocol<ReadHalf<TBufferChannel>>,
1126
        TBinaryOutputProtocol<WriteHalf<TBufferChannel>>,
1127
    ) {
1128
        let mem = TBufferChannel::with_capacity(200, 200);
1129
1130
        let (r_mem, w_mem) = mem.split().unwrap();
1131
1132
        let i_prot = TBinaryInputProtocol::new(r_mem, strict);
1133
        let o_prot = TBinaryOutputProtocol::new(w_mem, strict);
1134
1135
        (i_prot, o_prot)
1136
    }
1137
1138
    fn assert_no_write<F>(mut write_fn: F, strict: bool)
1139
    where
1140
        F: FnMut(&mut TBinaryOutputProtocol<WriteHalf<TBufferChannel>>) -> crate::Result<()>,
1141
    {
1142
        let (_, mut o_prot) = test_objects(strict);
1143
        assert!(write_fn(&mut o_prot).is_ok());
1144
        assert_eq!(o_prot.transport.write_bytes().len(), 0);
1145
    }
1146
1147
    #[test]
1148
    fn must_enforce_recursion_depth_limit() {
1149
        let mem = TBufferChannel::with_capacity(40, 40);
1150
        let (r_mem, _) = mem.split().unwrap();
1151
1152
        let config = TConfiguration::builder()
1153
            .max_recursion_depth(Some(2))
1154
            .build()
1155
            .unwrap();
1156
        let mut i_prot = TBinaryInputProtocol::with_config(r_mem, true, config);
1157
1158
        assert!(i_prot.read_struct_begin().is_ok());
1159
        assert_eq!(i_prot.recursion_depth, 1);
1160
1161
        assert!(i_prot.read_struct_begin().is_ok());
1162
        assert_eq!(i_prot.recursion_depth, 2);
1163
1164
        let result = i_prot.read_struct_begin();
1165
        assert!(result.is_err());
1166
        match result {
1167
            Err(crate::Error::Protocol(e)) => {
1168
                assert_eq!(e.kind, ProtocolErrorKind::DepthLimit);
1169
            }
1170
            _ => panic!("Expected protocol error with DepthLimit"),
1171
        }
1172
1173
        assert!(i_prot.read_struct_end().is_ok());
1174
        assert_eq!(i_prot.recursion_depth, 1);
1175
        assert!(i_prot.read_struct_end().is_ok());
1176
        assert_eq!(i_prot.recursion_depth, 0);
1177
    }
1178
1179
    #[test]
1180
    fn must_reject_negative_container_sizes() {
1181
        let mem = TBufferChannel::with_capacity(40, 40);
1182
        let (r_mem, mut w_mem) = mem.split().unwrap();
1183
1184
        let mut i_prot = TBinaryInputProtocol::new(r_mem, true);
1185
1186
        w_mem.set_readable_bytes(&[0x0F, 0xFF, 0xFF, 0xFF, 0xFF]);
1187
1188
        let result = i_prot.read_list_begin();
1189
        assert!(result.is_err());
1190
        match result {
1191
            Err(crate::Error::Protocol(e)) => {
1192
                assert_eq!(e.kind, ProtocolErrorKind::NegativeSize);
1193
            }
1194
            _ => panic!("Expected protocol error with NegativeSize"),
1195
        }
1196
    }
1197
1198
    #[test]
1199
    fn must_enforce_container_size_limit() {
1200
        let mem = TBufferChannel::with_capacity(40, 40);
1201
        let (r_mem, mut w_mem) = mem.split().unwrap();
1202
1203
        let config = TConfiguration::builder()
1204
            .max_container_size(Some(100))
1205
            .build()
1206
            .unwrap();
1207
1208
        let mut i_prot = TBinaryInputProtocol::with_config(r_mem, true, config);
1209
1210
        w_mem.set_readable_bytes(&[0x0F, 0x00, 0x00, 0x00, 0xC8]);
1211
1212
        let result = i_prot.read_list_begin();
1213
        assert!(result.is_err());
1214
        match result {
1215
            Err(crate::Error::Protocol(e)) => {
1216
                assert_eq!(e.kind, ProtocolErrorKind::SizeLimit);
1217
                assert!(e
1218
                    .message
1219
                    .contains("Container size 200 exceeds maximum allowed size of 100"));
1220
            }
1221
            _ => panic!("Expected protocol error with SizeLimit"),
1222
        }
1223
    }
1224
1225
    #[test]
1226
    fn must_allow_containers_within_limit() {
1227
        let mem = TBufferChannel::with_capacity(200, 200);
1228
        let (r_mem, mut w_mem) = mem.split().unwrap();
1229
1230
        // Create protocol with container limit of 100
1231
        let config = TConfiguration::builder()
1232
            .max_container_size(Some(100))
1233
            .build()
1234
            .unwrap();
1235
        let mut i_prot = TBinaryInputProtocol::with_config(r_mem, true, config);
1236
1237
        let mut data = vec![0x08]; // TType::I32
1238
        data.extend_from_slice(&5i32.to_be_bytes()); // size = 5
1239
1240
        for i in 1i32..=5i32 {
1241
            data.extend_from_slice(&(i * 10).to_be_bytes());
1242
        }
1243
1244
        w_mem.set_readable_bytes(&data);
1245
1246
        let result = i_prot.read_list_begin();
1247
        assert!(result.is_ok());
1248
        let list_ident = result.unwrap();
1249
        assert_eq!(list_ident.size, 5);
1250
        assert_eq!(list_ident.element_type, TType::I32);
1251
    }
1252
1253
    #[test]
1254
    fn must_enforce_string_size_limit() {
1255
        let mem = TBufferChannel::with_capacity(100, 100);
1256
        let (r_mem, mut w_mem) = mem.split().unwrap();
1257
1258
        let config = TConfiguration::builder()
1259
            .max_string_size(Some(1000))
1260
            .build()
1261
            .unwrap();
1262
        let mut i_prot = TBinaryInputProtocol::with_config(r_mem, true, config);
1263
1264
        w_mem.set_readable_bytes(&[0x00, 0x00, 0x07, 0xD0]);
1265
1266
        let result = i_prot.read_string();
1267
        assert!(result.is_err());
1268
        match result {
1269
            Err(crate::Error::Protocol(e)) => {
1270
                assert_eq!(e.kind, ProtocolErrorKind::SizeLimit);
1271
                assert!(e
1272
                    .message
1273
                    .contains("Byte array size 2000 exceeds maximum allowed size of 1000"));
1274
            }
1275
            _ => panic!("Expected protocol error with SizeLimit"),
1276
        }
1277
    }
1278
1279
    #[test]
1280
    fn must_enforce_string_size_limit_on_non_strict_message_name() {
1281
        let mem = TBufferChannel::with_capacity(100, 100);
1282
        let (r_mem, mut w_mem) = mem.split().unwrap();
1283
1284
        let config = TConfiguration::builder()
1285
            .max_string_size(Some(1000))
1286
            .build()
1287
            .unwrap();
1288
        // non-strict: the first 4 bytes are the (positive) message-name length
1289
        let mut i_prot = TBinaryInputProtocol::with_config(r_mem, false, config);
1290
1291
        w_mem.set_readable_bytes(&[0x00, 0x00, 0x07, 0xD0]);
1292
1293
        let result = i_prot.read_message_begin();
1294
        assert!(result.is_err());
1295
        match result {
1296
            Err(crate::Error::Protocol(e)) => {
1297
                assert_eq!(e.kind, ProtocolErrorKind::SizeLimit);
1298
                assert!(e
1299
                    .message
1300
                    .contains("Message name size 2000 exceeds maximum allowed size of 1000"));
1301
            }
1302
            _ => panic!("Expected protocol error with SizeLimit"),
1303
        }
1304
    }
1305
1306
    #[test]
1307
    fn must_allow_non_strict_message_name_at_limit() {
1308
        let mem = TBufferChannel::with_capacity(100, 100);
1309
        let (r_mem, mut w_mem) = mem.split().unwrap();
1310
1311
        let config = TConfiguration::builder()
1312
            .max_string_size(Some(5))
1313
            .build()
1314
            .unwrap();
1315
        // non-strict: the first 4 bytes are the (positive) message-name length
1316
        let mut i_prot = TBinaryInputProtocol::with_config(r_mem, false, config);
1317
1318
        // name length 5 (== limit), name "hello", message type Call, sequence 0
1319
        w_mem.set_readable_bytes(&[
1320
            0x00, 0x00, 0x00, 0x05, b'h', b'e', b'l', b'l', b'o', 0x01, 0x00, 0x00, 0x00, 0x00,
1321
        ]);
1322
1323
        let ident = i_prot.read_message_begin().unwrap();
1324
        assert_eq!(ident.name, "hello");
1325
        assert_eq!(ident.message_type, TMessageType::Call);
1326
        assert_eq!(ident.sequence_number, 0);
1327
    }
1328
1329
    #[test]
1330
    fn must_allow_strings_within_limit() {
1331
        let mem = TBufferChannel::with_capacity(100, 100);
1332
        let (r_mem, mut w_mem) = mem.split().unwrap();
1333
1334
        let config = TConfiguration::builder()
1335
            .max_string_size(Some(1000))
1336
            .build()
1337
            .unwrap();
1338
        let mut i_prot = TBinaryInputProtocol::with_config(r_mem, true, config);
1339
1340
        w_mem.set_readable_bytes(&[0x00, 0x00, 0x00, 0x05, b'h', b'e', b'l', b'l', b'o']);
1341
1342
        let result = i_prot.read_string();
1343
        assert!(result.is_ok());
1344
        assert_eq!(result.unwrap(), "hello");
1345
    }
1346
}