Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / DynamicInterface / Server_Request.cpp
bloba2f01df03929fff899d73aa81d74b58fa5510902
1 // Implementation of the Dynamic Server Skeleton Interface.
3 #include "tao/DynamicInterface/Server_Request.h"
4 #include "tao/DynamicInterface/DII_Arguments.h"
5 #include "tao/DynamicInterface/Unknown_User_Exception.h"
6 #include "tao/PortableServer/Collocated_Arguments_Converter.h"
7 #include "tao/AnyTypeCode/NVList.h"
8 #include "tao/GIOP_Utils.h"
9 #include "tao/AnyTypeCode/Marshal.h"
10 #include "tao/AnyTypeCode/TypeCode.h"
11 #include "tao/AnyTypeCode/Any_Impl.h"
12 #include "tao/operation_details.h"
13 #include "tao/SystemException.h"
15 #if !defined (__ACE_INLINE__)
16 # include "tao/DynamicInterface/Server_Request.inl"
17 #endif /* ! __ACE_INLINE__ */
19 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
21 // Reference counting for DSI ServerRequest object.
22 CORBA::ULong
23 CORBA::ServerRequest::_incr_refcount ()
25 return ++this->refcount_;
28 CORBA::ULong
29 CORBA::ServerRequest::_decr_refcount ()
31 CORBA::ULong const new_count = --this->refcount_;
33 if (new_count == 0)
34 delete this;
36 return new_count;
39 CORBA::ServerRequest::ServerRequest (TAO_ServerRequest &orb_server_request)
40 : lazy_evaluation_ (false),
41 ctx_ (CORBA::Context::_nil ()),
42 params_ (CORBA::NVList::_nil ()),
43 retval_ (0),
44 exception_ (0),
45 refcount_ (1),
46 orb_server_request_ (orb_server_request),
47 sent_gateway_exception_ (false)
49 this->orb_server_request_.is_dsi ();
52 CORBA::ServerRequest::~ServerRequest ()
54 if (this->params_ != 0)
56 ::CORBA::release (this->params_);
59 delete this->retval_;
60 delete this->exception_;
63 // Unmarshal in/inout params, and set up to marshal the appropriate
64 // inout/out/return values later on.
65 void
66 CORBA::ServerRequest::arguments (CORBA::NVList_ptr &list)
68 // arguments() must be called before either of these.
69 if (this->params_ != 0 || this->exception_ != 0)
71 throw ::CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 7, CORBA::COMPLETED_NO);
74 // In a collocated situation there will not be an incoming CDR stream
75 // in which case we can get the arguments from the
76 // operation_details using the 'collocated argument converter'.
77 if (this->orb_server_request_.collocated ())
79 this->params_ = list;
81 if (this->orb_server_request_.operation_details ()->cac () != 0)
83 TAO_OutputCDR output;
84 this->orb_server_request_.operation_details ()->cac (
85 )->dsi_convert_request (this->orb_server_request_,
86 output);
88 TAO_InputCDR input(output);
89 this->params_->_tao_decode (input, CORBA::ARG_IN | CORBA::ARG_INOUT);
92 else
94 // Save params for later use when marshaling the reply.
95 this->params_ = list;
97 // in the case of a GIOP::LocateRequest there is no incoming CDR stream
98 // so skip any attempt to decode arguments (now or later)
99 if (this->orb_server_request_.incoming () != 0)
101 this->params_->_tao_incoming_cdr (*this->orb_server_request_.incoming (),
102 CORBA::ARG_IN | CORBA::ARG_INOUT,
103 this->lazy_evaluation_);
105 // Pass this alignment back to the TAO_ServerRequest.
106 this->orb_server_request_.dsi_nvlist_align (
107 this->params_->_tao_target_alignment ());
112 // Store the result value. There's either an exception, or a result,
113 // but not both of them. Results can be reported (at most once)
114 // only after the parameter list has been provided (maybe empty).
115 void
116 CORBA::ServerRequest::set_result (const CORBA::Any &value)
118 // Setting a result when another result already exists or if an exception
119 // exists or before the args have been processed is an error.
120 if (this->retval_ != 0 || this->exception_ != 0 || this->params_ == 0)
122 throw ::CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 8, CORBA::COMPLETED_NO);
125 ACE_NEW_THROW_EX (this->retval_,
126 CORBA::Any (value),
127 CORBA::NO_MEMORY ());
130 // NOTE: if "" is set, there has been a system exception,
131 // and it will take precedence over exceptions reported using the
132 // set_exception() mechanism of the ServerRequest, which we assume
133 // the application writer will use to report only user exceptions.
134 // If both types of exception happen on the same invocation, the user
135 // exception will be lost.
137 // Store the exception value.
138 void
139 CORBA::ServerRequest::set_exception (const CORBA::Any &value)
141 CORBA::TypeCode_var tc = value.type ();
143 CORBA::TCKind const kind = tc->kind ();
145 // set_exception() can be called at any time, but the Any arg MUST
146 // contain an exception.
147 if (kind != CORBA::tk_except)
149 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 21, CORBA::COMPLETED_MAYBE);
152 ACE_NEW_THROW_EX (this->exception_,
153 CORBA::Any (value),
154 CORBA::NO_MEMORY ());
156 this->orb_server_request_.reply_status (GIOP::USER_EXCEPTION);
159 // This method will be utilized by the DSI servant to marshal outgoing
160 // parameters.
161 void
162 CORBA::ServerRequest::dsi_marshal ()
164 // There was a user exception, no need to marshal any parameters.
165 if (this->sent_gateway_exception_)
167 return;
170 // In a collocated situation there is no outgoing CDR stream.
171 // So, in case of an exception we just raise the UnknownUserException
172 // and for a regular reply we use the 'collocated argument converter'.
173 if (this->orb_server_request_.collocated ())
175 if (this->orb_server_request_.reply_status () == GIOP::USER_EXCEPTION)
177 throw CORBA::UnknownUserException (*this->exception_);
179 else if (this->orb_server_request_.operation_details ()->cac () != 0)
181 TAO_OutputCDR output;
182 // marshal the return value if any
183 if (this->retval_ != 0)
185 this->retval_->impl ()->marshal_value (output);
188 // marshal the "inout" and "out" parameters.
189 if (this->params_ != 0)
191 this->params_->_tao_encode (
192 output,
193 CORBA::ARG_INOUT | CORBA::ARG_OUT);
196 TAO_InputCDR input (output);
197 // set reply parameters
198 this->orb_server_request_.operation_details ()->cac (
199 )->dsi_convert_reply (this->orb_server_request_,
200 input);
203 else
205 if (this->orb_server_request_.reply_status () == GIOP::NO_EXCEPTION)
207 // In DSI, we can't rely on the skeleton to do this.
208 if (this->retval_ == 0 && this->params_ == 0)
210 this->orb_server_request_.argument_flag (false);
213 this->orb_server_request_.init_reply ();
215 // Send the return value, if any.
216 if (this->retval_ != 0)
218 this->retval_->impl ()->marshal_value (
219 *this->orb_server_request_.outgoing ());
222 // Send the "inout" and "out" parameters.
223 if (this->params_ != 0)
225 this->params_->_tao_encode (
226 *this->orb_server_request_.outgoing (),
227 CORBA::ARG_INOUT | CORBA::ARG_OUT);
230 else
232 // This defaults to true, but just to be safe...
233 this->orb_server_request_.argument_flag (true);
235 // Write the reply header to the ORB request's outgoing CDR stream.
236 this->orb_server_request_.init_reply ();
238 this->exception_->impl ()->marshal_value (
239 *this->orb_server_request_.outgoing ());
243 // in case a deferred_reply is specified (like for GIOP::LocateRequest)
244 // do not send a reply here
245 if (!this->orb_server_request_.deferred_reply ())
247 this->orb_server_request_.tao_send_reply ();
251 void
252 CORBA::ServerRequest::gateway_exception_reply (ACE_CString &raw_exception)
254 // This defaults to 1, but just to be safe...
255 this->orb_server_request_.argument_flag (true);
257 // This reply path handles only user exceptions.
258 this->orb_server_request_.reply_status (GIOP::USER_EXCEPTION);
260 this->orb_server_request_.init_reply ();
262 // We know nothing about this exception, so we marshal it as a block
263 // of bytes. The outgoing stream's byte order has already been matched
264 // to the original source of the reply.
265 this->orb_server_request_.outgoing ()->write_octet_array (
266 reinterpret_cast<const CORBA::Octet *> (raw_exception.fast_rep ()),
267 static_cast<CORBA::ULong> (raw_exception.length () + ACE_CDR::MAX_ALIGNMENT));
269 // This will prevent the marshaling of any parameters into this reply.
270 this->sent_gateway_exception_ = true;
272 this->orb_server_request_.tao_send_reply ();
275 TAO_END_VERSIONED_NAMESPACE_DECL