#include <stdlib.h>
#include "TUrl.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TEnv.h"
#include "TSystem.h"
TObjArray *TUrl::fgSpecialProtocols;
ClassImp(TUrl)
TUrl::TUrl(const char *url, Bool_t defaultIsFile)
{
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   SetUrl(url, defaultIsFile);
}
void TUrl::SetUrl(const char *url, Bool_t defaultIsFile)
{
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   if (!url || !strlen(url)) {
      fPort = -1;
      return;
   }
   
   fUrl       = "";
   fProtocol  = "http";
   fUser      = "";
   fPasswd    = "";
   fHost      = "";
   fPort      = 80;
   fFile      = "";
   fAnchor    = "";
   fOptions   = "";
   
   if (url[0] == '/')
      defaultIsFile = kTRUE;
   
   char *s, sav;
   char *u, *u0 = Strip(url);
tryfile:
   u = u0;
   
   for (int i = 0; i < GetSpecialProtocols()->GetEntriesFast(); i++) {
      TObjString *os = (TObjString*) GetSpecialProtocols()->UncheckedAt(i);
      TString s1 = os->GetString();
      int l = s1.Length();
      Bool_t stripoff = kFALSE;
      if (s1.EndsWith("/-")) {
         stripoff = kTRUE;
         s1 = s1.Strip(TString::kTrailing, '-');
         l--;
      }
      if (!strncmp(u, s1, l)) {
         if (s1(0) == '/' && s1(l-1) == '/') {
            
            fProtocol = s1(1, l-2);
            if (stripoff)
               l--;    
            else
               l = 0;  
         } else {
            
            fProtocol = s1(0, l-1);
         }
         if (!strncmp(u+l, "//", 2))
            u += l+2;
         else
            u += l;
         fPort = 0;
         FindFile(u, kFALSE);
         delete [] u0;
         return;
      }
   }
   u = u0;
   char *t, *s2;
   
   if ((s = strstr(u, ":/")) && u+1 != s) {
      if (*(s+2) != '/') {
         Error("TUrl", "%s malformed, URL must contain \"://\"", u0);
         fPort = -1;
         goto cleanup;
      }
      sav = *s;
      *s = 0;
      SetProtocol(u, kTRUE);
      *s = sav;
      s += 3;
      if (!*s) {
         
         fPort = -1;
         goto cleanup;
      }
   } else {
      if (defaultIsFile) {
         char *newu = new char [strlen("file:") + strlen(u0) + 1];
         sprintf(newu, "file:%s", u0);
         delete [] u0;
         u0 = newu;
         goto tryfile;
      }
      s = u;
   }
   
   u = s;
   t = s;
again:
   if ((s = strchr(t, '@'))) {
      if (*(s-1) == '\\') {
         t = s+1;
         goto again;
      }
      sav = *s;
      *s = 0;
      if ((s2 = strchr(u, ':'))) {
         *s2 = 0;
         fUser = u;
         *s2 = ':';
         s2++;
         if (*s2) {
            fPasswd = s2;
            fPasswd.ReplaceAll("\\@", "@");
         }
      } else
         fUser = u;
      *s = sav;
      s++;
   } else
      s = u;
   
   u = s;
   if ((s = strchr(u, ':')) || (s = strchr(u, '/'))) {
      if ((strchr (u, ':') > strchr(u, '/')) && (strchr (u, '/')))
         s = strchr(u, '/');
      sav = *s;
      *s = 0;
      fHost = u;
      *s = sav;
      if (sav == ':') {
         s++;
         
         if (!*s) {
            fPort = -1;
            goto cleanup;
         }
         u = s;
         if ((s = strchr(u, '/'))) {
            sav = *s;
            *s = 0;
            fPort = atoi(u);
            *s = sav;
         } else {
            fPort = atoi(u);
            goto cleanup;
         }
      }
   } else {
      fHost = u;
      goto cleanup;
   }
   if (!*s) goto cleanup;
   
   u = s;
   if (*u == '/' && fHost.Length())
      u++;
   FindFile(u);
cleanup:
   delete [] u0;
}
void TUrl::FindFile(char *u, Bool_t stripDoubleSlash)
{
   
   char *s, sav;
   
   char *opt = strchr(u, '?');
   char *anc = strchr(u, '#');
   
   if (opt && anc && opt > anc) {
      fPort = -1;
      return;
   }
   if ((s = opt) || (s = anc)) {
      sav = *s;
      *s = 0;
      fFile = u;
      if (stripDoubleSlash)
         fFile.ReplaceAll("//", "/");
      *s = sav;
      s++;
      if (sav == '?') {
         
         if (!*s) {
            
            return;
         }
         u = s;
         if ((s = strchr(u, '#'))) {
            sav = *s;
            *s = 0;
            fOptions = u;
            *s = sav;
            s++;
         } else {
            fOptions = u;
            return;
         }
      }
      if (!*s) {
         
         return;
      }
   } else {
      fFile = u;
      if (stripDoubleSlash)
         fFile.ReplaceAll("//", "/");
      return;
   }
   
   fAnchor = s;
}
TUrl::TUrl(const TUrl &url) : TObject(url)
{
   
   fUrl      = url.fUrl;
   fProtocol = url.fProtocol;
   fUser     = url.fUser;
   fPasswd   = url.fPasswd;
   fHost     = url.fHost;
   fFile     = url.fFile;
   fAnchor   = url.fAnchor;
   fOptions  = url.fOptions;
   fPort     = url.fPort;
   fFileOA   = url.fFileOA;
   fHostFQ   = url.fHostFQ;
}
TUrl &TUrl::operator=(const TUrl &rhs)
{
   
   if (this != &rhs) {
      TObject::operator=(rhs);
      fUrl      = rhs.fUrl;
      fProtocol = rhs.fProtocol;
      fUser     = rhs.fUser;
      fPasswd   = rhs.fPasswd;
      fHost     = rhs.fHost;
      fFile     = rhs.fFile;
      fAnchor   = rhs.fAnchor;
      fOptions  = rhs.fOptions;
      fPort     = rhs.fPort;
      fFileOA   = rhs.fFileOA;
      fHostFQ   = rhs.fHostFQ;
   }
   return *this;
}
const char *TUrl::GetUrl(Bool_t withDeflt)
{
   
   
   if (IsValid() && fUrl == "") {
      
      for (int i = 0; i < GetSpecialProtocols()->GetEntriesFast(); i++) {
         TObjString *os = (TObjString*) GetSpecialProtocols()->UncheckedAt(i);
         TString &s = os->String();
         int l = s.Length();
         if (fProtocol == s(0, l-1)) {
            if (fFile[0] == '/')
               fUrl = fProtocol + "://" + fFile;
            else
               fUrl = fProtocol + ":" + fFile;
            if (fOptions != "") {
               fUrl += "?";
               fUrl += fOptions;
            }
            if (fAnchor != "") {
               fUrl += "#";
               fUrl += fAnchor;
            }
            return fUrl;
         }
      }
      Bool_t deflt = kFALSE;
      if ((!fProtocol.CompareTo("http")  && fPort == 80)   ||
          (fProtocol.BeginsWith("proof") && fPort == 1093) ||
          (fProtocol.BeginsWith("root")  && fPort == 1094) ||
          (!fProtocol.CompareTo("ftp")   && fPort == 20)   ||
          (!fProtocol.CompareTo("news")  && fPort == 119)  ||
           fPort == 0)
         deflt = kTRUE;
      fUrl = fProtocol + "://";
      if (fUser != "") {
         fUrl += fUser;
         if (fPasswd != "") {
            fUrl += ":";
            TString passwd = fPasswd;
            passwd.ReplaceAll("@", "\\@");
            fUrl += passwd;
         }
         fUrl += "@";
      }
      if (!deflt || withDeflt) {
         char p[10];
         sprintf(p, "%d", fPort);
         fUrl = fUrl + fHost + ":" + p + "/" + fFile;
      } else
         fUrl = fUrl + fHost + "/" + fFile;
      if (fOptions != "") {
         fUrl += "?";
         fUrl += fOptions;
      }
      if (fAnchor != "") {
         fUrl += "#";
         fUrl += fAnchor;
      }
   }
   fUrl.ReplaceAll("////", "///");
   return fUrl;
}
const char *TUrl::GetHostFQDN() const
{
   
   
   if (fHostFQ == "") {
      TInetAddress adr(gSystem->GetHostByName(fHost));
      if (adr.IsValid()) {
         fHostFQ = adr.GetHostName();
         if (fHostFQ == "UnNamedHost")
            fHostFQ = adr.GetHostAddress();
      } else
         fHostFQ = "-";
   }
   if (fHostFQ == "-")
      return fHost;
   return fHostFQ;
}
const char *TUrl::GetFileAndOptions() const
{
   
   
   
   if (fFileOA == "") {
      fFileOA = fFile;
      if (fOptions != "") {
         fFileOA += "?";
         fFileOA += fOptions;
      }
      if (fAnchor != "") {
         fFileOA += "#";
         fFileOA += fAnchor;
      }
   }
   return fFileOA;
}
void TUrl::SetProtocol(const char *proto, Bool_t setDefaultPort)
{
   
   fProtocol = proto;
   if (setDefaultPort) {
      if (!fProtocol.CompareTo("http"))
         fPort = 80;
      else if (fProtocol.BeginsWith("proof"))  
         fPort = 1093;
      else if (fProtocol.BeginsWith("root"))   
         fPort = 1094;
      else if (!fProtocol.CompareTo("ftp"))
         fPort = 20;
      else if (!fProtocol.CompareTo("news"))
         fPort = 119;
      else {
         
         fPort = 0;
      }
   }
   fUrl = "";
}
Int_t TUrl::Compare(const TObject *obj) const
{
   
   if (this == obj) return 0;
   if (TUrl::Class() != obj->IsA()) return -1;
   return TString(((TUrl*)this)->GetUrl()).CompareTo(((TUrl*)obj)->GetUrl(),
                                                     TString::kExact);
}
void TUrl::Print(Option_t *) const
{
   
   if (fPort == -1)
      Printf("Illegal URL");
   Printf("%s", ((TUrl*)this)->GetUrl());
}
TObjArray *TUrl::GetSpecialProtocols()
{
   
   
   
   
   static Bool_t usedEnv = kFALSE;
   if (!fgSpecialProtocols)
      fgSpecialProtocols = new TObjArray;
   if (!gEnv) {
      if (fgSpecialProtocols->GetEntriesFast() == 0)
         fgSpecialProtocols->Add(new TObjString("file:"));
      return fgSpecialProtocols;
   }
   if (fgSpecialProtocols->GetEntriesFast() > 0 && usedEnv)
      return fgSpecialProtocols;
   fgSpecialProtocols->Delete();
   const char *protos = gEnv->GetValue("Url.Special", "file: rfio: hpss: castor: dcache: dcap:");
   usedEnv = kTRUE;
   if (protos) {
      Int_t cnt = 0;
      char *p = StrDup(protos);
      while (1) {
         TObjString *proto = new TObjString(strtok(!cnt ? p : 0, " "));
         if (proto->String().IsNull()) {
            delete proto;
            break;
         }
         fgSpecialProtocols->Add(proto);
         cnt++;
      }
      delete [] p;
   }
   return fgSpecialProtocols;
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.