blob: b3f305f031aa6b3e9a4dff1099c8449e4faaf485 [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
Allen George0e22c362017-01-30 07:15:00 -050020use ProtocolErrorKind;
21use super::{TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
Allen George8b96bfb2016-11-02 08:01:08 -040022 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
Allen George8b96bfb2016-11-02 08:01:08 -040043/// use thrift;
44/// use thrift::protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
45/// use thrift::protocol::{TBinaryInputProtocol, TBinaryOutputProtocol, TStoredInputProtocol};
46/// use thrift::server::TProcessor;
Allen George0e22c362017-01-30 07:15:00 -050047/// use thrift::transport::{TIoChannel, TTcpChannel};
Allen George8b96bfb2016-11-02 08:01:08 -040048///
49/// // sample processor
50/// struct ActualProcessor;
51/// impl TProcessor for ActualProcessor {
52/// fn process(
Allen George0e22c362017-01-30 07:15:00 -050053/// &self,
Allen George8b96bfb2016-11-02 08:01:08 -040054/// _: &mut TInputProtocol,
55/// _: &mut TOutputProtocol
56/// ) -> thrift::Result<()> {
57/// unimplemented!()
58/// }
59/// }
Allen George0e22c362017-01-30 07:15:00 -050060/// let processor = ActualProcessor {};
Allen George8b96bfb2016-11-02 08:01:08 -040061///
62/// // construct the shared transport
Allen George0e22c362017-01-30 07:15:00 -050063/// let mut channel = TTcpChannel::new();
64/// channel.open("localhost:9090").unwrap();
65///
66/// let (i_chan, o_chan) = channel.split().unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -040067///
68/// // construct the actual input and output protocols
Allen George0e22c362017-01-30 07:15:00 -050069/// let mut i_prot = TBinaryInputProtocol::new(i_chan, true);
70/// let mut o_prot = TBinaryOutputProtocol::new(o_chan, true);
Allen George8b96bfb2016-11-02 08:01:08 -040071///
72/// // message identifier received from remote and modified to remove the service name
73/// let new_msg_ident = TMessageIdentifier::new("service_call", TMessageType::Call, 1);
74///
75/// // construct the proxy input protocol
76/// let mut proxy_i_prot = TStoredInputProtocol::new(&mut i_prot, new_msg_ident);
77/// let res = processor.process(&mut proxy_i_prot, &mut o_prot);
78/// ```
Allen George0e22c362017-01-30 07:15:00 -050079// FIXME: implement Debug
Allen George8b96bfb2016-11-02 08:01:08 -040080pub 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(...)`.
Allen George0e22c362017-01-30 07:15:00 -050091 pub fn new(
92 wrapped: &mut TInputProtocol,
93 message_ident: TMessageIdentifier,
94 ) -> TStoredInputProtocol {
Allen George8b96bfb2016-11-02 08:01:08 -040095 TStoredInputProtocol {
96 inner: wrapped,
97 message_ident: message_ident.into(),
98 }
99 }
100}
101
102impl<'a> TInputProtocol for TStoredInputProtocol<'a> {
103 fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
Allen George0e22c362017-01-30 07:15:00 -0500104 self.message_ident
105 .take()
106 .ok_or_else(
107 || {
108 ::errors::new_protocol_error(
109 ProtocolErrorKind::Unknown,
110 "message identifier already read",
111 )
112 },
113 )
Allen George8b96bfb2016-11-02 08:01:08 -0400114 }
115
116 fn read_message_end(&mut self) -> ::Result<()> {
117 self.inner.read_message_end()
118 }
119
120 fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
121 self.inner.read_struct_begin()
122 }
123
124 fn read_struct_end(&mut self) -> ::Result<()> {
125 self.inner.read_struct_end()
126 }
127
128 fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
129 self.inner.read_field_begin()
130 }
131
132 fn read_field_end(&mut self) -> ::Result<()> {
133 self.inner.read_field_end()
134 }
135
136 fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
137 self.inner.read_bytes()
138 }
139
140 fn read_bool(&mut self) -> ::Result<bool> {
141 self.inner.read_bool()
142 }
143
144 fn read_i8(&mut self) -> ::Result<i8> {
145 self.inner.read_i8()
146 }
147
148 fn read_i16(&mut self) -> ::Result<i16> {
149 self.inner.read_i16()
150 }
151
152 fn read_i32(&mut self) -> ::Result<i32> {
153 self.inner.read_i32()
154 }
155
156 fn read_i64(&mut self) -> ::Result<i64> {
157 self.inner.read_i64()
158 }
159
160 fn read_double(&mut self) -> ::Result<f64> {
161 self.inner.read_double()
162 }
163
164 fn read_string(&mut self) -> ::Result<String> {
165 self.inner.read_string()
166 }
167
168 fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
169 self.inner.read_list_begin()
170 }
171
172 fn read_list_end(&mut self) -> ::Result<()> {
173 self.inner.read_list_end()
174 }
175
176 fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
177 self.inner.read_set_begin()
178 }
179
180 fn read_set_end(&mut self) -> ::Result<()> {
181 self.inner.read_set_end()
182 }
183
184 fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
185 self.inner.read_map_begin()
186 }
187
188 fn read_map_end(&mut self) -> ::Result<()> {
189 self.inner.read_map_end()
190 }
191
192 // utility
193 //
194
195 fn read_byte(&mut self) -> ::Result<u8> {
196 self.inner.read_byte()
197 }
198}