blob: 6826c00a8744a5e0ba5d949523c4847920dcce92 [file] [log] [blame]
Allen George8b96bfb2016-11-02 08:01:08 -04001// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use std::convert::Into;
19
20use ::ProtocolErrorKind;
21use super::{TFieldIdentifier, TListIdentifier, TMapIdentifier, TMessageIdentifier, TInputProtocol,
22 TSetIdentifier, TStructIdentifier};
23
24/// `TInputProtocol` required to use a `TMultiplexedProcessor`.
25///
26/// A `TMultiplexedProcessor` reads incoming message identifiers to determine to
27/// which `TProcessor` requests should be forwarded. However, once read, those
28/// message identifier bytes are no longer on the wire. Since downstream
29/// processors expect to read message identifiers from the given input protocol
30/// we need some way of supplying a `TMessageIdentifier` with the service-name
31/// stripped. This implementation stores the received `TMessageIdentifier`
32/// (without the service name) and passes it to the wrapped `TInputProtocol`
33/// when `TInputProtocol::read_message_begin(...)` is called. It delegates all
34/// other calls directly to the wrapped `TInputProtocol`.
35///
36/// This type **should not** be used by application code.
37///
38/// # Examples
39///
40/// Create and use a `TStoredInputProtocol`.
41///
42/// ```no_run
43/// use std::cell::RefCell;
44/// use std::rc::Rc;
45/// use thrift;
46/// use thrift::protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
47/// use thrift::protocol::{TBinaryInputProtocol, TBinaryOutputProtocol, TStoredInputProtocol};
48/// use thrift::server::TProcessor;
49/// use thrift::transport::{TTcpTransport, TTransport};
50///
51/// // sample processor
52/// struct ActualProcessor;
53/// impl TProcessor for ActualProcessor {
54/// fn process(
55/// &mut self,
56/// _: &mut TInputProtocol,
57/// _: &mut TOutputProtocol
58/// ) -> thrift::Result<()> {
59/// unimplemented!()
60/// }
61/// }
62/// let mut processor = ActualProcessor {};
63///
64/// // construct the shared transport
65/// let mut transport = TTcpTransport::new();
66/// transport.open("localhost:9090").unwrap();
67/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
68///
69/// // construct the actual input and output protocols
70/// let mut i_prot = TBinaryInputProtocol::new(transport.clone(), true);
71/// let mut o_prot = TBinaryOutputProtocol::new(transport.clone(), true);
72///
73/// // message identifier received from remote and modified to remove the service name
74/// let new_msg_ident = TMessageIdentifier::new("service_call", TMessageType::Call, 1);
75///
76/// // construct the proxy input protocol
77/// let mut proxy_i_prot = TStoredInputProtocol::new(&mut i_prot, new_msg_ident);
78/// let res = processor.process(&mut proxy_i_prot, &mut o_prot);
79/// ```
80pub struct TStoredInputProtocol<'a> {
81 inner: &'a mut TInputProtocol,
82 message_ident: Option<TMessageIdentifier>,
83}
84
85impl<'a> TStoredInputProtocol<'a> {
86 /// Create a `TStoredInputProtocol` that delegates all calls other than
87 /// `TInputProtocol::read_message_begin(...)` to a `wrapped`
88 /// `TInputProtocol`. `message_ident` is the modified message identifier -
89 /// with service name stripped - that will be passed to
90 /// `wrapped.read_message_begin(...)`.
91 pub fn new(wrapped: &mut TInputProtocol,
92 message_ident: TMessageIdentifier)
93 -> TStoredInputProtocol {
94 TStoredInputProtocol {
95 inner: wrapped,
96 message_ident: message_ident.into(),
97 }
98 }
99}
100
101impl<'a> TInputProtocol for TStoredInputProtocol<'a> {
102 fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
103 self.message_ident.take().ok_or_else(|| {
104 ::errors::new_protocol_error(ProtocolErrorKind::Unknown,
105 "message identifier already read")
106 })
107 }
108
109 fn read_message_end(&mut self) -> ::Result<()> {
110 self.inner.read_message_end()
111 }
112
113 fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
114 self.inner.read_struct_begin()
115 }
116
117 fn read_struct_end(&mut self) -> ::Result<()> {
118 self.inner.read_struct_end()
119 }
120
121 fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
122 self.inner.read_field_begin()
123 }
124
125 fn read_field_end(&mut self) -> ::Result<()> {
126 self.inner.read_field_end()
127 }
128
129 fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
130 self.inner.read_bytes()
131 }
132
133 fn read_bool(&mut self) -> ::Result<bool> {
134 self.inner.read_bool()
135 }
136
137 fn read_i8(&mut self) -> ::Result<i8> {
138 self.inner.read_i8()
139 }
140
141 fn read_i16(&mut self) -> ::Result<i16> {
142 self.inner.read_i16()
143 }
144
145 fn read_i32(&mut self) -> ::Result<i32> {
146 self.inner.read_i32()
147 }
148
149 fn read_i64(&mut self) -> ::Result<i64> {
150 self.inner.read_i64()
151 }
152
153 fn read_double(&mut self) -> ::Result<f64> {
154 self.inner.read_double()
155 }
156
157 fn read_string(&mut self) -> ::Result<String> {
158 self.inner.read_string()
159 }
160
161 fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
162 self.inner.read_list_begin()
163 }
164
165 fn read_list_end(&mut self) -> ::Result<()> {
166 self.inner.read_list_end()
167 }
168
169 fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
170 self.inner.read_set_begin()
171 }
172
173 fn read_set_end(&mut self) -> ::Result<()> {
174 self.inner.read_set_end()
175 }
176
177 fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
178 self.inner.read_map_begin()
179 }
180
181 fn read_map_end(&mut self) -> ::Result<()> {
182 self.inner.read_map_end()
183 }
184
185 // utility
186 //
187
188 fn read_byte(&mut self) -> ::Result<u8> {
189 self.inner.read_byte()
190 }
191}