TFileInfo.cxx

Go to the documentation of this file.
00001 // @(#)root/base:$Id: TFileInfo.cxx 38223 2011-02-25 12:36:36Z ganis $
00002 // Author: Andreas-Joachim Peters   20/9/2005
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TFileInfo                                                            //
00015 //                                                                      //
00016 // Class describing a generic file including meta information.          //
00017 //                                                                      //
00018 //////////////////////////////////////////////////////////////////////////
00019 
00020 #include "Riostream.h"
00021 #include "TFileInfo.h"
00022 #include "TRegexp.h"
00023 #include "TSystem.h"
00024 #include "TClass.h"
00025 
00026 
00027 ClassImp(TFileInfo)
00028 ClassImp(TFileInfoMeta)
00029 
00030 //______________________________________________________________________________
00031 TFileInfo::TFileInfo(const char *in, Long64_t size, const char *uuid,
00032                      const char *md5, TObject *meta)
00033    : fCurrentUrl(0), fUrlList(0), fSize(-1), fUUID(0), fMD5(0),
00034      fMetaDataList(0)
00035 {
00036    // Constructor.
00037 
00038    // Get initializations form the input string: this will set at least the
00039    // current URL; but it may set more: see TFileInfo::ParseInput().
00040    ParseInput(in);
00041 
00042    // Now also honour the input arguments: the size
00043    if (size > -1) fSize = size;
00044    // The UUID
00045    if (uuid) {
00046       SafeDelete(fUUID);
00047       fUUID = new TUUID(uuid);
00048    } else if (!fUUID) {
00049       fUUID = new TUUID;
00050    }
00051    // The MD5
00052    if (md5) {
00053       SafeDelete(fMD5);
00054       fMD5 = new TMD5((const UChar_t*)md5);
00055    }
00056    // The meta information
00057    if (meta) {
00058       RemoveMetaData(meta->GetName());
00059       AddMetaData(meta);
00060    }
00061 
00062    // Now set the name from the UUID
00063    SetName(fUUID->AsString());
00064    SetTitle("TFileInfo");
00065 }
00066 
00067 //______________________________________________________________________________
00068 TFileInfo::TFileInfo(const TFileInfo &fi) : TNamed(fi.GetName(), fi.GetTitle()),
00069                                             fCurrentUrl(0), fUrlList(0),
00070                                             fSize(fi.fSize), fUUID(0), fMD5(0),
00071                                             fMetaDataList(0)
00072 {
00073    // Copy constructor.
00074 
00075    if (fi.fUrlList) {
00076       fUrlList = new TList;
00077       fUrlList->SetOwner();
00078       TIter nxu(fi.fUrlList);
00079       TUrl *u = 0;
00080       while ((u = (TUrl *)nxu())) {
00081          fUrlList->Add(new TUrl(u->GetUrl(), kTRUE));
00082       }
00083       ResetUrl();
00084    }
00085    fSize = fi.fSize;
00086 
00087    if (fi.fUUID)
00088       fUUID = new TUUID(fi.fUUID->AsString());
00089 
00090    if (fi.fMD5)
00091       fMD5 = new TMD5(*(fi.fMD5));
00092 
00093    // Staged and corrupted bits
00094    ResetBit(TFileInfo::kStaged);
00095    ResetBit(TFileInfo::kCorrupted);
00096    if (fi.TestBit(TFileInfo::kStaged)) SetBit(TFileInfo::kStaged);
00097    if (fi.TestBit(TFileInfo::kCorrupted)) SetBit(TFileInfo::kCorrupted);
00098 
00099    if (fi.fMetaDataList) {
00100       fMetaDataList = new TList;
00101       fMetaDataList->SetOwner();
00102       TIter nxm(fi.fMetaDataList);
00103       TFileInfoMeta *fim = 0;
00104       while ((fim = (TFileInfoMeta *)nxm())) {
00105          fMetaDataList->Add(new TFileInfoMeta(*fim));
00106       }
00107    }
00108 }
00109 
00110 //______________________________________________________________________________
00111 TFileInfo::~TFileInfo()
00112 {
00113    // Destructor.
00114 
00115    SafeDelete(fMetaDataList);
00116    SafeDelete(fUUID);
00117    SafeDelete(fMD5);
00118    SafeDelete(fUrlList);
00119 }
00120 
00121 //______________________________________________________________________________
00122 void TFileInfo::ParseInput(const char *in)
00123 {
00124    // Parse the input line to extract init information from 'in'; the input
00125    // string is tokenized on ' '; the tokens can be prefixed by the following
00126    // keys:
00127    //
00128    //   url:<url1>,<url2>,...     URLs for the file; stored in the order given
00129    //   sz:<size>                 size of the file in bytes
00130    //   md5:<md5_ascii>           MD5 sum of the file in ASCII form
00131    //   uuid:<uuid>               UUID of the file
00132    //
00133    //   tree:<name>,<entries>,<first>,<last>
00134    //                             meta-information about a tree in the file; the
00135    //                             should be in the form <subdir>/tree-name;'entries' is
00136    //                             the number of entries in the tree; 'first' and 'last'
00137    //                             define the entry range.
00138    //
00139    //   obj:<name>,<class>,<entries>
00140    //                             meta-information about a generic object in the file;
00141    //                             the should be in the form <subdir>/obj-name; 'class'
00142    //                             is the object class; 'entries' is the number of occurences
00143    //                             for this object.
00144    // Multiple occurences of 'tree:' or 'obj:' can be specified.
00145    // The initializations done via the input string are superseeded by the ones by other
00146    // parameters in the constructor, if any.
00147    // If no key is given, the token is interpreted as URL(s).
00148 
00149    // Nothing to do if the string is empty
00150    if (!in || strlen(in) <= 0) return;
00151 
00152    TString sin(in), t;
00153    Int_t f1 = 0;
00154    while (sin.Tokenize(t, f1, " ")) {
00155       if (t.BeginsWith("sz:")) {
00156          // The size
00157          t.Replace(0, 3, "");
00158          if (t.IsDigit()) sscanf(t.Data(), "%lld", &fSize);
00159       } else if (t.BeginsWith("md5:")) {
00160          // The MD5
00161          t.Replace(0, 4, "");
00162          if (t.Length() >= 32) {
00163             fMD5 = new TMD5;
00164             if (fMD5->SetDigest(t) != 0)
00165                SafeDelete(fMD5);
00166          }
00167       } else if (t.BeginsWith("uuid:")) {
00168          // The UUID
00169          t.Replace(0, 5, "");
00170          if (t.Length() > 0) fUUID = new TUUID(t);
00171       } else if (t.BeginsWith("tree:")) {
00172          // A tree
00173          t.Replace(0, 5, "");
00174          TString nm, se, sf, sl;
00175          Long64_t ent = -1, fst= -1, lst = -1;
00176          Int_t f2 = 0;
00177          if (t.Tokenize(nm, f2, ","))
00178             if (t.Tokenize(se, f2, ","))
00179                if (t.Tokenize(sf, f2, ","))
00180                   t.Tokenize(sl, f2, ",");
00181          if (!(nm.IsNull())) {
00182             if (se.IsDigit()) sscanf(se.Data(), "%lld", &ent);
00183             if (sf.IsDigit()) sscanf(sf.Data(), "%lld", &fst);
00184             if (sl.IsDigit()) sscanf(sl.Data(), "%lld", &lst);
00185             TFileInfoMeta *meta = new TFileInfoMeta(nm, "TTree", ent, fst, lst);
00186             RemoveMetaData(meta->GetName());
00187             AddMetaData(meta);
00188          }
00189       } else if (t.BeginsWith("obj:")) {
00190          // A generic object
00191          t.Replace(0, 4, "");
00192          TString nm, cl, se;
00193          Long64_t ent = -1;
00194          Int_t f2 = 0;
00195          if (t.Tokenize(nm, f2, ","))
00196             if (t.Tokenize(cl, f2, ","))
00197                t.Tokenize(se, f2, ",");
00198          if (cl.IsNull()) cl = "TObject";
00199          if (!(nm.IsNull())) {
00200             if (se.IsDigit()) sscanf(se.Data(), "%lld", &ent);
00201             TFileInfoMeta *meta = new TFileInfoMeta(nm, cl, ent);
00202             AddMetaData(meta);
00203          }
00204       } else {
00205          // A (set of) URL(s)
00206          if (t.BeginsWith("url:")) t.Replace(0, 4, "");
00207          TString u;
00208          Int_t f2 = 0;
00209          while (t.Tokenize(u, f2, ",")) {
00210             if (!(u.IsNull())) AddUrl(u);
00211          }
00212       }
00213    }
00214 }
00215 
00216 //______________________________________________________________________________
00217 void TFileInfo::SetUUID(const char *uuid)
00218 {
00219    // Set the UUID to the value associated to the string 'uuid'. This is
00220    // useful to set the UUID to the one of the ROOT file during verification.
00221    // NB: we do not change the name in here, because this would screw up lists
00222    //     of these objects hashed on the name. Those lists need to be rebuild.
00223    //     TFileCollection does that in RemoveDuplicates.
00224 
00225    if (uuid) {
00226       if (fUUID) delete fUUID;
00227       fUUID = new TUUID(uuid);
00228    }
00229 }
00230 
00231 //______________________________________________________________________________
00232 TUrl *TFileInfo::GetCurrentUrl() const
00233 {
00234    // Return the current url.
00235 
00236    if (!fCurrentUrl)
00237       const_cast<TFileInfo*>(this)->ResetUrl();
00238    return fCurrentUrl;
00239 }
00240 
00241 //______________________________________________________________________________
00242 TUrl *TFileInfo::NextUrl()
00243 {
00244    // Iterator function, start iteration by calling ResetUrl().
00245    // The first call to NextUrl() will return the 1st element,
00246    // the seconde the 2nd element etc. Returns 0 in case no more urls.
00247 
00248    if (!fUrlList)
00249       return 0;
00250 
00251    TUrl *returl = fCurrentUrl;
00252 
00253    if (fCurrentUrl)
00254       fCurrentUrl = (TUrl*)fUrlList->After(fCurrentUrl);
00255 
00256    return returl;
00257 }
00258 
00259 //______________________________________________________________________________
00260 TUrl *TFileInfo::FindByUrl(const char *url, Bool_t withDeflt)
00261 {
00262    // Find an element from a URL. Returns 0 if not found.
00263 
00264    TIter nextUrl(fUrlList);
00265    TUrl *urlelement;
00266 
00267    TRegexp rg(url);
00268    while  ((urlelement = (TUrl*) nextUrl())) {
00269       if (TString(urlelement->GetUrl(withDeflt)).Index(rg) != kNPOS) {
00270          return urlelement;
00271       }
00272    }
00273    return 0;
00274 }
00275 
00276 //______________________________________________________________________________
00277 Bool_t TFileInfo::AddUrl(const char *url, Bool_t infront)
00278 {
00279    // Add a new URL. If 'infront' is TRUE the new url is pushed at the beginning
00280    // of the list; otherwise is pushed back.
00281    // Returns kTRUE if successful, kFALSE otherwise.
00282 
00283    if (FindByUrl(url))
00284       return kFALSE;
00285 
00286    if (!fUrlList) {
00287       fUrlList = new TList;
00288       fUrlList->SetOwner();
00289    }
00290 
00291    TUrl *newurl = new TUrl(url, kTRUE);
00292    // We set the current Url to the first url added
00293    if (fUrlList->GetSize() == 0)
00294       fCurrentUrl = newurl;
00295 
00296    if (infront)
00297       fUrlList->AddFirst(newurl);
00298    else
00299       fUrlList->Add(newurl);
00300    return kTRUE;
00301 }
00302 
00303 //______________________________________________________________________________
00304 Bool_t TFileInfo::RemoveUrl(const char *url)
00305 {
00306    // Remove an URL. Returns kTRUE if successful, kFALSE otherwise.
00307 
00308    TUrl *lurl;
00309    if ((lurl = FindByUrl(url))) {
00310       fUrlList->Remove(lurl);
00311       if (lurl == fCurrentUrl)
00312          ResetUrl();
00313       delete lurl;
00314       return kTRUE;
00315    }
00316    return kFALSE;
00317 }
00318 
00319 //______________________________________________________________________________
00320 Bool_t TFileInfo::SetCurrentUrl(const char *url)
00321 {
00322    // Set 'url' as current URL, if in the list
00323    // Return kFALSE if not in the list
00324 
00325    TUrl *lurl;
00326    if ((lurl = FindByUrl(url))) {
00327       fCurrentUrl = lurl;
00328       return kTRUE;
00329    }
00330    return kFALSE;
00331 }
00332 
00333 //______________________________________________________________________________
00334 Bool_t TFileInfo::SetCurrentUrl(TUrl *url)
00335 {
00336    // Set 'url' as current URL, if in the list
00337    // Return kFALSE if not in the list
00338 
00339    if (url && fUrlList && fUrlList->FindObject(url)) {
00340       fCurrentUrl = url;
00341       return kTRUE;
00342    }
00343    return kFALSE;
00344 }
00345 
00346 //______________________________________________________________________________
00347 Bool_t TFileInfo::AddMetaData(TObject *meta)
00348 {
00349    // Add's a meta data object to the file info object. The object will be
00350    // adopted by the TFileInfo and should not be deleted by the user.
00351    // Typically objects of class TFileInfoMeta or derivatives should be added,
00352    // but any class is accepted.
00353    // Returns kTRUE if successful, kFALSE otherwise.
00354 
00355    if (meta) {
00356       if (!fMetaDataList) {
00357          fMetaDataList = new TList;
00358          fMetaDataList->SetOwner();
00359       }
00360       fMetaDataList->Add(meta);
00361       return kTRUE;
00362    }
00363    return kFALSE;
00364 }
00365 
00366 //______________________________________________________________________________
00367 Bool_t TFileInfo::RemoveMetaData(const char *meta)
00368 {
00369    // Remove the metadata obeject. If meta is 0 remove all meta data objects.
00370    // Returns kTRUE if successful, kFALSE otherwise.
00371 
00372    if (fMetaDataList) {
00373       if (!meta || strlen(meta) <= 0) {
00374          SafeDelete(fMetaDataList);
00375          return kTRUE;
00376       } else {
00377          TObject *o = fMetaDataList->FindObject(meta);
00378          if (o) {
00379             fMetaDataList->Remove(o);
00380             delete o;
00381             return kTRUE;
00382          }
00383       }
00384    }
00385    return kFALSE;
00386 }
00387 
00388 //______________________________________________________________________________
00389 TFileInfoMeta *TFileInfo::GetMetaData(const char *meta) const
00390 {
00391    // Get meta data object with specified name. If meta is 0
00392    // get first meta data object. Returns 0 in case no
00393    // suitable meta data object is found.
00394 
00395    if (fMetaDataList) {
00396       TFileInfoMeta *m;
00397       if (!meta || strlen(meta) <= 0)
00398          m = (TFileInfoMeta *) fMetaDataList->First();
00399       else
00400          m = (TFileInfoMeta *) fMetaDataList->FindObject(meta);
00401       if (m) {
00402          TClass *c = m->IsA();
00403          return (c && c->InheritsFrom(TFileInfoMeta::Class())) ? m : 0;
00404       }
00405    }
00406    return 0;
00407 }
00408 
00409 //______________________________________________________________________________
00410 Int_t TFileInfo::Compare(const TObject *obj) const
00411 {
00412    // Compare TFileInfo object by their first urls.
00413 
00414    if (this == obj) return 0;
00415    if (TFileInfo::Class() != obj->IsA()) return -1;
00416    return (GetFirstUrl()->Compare(((TFileInfo*)obj)->GetFirstUrl()));
00417 }
00418 
00419 //______________________________________________________________________________
00420 void TFileInfo::Print(Option_t *option) const
00421 {
00422    // Print information about this object. If option contains 'L' a long listing
00423    // will be printed (on multiple lines). Otherwise one line is printed with the
00424    // following information: current url, default tree name|class|entries, md5;
00425    // the default tree name is passed via the option ("T:<default_tree>") by the
00426    // owning TFileCollection.
00427 
00428    if (GetMD5()) GetMD5()->Final();
00429    TString opt(option);
00430    if (opt.Contains("L", TString::kIgnoreCase)) {
00431 
00432       Printf("UUID: %s\nMD5:  %s\nSize: %lld", GetUUID() ? GetUUID()->AsString() : "undef",
00433                                                GetMD5() ? GetMD5()->AsString() : "undef",
00434                                                GetSize());
00435 
00436       TIter next(fUrlList);
00437       TUrl *u;
00438       Printf(" === URLs ===");
00439       while ((u = (TUrl*)next()))
00440          Printf(" URL:  %s", u->GetUrl());
00441 
00442       TIter nextm(fMetaDataList);
00443       TObject *m = 0;   // can be any TObject not only TFileInfoMeta
00444       while ((m = (TObject*) nextm())) {
00445          Printf(" === Meta Data Object ===");
00446          m->Print();
00447       }
00448    } else {
00449       TString out("current-url-undef -|-|- md5-undef");
00450       if (GetCurrentUrl()) out.ReplaceAll("current-url-undef", GetCurrentUrl()->GetUrl());
00451       // Extract the default tree name, if any
00452       TString deft;
00453       if (opt.Contains("T:")) deft = opt(opt.Index("T:")+2, opt.Length());
00454       TFileInfoMeta *meta = 0;
00455       if (fMetaDataList && !deft.IsNull()) meta = (TFileInfoMeta *) fMetaDataList->FindObject(deft);
00456       if (fMetaDataList && !meta) meta = (TFileInfoMeta *) fMetaDataList->First();
00457       if (meta) out.ReplaceAll("-|-|-", TString::Format("%s|%s|%lld", meta->GetName(),
00458                                         meta->GetTitle(), meta->GetEntries()));
00459       if (GetMD5())
00460          out.ReplaceAll("md5-undef", TString::Format("%s", GetMD5()->AsString()));
00461       Printf("%s", out.Data());
00462    }
00463 }
00464 
00465 
00466 //______________________________________________________________________________
00467 TFileInfoMeta::TFileInfoMeta(const char *objPath, const char *objClass,
00468                              Long64_t entries, Long64_t first, Long64_t last,
00469                              Long64_t totbytes, Long64_t zipbytes)
00470               : TNamed(objPath, objClass), fEntries(entries), fFirst(first),
00471                 fLast(last), fTotBytes(totbytes), fZipBytes(zipbytes)
00472 {
00473    // Create file meta data object.
00474 
00475    TString p = objPath;
00476    if (!p.BeginsWith("/")) {
00477       p.Prepend("/");
00478       SetName(p);
00479    }
00480 
00481    TClass *c = TClass::GetClass(objClass);
00482    fIsTree = (c && c->InheritsFrom("TTree")) ? kTRUE : kFALSE;
00483    ResetBit(TFileInfoMeta::kExternal);
00484 }
00485 
00486 //______________________________________________________________________________
00487 TFileInfoMeta::TFileInfoMeta(const char *objPath, const char *objDir,
00488                              const char *objClass, Long64_t entries,
00489                              Long64_t first, Long64_t last,
00490                              Long64_t totbytes, Long64_t zipbytes)
00491               : TNamed(objPath, objClass), fEntries(entries), fFirst(first),
00492                 fLast(last), fTotBytes(totbytes), fZipBytes(zipbytes)
00493 {
00494    // Create file meta data object.
00495 
00496    TString sdir = objDir;
00497    if (!sdir.BeginsWith("/"))
00498       sdir.Prepend("/");
00499    if (!sdir.EndsWith("/"))
00500       sdir += "/";
00501    sdir += objPath;
00502    SetName(sdir);
00503 
00504    TClass *c = TClass::GetClass(objClass);
00505    fIsTree = (c && c->InheritsFrom("TTree")) ? kTRUE : kFALSE;
00506    ResetBit(TFileInfoMeta::kExternal);
00507 }
00508 
00509 //______________________________________________________________________________
00510 TFileInfoMeta::TFileInfoMeta(const TFileInfoMeta &m)
00511               : TNamed(m.GetName(), m.GetTitle())
00512 {
00513    // Copy constructor
00514 
00515    fEntries = m.fEntries;
00516    fFirst = m.fFirst;
00517    fLast = m.fLast;
00518    fIsTree = m.fIsTree;
00519    fTotBytes = m.fTotBytes;
00520    fZipBytes = m.fZipBytes;
00521    ResetBit(TFileInfoMeta::kExternal);
00522    if (m.TestBit(TFileInfoMeta::kExternal)) SetBit(TFileInfoMeta::kExternal);
00523 }
00524 
00525 //______________________________________________________________________________
00526 const char *TFileInfoMeta::GetDirectory() const
00527 {
00528    // Get the object's directory in the ROOT file.
00529 
00530    return gSystem->DirName(GetName());
00531 }
00532 
00533 //______________________________________________________________________________
00534 const char *TFileInfoMeta::GetObject() const
00535 {
00536    // Get the object name, with path stripped off. For full path
00537    // use GetName().
00538 
00539    return gSystem->BaseName(GetName());
00540 }
00541 
00542 //______________________________________________________________________________
00543 void TFileInfoMeta::Print(Option_t * /* option */) const
00544 {
00545    // Print information about this object.
00546 
00547    Printf(" Name:    %s\n Class:   %s\n Entries: %lld\n"
00548           " First:   %lld\n Last:    %lld",
00549           fName.Data(), fTitle.Data(), fEntries, fFirst, fLast);
00550 }

Generated on Tue Jul 5 14:11:20 2011 for ROOT_528-00b_version by  doxygen 1.5.1