GIOP_Message_Generator_Parser_12.cpp

Go to the documentation of this file.
00001 #include "tao/GIOP_Message_Generator_Parser_12.h"
00002 #include "tao/GIOPC.h"
00003 #include "tao/GIOP_Utils.h"
00004 #include "tao/GIOP_Message_Locate_Header.h"
00005 #include "tao/operation_details.h"
00006 #include "tao/debug.h"
00007 #include "tao/Pluggable_Messaging_Utils.h"
00008 #include "tao/GIOP_Message_State.h"
00009 #include "tao/TAO_Server_Request.h"
00010 #include "tao/TAOC.h"
00011 #include "tao/ORB_Core.h"
00012 #include "tao/Transport.h"
00013 #include "tao/CDR.h"
00014 
00015 ACE_RCSID (tao,
00016            GIOP_Message_Gen_Parser_12,
00017            "GIOP_Message_Generator_Parser_12.cpp,v 1.33 2006/04/20 12:37:17 jwillemsen Exp")
00018 
00019 // This is used by GIOP1.2. This is to align the message body on a
00020 // 8-octet boundary. This is declared static so that it is in file
00021 // scope.
00022 static const size_t TAO_GIOP_MESSAGE_ALIGN_PTR = 8;
00023 
00024 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00025 
00026 int
00027 TAO_GIOP_Message_Generator_Parser_12::write_request_header (
00028     const TAO_Operation_Details &opdetails,
00029     TAO_Target_Specification &spec,
00030     TAO_OutputCDR &msg
00031   )
00032 {
00033   // First the request id
00034   msg << opdetails.request_id ();
00035 
00036   const CORBA::Octet response_flags = opdetails.response_flags ();
00037 
00038 
00039   // Here are the Octet values for different policies
00040   // '00000000' for SYNC_NONE
00041   // '00000000' for SYNC_WITH_TRANSPORT
00042   // '00000010' for SYNC_WITH_SERVER
00043   // '00000011' for SYNC_WITH_TARGET
00044   // '00000011' for regular two ways, but if they are invoked via a
00045   // DII with INV_NO_RESPONSE flag set then we need to send '00000001'
00046   //
00047   // We have not implemented the policy INV_NO_RESPONSE for DII.
00048   if (response_flags == TAO_TWOWAY_RESPONSE_FLAG)
00049     msg << ACE_OutputCDR::from_octet (3);
00050   // Second the response flags
00051   // Sync scope - ignored by server if request is not oneway.
00052   else if (response_flags == CORBA::Octet (Messaging::SYNC_NONE)
00053            || response_flags == CORBA::Octet (Messaging::SYNC_WITH_TRANSPORT)
00054            || response_flags == CORBA::Octet (TAO::SYNC_EAGER_BUFFERING)
00055            || response_flags == CORBA::Octet (TAO::SYNC_DELAYED_BUFFERING))
00056     // No response required.
00057     msg << ACE_OutputCDR::from_octet (0);
00058 
00059   else if (response_flags == CORBA::Octet (Messaging::SYNC_WITH_SERVER))
00060     // Return before dispatching to the servant
00061     msg << ACE_OutputCDR::from_octet (1);
00062 
00063   else if (response_flags == CORBA::Octet (Messaging::SYNC_WITH_TARGET))
00064     // Return after dispatching servant.
00065     msg << ACE_OutputCDR::from_octet (3);
00066   else
00067     // Until more flags are defined by the OMG.
00068     return 0;
00069 
00070   // The reserved field
00071   CORBA::Octet reserved[3] = {0, 0, 0};
00072 
00073   msg.write_octet_array (reserved, 3);
00074 
00075   if (this->marshall_target_spec (spec,
00076                                   msg) == 0)
00077     return 0;
00078 
00079   // Write the operation name
00080   msg.write_string (opdetails.opname_len (),
00081                     opdetails.opname ());
00082 
00083   // Write the service context list
00084   msg << opdetails.request_service_info ();
00085 
00086   // We align the pointer only if the operation has arguments.
00087   if (opdetails.argument_flag ()
00088       && msg.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
00089     {
00090       return 0;
00091     }
00092 
00093   return 1;
00094 }
00095 
00096 
00097 int
00098 TAO_GIOP_Message_Generator_Parser_12::write_locate_request_header (
00099     CORBA::ULong request_id,
00100     TAO_Target_Specification    &spec,
00101     TAO_OutputCDR &msg
00102   )
00103 {
00104   // Write the request id
00105   msg << request_id;
00106 
00107   // Write the target address
00108   if (this->marshall_target_spec (spec,
00109                                   msg) == 0)
00110     return 0;
00111 
00112   // I dont think we need to align the pointer to an 8 byte boundary
00113   // here.
00114   // We need to align the pointer
00115   //  if (msg.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
00116   //  return 0;
00117 
00118   // Return success
00119   return 1;
00120 }
00121 
00122 int
00123 TAO_GIOP_Message_Generator_Parser_12::write_reply_header (
00124     TAO_OutputCDR & output,
00125     TAO_Pluggable_Reply_Params_Base &reply
00126     ACE_ENV_ARG_DECL_NOT_USED /* ACE_ENV_SINGLE_ARG_PARAMETER */
00127   )
00128     ACE_THROW_SPEC ((CORBA::SystemException))
00129 {
00130   // Write the request ID
00131   output.write_ulong (reply.request_id_);
00132 
00133    // Write the reply status
00134   if (reply.reply_status_ ==
00135       TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD_PERM)
00136     {
00137       // Not sure when we will use this.
00138       output.write_ulong (TAO_GIOP_LOCATION_FORWARD_PERM);
00139     }
00140   else if (reply.reply_status_ ==
00141            TAO_PLUGGABLE_MESSAGE_NEEDS_ADDRESSING_MODE)
00142     {
00143       // Not sure when we will use this.
00144       output.write_ulong (TAO_GIOP_LOC_NEEDS_ADDRESSING_MODE);
00145     }
00146   else
00147     {
00148       this->marshal_reply_status (output,
00149                                   reply);
00150     }
00151 
00152 #if (TAO_HAS_MINIMUM_CORBA == 1)
00153   output << reply.service_context_notowned ();
00154 #else
00155   if (reply.is_dsi_ == 0)
00156     {
00157       output << reply.service_context_notowned ();
00158     }
00159   else
00160     {
00161       IOP::ServiceContextList &svc_ctx =
00162         reply.service_context_notowned ();
00163       CORBA::ULong l = svc_ctx.length ();
00164 
00165       // Now marshal the rest of the service context objects
00166       output << l;
00167 
00168       for (CORBA::ULong i = 0; i != l; ++i)
00169         {
00170           output << svc_ctx[i];
00171         }
00172 
00173     }
00174 #endif /*TAO_HAS_MINIMUM_CORBA */
00175 
00176   if (reply.argument_flag_)
00177     {
00178       // If we have some data to be marshalled, then we align the
00179       // pointer to a 8 byte boundary.  Else, we just leave it throu
00180       if (output.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
00181         {
00182           return 0;
00183         }
00184     }
00185   return 1;
00186 }
00187 
00188 
00189 int
00190 TAO_GIOP_Message_Generator_Parser_12::write_locate_reply_mesg (
00191     TAO_OutputCDR & output,
00192     CORBA::ULong request_id,
00193     TAO_GIOP_Locate_Status_Msg &status_info
00194   )
00195 {
00196   output.write_ulong (request_id);
00197 
00198   // Make the header for the locate request
00199   output.write_ulong (status_info.status);
00200 
00201   // Note: We dont align the pointer to an 8 byte boundary for a
00202   // locate reply body. This is due to an urgent issue raised by Michi
00203   // in the OMG. I discussed this with Michi today (09/07/2001) and I
00204   // learn that this has been passed. Hence the change..
00205   /*
00206   if (status_info.status == TAO_GIOP_OBJECT_FORWARD ||
00207       status_info.status == TAO_GIOP_OBJECT_FORWARD_PERM)
00208     {
00209       // We have to send some data, so align the pointer
00210       if (output.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
00211         {
00212           return 0;
00213         }
00214     }
00215   */
00216   switch (status_info.status)
00217     {
00218     case TAO_GIOP_OBJECT_FORWARD:
00219 
00220       // More likely than not we will not have this in TAO
00221     case TAO_GIOP_OBJECT_FORWARD_PERM:
00222       {
00223         CORBA::Object_ptr object_ptr =
00224           status_info.forward_location_var.in ();
00225 
00226         if ((output << object_ptr) == 0)
00227         {
00228           if (TAO_debug_level > 0)
00229             {
00230               ACE_DEBUG ((
00231                   LM_DEBUG,
00232                   ACE_TEXT ("TAO (%P|%t|%N|%l) write_locate_reply_mesg-")
00233                   ACE_TEXT (" cannot marshal object reference\n")
00234                 ));
00235             }
00236         }
00237       }
00238       break;
00239     case TAO_GIOP_LOC_SYSTEM_EXCEPTION:
00240     case TAO_GIOP_LOC_NEEDS_ADDRESSING_MODE:
00241       // Do we do these in TAO??
00242       // What to do here???? I dont really know. I have to do a survey
00243       // of the specifications that uses this.
00244       break;
00245     default:
00246       break;
00247     }
00248 
00249   return 1;
00250 }
00251 
00252 bool
00253 TAO_GIOP_Message_Generator_Parser_12::write_fragment_header (
00254   TAO_OutputCDR & cdr,
00255   CORBA::ULong request_id)
00256 {
00257   return (cdr << request_id);
00258 
00259   // No need to align write pointer to an 8 byte boundary since it
00260   // should already be aligned (12 for GIOP messager + 4 for fragment
00261   // header = 16 -- a multiple of 8)
00262 }
00263 
00264 int
00265 TAO_GIOP_Message_Generator_Parser_12::parse_request_header (
00266     TAO_ServerRequest &request
00267   )
00268 {
00269   // Get the input CDR in the request class
00270   TAO_InputCDR & input = *request.incoming ();
00271 
00272   CORBA::Boolean hdr_status = (CORBA::Boolean) input.good_bit ();
00273 
00274   CORBA::ULong req_id = 0;
00275   // Get the rest of the request header ...
00276   hdr_status = hdr_status && input.read_ulong (req_id);
00277 
00278   request.request_id (req_id);
00279 
00280   CORBA::Octet response_flags = CORBA::Octet();
00281   hdr_status = hdr_status && input.read_octet (response_flags);
00282 
00283   request.response_expected ((response_flags > 0));
00284 
00285   // The high bit of the octet has been set if the SyncScope policy
00286   // value is SYNC_WITH_SERVER.
00287   request.sync_with_server ((response_flags == 1));
00288 
00289   // Reserved field
00290   input.skip_bytes (3);
00291 
00292   // Unmarshal the target address field.
00293   hdr_status =
00294     hdr_status && request.profile ().unmarshall_target_address(input);
00295 
00296   CORBA::ULong length = 0;
00297   hdr_status = hdr_status && input.read_ulong (length);
00298 
00299   if (hdr_status)
00300     {
00301       // Do not include NULL character at the end.
00302       // @@ This is not getting demarshaled using the codeset
00303       //    translators!
00304 
00305       // Notice that there are no memory allocations involved
00306       // here!
00307 
00308       request.operation (input.rd_ptr (),
00309                          length - 1,
00310                          0 /* TAO_ServerRequest does NOT own string */);
00311       hdr_status = input.skip_bytes (length);
00312     }
00313 
00314   // Tear out the service context ... we currently ignore it, but it
00315   // should probably be passed to each ORB service as appropriate
00316   // (e.g. transactions, security).
00317   //
00318   // NOTE: As security support kicks in, this is a good place to
00319   // verify a digital signature, if that is required in this security
00320   // environment.  It may be required even when using IPSEC security
00321   // infrastructure.
00322   IOP::ServiceContextList &req_service_info =
00323     request.request_service_info ();
00324 
00325   input >> req_service_info;
00326 
00327   // Check an process if BiDir contexts are available
00328   if (request.orb_core ()->bidir_giop_policy ())
00329     this->check_bidirectional_context (request);
00330 
00331   if (input.length () > 0)
00332     {
00333       // Reset the read_ptr to an 8-byte boundary.
00334       input.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
00335     }
00336 
00337   return hdr_status ? 0 : -1;
00338 }
00339 
00340 
00341 int
00342 TAO_GIOP_Message_Generator_Parser_12::parse_locate_header (
00343     TAO_GIOP_Locate_Request_Header &request
00344   )
00345 {
00346   // Get the stream .
00347   TAO_InputCDR &msg = request.incoming_stream ();
00348 
00349   CORBA::Boolean hdr_status = 1;
00350 
00351   // Get the request id.
00352   CORBA::ULong req_id = 0;
00353   hdr_status = msg.read_ulong (req_id);
00354 
00355   // Store it in the Locate request classes
00356   request.request_id (req_id);
00357 
00358   // Unmarshal the target address field.
00359   hdr_status =
00360     hdr_status && request.profile ().unmarshall_target_address(msg);
00361 
00362   // Reset the pointer to an 8-byte bouns]dary
00363   msg.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
00364 
00365   return hdr_status ? 0 : -1;
00366 }
00367 
00368 int
00369 TAO_GIOP_Message_Generator_Parser_12::parse_reply (
00370     TAO_InputCDR &cdr,
00371     TAO_Pluggable_Reply_Params &params
00372   )
00373 {
00374   if (TAO_GIOP_Message_Generator_Parser::parse_reply (cdr,
00375                                                       params) == -1)
00376 
00377     return -1;
00378 
00379   if ((cdr >> params.svc_ctx_) == 0)
00380     {
00381       // if (TAO_debug_level > 0)
00382         ACE_ERROR ((LM_ERROR,
00383                     ACE_TEXT ("TAO (%P|%t) parse_reply, ")
00384                     ACE_TEXT ("extracting context\n")));
00385 
00386       return -1;
00387     }
00388 
00389   if (cdr.length () > 0)
00390     {
00391       // Align the read pointer on an 8-byte boundary
00392       cdr.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
00393     }
00394 
00395   return 0;
00396 }
00397 
00398 int
00399 TAO_GIOP_Message_Generator_Parser_12::parse_locate_reply (
00400     TAO_InputCDR &cdr,
00401     TAO_Pluggable_Reply_Params &params
00402   )
00403 {
00404   if (TAO_GIOP_Message_Generator_Parser::parse_locate_reply (cdr,
00405                                                              params) == -1)
00406 
00407     return -1;
00408 
00409   // Note: We dont align the pointer to an 8 byte boundary for a
00410   // locate reply body. This is due to an urgent issue raised by Michi
00411   // in the OMG. I discussed this with Michi today (09/07/2001) and I
00412   // learn that this has been passed. Hence the change..
00413   /*if (cdr.length () > 0)
00414     {
00415       // Align the read pointer on an 8-byte boundary
00416       cdr.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
00417       }*/
00418 
00419   return 0;
00420 }
00421 
00422 
00423 CORBA::Octet
00424 TAO_GIOP_Message_Generator_Parser_12::major_version (void)
00425 {
00426   return (CORBA::Octet) 1;
00427 }
00428 
00429 
00430 CORBA::Octet
00431 TAO_GIOP_Message_Generator_Parser_12::minor_version (void)
00432 {
00433   return (CORBA::Octet) 2;
00434 }
00435 
00436 int
00437 TAO_GIOP_Message_Generator_Parser_12::is_ready_for_bidirectional (void)
00438 {
00439   // We do support bidirectional
00440   return 1;
00441 }
00442 
00443 
00444 
00445 int
00446 TAO_GIOP_Message_Generator_Parser_12::marshall_target_spec (
00447     TAO_Target_Specification &spec,
00448     TAO_OutputCDR &msg
00449   )
00450 {
00451   switch (spec.specifier ())
00452     {
00453     case TAO_Target_Specification::Key_Addr:
00454       {
00455         // As this is a union send in the discriminant first
00456         msg << GIOP::KeyAddr;
00457 
00458         // Get the object key
00459         const TAO::ObjectKey *key = spec.object_key ();
00460 
00461         if (key)
00462           {
00463             // Marshall in the object key
00464             msg << *key;
00465           }
00466         else
00467           {
00468             if (TAO_debug_level)
00469               ACE_DEBUG ((LM_DEBUG,
00470                           ACE_TEXT ("(%N |%l) Unable to handle this request \n")));
00471             return 0;
00472           }
00473         break;
00474       }
00475     case TAO_Target_Specification::Profile_Addr:
00476       {
00477         // As this is a union send in the discriminant first
00478         msg << GIOP::ProfileAddr;
00479 
00480         // Get the profile
00481         const IOP::TaggedProfile *pfile = spec.profile ();
00482 
00483         if (pfile)
00484           {
00485             // Marshall in the object key
00486             msg << *pfile;
00487           }
00488         else
00489           {
00490             if (TAO_debug_level)
00491               ACE_DEBUG ((LM_DEBUG,
00492                           ACE_TEXT ("(%N |%l) Unable to handle this request \n")));
00493             return 0;
00494           }
00495         break;
00496       }
00497     case TAO_Target_Specification::Reference_Addr:
00498       {
00499         // As this is a union send in the discriminant first
00500         msg << GIOP::ReferenceAddr;
00501 
00502         // Get the IOR
00503         IOP::IOR *ior;
00504         CORBA::ULong index = spec.iop_ior (ior);
00505 
00506         if (ior)
00507           {
00508             // This is a struct IORAddressingInfo. So, marshall each
00509             // member of the struct one after another in the order
00510             // defined.
00511             msg << index;
00512             msg << *ior;
00513           }
00514         else
00515           {
00516             if (TAO_debug_level)
00517               {
00518                 ACE_DEBUG ((LM_DEBUG,
00519                             ACE_TEXT ("(%N |%l) Unable to handle this request \n")));
00520               }
00521             return 0;
00522           }
00523         break;
00524       }
00525     default:
00526       if (TAO_debug_level)
00527         {
00528           ACE_DEBUG ((LM_DEBUG,
00529                       ACE_TEXT ("(%N |%l) Unable to handle this request \n")));
00530         }
00531       return 0;
00532     }
00533 
00534   return 1;
00535 }
00536 
00537 
00538 int
00539 TAO_GIOP_Message_Generator_Parser_12::check_bidirectional_context (
00540     TAO_ServerRequest &request)
00541 {
00542   TAO_Service_Context &service_context = request.request_service_context ();
00543 
00544   // Check whether we have the BiDir service context info available in
00545   // the ServiceContextList
00546   if (service_context.is_service_id (IOP::BI_DIR_IIOP)
00547       == 1)
00548     {
00549       return this->process_bidir_context (service_context,
00550                                           request.transport ());
00551     }
00552 
00553   return 0;
00554 }
00555 
00556 int
00557 TAO_GIOP_Message_Generator_Parser_12::process_bidir_context (
00558     TAO_Service_Context &service_context,
00559     TAO_Transport *transport)
00560 {
00561   // Get the context info
00562   IOP::ServiceContext context;
00563   context.context_id = IOP::BI_DIR_IIOP;
00564 
00565   if (service_context.get_context (context) != 1)
00566       ACE_ERROR_RETURN ((LM_ERROR,
00567                          ACE_TEXT ("(%P|%t) Context info not found \n")),
00568                         -1);
00569 
00570   TAO_InputCDR cdr (reinterpret_cast<const char*> (
00571                       context.context_data.get_buffer ()),
00572                     context.context_data.length ());
00573 
00574   return transport->tear_listen_point_list (cdr);
00575 }
00576 
00577 size_t
00578 TAO_GIOP_Message_Generator_Parser_12::fragment_header_length (void) const
00579 {
00580   return TAO_GIOP_MESSAGE_FRAGMENT_HEADER;
00581 }
00582 
00583 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 11:54:12 2006 for TAO by doxygen 1.3.6