Classes | Public Member Functions | Private Member Functions

TAO_CORBALOC_Parser Class Reference

Implements the <corbaloc:> IOR format. More...

#include <CORBALOC_Parser.h>

Inheritance diagram for TAO_CORBALOC_Parser:
Inheritance graph
[legend]
Collaboration diagram for TAO_CORBALOC_Parser:
Collaboration graph
[legend]

List of all members.

Classes

struct  parsed_endpoint

Public Member Functions

 TAO_CORBALOC_Parser (void)
 Constructor.
virtual ~TAO_CORBALOC_Parser (void)
 The destructor.
virtual bool match_prefix (const char *ior_string) const
virtual CORBA::Object_ptr parse_string (const char *ior, CORBA::ORB_ptr orb)
 Parse the ior-string that is passed.

Private Member Functions

CORBA::Object_ptr make_stub_from_mprofile (CORBA::ORB_ptr orb, TAO_MProfile &mprofile)
CORBA::Object_ptr parse_string_rir_helper (const char *corbaloc_name, CORBA::ORB_ptr orb)
 Gets the pointer to the key_string when the protocol used is RIR.
void make_canonical (const char *ior, size_t ior_len, ACE_CString &canonical_endpoint)

Detailed Description

Implements the <corbaloc:> IOR format.

This class implements the <corbaloc:> IOR format. It is dynamically loaded by the ORB and used to parse the string to separate the individual <obj_addr> from the list of object addresses <obj_addr_list>.

Definition at line 46 of file CORBALOC_Parser.h.


Constructor & Destructor Documentation

TAO_CORBALOC_Parser::TAO_CORBALOC_Parser ( void   ) 

Constructor.

TAO_CORBALOC_Parser::~TAO_CORBALOC_Parser ( void   )  [virtual]

The destructor.

Definition at line 36 of file CORBALOC_Parser.cpp.

{
}


Member Function Documentation

void TAO_CORBALOC_Parser::make_canonical ( const char *  ior,
size_t  ior_len,
ACE_CString canonical_endpoint 
) [private]

Definition at line 240 of file CORBALOC_Parser.cpp.

{
  const char *separator = ACE_OS::strchr (ior, ':');

  // A special case for handling iiop
  if (ior[0] != ':' && ACE_OS::strncmp (ior,iiop_token,iiop_token_len) != 0)
    {
      canonical_endpoint.set (separator+1,
                              prot_addr_len - (separator - ior) - 1,1);
      return;
    }

  const char *addr_base = separator+1;
  const char *addr_tail = ior + prot_addr_len;
  // skip past version, if any
  separator = ACE_OS::strchr (addr_base,'@');
  if (separator != 0 && separator < addr_tail)
    {
      canonical_endpoint.set (addr_base,(separator - addr_base)+1,1);
      addr_base = separator + 1;
    }
  else
    canonical_endpoint.clear ();

  ACE_CString raw_host;
  ACE_CString raw_port;
  separator = ACE_OS::strchr (addr_base,':');
#if defined (ACE_HAS_IPV6)
  // IPv6 numeric address in host string?

  // Check if this is an address containing a decimal IPv6 address representation.
  if (addr_base < addr_tail && addr_base[0] == '[')
    {
      // In this case we have to find the end of the numeric address and
      // start looking for the port separator from there.
      const char *cp_pos = ACE_OS::strchr(addr_base, ']');
      if (cp_pos == 0 || cp_pos >= addr_tail)
        {
          // No valid IPv6 address specified but that will come out later.
          if (TAO_debug_level > 0)
            {
              ACE_ERROR ((LM_ERROR,
                         ACE_TEXT ("\nTAO (%P|%t) TAO_CORBALOC_Parser: ")
                         ACE_TEXT ("Invalid IPv6 decimal address specified.\n")));
            }
          separator = 0;
        }
      else
        {
          if (cp_pos[1] == ':')    // Look for a port
            separator = cp_pos + 1;
          else
            separator = 0;
        }
    }
#endif /* ACE_HAS_IPV6 */

  if (separator != 0 && separator < addr_tail)
    {
      // we have a port number
      raw_host.set (addr_base, (separator - addr_base), 1);
      raw_port.set (separator, (addr_tail - separator), 1);
    }
  else
    {
      // we must default port #
      if (addr_base < addr_tail)
        raw_host.set (addr_base, (addr_tail - addr_base),1);
      raw_port.set (":2809");
    }

  if (raw_host.length() == 0)
    {
      ACE_INET_Addr host_addr;

      char tmp_host [MAXHOSTNAMELEN + 1];

      // If no host is specified: assign the default host, i.e. the
      // local host.
      if (host_addr.get_host_name (tmp_host,
                                   sizeof (tmp_host)) != 0)
        {
          // Can't get the IP address since the INET_Addr wasn't
          // initialized.  Just throw an exception.

          if (TAO_debug_level > 0)
            ACE_DEBUG ((LM_DEBUG,
                        ACE_TEXT ("TAO (%P|%t) ")
                        ACE_TEXT ("cannot determine hostname.\n")));

          throw ::CORBA::INV_OBJREF
                     (CORBA::SystemException::_tao_minor_code
                      (TAO::VMCID, EINVAL),
                      CORBA::COMPLETED_NO);
        }
      else
        {
          canonical_endpoint += tmp_host;
        }
    }
  else
    {
      canonical_endpoint += raw_host;
    }

  canonical_endpoint += raw_port;
}

