1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 #ifndef ICE_INCOMING_H
6 #define ICE_INCOMING_H
7 
8 #include <Ice/InstanceF.h>
9 #include <Ice/ConnectionIF.h>
10 #include <Ice/ServantLocatorF.h>
11 #include <Ice/ServantManagerF.h>
12 #include <Ice/OutputStream.h>
13 #include <Ice/InputStream.h>
14 #include <Ice/Object.h>
15 #include <Ice/Current.h>
16 #include <Ice/IncomingAsyncF.h>
17 #include <Ice/ObserverHelper.h>
18 #include <Ice/ResponseHandlerF.h>
19 
20 #include <deque>
21 
22 #ifdef ICE_CPP11_MAPPING
23 
24 namespace Ice
25 {
26 
27 /**
28  * Base class for marshaled result structures, which are generated for operations having the
29  * marshaled-result metadata tag.
30  * \headerfile Ice/Ice.h
31  */
32 class ICE_API MarshaledResult
33 {
34 public:
35 
36     /**
37      * The constructor requires the Current object that was passed to the servant.
38      */
39     MarshaledResult(const Current& current);
40 
41     /**
42      * Obtains the output stream that is used to marshal the results.
43      * @return The output stream.
44      */
getOutputStream()45     std::shared_ptr<OutputStream> getOutputStream() const
46     {
47         return ostr;
48     }
49 
50 protected:
51 
52     /** The output stream used to marshal the results. */
53     std::shared_ptr<OutputStream> ostr;
54 };
55 
56 }
57 
58 #endif
59 
60 namespace IceInternal
61 {
62 
63 class ICE_API IncomingBase : private IceUtil::noncopyable
64 {
65 public:
66 
67     Ice::OutputStream* startWriteParams();
68     void endWriteParams();
69     void writeEmptyParams();
70     void writeParamEncaps(const Ice::Byte*, Ice::Int, bool);
71 
72 #ifdef ICE_CPP11_MAPPING
73     void setMarshaledResult(const Ice::MarshaledResult&);
74 #endif
75 
76     void response(bool);
77     void exception(const std::exception&, bool);
78     void exception(const std::string&, bool);
79 #if defined(_MSC_VER) && (_MSC_VER == 1500)
80     //
81     // COMPILERFIX v90 get confused with overloads above
82     // when passing a const char* as first argument.
83     //
exception(const char * msg,bool amd)84     void exception(const char* msg, bool amd)
85     {
86         exception(std::string(msg), amd);
87     }
88 #endif
89 
90 protected:
91 
92     IncomingBase(Instance*, ResponseHandler*, Ice::Connection*, const Ice::ObjectAdapterPtr&, bool, Ice::Byte, Ice::Int);
93     IncomingBase(IncomingBase&);
94 
95     void warning(const Ice::Exception&) const;
96     void warning(const std::string&) const;
97 
98     bool servantLocatorFinished(bool);
99 
100     void handleException(const std::exception&, bool);
101     void handleException(const std::string&, bool);
102 
103 #if defined(_MSC_VER) && (_MSC_VER == 1500)
104     //
105     // COMPILERFIX v90 get confused with overloads above
106     // when passing a const char* as first argument.
107     //
handleException(const char * msg,bool amd)108     void handleException(const char* msg, bool amd)
109     {
110         handleException(std::string(msg), amd);
111     }
112 #endif
113 
114     Ice::Current _current;
115     Ice::ObjectPtr _servant;
116     Ice::ServantLocatorPtr _locator;
117 #ifdef ICE_CPP11_MAPPING
118     ::std::shared_ptr<void> _cookie;
119 #else
120     Ice::LocalObjectPtr _cookie;
121 #endif
122     DispatchObserver _observer;
123     bool _response;
124     Ice::Byte _compress;
125     Ice::FormatType _format;
126     Ice::OutputStream _os;
127 
128     //
129     // Optimization. The request handler may not be deleted while a
130     // stack-allocated Incoming still holds it.
131     //
132     ResponseHandler* _responseHandler;
133 
134 #ifdef ICE_CPP11_MAPPING
135     using DispatchInterceptorCallbacks = std::deque<std::pair<std::function<bool()>,
136                                                               std::function<bool(std::exception_ptr)>>>;
137 #else
138     typedef std::deque<Ice::DispatchInterceptorAsyncCallbackPtr> DispatchInterceptorCallbacks;
139 #endif
140     DispatchInterceptorCallbacks _interceptorCBs;
141 };
142 
143 // TODO: fix this warning
144 #if defined(_MSC_VER) && (_MSC_VER >= 1900)
145 #   pragma warning(push)
146 #   pragma warning(disable:4239)
147 #endif
148 
149 class ICE_API Incoming : public IncomingBase
150 {
151 public:
152 
153     Incoming(Instance*, ResponseHandler*, Ice::Connection*, const Ice::ObjectAdapterPtr&, bool, Ice::Byte, Ice::Int);
154 
getCurrent()155     const Ice::Current& getCurrent()
156     {
157         return _current;
158     }
159 
160 #ifdef ICE_CPP11_MAPPING
161     void push(std::function<bool()>, std::function<bool(std::exception_ptr)>);
162 #else
163     void push(const Ice::DispatchInterceptorAsyncCallbackPtr&);
164 #endif
165     void pop();
166 
setAsync(const IncomingAsyncPtr & in)167     void setAsync(const IncomingAsyncPtr& in)
168     {
169         assert(!_inAsync);
170         _inAsync = in;
171     }
172 
173     void startOver();
174 
setFormat(Ice::FormatType format)175     void setFormat(Ice::FormatType format)
176     {
177         _format = format;
178     }
179 
180     void invoke(const ServantManagerPtr&, Ice::InputStream*);
181 
182     // Inlined for speed optimization.
skipReadParams()183     void skipReadParams()
184     {
185         _current.encoding = _is->skipEncapsulation();
186     }
startReadParams()187     Ice::InputStream* startReadParams()
188     {
189         //
190         // Remember the encoding used by the input parameters, we'll
191         // encode the response parameters with the same encoding.
192         //
193         _current.encoding = _is->startEncapsulation();
194         return _is;
195     }
endReadParams()196     void endReadParams() const
197     {
198         _is->endEncapsulation();
199     }
readEmptyParams()200     void readEmptyParams()
201     {
202         _current.encoding = _is->skipEmptyEncapsulation();
203     }
readParamEncaps(const Ice::Byte * & v,Ice::Int & sz)204     void readParamEncaps(const Ice::Byte*& v, Ice::Int& sz)
205     {
206         _current.encoding = _is->readEncapsulation(v, sz);
207     }
208 
209 private:
210 
211     friend class IncomingAsync;
212 
213     Ice::InputStream* _is;
214     Ice::Byte* _inParamPos;
215 
216     IncomingAsyncPtr _inAsync;
217 };
218 
219 #if defined(_MSC_VER) && (_MSC_VER >= 1900)
220 #   pragma warning(pop)
221 #endif
222 
223 }
224 
225 #endif
226