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            "$Id: GIOP_Message_Generator_Parser_12.cpp 80861 2008-03-07 13:48:34Z johnnyw $")
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 bool
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   // First the request id
00033   if (!(msg << opdetails.request_id ()))
00034     return false;
00035 
00036   CORBA::Octet const response_flags = opdetails.response_flags ();
00037 
00038   // Here are the Octet values for different policies
00039   // '00000000' for SYNC_NONE
00040   // '00000000' for SYNC_WITH_TRANSPORT
00041   // '00000010' for SYNC_WITH_SERVER
00042   // '00000011' for SYNC_WITH_TARGET
00043   // '00000011' for regular two ways, but if they are invoked via a
00044   // DII with INV_NO_RESPONSE flag set then we need to send '00000001'
00045   //
00046   // We have not implemented the policy INV_NO_RESPONSE for DII.
00047   if (response_flags == TAO_TWOWAY_RESPONSE_FLAG)
00048     msg << ACE_OutputCDR::from_octet (3);
00049   // Second the response flags
00050   // Sync scope - ignored by server if request is not oneway.
00051   else if (response_flags == CORBA::Octet (Messaging::SYNC_NONE)
00052            || response_flags == CORBA::Octet (Messaging::SYNC_WITH_TRANSPORT)
00053            || response_flags == CORBA::Octet (TAO::SYNC_DELAYED_BUFFERING))
00054     // No response required.
00055     msg << ACE_OutputCDR::from_octet (0);
00056 
00057   else if (response_flags == CORBA::Octet (Messaging::SYNC_WITH_SERVER))
00058     // Return before dispatching to the servant
00059     msg << ACE_OutputCDR::from_octet (1);
00060 
00061   else if (response_flags == CORBA::Octet (Messaging::SYNC_WITH_TARGET))
00062     // Return after dispatching servant.
00063     msg << ACE_OutputCDR::from_octet (3);
00064   else
00065     // Until more flags are defined by the OMG.
00066     return false;
00067 
00068   // The reserved field
00069   CORBA::Octet reserved[3] = {0, 0, 0};
00070 
00071   msg.write_octet_array (reserved, 3);
00072 
00073   if (!this->marshall_target_spec (spec, msg))
00074     return false;
00075 
00076   // Write the operation name
00077   msg.write_string (opdetails.opname_len (),
00078                     opdetails.opname ());
00079 
00080   // Write the service context list
00081   if (!(msg << opdetails.request_service_info ()))
00082     return false;
00083 
00084   // We align the pointer only if the operation has arguments.
00085   if (opdetails.argument_flag ()
00086       && msg.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
00087     {
00088       return false;
00089     }
00090 
00091   return true;
00092 }
00093 
00094 bool
00095 TAO_GIOP_Message_Generator_Parser_12::write_locate_request_header (
00096     CORBA::ULong request_id,
00097     TAO_Target_Specification &spec,
00098     TAO_OutputCDR &msg)
00099 {
00100   // Write the request id
00101   if (!(msg << request_id))
00102     return false;
00103 
00104   // Write the target address
00105   if (!(this->marshall_target_spec (spec, msg)))
00106     return false;
00107 
00108   // I dont think we need to align the pointer to an 8 byte boundary
00109   // here.
00110   // We need to align the pointer
00111   //  if (msg.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
00112   //  return 0;
00113 
00114   // Return success
00115   return true;
00116 }
00117 
00118 bool
00119 TAO_GIOP_Message_Generator_Parser_12::write_reply_header (
00120     TAO_OutputCDR & output,
00121     TAO_Pluggable_Reply_Params_Base &reply)
00122 {
00123   // Write the request ID
00124   output.write_ulong (reply.request_id_);
00125 
00126   // Write the reply status
00127   output.write_ulong (reply.reply_status ());
00128 
00129   if (!(output << reply.service_context_notowned ()))
00130     return false;
00131 
00132   if (reply.argument_flag_)
00133     {
00134       // If we have some data to be marshalled, then we align the
00135       // pointer to a 8 byte boundary.  Else, we just leave it throu
00136       if (output.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
00137         {
00138           return false;
00139         }
00140     }
00141   return true;
00142 }
00143 
00144 bool
00145 TAO_GIOP_Message_Generator_Parser_12::write_locate_reply_mesg (
00146     TAO_OutputCDR & output,
00147     CORBA::ULong request_id,
00148     TAO_GIOP_Locate_Status_Msg &status_info)
00149 {
00150   output.write_ulong (request_id);
00151 
00152   // Make the header for the locate request
00153   output.write_ulong (status_info.status);
00154 
00155   // Note: We dont align the pointer to an 8 byte boundary for a
00156   // locate reply body. This is due to an urgent issue raised by Michi
00157   // in the OMG. I discussed this with Michi today (09/07/2001) and I
00158   // learn that this has been passed. Hence the change..
00159   /*
00160   if (status_info.status == TAO_GIOP_OBJECT_FORWARD ||
00161       status_info.status == TAO_GIOP_OBJECT_FORWARD_PERM)
00162     {
00163       // We have to send some data, so align the pointer
00164       if (output.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
00165         {
00166           return false;
00167         }
00168     }
00169   */
00170   switch (status_info.status)
00171     {
00172     case GIOP::OBJECT_FORWARD:
00173 
00174       // More likely than not we will not have this in TAO
00175     case GIOP::OBJECT_FORWARD_PERM:
00176       {
00177         CORBA::Object_ptr object_ptr =
00178           status_info.forward_location_var.in ();
00179 
00180         if ( ! (output << object_ptr))
00181         {
00182           if (TAO_debug_level > 0)
00183             {
00184               ACE_ERROR ((
00185                   LM_ERROR,
00186                   ACE_TEXT ("TAO (%P|%t|%N|%l) write_locate_reply_mesg-")
00187                   ACE_TEXT (" cannot marshal object reference\n")
00188                 ));
00189             }
00190         }
00191       }
00192       break;
00193     case GIOP::LOC_SYSTEM_EXCEPTION:
00194     case GIOP::LOC_NEEDS_ADDRESSING_MODE:
00195       // Do we do these in TAO??
00196       // What to do here???? I dont really know. I have to do a survey
00197       // of the specifications that uses this.
00198       break;
00199     default:
00200       break;
00201     }
00202 
00203   return true;
00204 }
00205 
00206 bool
00207 TAO_GIOP_Message_Generator_Parser_12::write_fragment_header (
00208   TAO_OutputCDR & cdr,
00209   CORBA::ULong request_id)
00210 {
00211   return (cdr << request_id);
00212 
00213   // No need to align write pointer to an 8 byte boundary since it
00214   // should already be aligned (12 for GIOP messager + 4 for fragment
00215   // header = 16 -- a multiple of 8)
00216 }
00217 
00218 int
00219 TAO_GIOP_Message_Generator_Parser_12::parse_request_header (
00220     TAO_ServerRequest &request)
00221 {
00222   // Get the input CDR in the request class
00223   TAO_InputCDR & input = *request.incoming ();
00224 
00225   CORBA::Boolean hdr_status = (CORBA::Boolean) input.good_bit ();
00226 
00227   CORBA::ULong req_id = 0;
00228   // Get the rest of the request header ...
00229   hdr_status = hdr_status && input.read_ulong (req_id);
00230 
00231   request.request_id (req_id);
00232 
00233   CORBA::Octet response_flags = CORBA::Octet();
00234   hdr_status = hdr_status && input.read_octet (response_flags);
00235 
00236   request.response_expected ((response_flags > 0));
00237 
00238   // The high bit of the octet has been set if the SyncScope policy
00239   // value is SYNC_WITH_SERVER.
00240   request.sync_with_server ((response_flags == 1));
00241 
00242   // Reserved field
00243   input.skip_bytes (3);
00244 
00245   // Unmarshal the target address field.
00246   hdr_status =
00247     hdr_status && request.profile ().unmarshall_target_address(input);
00248 
00249   CORBA::ULong length = 0;
00250   hdr_status = hdr_status && input.read_ulong (length);
00251 
00252   if (hdr_status)
00253     {
00254       // Do not include NULL character at the end.
00255       // @@ This is not getting demarshaled using the codeset
00256       //    translators!
00257 
00258       // Notice that there are no memory allocations involved
00259       // here!
00260       request.operation (input.rd_ptr (),
00261                          length - 1,
00262                          0 /* TAO_ServerRequest does NOT own string */);
00263       hdr_status = input.skip_bytes (length);
00264     }
00265 
00266   // Tear out the service context ... we currently ignore it, but it
00267   // should probably be passed to each ORB service as appropriate
00268   // (e.g. transactions, security).
00269   //
00270   // NOTE: As security support kicks in, this is a good place to
00271   // verify a digital signature, if that is required in this security
00272   // environment.  It may be required even when using IPSEC security
00273   // infrastructure.
00274   IOP::ServiceContextList &req_service_info = request.request_service_info ();
00275 
00276   if (!(input >> req_service_info))
00277     {
00278       if (TAO_debug_level)
00279         {
00280           ACE_ERROR ((LM_ERROR,
00281                       ACE_TEXT ("TAO (%P|%t) parse_request_header, ")
00282                       ACE_TEXT ("extracting context\n")));
00283         }
00284 
00285       return -1;
00286     }
00287 
00288   if (req_service_info.length() > 0)
00289     {
00290       request.orb_core ()->service_context_registry ().
00291         process_service_contexts (request);
00292     }
00293 
00294   if (input.length () > 0)
00295     {
00296       // Reset the read_ptr to an 8-byte boundary.
00297       input.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
00298     }
00299 
00300   return hdr_status ? 0 : -1;
00301 }
00302 
00303 
00304 int
00305 TAO_GIOP_Message_Generator_Parser_12::parse_locate_header (
00306     TAO_GIOP_Locate_Request_Header &request)
00307 {
00308   // Get the stream .
00309   TAO_InputCDR &msg = request.incoming_stream ();
00310 
00311   // Get the request id.
00312   CORBA::ULong req_id = 0;
00313   CORBA::Boolean hdr_status = msg.read_ulong (req_id);
00314 
00315   // Store it in the Locate request classes
00316   request.request_id (req_id);
00317 
00318   // Unmarshal the target address field.
00319   hdr_status =
00320     hdr_status && request.profile ().unmarshall_target_address(msg);
00321 
00322   // Reset the pointer to an 8-byte bouns]dary
00323   msg.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
00324 
00325   return hdr_status ? 0 : -1;
00326 }
00327 
00328 int
00329 TAO_GIOP_Message_Generator_Parser_12::parse_reply (
00330     TAO_InputCDR &cdr,
00331     TAO_Pluggable_Reply_Params &params)
00332 {
00333   if (TAO_GIOP_Message_Generator_Parser::parse_reply (cdr, params) == -1)
00334     return -1;
00335 
00336   if (!(cdr >> params.svc_ctx_))
00337     {
00338       if (TAO_debug_level)
00339         {
00340           ACE_ERROR ((LM_ERROR,
00341                       ACE_TEXT ("TAO (%P|%t) parse_reply, ")
00342                       ACE_TEXT ("extracting context\n")));
00343         }
00344 
00345       return -1;
00346     }
00347 
00348   if (cdr.length () > 0)
00349     {
00350       // Align the read pointer on an 8-byte boundary
00351       cdr.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
00352     }
00353 
00354   return 0;
00355 }
00356 
00357 int
00358 TAO_GIOP_Message_Generator_Parser_12::parse_locate_reply (
00359     TAO_InputCDR &cdr,
00360     TAO_Pluggable_Reply_Params &params)
00361 {
00362   if (TAO_GIOP_Message_Generator_Parser::parse_locate_reply (cdr, params) == -1)
00363     return -1;
00364 
00365   // Note: We dont align the pointer to an 8 byte boundary for a
00366   // locate reply body. This is due to an urgent issue raised by Michi
00367   // in the OMG. I discussed this with Michi today (09/07/2001) and I
00368   // learn that this has been passed. Hence the change..
00369   /*if (cdr.length () > 0)
00370     {
00371       // Align the read pointer on an 8-byte boundary
00372       cdr.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
00373       }*/
00374 
00375   return 0;
00376 }
00377 
00378 
00379 CORBA::Octet
00380 TAO_GIOP_Message_Generator_Parser_12::major_version (void) const
00381 {
00382   return static_cast<CORBA::Octet> (1);
00383 }
00384 
00385 
00386 CORBA::Octet
00387 TAO_GIOP_Message_Generator_Parser_12::minor_version (void) const
00388 {
00389   return static_cast<CORBA::Octet> (2);
00390 }
00391 
00392 bool
00393 TAO_GIOP_Message_Generator_Parser_12::is_ready_for_bidirectional (void) const
00394 {
00395   // We do support bidirectional
00396   return true;
00397 }
00398 
00399 bool
00400 TAO_GIOP_Message_Generator_Parser_12::marshall_target_spec (
00401     TAO_Target_Specification &spec,
00402     TAO_OutputCDR &msg)
00403 {
00404   switch (spec.specifier ())
00405     {
00406     case TAO_Target_Specification::Key_Addr:
00407       {
00408         // As this is a union send in the discriminant first
00409         if (!(msg << GIOP::KeyAddr))
00410           return false;
00411 
00412         // Get the object key
00413         const TAO::ObjectKey *key = spec.object_key ();
00414 
00415         if (key)
00416           {
00417             // Marshall in the object key
00418             if (!(msg << *key))
00419               return false;
00420           }
00421         else
00422           {
00423             if (TAO_debug_level)
00424               {
00425                 ACE_DEBUG ((LM_DEBUG,
00426                             ACE_TEXT ("(%N |%l) Unable to handle this request\n")));
00427               }
00428             return false;
00429           }
00430         break;
00431       }
00432     case TAO_Target_Specification::Profile_Addr:
00433       {
00434         // As this is a union send in the discriminant first
00435         if (!(msg << GIOP::ProfileAddr))
00436           return false;
00437 
00438         // Get the profile
00439         const IOP::TaggedProfile *pfile = spec.profile ();
00440 
00441         if (pfile)
00442           {
00443             // Marshall in the object key
00444             if (!(msg << *pfile))
00445               return false;
00446           }
00447         else
00448           {
00449             if (TAO_debug_level)
00450               {
00451                 ACE_DEBUG ((LM_DEBUG,
00452                             ACE_TEXT ("(%N |%l) Unable to handle this request\n")));
00453               }
00454             return false;
00455           }
00456         break;
00457       }
00458     case TAO_Target_Specification::Reference_Addr:
00459       {
00460         // As this is a union send in the discriminant first
00461         if (!(msg << GIOP::ReferenceAddr))
00462           return false;
00463 
00464         // Get the IOR
00465         IOP::IOR *ior = 0;
00466         CORBA::ULong const index = spec.iop_ior (ior);
00467 
00468         if (ior)
00469           {
00470             // This is a struct IORAddressingInfo. So, marshall each
00471             // member of the struct one after another in the order
00472             // defined.
00473             if (!(msg << index))
00474               return false;
00475             if (!(msg << *ior))
00476               return false;;
00477           }
00478         else
00479           {
00480             if (TAO_debug_level)
00481               {
00482                 ACE_DEBUG ((LM_DEBUG,
00483                             ACE_TEXT ("(%N |%l) Unable to handle this request\n")));
00484               }
00485             return false;
00486           }
00487         break;
00488       }
00489     default:
00490       if (TAO_debug_level)
00491         {
00492           ACE_DEBUG ((LM_DEBUG,
00493                       ACE_TEXT ("(%N |%l) Unable to handle this request\n")));
00494         }
00495       return false;
00496     }
00497 
00498   return true;
00499 }
00500 
00501 size_t
00502 TAO_GIOP_Message_Generator_Parser_12::fragment_header_length (void) const
00503 {
00504   return TAO_GIOP_MESSAGE_FRAGMENT_HEADER;
00505 }
00506 
00507 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:37:52 2010 for TAO by  doxygen 1.4.7