text: // $Id: URL_Addr.cpp 91673 2010-09-08 18:49:47Z johnnyw $
  
  #include "URL_Addr.h"
  #include "ace/Log_Msg.h"
  #include "ace/OS_NS_string.h"
  #include "ace/OS_NS_stdio.h"
  #include "ace/OS_NS_stdlib.h"
  #include "ace/OS_Memory.h"
  
  ACE_URL_Addr::ACE_URL_Addr (void)
    : path_name_ (0),
      addr_string_ (0),
      addr_string_len_ (0)
  {
  }
  
  int
  ACE_URL_Addr::addr_to_string (ACE_TCHAR *s,
                                size_t size,
                                int ipaddr_format) const
  {
    const size_t total_len =
      ACE_OS::strlen (ipaddr_format == 0 ?
                      this->get_host_name () :
                      this->get_host_addr ())
      + ACE_OS::strlen ("65536") // Assume the max port number.
      + ACE_OS::strlen (this->get_path_name ())
      + sizeof (':')
      + sizeof ('/')
      + sizeof ('\0'); // For trailing '\0'.
  
    if (size < total_len)
      return -1;
    else
      {
        ACE_OS::sprintf (s, ACE_TEXT ("%s:%d/%s"),
                         ACE_TEXT_CHAR_TO_TCHAR (ipaddr_format == 0
                                                 ? this->get_host_name ()
                                                 : this->get_host_addr ()),
                         this->get_port_number (),
                         this->get_path_name ());
        return 0;
      }
  }
  
  const ACE_TCHAR *
  ACE_URL_Addr::addr_to_string (int ipaddr_format) const
  {
    ACE_URL_Addr *this_ptr = const_cast<ACE_URL_Addr *> (this);
  
    size_t size =
      ACE_OS::strlen (ipaddr_format == 0 ?
                      this->get_host_name () :
                      this->get_host_addr ())
      + ACE_OS::strlen ("65536") // Assume the max port number.
      + ACE_OS::strlen (this->get_path_name ())
      + sizeof (':')
      + sizeof ('/')
      + sizeof ('\0'); // For trailing '\0'.
  
    if (size > this->addr_string_len_)
      {
        ACE_ALLOCATOR_RETURN (this_ptr->addr_string_,
                              (ACE_TCHAR *) ACE_OS::realloc ((void *) this->addr_string_,
                                                             size),
                              0);
        this_ptr->addr_string_len_ = size;
      }
    ACE_OS::sprintf (this->addr_string_,
                     ACE_TEXT ("%s:%d/%s"),
                     ACE_TEXT_CHAR_TO_TCHAR (ipaddr_format == 0
                                             ? this->get_host_name ()
                                            : this->get_host_addr ()),
                     this->get_port_number (),
                     this->get_path_name ());
    return this->addr_string_;
  }
  
  int
  ACE_URL_Addr::string_to_addr (const ACE_TCHAR *s,
                                int /* address_family */)
  {
    int result;
    ACE_TCHAR *t;
  
    // Need to make a duplicate since we'll be overwriting the string.
    ACE_ALLOCATOR_RETURN (t,
                          ACE_OS::strdup (s),
                          -1);
  
  
    // First split off the path_name.
  
    ACE_TCHAR *path_name = ACE_OS::strchr (t, ACE_TEXT ('/'));
    const ACE_TCHAR *name = ACE_TEXT ("index.html");
    if (path_name != 0)
      {
        if (ACE_OS::strlen (path_name + 1) > 0)
          name = path_name + 1;
  
        *path_name = '\0';
      }
  
    ACE_ALLOCATOR_RETURN (this->path_name_,
                          // Skip over '/'
                          ACE_OS::strdup (name),
                          -1);
  
    // Now handle the host address and port number.
    ACE_TCHAR *port_number = ACE_OS::strchr (t, ':');
  
    if (port_number == 0)
      {
        // Assume it's an ip-address or ip-number.
        result = this->ACE_INET_Addr::set (ACE_DEFAULT_HTTP_PORT,
                                           t);
      }
    else
      {
        *port_number = '\0';
        u_short port = (u_short) ACE_OS::atoi (port_number + 1); // Skip over ':'
        result = this->ACE_INET_Addr::set (port, t);
      }
  
    ACE_OS::free (ACE_MALLOC_T (t));
    return result;
  }
  
  ACE_URL_Addr::ACE_URL_Addr (const ACE_URL_Addr &addr)
    : ACE_INET_Addr (),
      path_name_ (0),
      addr_string_ (0),
      addr_string_len_ (0)
  {
    if (this->set (addr) == -1)
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("%p\n"),
                  ACE_TEXT ("ACE_URL_Addr::ACE_URL_Addr")));
  }
  
  int
  ACE_URL_Addr::set (const ACE_URL_Addr &addr)
  {
    ACE_OS::free (reinterpret_cast<void *> (const_cast<ACE_TCHAR *>
                                                        (this->path_name_)));
    ACE_OS::free (reinterpret_cast<void *> (const_cast<ACE_TCHAR *>
                                                        (this->addr_string_)));
    if (this->ACE_INET_Addr::set (addr) == -1)
      return -1;
    else
      {
        if (addr.path_name_)
          ACE_ALLOCATOR_RETURN (this->path_name_,
                                ACE_OS::strdup (addr.path_name_),
                                -1);
        if (addr.addr_string_)
          ACE_ALLOCATOR_RETURN (this->addr_string_,
                                ACE_OS::strdup (addr.addr_string_),
                                -1);
        this->addr_string_len_ =
          addr.addr_string_len_;
        return 0;
      }
  }
  
  void
  ACE_URL_Addr::operator= (const ACE_URL_Addr &addr)
  {
    if (this->set (addr) == -1)
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("%p\n"),
                  ACE_TEXT ("ACE_URL_Addr::ACE_URL_Addr")));
  }
  
  u_long
  ACE_URL_Addr::hash (void) const
  {
    u_long result = this->ACE_INET_Addr::hash ()
      + ACE::hash_pjw (this->get_path_name ());
  
    return result;
  }
  
  bool
  ACE_URL_Addr::operator== (const ACE_URL_Addr &addr) const
  {
    return ACE_OS::strcmp (addr.get_path_name (),
                           this->get_path_name ()) == 0
      && addr.get_port_number () == this->get_port_number ()
      && addr.get_ip_address () == this->get_ip_address ();
  }
  
  bool
  ACE_URL_Addr::operator!= (const ACE_URL_Addr &addr) const
  {
    return !(*this == addr);
  }
  
  ACE_URL_Addr::ACE_URL_Addr (const ACE_TCHAR *host_name,
                              const ACE_TCHAR *path_name,
                              u_short port)
    : ACE_INET_Addr (port, host_name),
      path_name_ (ACE_OS::strdup (path_name)),
      addr_string_ (0),
      addr_string_len_ (0)
  {
  }
  
  const ACE_TCHAR *
  ACE_URL_Addr::get_path_name (void) const
  {
    return this->path_name_;
  }
  
  ACE_URL_Addr::~ACE_URL_Addr (void)
  {
    ACE_OS::free (reinterpret_cast<void *> (const_cast<ACE_TCHAR *>
                                                        (this->path_name_)));
    ACE_OS::free (reinterpret_cast<void *> (const_cast<ACE_TCHAR *>
                                                        (this->addr_string_)));
    this->path_name_ = 0;
  }
  
  int
  ACE_URL_Addr::destroy (void)
  {
    // Commit suicide.
    delete this;
    return 0;
  }
  