CORBA::Object_ptr TAO_CORBALOC_Parser::make_stub_from_mprofile ( CORBA::ORB_ptr  orb,
TAO_MProfile mprofile 
) [private]

Make a stub from the MProfile that is created in parse_string_mprofile_helper. Using this stub, create an object reference which is sent to the application.

All is well, so release the stub object from its auto_ptr.

Return the object reference to the application.

Shouldnt come here: if so, return nil reference.

Definition at line 50 of file CORBALOC_Parser.cpp.

{
  // Create a TAO_Stub.
  TAO_Stub *data = orb->orb_core ()->create_stub ((const char *) 0, mprofile);

  TAO_Stub_Auto_Ptr safe_data (data);

  CORBA::Object_var obj = orb->orb_core ()->create_object (data);

  if (!CORBA::is_nil (obj.in ()))
    {
      /// All is well, so release the stub object from its
      /// auto_ptr.
      (void) safe_data.release ();

      /// Return the object reference to the application.
      return obj._retn ();
    }

  /// Shouldnt come here: if so, return nil reference.
  return CORBA::Object::_nil ();
}

bool TAO_CORBALOC_Parser::match_prefix ( const char *  ior_string  )  const [virtual]

= The IOR_Parser methods, please read the documentation in IOR_Parser.h

Implements TAO_IOR_Parser.

Definition at line 41 of file CORBALOC_Parser.cpp.

{
  // Check if the prefix is 'corbaloc:' and return the result.
  return (ACE_OS::strncmp (ior_string,
                           prefix,
                           prefix_len) == 0);
}

CORBA::Object_ptr TAO_CORBALOC_Parser::parse_string ( const char *  ior,
CORBA::ORB_ptr  orb 
) [virtual]

Parse the ior-string that is passed.

Implements TAO_IOR_Parser.

Definition at line 92 of file CORBALOC_Parser.cpp.

