summaryrefslogtreecommitdiff
path: root/TAO/tao/GIOP_Message_Generator_Parser_12.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/GIOP_Message_Generator_Parser_12.cpp')
-rw-r--r--TAO/tao/GIOP_Message_Generator_Parser_12.cpp572
1 files changed, 572 insertions, 0 deletions
diff --git a/TAO/tao/GIOP_Message_Generator_Parser_12.cpp b/TAO/tao/GIOP_Message_Generator_Parser_12.cpp
new file mode 100644
index 00000000000..2854acd6de4
--- /dev/null
+++ b/TAO/tao/GIOP_Message_Generator_Parser_12.cpp
@@ -0,0 +1,572 @@
+#include "tao/GIOP_Message_Generator_Parser_12.h"
+#include "tao/GIOPC.h"
+#include "tao/GIOP_Utils.h"
+#include "tao/GIOP_Message_Locate_Header.h"
+#include "tao/operation_details.h"
+#include "tao/debug.h"
+#include "tao/Pluggable_Messaging_Utils.h"
+#include "tao/GIOP_Message_State.h"
+#include "tao/TAO_Server_Request.h"
+#include "tao/TAOC.h"
+#include "tao/ORB_Core.h"
+#include "tao/Transport.h"
+#include "tao/CDR.h"
+
+ACE_RCSID (tao,
+ GIOP_Message_Gen_Parser_12,
+ "$Id$")
+
+// This is used by GIOP1.2. This is to align the message body on a
+// 8-octet boundary. This is declared static so that it is in file
+// scope.
+static const size_t TAO_GIOP_MESSAGE_ALIGN_PTR = 8;
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+bool
+TAO_GIOP_Message_Generator_Parser_12::write_request_header (
+ const TAO_Operation_Details &opdetails,
+ TAO_Target_Specification &spec,
+ TAO_OutputCDR &msg)
+{
+ // First the request id
+ msg << opdetails.request_id ();
+
+ CORBA::Octet const response_flags = opdetails.response_flags ();
+
+ // Here are the Octet values for different policies
+ // '00000000' for SYNC_NONE
+ // '00000000' for SYNC_WITH_TRANSPORT
+ // '00000010' for SYNC_WITH_SERVER
+ // '00000011' for SYNC_WITH_TARGET
+ // '00000011' for regular two ways, but if they are invoked via a
+ // DII with INV_NO_RESPONSE flag set then we need to send '00000001'
+ //
+ // We have not implemented the policy INV_NO_RESPONSE for DII.
+ if (response_flags == TAO_TWOWAY_RESPONSE_FLAG)
+ msg << ACE_OutputCDR::from_octet (3);
+ // Second the response flags
+ // Sync scope - ignored by server if request is not oneway.
+ else if (response_flags == CORBA::Octet (Messaging::SYNC_NONE)
+ || response_flags == CORBA::Octet (Messaging::SYNC_WITH_TRANSPORT)
+ || response_flags == CORBA::Octet (TAO::SYNC_EAGER_BUFFERING)
+ || response_flags == CORBA::Octet (TAO::SYNC_DELAYED_BUFFERING))
+ // No response required.
+ msg << ACE_OutputCDR::from_octet (0);
+
+ else if (response_flags == CORBA::Octet (Messaging::SYNC_WITH_SERVER))
+ // Return before dispatching to the servant
+ msg << ACE_OutputCDR::from_octet (1);
+
+ else if (response_flags == CORBA::Octet (Messaging::SYNC_WITH_TARGET))
+ // Return after dispatching servant.
+ msg << ACE_OutputCDR::from_octet (3);
+ else
+ // Until more flags are defined by the OMG.
+ return false;
+
+ // The reserved field
+ CORBA::Octet reserved[3] = {0, 0, 0};
+
+ msg.write_octet_array (reserved, 3);
+
+ if (this->marshall_target_spec (spec,
+ msg) == false)
+ return false;
+
+ // Write the operation name
+ msg.write_string (opdetails.opname_len (),
+ opdetails.opname ());
+
+ // Write the service context list
+ msg << opdetails.request_service_info ();
+
+ // We align the pointer only if the operation has arguments.
+ if (opdetails.argument_flag ()
+ && msg.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+TAO_GIOP_Message_Generator_Parser_12::write_locate_request_header (
+ CORBA::ULong request_id,
+ TAO_Target_Specification &spec,
+ TAO_OutputCDR &msg)
+{
+ // Write the request id
+ msg << request_id;
+
+ // Write the target address
+ if (this->marshall_target_spec (spec,
+ msg) == false)
+ return false;
+
+ // I dont think we need to align the pointer to an 8 byte boundary
+ // here.
+ // We need to align the pointer
+ // if (msg.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
+ // return 0;
+
+ // Return success
+ return true;
+}
+
+bool
+TAO_GIOP_Message_Generator_Parser_12::write_reply_header (
+ TAO_OutputCDR & output,
+ TAO_Pluggable_Reply_Params_Base &reply)
+{
+ // Write the request ID
+ output.write_ulong (reply.request_id_);
+
+ // Write the reply status
+ if (reply.reply_status_ ==
+ TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD_PERM)
+ {
+ // Not sure when we will use this.
+ output.write_ulong (TAO_GIOP_LOCATION_FORWARD_PERM);
+ }
+ else if (reply.reply_status_ ==
+ TAO_PLUGGABLE_MESSAGE_NEEDS_ADDRESSING_MODE)
+ {
+ // Not sure when we will use this.
+ output.write_ulong (TAO_GIOP_LOC_NEEDS_ADDRESSING_MODE);
+ }
+ else
+ {
+ this->marshal_reply_status (output,
+ reply);
+ }
+
+#if (TAO_HAS_MINIMUM_CORBA == 1)
+ output << reply.service_context_notowned ();
+#else
+ if (reply.is_dsi_ == false)
+ {
+ output << reply.service_context_notowned ();
+ }
+ else
+ {
+ IOP::ServiceContextList &svc_ctx =
+ reply.service_context_notowned ();
+ CORBA::ULong const l = svc_ctx.length ();
+
+ // Now marshal the rest of the service context objects
+ output << l;
+
+ for (CORBA::ULong i = 0; i != l; ++i)
+ {
+ output << svc_ctx[i];
+ }
+
+ }
+#endif /*TAO_HAS_MINIMUM_CORBA */
+
+ if (reply.argument_flag_)
+ {
+ // If we have some data to be marshalled, then we align the
+ // pointer to a 8 byte boundary. Else, we just leave it throu
+ if (output.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+TAO_GIOP_Message_Generator_Parser_12::write_locate_reply_mesg (
+ TAO_OutputCDR & output,
+ CORBA::ULong request_id,
+ TAO_GIOP_Locate_Status_Msg &status_info)
+{
+ output.write_ulong (request_id);
+
+ // Make the header for the locate request
+ output.write_ulong (status_info.status);
+
+ // Note: We dont align the pointer to an 8 byte boundary for a
+ // locate reply body. This is due to an urgent issue raised by Michi
+ // in the OMG. I discussed this with Michi today (09/07/2001) and I
+ // learn that this has been passed. Hence the change..
+ /*
+ if (status_info.status == TAO_GIOP_OBJECT_FORWARD ||
+ status_info.status == TAO_GIOP_OBJECT_FORWARD_PERM)
+ {
+ // We have to send some data, so align the pointer
+ if (output.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
+ {
+ return false;
+ }
+ }
+ */
+ switch (status_info.status)
+ {
+ case TAO_GIOP_OBJECT_FORWARD:
+
+ // More likely than not we will not have this in TAO
+ case TAO_GIOP_OBJECT_FORWARD_PERM:
+ {
+ CORBA::Object_ptr object_ptr =
+ status_info.forward_location_var.in ();
+
+ if ( ! (output << object_ptr))
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((
+ LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t|%N|%l) write_locate_reply_mesg-")
+ ACE_TEXT (" cannot marshal object reference\n")
+ ));
+ }
+ }
+ }
+ break;
+ case TAO_GIOP_LOC_SYSTEM_EXCEPTION:
+ case TAO_GIOP_LOC_NEEDS_ADDRESSING_MODE:
+ // Do we do these in TAO??
+ // What to do here???? I dont really know. I have to do a survey
+ // of the specifications that uses this.
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool
+TAO_GIOP_Message_Generator_Parser_12::write_fragment_header (
+ TAO_OutputCDR & cdr,
+ CORBA::ULong request_id)
+{
+ return (cdr << request_id);
+
+ // No need to align write pointer to an 8 byte boundary since it
+ // should already be aligned (12 for GIOP messager + 4 for fragment
+ // header = 16 -- a multiple of 8)
+}
+
+int
+TAO_GIOP_Message_Generator_Parser_12::parse_request_header (
+ TAO_ServerRequest &request)
+{
+ // Get the input CDR in the request class
+ TAO_InputCDR & input = *request.incoming ();
+
+ CORBA::Boolean hdr_status = (CORBA::Boolean) input.good_bit ();
+
+ CORBA::ULong req_id = 0;
+ // Get the rest of the request header ...
+ hdr_status = hdr_status && input.read_ulong (req_id);
+
+ request.request_id (req_id);
+
+ CORBA::Octet response_flags = CORBA::Octet();
+ hdr_status = hdr_status && input.read_octet (response_flags);
+
+ request.response_expected ((response_flags > 0));
+
+ // The high bit of the octet has been set if the SyncScope policy
+ // value is SYNC_WITH_SERVER.
+ request.sync_with_server ((response_flags == 1));
+
+ // Reserved field
+ input.skip_bytes (3);
+
+ // Unmarshal the target address field.
+ hdr_status =
+ hdr_status && request.profile ().unmarshall_target_address(input);
+
+ CORBA::ULong length = 0;
+ hdr_status = hdr_status && input.read_ulong (length);
+
+ if (hdr_status)
+ {
+ // Do not include NULL character at the end.
+ // @@ This is not getting demarshaled using the codeset
+ // translators!
+
+ // Notice that there are no memory allocations involved
+ // here!
+
+ request.operation (input.rd_ptr (),
+ length - 1,
+ 0 /* TAO_ServerRequest does NOT own string */);
+ hdr_status = input.skip_bytes (length);
+ }
+
+ // Tear out the service context ... we currently ignore it, but it
+ // should probably be passed to each ORB service as appropriate
+ // (e.g. transactions, security).
+ //
+ // NOTE: As security support kicks in, this is a good place to
+ // verify a digital signature, if that is required in this security
+ // environment. It may be required even when using IPSEC security
+ // infrastructure.
+ IOP::ServiceContextList &req_service_info =
+ request.request_service_info ();
+
+ input >> req_service_info;
+
+ // Check an process if BiDir contexts are available
+ if (request.orb_core ()->bidir_giop_policy ())
+ {
+ this->check_bidirectional_context (request);
+ }
+
+ if (input.length () > 0)
+ {
+ // Reset the read_ptr to an 8-byte boundary.
+ input.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
+ }
+
+ return hdr_status ? 0 : -1;
+}
+
+
+int
+TAO_GIOP_Message_Generator_Parser_12::parse_locate_header (
+ TAO_GIOP_Locate_Request_Header &request)
+{
+ // Get the stream .
+ TAO_InputCDR &msg = request.incoming_stream ();
+
+ CORBA::Boolean hdr_status = 1;
+
+ // Get the request id.
+ CORBA::ULong req_id = 0;
+ hdr_status = msg.read_ulong (req_id);
+
+ // Store it in the Locate request classes
+ request.request_id (req_id);
+
+ // Unmarshal the target address field.
+ hdr_status =
+ hdr_status && request.profile ().unmarshall_target_address(msg);
+
+ // Reset the pointer to an 8-byte bouns]dary
+ msg.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
+
+ return hdr_status ? 0 : -1;
+}
+
+int
+TAO_GIOP_Message_Generator_Parser_12::parse_reply (
+ TAO_InputCDR &cdr,
+ TAO_Pluggable_Reply_Params &params)
+{
+ if (TAO_GIOP_Message_Generator_Parser::parse_reply (cdr,
+ params) == -1)
+
+ return -1;
+
+ if ((cdr >> params.svc_ctx_) == 0)
+ {
+ // if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) parse_reply, ")
+ ACE_TEXT ("extracting context\n")));
+
+ return -1;
+ }
+
+ if (cdr.length () > 0)
+ {
+ // Align the read pointer on an 8-byte boundary
+ cdr.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
+ }
+
+ return 0;
+}
+
+int
+TAO_GIOP_Message_Generator_Parser_12::parse_locate_reply (
+ TAO_InputCDR &cdr,
+ TAO_Pluggable_Reply_Params &params)
+{
+ if (TAO_GIOP_Message_Generator_Parser::parse_locate_reply (cdr,
+ params) == -1)
+
+ return -1;
+
+ // Note: We dont align the pointer to an 8 byte boundary for a
+ // locate reply body. This is due to an urgent issue raised by Michi
+ // in the OMG. I discussed this with Michi today (09/07/2001) and I
+ // learn that this has been passed. Hence the change..
+ /*if (cdr.length () > 0)
+ {
+ // Align the read pointer on an 8-byte boundary
+ cdr.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
+ }*/
+
+ return 0;
+}
+
+
+CORBA::Octet
+TAO_GIOP_Message_Generator_Parser_12::major_version (void) const
+{
+ return static_cast<CORBA::Octet> (1);
+}
+
+
+CORBA::Octet
+TAO_GIOP_Message_Generator_Parser_12::minor_version (void) const
+{
+ return static_cast<CORBA::Octet> (2);
+}
+
+bool
+TAO_GIOP_Message_Generator_Parser_12::is_ready_for_bidirectional (void) const
+{
+ // We do support bidirectional
+ return true;
+}
+
+bool
+TAO_GIOP_Message_Generator_Parser_12::marshall_target_spec (
+ TAO_Target_Specification &spec,
+ TAO_OutputCDR &msg)
+{
+ switch (spec.specifier ())
+ {
+ case TAO_Target_Specification::Key_Addr:
+ {
+ // As this is a union send in the discriminant first
+ msg << GIOP::KeyAddr;
+
+ // Get the object key
+ const TAO::ObjectKey *key = spec.object_key ();
+
+ if (key)
+ {
+ // Marshall in the object key
+ msg << *key;
+ }
+ else
+ {
+ if (TAO_debug_level)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%N |%l) Unable to handle this request \n")));
+ }
+ return false;
+ }
+ break;
+ }
+ case TAO_Target_Specification::Profile_Addr:
+ {
+ // As this is a union send in the discriminant first
+ msg << GIOP::ProfileAddr;
+
+ // Get the profile
+ const IOP::TaggedProfile *pfile = spec.profile ();
+
+ if (pfile)
+ {
+ // Marshall in the object key
+ msg << *pfile;
+ }
+ else
+ {
+ if (TAO_debug_level)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%N |%l) Unable to handle this request \n")));
+ }
+ return false;
+ }
+ break;
+ }
+ case TAO_Target_Specification::Reference_Addr:
+ {
+ // As this is a union send in the discriminant first
+ msg << GIOP::ReferenceAddr;
+
+ // Get the IOR
+ IOP::IOR *ior = 0;
+ CORBA::ULong index = spec.iop_ior (ior);
+
+ if (ior)
+ {
+ // This is a struct IORAddressingInfo. So, marshall each
+ // member of the struct one after another in the order
+ // defined.
+ msg << index;
+ msg << *ior;
+ }
+ else
+ {
+ if (TAO_debug_level)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%N |%l) Unable to handle this request \n")));
+ }
+ return 0;
+ }
+ break;
+ }
+ default:
+ if (TAO_debug_level)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%N |%l) Unable to handle this request \n")));
+ }
+ return false;
+ }
+
+ return true;
+}
+
+
+bool
+TAO_GIOP_Message_Generator_Parser_12::check_bidirectional_context (
+ TAO_ServerRequest &request)
+{
+ TAO_Service_Context &service_context = request.request_service_context ();
+
+ // Check whether we have the BiDir service context info available in
+ // the ServiceContextList
+ if (service_context.is_service_id (IOP::BI_DIR_IIOP))
+ {
+ return this->process_bidir_context (service_context,
+ request.transport ());
+ }
+
+ return false;
+}
+
+bool
+TAO_GIOP_Message_Generator_Parser_12::process_bidir_context (
+ TAO_Service_Context &service_context,
+ TAO_Transport *transport)
+{
+ // Get the context info
+ IOP::ServiceContext context;
+ context.context_id = IOP::BI_DIR_IIOP;
+
+ if (service_context.get_context (context) != 1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) Context info not found \n")),
+ false);
+
+ TAO_InputCDR cdr (reinterpret_cast<const char*> (
+ context.context_data.get_buffer ()),
+ context.context_data.length ());
+
+ return transport->tear_listen_point_list (cdr);
+}
+
+size_t
+TAO_GIOP_Message_Generator_Parser_12::fragment_header_length (void) const
+{
+ return TAO_GIOP_MESSAGE_FRAGMENT_HEADER;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL