Updated logging to include the class/method so that it is more obvious where these...
[ACE_TAO.git] / TAO / tao / GIOP_Message_Generator_Parser_10.cpp
blobd5bb7996fa8768f754139a9fceb1d5d9175ba308
1 // -*- C++ -*-
2 #include "tao/GIOP_Message_Generator_Parser_10.h"
3 #include "tao/GIOP_Utils.h"
4 #include "tao/GIOP_Message_Locate_Header.h"
5 #include "tao/operation_details.h"
6 #include "tao/debug.h"
7 #include "tao/Pluggable_Messaging_Utils.h"
8 #include "tao/TAO_Server_Request.h"
9 #include "tao/ORB_Constants.h"
10 #include "tao/CDR.h"
11 #include "tao/SystemException.h"
13 #include "ace/Log_Msg.h"
14 #include <cstring>
16 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
18 bool
19 TAO_GIOP_Message_Generator_Parser_10::write_request_header (
20 const TAO_Operation_Details &opdetails,
21 TAO_Target_Specification &spec,
22 TAO_OutputCDR &msg)
24 // Write the service context list
25 if (!(msg << opdetails.request_service_info ()))
26 return false;
28 // The request ID
29 if (!(msg << opdetails.request_id ()))
30 return false;
32 CORBA::Octet const response_flags = opdetails.response_flags ();
34 // Write the response flags
35 if (response_flags == TAO_TWOWAY_RESPONSE_FLAG)
37 msg << ACE_OutputCDR::from_octet (1);
39 else
41 msg << ACE_OutputCDR::from_octet (0);
44 // In this case we cannot recognise anything other than the Object
45 // key as the address disposition variable. But we do a sanity check
46 // anyway.
47 const TAO::ObjectKey *key = spec.object_key ();
49 if (key)
51 // Put in the object key
52 msg << *key;
54 else
56 if (TAO_debug_level)
58 TAOLIB_ERROR ((LM_ERROR,
59 ACE_TEXT ("(%N |%l) Unable to handle this request\n")));
61 return false;
64 msg.write_string (opdetails.opname_len (), opdetails.opname ());
66 // Last element of request header is the principal; no portable way
67 // to get it, we just pass empty principal (convention: indicates
68 // "anybody"). Steps upward in security include passing an
69 // unverified user ID, and then verifying the message (i.e. a dummy
70 // service context entry is set up to hold a digital signature for
71 // this message, then patched shortly before it's sent).
73 /***** This has been deprecated in the 2.4 spec ******/
75 #if defined (TAO_PEER_REQUIRES_PRINCIPAL)
77 char username[BUFSIZ];
78 char *result =
79 ACE_OS::cuserid (username,
80 BUFSIZ);
82 if (result != 0)
84 const CORBA::ULong username_size =
85 static_cast<CORBA::ULong> (std::strlen (username));
87 CORBA::Octet *buffer =
88 CORBA::OctetSeq::allocbuf (username_size + 1);
90 ACE_OS::memcpy (buffer,
91 username,
92 username_size + 1);
94 req_principal.replace (username_size + 1,
95 username_size + 1,
96 buffer,
97 1);
100 #else
102 CORBA::OctetSeq req_principal (0);
103 req_principal.length (0);
105 #endif /* TAO_PEER_REQUIRES_PRINCIPAL */
107 msg << req_principal;
109 return true;
112 bool
113 TAO_GIOP_Message_Generator_Parser_10::write_locate_request_header (
114 CORBA::ULong request_id,
115 TAO_Target_Specification &spec,
116 TAO_OutputCDR &msg)
118 msg << request_id;
120 // In this case we cannot recognise anything other than the Object
121 // key as the address disposition variable. But we do a sanity check
122 // anyway.
123 const TAO::ObjectKey *key = spec.object_key ();
125 if (key)
127 // Everything is fine
128 msg << *key;
130 else
132 if (TAO_debug_level)
134 TAOLIB_ERROR ((LM_ERROR,
135 ACE_TEXT ("(%N | %l) Unable to handle this request\n")));
137 return false;
140 return true;
143 bool
144 TAO_GIOP_Message_Generator_Parser_10::write_reply_header (
145 TAO_OutputCDR &output,
146 TAO_Pluggable_Reply_Params_Base &reply)
148 // Write the service context list.
149 #if (TAO_HAS_MINIMUM_CORBA == 1)
150 if (!(output << reply.service_context_notowned ()))
151 return false;
152 #else
153 if (!reply.is_dsi_)
155 if (!(output << reply.service_context_notowned ()))
156 return false;
158 else
160 // If lazy evaluation is enabled then we are going to insert an
161 // extra node at the end of the service context list, just to
162 // force the appropriate padding.
163 // But first we take it out any of them..
164 CORBA::ULong count = 0;
165 IOP::ServiceContextList &svc_ctx = reply.service_context_notowned ();
166 CORBA::ULong const l = svc_ctx.length ();
167 CORBA::ULong i;
169 for (i = 0; i != l; ++i)
171 if (svc_ctx[i].context_id == TAO_SVC_CONTEXT_ALIGN)
173 continue;
176 ++count;
179 // Now increment it to account for the last dummy one...
180 ++count;
182 // Now marshal the rest of the service context objects
183 if (!(output << count))
184 return false;
186 for (i = 0; i != l; ++i)
188 if (svc_ctx[i].context_id == TAO_SVC_CONTEXT_ALIGN)
190 continue;
193 if (!(output << svc_ctx[i]))
194 return false;
199 if (reply.is_dsi_ == true)
201 // @@ Much of this code is GIOP 1.1 specific and should be
202 ptrdiff_t target = reply.dsi_nvlist_align_;
204 ptrdiff_t const current =
205 ptrdiff_t (output.current_alignment ()) % ACE_CDR::MAX_ALIGNMENT;
207 CORBA::ULong pad = 0;
209 if (target == 0)
211 // We want to generate adequate padding to start the request
212 // id on a 8 byte boundary, two cases:
213 // - If the dummy tag starts on a 4 byte boundary and the
214 // dummy sequence has 0 elements then we have:
215 // 4:tag 8:sequence_length 4:sequence_body 4:request_id
216 // 8:payload
217 // - If the dummy tag starts on an 8 byte boundary, with 4
218 // elements we get:
219 // 8:tag 4:sequence_length 8:sequence_body 4:request_id
220 // 8:payload
221 if (current != 0 && current <= ACE_CDR::LONG_ALIGN)
223 pad = 4;
226 else if (target != ACE_CDR::LONG_ALIGN)
228 // The situation reverses, we want to generate adequate
229 // padding to start the request id on a 4 byte boundary, two
230 // cases:
231 // - If the dummy tag starts on a 4 byte boundary and the
232 // dummy sequence has 4 elements then we have:
233 // 4:tag 8:sequence_length 4:sequence_body 8:request_id
234 // 4:payload
235 // - If the dummy tag starts on an 8 byte boundary, with 0
236 // elements we get:
237 // 8:tag 4:sequence_length 8:sequence_body 8:request_id
238 // 4:payload
239 if (current > ACE_CDR::LONG_ALIGN)
241 pad = 4;
244 else if (target == ACE_CDR::MAX_ALIGNMENT)
246 pad = 0;
248 else
250 // <target> can only have the values above
251 throw ::CORBA::MARSHAL ();
254 output << CORBA::ULong (TAO_SVC_CONTEXT_ALIGN);
255 output << pad;
257 for (CORBA::ULong j = 0; j != pad; ++j)
259 output << ACE_OutputCDR::from_octet(0);
262 #endif /* TAO_HAS_MINIMUM_CORBA */
264 // Write the request ID
265 output.write_ulong (reply.request_id_);
267 // Write the reply status
268 output.write_ulong (reply.reply_status ());
270 return true;
274 bool
275 TAO_GIOP_Message_Generator_Parser_10::write_locate_reply_mesg (
276 TAO_OutputCDR &output,
277 CORBA::ULong request_id,
278 TAO_GIOP_Locate_Status_Msg &status_info)
280 // Make the header for the locate request
281 output.write_ulong (request_id);
282 output.write_ulong (status_info.status);
284 if (status_info.status == GIOP::OBJECT_FORWARD)
286 CORBA::Object_ptr object_ptr = status_info.forward_location_var.in ();
288 if (!(output << object_ptr))
290 if (TAO_debug_level > 0)
292 TAOLIB_ERROR ((
293 LM_ERROR,
294 ACE_TEXT ("TAO (%P|%t|%N|%l) write_locate_reply_mesg-")
295 ACE_TEXT (" cannot marshal object reference\n")
298 return false;
302 return true;
305 bool
306 TAO_GIOP_Message_Generator_Parser_10::write_fragment_header (
307 TAO_OutputCDR & /* cdr */,
308 CORBA::ULong /* request_id */)
310 // GIOP fragments are not supported in GIOP 1.0.
311 return false;
316 TAO_GIOP_Message_Generator_Parser_10::parse_request_header (
317 TAO_ServerRequest &request)
319 // Tear out the service context ... we currently ignore it, but it
320 // should probably be passed to each ORB service as appropriate
321 // (e.g. transactions, security).
323 // NOTE: As security support kicks in, this is a good place to
324 // verify a digital signature, if that is required in this security
325 // environment. It may be required even when using IPSEC security
326 // infrastructure.
328 // Get the input CDR in the request class
329 TAO_InputCDR & input = *request.incoming ();
331 IOP::ServiceContextList &service_info = request.request_service_info ();
333 if (!(input >> service_info))
334 return -1;
336 CORBA::Boolean hdr_status = (CORBA::Boolean) input.good_bit ();
338 CORBA::ULong req_id = 0;
340 // Get the rest of the request header ...
341 hdr_status = hdr_status && input.read_ulong (req_id);
343 request.request_id (req_id);
345 CORBA::Octet response_flags = CORBA::Octet();
346 hdr_status = hdr_status && input.read_octet (response_flags);
347 request.response_expected ((response_flags != 0));
349 // This is not supported now in GIOP 1.1
350 request.sync_with_server (0);
352 // We use ad-hoc demarshalling here: there is no need to increase
353 // the reference count on the CDR message block, because this key
354 // will not outlive the request (or the message block).
356 hdr_status =
357 hdr_status && request.profile ().unmarshall_object_key (input);
359 // According to the CORBA 2.6.1 (and older) specification, the operation
360 // name is an IDL Identifier. Identifiers must be composed of ASCII letters,
361 // numbers, and underscores, starting with a letter. Based on this, and
362 // the fact that I could find no text explicitly requiring operation name
363 // translation, nor could others in the CORBA community, the operation name
364 // will not be translated regardless of the translation of other strings.
366 CORBA::ULong length = 0;
367 hdr_status = hdr_status && input.read_ulong (length);
369 if (hdr_status)
371 // Do not include NULL character at the end.
372 // @@ This is not getting demarshaled using the codeset
373 // translators!
375 // Notice that there are no memory allocations involved
376 // here!
377 request.operation (input.rd_ptr (),
378 length - 1,
379 0 /* TAO_ServerRequest does NOT own string */);
380 hdr_status = input.skip_bytes (length);
383 if (hdr_status)
385 /**** This has been deprecated in 2.4 ****/
386 /*CORBA::Principal_var principal;
388 input >> principal.out ();
390 request.requesting_principal (principal.in ()); */
392 CORBA::OctetSeq oct_seq;
393 input >> oct_seq;
394 request.requesting_principal (oct_seq);
395 hdr_status = (CORBA::Boolean) input.good_bit ();
398 return hdr_status ? 0 : -1;
402 TAO_GIOP_Message_Generator_Parser_10::parse_locate_header (
403 TAO_GIOP_Locate_Request_Header &request)
405 // Get the stream
406 TAO_InputCDR &msg = request.incoming_stream ();
408 // Get the request id
409 CORBA::ULong req_id = 0;
410 CORBA::Boolean hdr_status = msg.read_ulong (req_id);
412 // Store it in the Locate request classes
413 request.request_id (req_id);
415 // Get the object key
416 hdr_status = hdr_status && request.profile ().unmarshall_object_key (msg);
418 return hdr_status ? 0 : -1;
422 TAO_GIOP_Message_Generator_Parser_10::parse_reply (
423 TAO_InputCDR &cdr,
424 TAO_Pluggable_Reply_Params &params)
426 // Read the service context list first
427 if (!(cdr >> params.svc_ctx_))
429 if (TAO_debug_level > 0)
431 TAOLIB_ERROR ((LM_ERROR,
432 ACE_TEXT ("TAO (%P|%t) parse_reply, ")
433 ACE_TEXT ("extracting context\n")));
435 return -1;
438 // Call the base class for further processing
439 if (TAO_GIOP_Message_Generator_Parser::parse_reply (cdr, params) == -1)
440 return -1;
442 return 0;
447 TAO_GIOP_Message_Generator_Parser_10::parse_locate_reply (
448 TAO_InputCDR &cdr,
449 TAO_Pluggable_Reply_Params &params)
451 if (TAO_GIOP_Message_Generator_Parser::parse_locate_reply (cdr,
452 params) == -1)
454 return -1;
456 return 0;
459 CORBA::Octet
460 TAO_GIOP_Message_Generator_Parser_10::major_version () const
462 // Any harm in hardcoding??
463 return static_cast<CORBA::Octet> (1);
466 CORBA::Octet
467 TAO_GIOP_Message_Generator_Parser_10::minor_version () const
469 // Any harm in hardcoding??
470 return 0;
473 size_t
474 TAO_GIOP_Message_Generator_Parser_10::fragment_header_length () const
476 return 0;
479 TAO_END_VERSIONED_NAMESPACE_DECL