summaryrefslogtreecommitdiff
path: root/TAO/tao/GIOP_Message_Factory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/GIOP_Message_Factory.cpp')
-rw-r--r--TAO/tao/GIOP_Message_Factory.cpp446
1 files changed, 344 insertions, 102 deletions
diff --git a/TAO/tao/GIOP_Message_Factory.cpp b/TAO/tao/GIOP_Message_Factory.cpp
index 2b62bc0b6be..d61251fa1a0 100644
--- a/TAO/tao/GIOP_Message_Factory.cpp
+++ b/TAO/tao/GIOP_Message_Factory.cpp
@@ -42,55 +42,129 @@
// reported.
#include "tao/GIOP_Message_Factory.h"
+#include "tao/GIOP_Utils.h"
#include "tao/Any.h"
+#include "tao/ORB_Core.h"
#if !defined (__ACE_INLINE__)
# include "tao/GIOP_Message_Factory.i"
#endif /* __ACE_INLINE__ */
-TAO_GIOP_Message_Factory::TAO_GIOP_Message_Factory (void)
+
+
+//
+// Client Side Message Factory Methods
+//
+
+TAO_GIOP_Client_Message_Factory::TAO_GIOP_Client_Message_Factory (void)
{
}
-TAO_GIOP_Message_Factory::~TAO_GIOP_Message_Factory (void)
+TAO_GIOP_Client_Message_Factory::~TAO_GIOP_Client_Message_Factory (void)
{
}
-/*CORBA::Boolean
-TAO_GIOP_Message_Factory::start_message (const TAO_GIOP_Version &version,
- TAO_GIOP_Message_Factory::Message_Type t,
- TAO_OutputCDR &msg)
+int
+TAO_GIOP_Client_Message_Factory::handle_input (TAO_Transport *transport,
+ TAO_ORB_Core */*orb_core*/,
+ TAO_Message_State_Factory &mesg_state,
+ ACE_Time_Value *max_wait_time)
{
- msg.reset ();
-
- static CORBA::Octet magic[] =
- {
- // The following works on non-ASCII platforms, such as MVS (which
- // uses EBCDIC).
- 0x47, // 'G'
- 0x49, // 'I'
- 0x4f, // 'O'
- 0x50, // 'P'
- };
-
- static int magic_size = sizeof (magic)/sizeof (magic[0]);
- msg.write_octet_array (magic, magic_size);
- msg.write_octet (version.major);
- msg.write_octet (version.minor);
- msg.write_octet (TAO_ENCAP_BYTE_ORDER);
- msg.write_octet ((CORBA::Octet) type);
-
- // Write a dummy <size> later it is set to the right value...
- CORBA::ULong size = 0;
- msg.write_ulong (size);
+ TAO_GIOP_Message_State *state =
+ ACE_dynamic_cast (TAO_GIOP_Message_State *,
+ &mesg_state);
- return 1;
+ if (state->header_received () == 0)
+ {
+ if (TAO_GIOP_Utils::read_bytes_input (transport,
+ state->cdr,
+ TAO_GIOP_HEADER_LEN,
+ max_wait_time) == -1)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - %p\n"
+ "TAO_GIOP_Client_Message_Factory::handle_input"));
+ return -1;
+ }
+
+
+ if (this->parse_magic_bytes (state->cdr) == -1)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - %p\n"
+ "TAO_GIOP_Client_Message_Factory::handle_input, parse_bytes"));
+ return -1;
+ }
+
+ // Read the rest of the stuff. That should be read by the
+ // corresponding states
+ if (this->parse_header (state) == -1)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - %p\n"
+ "TAO_GIOP_Client_Message_Factory::handle_input"));
+ return -1;
+ }
+ }
+
+ size_t missing_data =
+ state->message_size - state->current_offset;
+
+
+ ssize_t n =
+ TAO_GIOP_Utils::read_buffer (transport,
+ state->cdr.rd_ptr () + state->current_offset,
+ missing_data,
+ max_wait_time);
+ if (n == -1)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - %p\n",
+ "TAO_GIOP_Client_Message_Factory::handle_input, read_buffer[1]"));
+ return -1;
+ }
+ else if (n == 0)
+ {
+ if (errno == EWOULDBLOCK)
+ return 0;
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - %p\n",
+ "TAO_GIOP_Client_Message::handle_input, read_buffer[2]"));
+ return -1;
+ }
+
+ state->current_offset += n;
+
+ if (state->current_offset == state->message_size)
+ {
+ if (TAO_debug_level >= 4)
+ {
+ size_t header_len = TAO_GIOP_HEADER_LEN;
+
+ // Need to include GIOPlite too.
+
+ char *buf = state->cdr.rd_ptr ();
+ buf -= header_len;
+ size_t msg_len = state->cdr.length () + header_len;
+ TAO_GIOP_Utils::dump_msg ("recv",
+ ACE_reinterpret_cast (u_char *,
+ buf),
+ msg_len);
+ }
+ }
+
+ return state->is_complete ();
}
-*/
+
CORBA::Boolean
-TAO_GIOP_Message_Factory::write_request_header (const IOP::ServiceContextList& /*svc_ctx*/,
+TAO_GIOP_Client_Message_Factory::write_request_header (const IOP::ServiceContextList& /*svc_ctx*/,
CORBA::ULong request_id,
CORBA::Octet response_flags,
TAO_Stub */*stub*/,
@@ -105,7 +179,7 @@ TAO_GIOP_Message_Factory::write_request_header (const IOP::ServiceContextList& /
// First the request id
msg << request_id;
-
+
// Second the response flags
switch (response_flags)
{
@@ -134,9 +208,7 @@ TAO_GIOP_Message_Factory::write_request_header (const IOP::ServiceContextList& /
// specific to GIOP 1.2. So some of the services would start
// using this at some point of time and we will have them here
// naturally out of a need.
-
default:
- // Until more flags are defined by the OMG.
return 0;
}
@@ -145,97 +217,267 @@ TAO_GIOP_Message_Factory::write_request_header (const IOP::ServiceContextList& /
-
-TAO_GIOP_Message_Factory::send_message (TAO_Transport *transport,
- TAO_OutputCDR &stream,
- ACE_Time_Value *max_wait_time = 0,
- TAO_Stub *stub = 0)
+int
+TAO_GIOP_Client_Message_Factory::send_message (TAO_Transport *transport,
+ TAO_OutputCDR &stream,
+ ACE_Time_Value *max_wait_time,
+ TAO_Stub *stub)
{
- // TAO_FUNCTION_PP_TIMEPROBE (TAO_GIOP_SEND_MESSAGE_START);
-
- // Ptr to first buffer.
- char *buf = (char *) stream.buffer ();
-
- // Length of all buffers.
- size_t total_len =
- stream.total_length ();
-
- // NOTE: Here would also be a fine place to calculate a digital
- // signature for the message and place it into a preallocated slot
- // in the "ServiceContext". Similarly, this is a good spot to
- // encrypt messages (or just the message bodies) if that's needed in
- // this particular environment and that isn't handled by the
- // networking infrastructure (e.g., IPSEC).
-
// Get the header length
size_t header_len = this->get_header_len ();
// Get the message size offset
size_t offset = this->get_message_size_offset ();
+
+ return TAO_GIOP_Utils::send_message (transport,
+ stream,
+ header_len,
+ offset,
+ max_wait_time,
+ stub);
+}
+
+
+
+//
+// Server Side Message Factory Methods
+//
+
+
+TAO_GIOP_Message_Acceptor::TAO_GIOP_Message_Acceptor (void)
+{
+ // Initialised...
+ this->accept_states_ = &(this->available_states_.giop_1_1_);
+
+}
+
+TAO_GIOP_Message_Acceptor::~TAO_GIOP_Message_Acceptor (void)
+{
+ //no-op
+}
+
+int
+TAO_GIOP_Message_Acceptor::handle_input (TAO_Transport *transport,
+ TAO_ORB_Core */*orb_core*/,
+ TAO_Message_State_Factory &mesg_state,
+ ACE_Time_Value *max_wait_time)
+{
+ TAO_GIOP_Message_State *state =
+ ACE_dynamic_cast (TAO_GIOP_Message_State *,
+ &mesg_state);
- CORBA::ULong bodylen = total_len - header_len;
-
-#if !defined (ACE_ENABLE_SWAP_ON_WRITE)
- *ACE_reinterpret_cast (CORBA::ULong *, buf + offset) = bodylen;
-#else
- if (!stream->do_byte_swap ())
- *ACE_reinterpret_cast (CORBA::ULong *,
- buf + offset) = bodylen;
- else
- ACE_CDR::swap_4 (ACE_reinterpret_cast (char *,
- &bodylen),
- buf + offset);
-#endif /* ACE_ENABLE_SWAP_ON_WRITE */
-
- // Strictly speaking, should not need to loop here because the
- // socket never gets set to a nonblocking mode ... some Linux
- // versions seem to need it though. Leaving it costs little.
- this->dump_msg ("send",
- ACE_reinterpret_cast (u_char *,
- buf),
- stream.length ());
-
- // This guarantees to send all data (bytes) or return an error.
- ssize_t n = transport->send (stub,
- stream.begin (),
- max_wait_time);
+ if (state->header_received () == 0)
+ {
+ if (TAO_GIOP_Utils::read_bytes_input (transport,
+ state->cdr,
+ TAO_GIOP_HEADER_LEN,
+ max_wait_time) == -1)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - %p\n"
+ "TAO_GIOP_Message_Acceptor::handle_input"));
+ return -1;
+ }
+
+ if (this->parse_magic_bytes (state->cdr,
+ state) == -1)
+ {
+ this->accept_states_->send_error (transport);
+
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - %p\n"
+ "TAO_GIOP_Message_Acceptor::handle_input, parse_bytes"));
+ return -1;
+ }
+
+ // Read the rest of the stuff. That should be read by the
+ // corresponding states
+ if (this->accept_states_->parse_header (state) == -1)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - %p\n"
+ "TAO_GIOP_Message_Acceptor::handle_input"));
+ return -1;
+ }
+ }
+
+ size_t missing_data =
+ state->message_size - state->current_offset;
+ ssize_t n =
+ TAO_GIOP_Utils::read_buffer (transport,
+ state->cdr.rd_ptr () + state->current_offset,
+ missing_data,
+ max_wait_time);
if (n == -1)
{
- if (TAO_orbdebug)
+ if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
- "TAO: (%P|%t) closing conn %d after fault %p\n",
- transport->handle (),
- "GIOP_Message_Factory::send_message ()"));
-
+ "TAO (%P|%t) - %p\n",
+ "TAO_GIOP_Message_Acceptor::handle_input, read_buffer[1]"));
return -1;
}
-
- // EOF.
- if (n == 0)
+ else if (n == 0)
{
- if (TAO_orbdebug)
+ if (errno == EWOULDBLOCK)
+ return 0;
+ if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
- "TAO: (%P|%t) GIOP::send_message () "
- "EOF, closing conn %d\n",
- transport->handle()));
+ "TAO (%P|%t) - %p\n",
+ "TAO_GIOP_Message_Acceptor::handle_input, read_buffer[2]"));
return -1;
}
- return 1;
+ state->current_offset += n;
+
+ if (state->current_offset == state->message_size)
+ {
+ if (TAO_debug_level >= 4)
+ {
+ size_t header_len = TAO_GIOP_HEADER_LEN;
+
+ // Need to include GIOPlite too.
+
+ char *buf = state->cdr.rd_ptr ();
+ buf -= header_len;
+ size_t msg_len = state->cdr.length () + header_len;
+ TAO_GIOP_Utils::dump_msg ("recv",
+ ACE_reinterpret_cast (u_char *,
+ buf),
+ msg_len);
+ }
+ }
+
+ return state->is_complete ();
}
-void
-TAO_GIOP_Message_Factory::dump_msg (const char */*label*/,
- const u_char */*ptr*/,
- size_t /*len*/)
+
+int
+TAO_GIOP_Message_Acceptor::
+process_connector_messages (TAO_Transport *transport,
+ TAO_ORB_Core *orb_core,
+ TAO_InputCDR &input,
+ CORBA::Octet message_type)
{
- if (TAO_debug_level >= 5)
+ char repbuf[ACE_CDR::DEFAULT_BUFSIZE];
+
+#if defined(ACE_HAS_PURIFY)
+ (void) ACE_OS::memset (repbuf,
+ '\0',
+ sizeof repbuf);
+#endif /* ACE_HAS_PURIFY */
+
+ TAO_OutputCDR output (repbuf,
+ sizeof repbuf,
+ TAO_ENCAP_BYTE_ORDER,
+ orb_core->output_cdr_buffer_allocator (),
+ orb_core->output_cdr_dblock_allocator (),
+ orb_core->orb_params ()->cdr_memcpy_tradeoff (),
+ orb_core->to_iso8859 (),
+ orb_core->to_unicode ());
+
+ switch (message_type)
{
- // I will have to print out all the relevant debug messages!!
- // Let me not wory about that now. I will get back to that at a
- // later date!!
+ case TAO_GIOP_REQUEST:
+ // Should be taken care by the state specific invocations. They
+ // could raise an exception or write things in the output CDR
+ // stream
+ this->accept_states_->process_connector_request (transport,
+ orb_core,
+ input,
+ output);
+ break;
+ case TAO_GIOP_LOCATEREQUEST:
+ this->accept_states_->process_connector_locate (transport,
+ orb_core,
+ input,
+ output);
+ break;
+ case TAO_GIOP_MESSAGERROR:
+ case TAO_GIOP_REPLY:
+ case TAO_GIOP_LOCATEREPLY:
+ case TAO_GIOP_CLOSECONNECTION:
+ default:
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) Illegal message received by server\n"));
+ return this->accept_states_->send_error (transport);
+ break;
}
+
+ return 0;
}
+int
+TAO_GIOP_Message_Acceptor::parse_magic_bytes (TAO_InputCDR &input,
+ TAO_GIOP_Message_State *state)
+{
+ // Grab the read pointer
+ char *buf = input.rd_ptr ();
+
+ // The values are hard-coded to support non-ASCII platforms.
+ if (!(buf [0] == 0x47 // 'G'
+ && buf [1] == 0x49 // 'I'
+ && buf [2] == 0x4f // 'O'
+ && buf [3] == 0x50)) // 'P'
+ {
+ // Could be GIOPlite..
+ //...
+
+ // For the present...
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) bad header, magic word [%c%c%c%c]\n",
+ buf[0],
+ buf[1],
+ buf[2],
+ buf[3]));
+ return -1;
+ }
+ state->giop_version.major = buf[TAO_GIOP_VERSION_MAJOR_OFFSET];
+ state->giop_version.minor = buf[TAO_GIOP_VERSION_MINOR_OFFSET];
+
+ // An extra variable?? Huh?? Can be removed??
+ CORBA::Octet major = state->giop_version.major;
+ CORBA::Octet minor = state->giop_version.minor;
+
+ if ((this->available_states_.check_major (major) == -1) ||
+ (this->available_states_.check_minor (minor) == -1))
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) bad version <%d.%d>\n",
+ major, minor));
+ return -1;
+ }
+
+ // Set the appropriate state
+ if (this->set_state (state) == -1)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t|%N|%l) Failure <error> in set_state ()\n"),
+ -1);
+ }
+ }
+
+ return 0;
+}
+
+
+int
+TAO_GIOP_Message_Acceptor::set_state (TAO_GIOP_Message_State * /*state*/)
+
+{
+ // Logic for selecting from a registry set should be here. Let me go
+ // first with normal stuff.
+ this->accept_states_ = &(this->available_states_.giop_1_1_);
+
+ return 1;
+}
+