{
  // The decomposition of a corbaloc string is in Section 13.6.10.
  //
  // following the "corbaloc:"
  //  a comma separated list of <prot_addr> strings
  //    for each,
  // Separate out the key, delimited by '/'
  // Split out the various parts of our corbaloc string, comma-delimited
  // For each part
  //   Determine the protocol
  //     If rir, defer to another function and return the object
  //     If iiop, make the profile with <endpoint>:<port>/<key>
  //     If another protocol, use <remainder>/<key>
  //   Search through the collection of protocols for the correct one
  //     If not found, throw exception
  //     If found, make our_connector from it.
  //     our_connector->make_mprofile_unchecked (...);
  //     object = this->make_stub_from_mprofile (...);
  // Return the object

  // Skip the prefix.  We know it is there because this method is only
  // called if match_prefix() returns 1.
  ior += ACE_OS::strlen(prefix);

  //  First check for rir
  if (ACE_OS::strncmp (ior,rir_token,rir_token_len) == 0)
    return this->parse_string_rir_helper (ior,orb);

  // set up space for parsed endpoints. there will be at least 1, and
  // most likely commas will separate endpoints, although they could be
  // part of an endpoint address for some protocols.
  size_t max_endpoint_count = 1;
  for (const char *comma = ACE_OS::strchr (ior,',');
       comma;
       comma = ACE_OS::strchr (comma+1,','))
    ++max_endpoint_count;

  ACE_Array<parsed_endpoint> endpoints(max_endpoint_count);
  endpoints.size (0);

  // Get the Connector Registry from the ORB.
  TAO_Connector_Registry *conn_reg =
    orb->orb_core ()->connector_registry();

  while (1) { // will loop on comma only.
    size_t len = 0;
    size_t ndx = endpoints.size();
    endpoints.size(ndx+1);
    int uiop_compatible = 0;
    TAO_ConnectorSetIterator conn_iter = 0;
    for (conn_iter = conn_reg->begin();
         conn_iter != conn_reg->end() &&
           endpoints[ndx].profile_ == 0;
         conn_iter ++)
      {
        endpoints[ndx].profile_ =
          (*conn_iter)->corbaloc_scan(ior,len);

        if (endpoints[ndx].profile_)
          {
            endpoints[ndx].obj_key_sep_ =
              (*conn_iter)->object_key_delimiter();
            uiop_compatible = (endpoints[ndx].obj_key_sep_ == '|');
            this->make_canonical (ior,len,endpoints[ndx].prot_addr_);
            ior += len;
            break;
          }
      }

    if (endpoints[ndx].profile_ == 0)
      {
        if (TAO_debug_level)
          ACE_ERROR ((LM_ERROR,
                      ACE_TEXT("(%P|%t) TAO_CORBALOC_Parser::parse_string ")
                      ACE_TEXT("could not parse from %C"),
                      ior));
        throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 10, CORBA::COMPLETED_NO);
      }
    if (*ior == ',') // more endpoints follow
      {
        ++ior;
        continue;
      }

    if (*ior == '/') // found key separator
      {
        ++ior;
        break;
      }

    if (*ior == '\0') // no key separator appended, use default key
      {
        break;
      }

    if (uiop_compatible && *(ior - 1) == '|')
      // Assume this is an old uiop style corbaloc. No need to warn here,
      // the UIOP_Connector::corbaloc_scan already did.
      break;

    // anything else is a violation.
    if (TAO_debug_level)
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT("(%P|%t) TAO_CORBALOC_Parser::parse_string ")
                  ACE_TEXT("could not parse from %C"),
                  ior));
    throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 10, CORBA::COMPLETED_NO);
  } // end of while

  // At this point, ior points at the start of the object key
  ACE_CString obj_key (*ior ? ior : (const char *)"NameService");

  // now take the collection of endpoints along with the decoded key and
  // mix them together to get the mprofile.
  TAO_MProfile mprofile (endpoints.size());

  for (size_t i = 0; i < endpoints.size(); i++)
    {
      ACE_CString full_ep = endpoints[i].prot_addr_ +
        endpoints[i].obj_key_sep_ +
        obj_key;
      const char * str = full_ep.c_str();
      endpoints[i].profile_->parse_string (str);
      int share = orb->orb_core()->orb_params()->shared_profile();
      if (mprofile.give_profile(endpoints[i].profile_, share) != -1)
        endpoints[i].profile_ = 0;
      else
        {
          // Although this ought never happen, we want to make some
          // indication back to the caller, more as an audit trail than
          // anything else. The only failure possible is that there was
          // insufficient heap to allocate the mprofile, hence the
          // mprofile's size is 0, and give_profile fails.
          if (TAO_debug_level)
            ACE_ERROR ((LM_ERROR,
                        ACE_TEXT("(%P|%t) TAO_CORBALOC_Parser::parse_string ")
                        ACE_TEXT("mprofile.give_profile failed for i = %d\n"),
                        i));
          throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 10, CORBA::COMPLETED_NO);
        }
    }

  // Get an object stub out.
  return this->make_stub_from_mprofile (orb, mprofile);
}

CORBA::Object_ptr TAO_CORBALOC_Parser::parse_string_rir_helper ( const char *  corbaloc_name,
CORBA::ORB_ptr  orb 
) [private]

Gets the pointer to the key_string when the protocol used is RIR.

Definition at line 75 of file CORBALOC_Parser.cpp.

{
  // Pass the key string as an argument to resolve_initial_references.
  // NameService is the default if an empty key string is supplied.
  const char *objkey = ior + rir_token_len;
  if (*objkey == '/') // there is an explicit object key, which may
                      // validly be null.
    objkey++;

  CORBA::Object_var rir_obj =
    orb->resolve_initial_references (*objkey == '\0' ? "NameService" : objkey);

  return rir_obj._retn ();
}


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines