// @(#)root/base:$Id$
// Author: Fons Rademakers   16/12/96

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TInetAddress                                                         //
//                                                                      //
// This class represents an Internet Protocol (IP) address.             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TInetAddress.h"
#include "TClass.h"

ClassImp(TInetAddress)

//______________________________________________________________________________
TInetAddress::TInetAddress()
{
   // Default ctor. Used in case of unknown host. Not a valid address.

   fHostname  = "UnknownHost";
   AddAddress(0);
   fFamily    = -1;
   fPort      = -1;
}

//______________________________________________________________________________
TInetAddress::TInetAddress(const char *host, UInt_t addr, Int_t family, Int_t port)
{
   // Create TInetAddress. Private ctor. TInetAddress objects can only
   // be created via the friend classes TSystem, TServerSocket and TSocket.
   // Use the IsValid() method to check the validity of a TInetAddress.

   AddAddress(addr);
   if (!strcmp(host, "????") || !strcmp(host, "UnNamedHost"))
      fHostname = GetHostAddress();
   else
      fHostname = host;
   fFamily    = family;
   fPort      = port;
}

//______________________________________________________________________________
TInetAddress::TInetAddress(const TInetAddress &adr) : TObject(adr)
{
   // TInetAddress copy ctor.

   fHostname  = adr.fHostname;
   fFamily    = adr.fFamily;
   fPort      = adr.fPort;
   fAddresses = adr.fAddresses;
   fAliases   = adr.fAliases;
}

//______________________________________________________________________________
TInetAddress& TInetAddress::operator=(const TInetAddress &rhs)
{
   // TInetAddress assignment operator.

   if (this != &rhs) {
      TObject::operator=(rhs);
      fHostname  = rhs.fHostname;
      fFamily    = rhs.fFamily;
      fPort      = rhs.fPort;
      fAddresses = rhs.fAddresses;
      fAliases   = rhs.fAliases;
   }
   return *this;
}

//______________________________________________________________________________
UChar_t *TInetAddress::GetAddressBytes() const
{
   // Returns the raw IP address in host byte order. The highest
   // order byte position is in addr[0]. To be prepared for 64-bit
   // IP addresses an array of bytes is returned.
   // User must delete allocated memory.

   UChar_t *addr = new UChar_t[4];

   addr[0] = (UChar_t) ((fAddresses[0] >> 24) & 0xFF);
   addr[1] = (UChar_t) ((fAddresses[0] >> 16) & 0xFF);
   addr[2] = (UChar_t) ((fAddresses[0] >> 8) & 0xFF);
   addr[3] = (UChar_t)  (fAddresses[0] & 0xFF);

   return addr;
}

//______________________________________________________________________________
const char *TInetAddress::GetHostAddress(UInt_t addr)
{
   // Returns the IP address string "%d.%d.%d.%d", use it to convert
   // alternative addresses obtained via GetAddresses().
   // Copy string immediately, it will be reused. Static function.

   return Form("%d.%d.%d.%d", (addr >> 24) & 0xFF,
                              (addr >> 16) & 0xFF,
                              (addr >>  8) & 0xFF,
                               addr & 0xFF);
}

//______________________________________________________________________________
const char *TInetAddress::GetHostAddress() const
{
   // Returns the IP address string "%d.%d.%d.%d".
   // Copy string immediately, it will be reused.

   return GetHostAddress(fAddresses[0]);
}

//______________________________________________________________________________
void TInetAddress::Print(Option_t *) const
{
   // Print internet address as string.

   if (fPort == -1)
      Printf("%s/%s (not connected)", GetHostName(), GetHostAddress());
   else
      Printf("%s/%s (port %d)", GetHostName(), GetHostAddress(), fPort);

   int i = 0;
   AddressList_t::const_iterator ai;
   for (ai = fAddresses.begin(); ai != fAddresses.end(); ai++) {
      if (!i) printf("%s:", fAddresses.size() == 1 ? "Address" : "Addresses");
      printf(" %s", GetHostAddress(*ai));
      i++;
   }
   if (i) printf("\n");

   i = 0;
   AliasList_t::const_iterator ali;
   for (ali = fAliases.begin(); ali != fAliases.end(); ali++) {
      if (!i) printf("%s:", fAliases.size() == 1 ? "Alias" : "Aliases");
      printf(" %s", ali->Data());
      i++;
   }
   if (i) printf("\n");
}

//______________________________________________________________________________
void TInetAddress::AddAddress(UInt_t addr)
{
   // Add alternative address to list of addresses.

   fAddresses.push_back(addr);
}

