Merge pull request #2303 from jwillemsen/jwi-803
[ACE_TAO.git] / TAO / tao / GIOP_Message_Generator_Parser_12.cpp
blob0dfc12ae0f41cf6c9d20aa16dd55c2b643d94111
1 // -*- C++ -*-
2 #include "tao/GIOP_Message_Generator_Parser_12.h"
3 #include "tao/GIOPC.h"
4 #include "tao/GIOP_Utils.h"
5 #include "tao/GIOP_Message_Locate_Header.h"
6 #include "tao/operation_details.h"
7 #include "tao/debug.h"
8 #include "tao/Pluggable_Messaging_Utils.h"
9 #include "tao/GIOP_Message_State.h"
10 #include "tao/TAO_Server_Request.h"
11 #include "tao/TAOC.h"
12 #include "tao/ORB_Core.h"
13 #include "tao/Transport.h"
14 #include "tao/CDR.h"
16 // This is used by GIOP1.2. This is to align the message body on a
17 // 8-octet boundary. This is declared static so that it is in file
18 // scope.
19 static constexpr size_t TAO_GIOP_MESSAGE_ALIGN_PTR = 8;
21 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
23 bool
24 TAO_GIOP_Message_Generator_Parser_12::write_request_header (
25 const TAO_Operation_Details &opdetails,
26 TAO_Target_Specification &spec,
27 TAO_OutputCDR &msg)
29 // First the request id
30 if (!(msg << opdetails.request_id ()))
31 return false;
33 CORBA::Octet const response_flags = opdetails.response_flags ();
35 // Here are the Octet values for different policies. See the meaning
36 // of response_flags of RequestHeader_1_2 in the CORBA specification as
37 // to why the values below are used.
38 // '00000000' for SYNC_NONE
39 // '00000000' for SYNC_WITH_TRANSPORT
40 // '00000001' for SYNC_WITH_SERVER
41 // '00000011' for SYNC_WITH_TARGET
42 // '00000011' for regular two ways, but if they are invoked via a
43 // DII with INV_NO_RESPONSE flag set then we need to send '00000001'
45 // We have not implemented the policy INV_NO_RESPONSE for DII.
46 if (response_flags == TAO_TWOWAY_RESPONSE_FLAG)
47 msg << ACE_OutputCDR::from_octet (3);
48 // Second the response flags
49 // Sync scope - ignored by server if request is not oneway.
50 else if (response_flags == CORBA::Octet (Messaging::SYNC_NONE)
51 || response_flags == CORBA::Octet (Messaging::SYNC_WITH_TRANSPORT)
52 || response_flags == CORBA::Octet (TAO::SYNC_DELAYED_BUFFERING))
53 // No response required.
54 msg << ACE_OutputCDR::from_octet (0);
56 else if (response_flags == CORBA::Octet (Messaging::SYNC_WITH_SERVER))
57 // Return before dispatching to the servant
58 msg << ACE_OutputCDR::from_octet (1);
60 else if (response_flags == CORBA::Octet (Messaging::SYNC_WITH_TARGET))
61 // Return after dispatching servant.
62 msg << ACE_OutputCDR::from_octet (3);
63 else
64 // Until more flags are defined by the OMG.
65 return false;
67 // The reserved field
68 CORBA::Octet reserved[3] = {0, 0, 0};
70 msg.write_octet_array (reserved, 3);
72 if (!this->marshall_target_spec (spec, msg))
73 return false;
75 // Write the operation name
76 msg.write_string (opdetails.opname_len (),
77 opdetails.opname ());
79 // Write the service context list
80 if (!(msg << opdetails.request_service_info ()))
81 return false;
83 // We align the pointer only if the operation has arguments.
84 if (opdetails.in_argument_flag ()
85 && msg.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
87 return false;
90 return true;
93 bool
94 TAO_GIOP_Message_Generator_Parser_12::write_locate_request_header (
95 CORBA::ULong request_id,
96 TAO_Target_Specification &spec,
97 TAO_OutputCDR &msg)
99 // Write the request id
100 if (!(msg << request_id))
101 return false;
103 // Write the target address
104 if (!(this->marshall_target_spec (spec, msg)))
105 return false;
107 // I dont think we need to align the pointer to an 8 byte boundary
108 // here.
109 // We need to align the pointer
110 // if (msg.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
111 // return 0;
113 // Return success
114 return true;
117 bool
118 TAO_GIOP_Message_Generator_Parser_12::write_reply_header (
119 TAO_OutputCDR & output,
120 TAO_Pluggable_Reply_Params_Base &reply)
122 // Write the request ID
123 if (!(output.write_ulong (reply.request_id_)))
124 return false;
126 // Write the reply status
127 if (!(output.write_ulong (reply.reply_status ())))
128 return false;
130 if (!(output << reply.service_context_notowned ()))
131 return false;
133 if (reply.argument_flag_)
135 // If we have some data to be marshalled, then we align the
136 // pointer to a 8 byte boundary. Else, we just leave it throu
137 if (output.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
139 return false;
142 return true;
145 bool
146 TAO_GIOP_Message_Generator_Parser_12::write_locate_reply_mesg (
147 TAO_OutputCDR & output,
148 CORBA::ULong request_id,
149 TAO_GIOP_Locate_Status_Msg &status_info)
151 if (!(output.write_ulong (request_id)))
152 return false;
154 // Make the header for the locate request
155 if (!(output.write_ulong (status_info.status)))
156 return false;
158 // Note: We dont align the pointer to an 8 byte boundary for a
159 // locate reply body. This is due to an urgent issue raised by Michi
160 // in the OMG. I discussed this with Michi today (09/07/2001) and I
161 // learn that this has been passed. Hence the change..
163 if (status_info.status == TAO_GIOP_OBJECT_FORWARD ||
164 status_info.status == TAO_GIOP_OBJECT_FORWARD_PERM)
166 // We have to send some data, so align the pointer
167 if (output.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
169 return false;
173 switch (status_info.status)
175 case GIOP::OBJECT_FORWARD:
177 // More likely than not we will not have this in TAO
178 case GIOP::OBJECT_FORWARD_PERM:
180 CORBA::Object_ptr object_ptr =
181 status_info.forward_location_var.in ();
183 if (!(output << object_ptr))
185 if (TAO_debug_level > 0)
187 TAOLIB_ERROR ((
188 LM_ERROR,
189 ACE_TEXT ("TAO (%P|%t|%N|%l) write_locate_reply_mesg-")
190 ACE_TEXT (" cannot marshal object reference\n")
195 break;
196 case GIOP::LOC_SYSTEM_EXCEPTION:
197 case GIOP::LOC_NEEDS_ADDRESSING_MODE:
198 // Do we do these in TAO??
199 // What to do here???? I dont really know. I have to do a survey
200 // of the specifications that uses this.
201 break;
202 default:
203 break;
206 return true;
209 bool
210 TAO_GIOP_Message_Generator_Parser_12::write_fragment_header (
211 TAO_OutputCDR & cdr,
212 CORBA::ULong request_id)
214 return (cdr << request_id);
216 // No need to align write pointer to an 8 byte boundary since it
217 // should already be aligned (12 for GIOP messager + 4 for fragment
218 // header = 16 -- a multiple of 8)
222 TAO_GIOP_Message_Generator_Parser_12::parse_request_header (
223 TAO_ServerRequest &request)
225 // Get the input CDR in the request class
226 TAO_InputCDR & input = *request.incoming ();
228 CORBA::Boolean hdr_status = input.good_bit ();
230 CORBA::ULong req_id = 0;
231 // Get the rest of the request header ...
232 hdr_status = hdr_status && input.read_ulong (req_id);
234 request.request_id (req_id);
236 CORBA::Octet response_flags = CORBA::Octet();
237 hdr_status = hdr_status && input.read_octet (response_flags);
239 request.response_expected ((response_flags > 0));
241 // The high bit of the octet has been set if the SyncScope policy
242 // value is SYNC_WITH_SERVER.
243 request.sync_with_server ((response_flags == 1));
245 // Reserved field
246 input.skip_bytes (3);
248 // Unmarshal the target address field.
249 hdr_status =
250 hdr_status && request.profile ().unmarshall_target_address(input);
252 CORBA::ULong length = 0;
253 hdr_status = hdr_status && input.read_ulong (length);
255 if (hdr_status)
257 // Do not include NULL character at the end.
258 // @@ This is not getting demarshaled using the codeset
259 // translators!
261 // Notice that there are no memory allocations involved
262 // here!
263 request.operation (input.rd_ptr (),
264 length - 1,
265 0 /* TAO_ServerRequest does NOT own string */);
266 hdr_status = input.skip_bytes (length);
269 // Tear out the service context ... we currently ignore it, but it
270 // should probably be passed to each ORB service as appropriate
271 // (e.g. transactions, security).
273 // NOTE: As security support kicks in, this is a good place to
274 // verify a digital signature, if that is required in this security
275 // environment. It may be required even when using IPSEC security
276 // infrastructure.
277 IOP::ServiceContextList &req_service_info = request.request_service_info ();
279 if (!(input >> req_service_info))
281 if (TAO_debug_level)
283 TAOLIB_ERROR ((LM_ERROR,
284 ACE_TEXT ("TAO (%P|%t) parse_request_header, ")
285 ACE_TEXT ("extracting context\n")));
288 return -1;
291 if (req_service_info.length() > 0)
293 request.orb_core ()->service_context_registry ().
294 process_service_contexts (req_service_info, *(request.transport ()), &request);
297 if (input.length () > 0)
299 // Reset the read_ptr to an 8-byte boundary.
300 input.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
303 return hdr_status ? 0 : -1;
308 TAO_GIOP_Message_Generator_Parser_12::parse_locate_header (
309 TAO_GIOP_Locate_Request_Header &request)
311 // Get the stream .
312 TAO_InputCDR &msg = request.incoming_stream ();
314 // Get the request id.
315 CORBA::ULong req_id = 0;
316 CORBA::Boolean hdr_status = msg.read_ulong (req_id);
318 // Store it in the Locate request classes
319 request.request_id (req_id);
321 // Unmarshal the target address field.
322 hdr_status =
323 hdr_status && request.profile ().unmarshall_target_address(msg);
325 // Reset the pointer to an 8-byte bouns]dary
326 msg.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
328 return hdr_status ? 0 : -1;
332 TAO_GIOP_Message_Generator_Parser_12::parse_reply (
333 TAO_InputCDR &cdr,
334 TAO_Pluggable_Reply_Params &params)
336 if (TAO_GIOP_Message_Generator_Parser::parse_reply (cdr, params) == -1)
337 return -1;
339 if (!(cdr >> params.svc_ctx_))
341 if (TAO_debug_level)
343 TAOLIB_ERROR ((LM_ERROR,
344 ACE_TEXT ("TAO (%P|%t) parse_reply, ")
345 ACE_TEXT ("extracting context\n")));
348 return -1;
351 if (cdr.length () > 0)
353 // Align the read pointer on an 8-byte boundary
354 cdr.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
357 return 0;
361 TAO_GIOP_Message_Generator_Parser_12::parse_locate_reply (
362 TAO_InputCDR &cdr,
363 TAO_Pluggable_Reply_Params &params)
365 if (TAO_GIOP_Message_Generator_Parser::parse_locate_reply (cdr, params) == -1)
366 return -1;
368 // Note: We dont align the pointer to an 8 byte boundary for a
369 // locate reply body. This is due to an urgent issue raised by Michi
370 // in the OMG. I discussed this with Michi today (09/07/2001) and I
371 // learn that this has been passed. Hence the change..
372 /*if (cdr.length () > 0)
374 // Align the read pointer on an 8-byte boundary
375 cdr.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
378 return 0;
382 CORBA::Octet
383 TAO_GIOP_Message_Generator_Parser_12::major_version () const
385 return static_cast<CORBA::Octet> (1);
389 CORBA::Octet
390 TAO_GIOP_Message_Generator_Parser_12::minor_version () const
392 return static_cast<CORBA::Octet> (2);
395 bool
396 TAO_GIOP_Message_Generator_Parser_12::is_ready_for_bidirectional () const
398 // We do support bidirectional
399 return true;
402 bool
403 TAO_GIOP_Message_Generator_Parser_12::marshall_target_spec (
404 TAO_Target_Specification &spec,
405 TAO_OutputCDR &msg)
407 switch (spec.specifier ())
409 case TAO_Target_Specification::Key_Addr:
411 // As this is a union send in the discriminant first
412 if (!(msg << GIOP::KeyAddr))
413 return false;
415 // Get the object key
416 const TAO::ObjectKey *key = spec.object_key ();
418 if (key)
420 // Marshall in the object key
421 if (!(msg << *key))
422 return false;
424 else
426 if (TAO_debug_level)
428 TAOLIB_DEBUG ((LM_DEBUG,
429 ACE_TEXT ("(%N |%l) Unable to handle this request\n")));
431 return false;
433 break;
435 case TAO_Target_Specification::Profile_Addr:
437 // As this is a union send in the discriminant first
438 if (!(msg << GIOP::ProfileAddr))
439 return false;
441 // Get the profile
442 const IOP::TaggedProfile *pfile = spec.profile ();
444 if (pfile)
446 // Marshall in the object key
447 if (!(msg << *pfile))
448 return false;
450 else
452 if (TAO_debug_level)
454 TAOLIB_DEBUG ((LM_DEBUG,
455 ACE_TEXT ("(%N |%l) Unable to handle this request\n")));
457 return false;
459 break;
461 case TAO_Target_Specification::Reference_Addr:
463 // As this is a union send in the discriminant first
464 if (!(msg << GIOP::ReferenceAddr))
465 return false;
467 // Get the IOR
468 IOP::IOR *ior = nullptr;
469 CORBA::ULong const index = spec.iop_ior (ior);
471 if (ior)
473 // This is a struct IORAddressingInfo. So, marshall each
474 // member of the struct one after another in the order
475 // defined.
476 if (!(msg << index))
477 return false;
478 if (!(msg << *ior))
479 return false;
481 else
483 if (TAO_debug_level)
485 TAOLIB_DEBUG ((LM_DEBUG,
486 ACE_TEXT ("(%N |%l) Unable to handle this request\n")));
488 return false;
490 break;
492 default:
493 if (TAO_debug_level)
495 TAOLIB_DEBUG ((LM_DEBUG,
496 ACE_TEXT ("(%N |%l) Unable to handle this request\n")));
498 return false;
501 return true;
504 size_t
505 TAO_GIOP_Message_Generator_Parser_12::fragment_header_length () const
507 return TAO_GIOP_MESSAGE_FRAGMENT_HEADER;
510 TAO_END_VERSIONED_NAMESPACE_DECL