//______________________________________________________________________________
void TInetAddress::AddAlias(const char *alias)
{
   // Add alias to list of aliases.

   fAliases.push_back(TString(alias));
}

//______________________________________________________________________________
void TInetAddress::Streamer(TBuffer &R__b)
{
   // Stream an object of class TInetAddress.

   if (R__b.IsReading()) {
      UInt_t R__s, R__c;
      Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
      if (R__v > 2) {
         R__b.ReadClassBuffer(TInetAddress::Class(), this, R__v, R__s, R__c);
         return;
      }
      // process old versions before automatic schema evolution
      UInt_t address;
      TObject::Streamer(R__b);
      fHostname.Streamer(R__b);
      R__b >> address;
      R__b >> fFamily;
      R__b >> fPort;
      if (R__v == 1)
         fAddresses.push_back(address);
      if (R__v > 1) {
         TInetAddress::AddressList_t &R__stl1 =  fAddresses;
         R__stl1.clear();
         int R__i, R__n;
         R__b >> R__n;
         R__stl1.reserve(R__n);
         for (R__i = 0; R__i < R__n; R__i++) {
            unsigned int R__t1;
            R__b >> R__t1;
            R__stl1.push_back(R__t1);
         }
         TInetAddress::AliasList_t &R__stl2 =  fAliases;
         R__stl2.clear();
         R__b >> R__n;
         R__stl2.reserve(R__n);
         for (R__i = 0; R__i < R__n; R__i++) {
            TString R__t2;
            R__t2.Streamer(R__b);
            R__stl2.push_back(R__t2);
         }
      }
      R__b.CheckByteCount(R__s, R__c, TInetAddress::IsA());
   } else {
      R__b.WriteClassBuffer(TInetAddress::Class(), this);
   }
}
 TInetAddress.cxx:1
 TInetAddress.cxx:2
 TInetAddress.cxx:3
 TInetAddress.cxx:4
 TInetAddress.cxx:5
 TInetAddress.cxx:6
 TInetAddress.cxx:7
 TInetAddress.cxx:8
 TInetAddress.cxx:9
 TInetAddress.cxx:10
 TInetAddress.cxx:11
 TInetAddress.cxx:12
 TInetAddress.cxx:13
 TInetAddress.cxx:14
 TInetAddress.cxx:15
 TInetAddress.cxx:16
 TInetAddress.cxx:17
 TInetAddress.cxx:18
 TInetAddress.cxx:19
 TInetAddress.cxx:20
 TInetAddress.cxx:21
 TInetAddress.cxx:22
 TInetAddress.cxx:23
 TInetAddress.cxx:24
 TInetAddress.cxx:25
 TInetAddress.cxx:26
 TInetAddress.cxx:27
 TInetAddress.cxx:28
 TInetAddress.cxx:29
 TInetAddress.cxx:30
 TInetAddress.cxx:31
 TInetAddress.cxx:32
 TInetAddress.cxx:33
 TInetAddress.cxx:34
 TInetAddress.cxx:35
 TInetAddress.cxx:36
 TInetAddress.cxx:37
 TInetAddress.cxx:38
 TInetAddress.cxx:39
 TInetAddress.cxx:40
 TInetAddress.cxx:41
 TInetAddress.cxx:42
 TInetAddress.cxx:43
 TInetAddress.cxx:44
 TInetAddress.cxx:45
 TInetAddress.cxx:46
 TInetAddress.cxx:47
 TInetAddress.cxx:48
 TInetAddress.cxx:49
 TInetAddress.cxx:50
 TInetAddress.cxx:51
 TInetAddress.cxx:52
 TInetAddress.cxx:53
 TInetAddress.cxx:54
 TInetAddress.cxx:55
 TInetAddress.cxx:56
 TInetAddress.cxx:57
 TInetAddress.cxx:58
 TInetAddress.cxx:59
 TInetAddress.cxx:60
 TInetAddress.cxx:61
 TInetAddress.cxx:62
 TInetAddress.cxx:63
 TInetAddress.cxx:64
 TInetAddress.cxx:65
 TInetAddress.cxx:66
 TInetAddress.cxx:67
 TInetAddress.cxx:68
 TInetAddress.cxx:69
 TInetAddress.cxx:70
 TInetAddress.cxx:71
 TInetAddress.cxx:72
 TInetAddress.cxx:73
 TInetAddress.cxx:74
 TInetAddress.cxx:75
 TInetAddress.cxx:76
 TInetAddress.cxx:77
 TInetAddress.cxx:78
 TInetAddress.cxx:79
 TInetAddress.cxx:80
 TInetAddress.cxx:81
 TInetAddress.cxx:82
 TInetAddress.cxx:83
 TInetAddress.cxx:84
 TInetAddress.cxx:85
 TInetAddress.cxx:86
 TInetAddress.cxx:87
 TInetAddress.cxx:88
 TInetAddress.cxx:89
 TInetAddress.cxx:90
 TInetAddress.cxx:91
 TInetAddress.cxx:92
 TInetAddress.cxx:93
 TInetAddress.cxx:94
 TInetAddress.cxx:95
 TInetAddress.cxx:96
 TInetAddress.cxx:97
 TInetAddress.cxx:98
 TInetAddress.cxx:99
 TInetAddress.cxx:100
 TInetAddress.cxx:101
 TInetAddress.cxx:102
 TInetAddress.cxx:103
 TInetAddress.cxx:104
 TInetAddress.cxx:105
 TInetAddress.cxx:106
 TInetAddress.cxx:107
 TInetAddress.cxx:108
 TInetAddress.cxx:109
 TInetAddress.cxx:110
 TInetAddress.cxx:111
 TInetAddress.cxx:112
 TInetAddress.cxx:113
 TInetAddress.cxx:114
 TInetAddress.cxx:115
 TInetAddress.cxx:116
 TInetAddress.cxx:117
 TInetAddress.cxx:118
 TInetAddress.cxx:119
 TInetAddress.cxx:120
 TInetAddress.cxx:121
 TInetAddress.cxx:122
 TInetAddress.cxx:123
 TInetAddress.cxx:124
 TInetAddress.cxx:125
 TInetAddress.cxx:126
 TInetAddress.cxx:127
 TInetAddress.cxx:128
 TInetAddress.cxx:129
 TInetAddress.cxx:130
 TInetAddress.cxx:131
 TInetAddress.cxx:132
 TInetAddress.cxx:133
 TInetAddress.cxx:134
 TInetAddress.cxx:135
 TInetAddress.cxx:136
 TInetAddress.cxx:137
 TInetAddress.cxx:138
 TInetAddress.cxx:139
 TInetAddress.cxx:140
 TInetAddress.cxx:141
 TInetAddress.cxx:142
 TInetAddress.cxx:143
 TInetAddress.cxx:144
 TInetAddress.cxx:145
 TInetAddress.cxx:146
 TInetAddress.cxx:147
 TInetAddress.cxx:148
 TInetAddress.cxx:149
 TInetAddress.cxx:150
 TInetAddress.cxx:151
 TInetAddress.cxx:152
 TInetAddress.cxx:153
 TInetAddress.cxx:154
 TInetAddress.cxx:155
 TInetAddress.cxx:156
 TInetAddress.cxx:157
 TInetAddress.cxx:158
 TInetAddress.cxx:159
 TInetAddress.cxx:160
 TInetAddress.cxx:161
 TInetAddress.cxx:162
 TInetAddress.cxx:163
 TInetAddress.cxx:164
 TInetAddress.cxx:165
 TInetAddress.cxx:166
 TInetAddress.cxx:167
 TInetAddress.cxx:168
 TInetAddress.cxx:169
 TInetAddress.cxx:170
 TInetAddress.cxx:171
 TInetAddress.cxx:172
 TInetAddress.cxx:173
 TInetAddress.cxx:174
 TInetAddress.cxx:175
 TInetAddress.cxx:176
 TInetAddress.cxx:177
 TInetAddress.cxx:178
 TInetAddress.cxx:179
 TInetAddress.cxx:180
 TInetAddress.cxx:181
 TInetAddress.cxx:182
 TInetAddress.cxx:183
 TInetAddress.cxx:184
 TInetAddress.cxx:185
 TInetAddress.cxx:186
 TInetAddress.cxx:187
 TInetAddress.cxx:188
 TInetAddress.cxx:189
 TInetAddress.cxx:190
 TInetAddress.cxx:191
 TInetAddress.cxx:192
 TInetAddress.cxx:193
 TInetAddress.cxx:194
 TInetAddress.cxx:195
 TInetAddress.cxx:196
 TInetAddress.cxx:197
 TInetAddress.cxx:198
 TInetAddress.cxx:199
 TInetAddress.cxx:200
 TInetAddress.cxx:201
 TInetAddress.cxx:202
 TInetAddress.cxx:203
 TInetAddress.cxx:204
 TInetAddress.cxx:205
 TInetAddress.cxx:206
 TInetAddress.cxx:207
 TInetAddress.cxx:208
 TInetAddress.cxx:209
 TInetAddress.cxx:210
 TInetAddress.cxx:211