#include "Riostream.h"
#include "TFileInfo.h"
#include "TRegexp.h"
#include "TSystem.h"
#include "TClass.h"
ClassImp(TFileInfo)
ClassImp(TFileInfoMeta)
TFileInfo::TFileInfo(const char *in, Long64_t size, const char *uuid,
const char *md5, TObject *meta)
: fCurrentUrl(0), fUrlList(0), fSize(-1), fUUID(0), fMD5(0),
fMetaDataList(0), fIndex(-1)
{
ParseInput(in);
if (size > -1) fSize = size;
if (uuid) {
SafeDelete(fUUID);
fUUID = new TUUID(uuid);
} else if (!fUUID) {
fUUID = new TUUID;
}
if (md5) {
SafeDelete(fMD5);
fMD5 = new TMD5();
fMD5->SetDigest(md5);
}
if (meta) {
RemoveMetaData(meta->GetName());
AddMetaData(meta);
}
SetName(fUUID->AsString());
SetTitle("TFileInfo");
ResetBit(TFileInfo::kSortWithIndex);
}
TFileInfo::TFileInfo(const TFileInfo &fi) : TNamed(fi.GetName(), fi.GetTitle()),
fCurrentUrl(0), fUrlList(0),
fSize(fi.fSize), fUUID(0), fMD5(0),
fMetaDataList(0), fIndex(fi.fIndex)
{
if (fi.fUrlList) {
fUrlList = new TList;
fUrlList->SetOwner();
TIter nxu(fi.fUrlList);
TUrl *u = 0;
while ((u = (TUrl *)nxu())) {
fUrlList->Add(new TUrl(u->GetUrl(), kTRUE));
}
ResetUrl();
}
fSize = fi.fSize;
if (fi.fUUID)
fUUID = new TUUID(fi.fUUID->AsString());
if (fi.fMD5)
fMD5 = new TMD5(*(fi.fMD5));
ResetBit(TFileInfo::kStaged);
ResetBit(TFileInfo::kCorrupted);
if (fi.TestBit(TFileInfo::kStaged)) SetBit(TFileInfo::kStaged);
if (fi.TestBit(TFileInfo::kCorrupted)) SetBit(TFileInfo::kCorrupted);
if (fi.fMetaDataList) {
fMetaDataList = new TList;
fMetaDataList->SetOwner();
TIter nxm(fi.fMetaDataList);
TFileInfoMeta *fim = 0;
while ((fim = (TFileInfoMeta *)nxm())) {
fMetaDataList->Add(new TFileInfoMeta(*fim));
}
}
ResetBit(TFileInfo::kSortWithIndex);
}
TFileInfo::~TFileInfo()
{
SafeDelete(fMetaDataList);
SafeDelete(fUUID);
SafeDelete(fMD5);
SafeDelete(fUrlList);
}
void TFileInfo::ParseInput(const char *in)
{
if (!in || strlen(in) <= 0) return;
TString sin(in), t;
Int_t f1 = 0;
while (sin.Tokenize(t, f1, " ")) {
if (t.BeginsWith("sz:")) {
t.Replace(0, 3, "");
if (t.IsDigit()) sscanf(t.Data(), "%lld", &fSize);
} else if (t.BeginsWith("md5:")) {
t.Replace(0, 4, "");
if (t.Length() >= 32) {
fMD5 = new TMD5;
if (fMD5->SetDigest(t) != 0)
SafeDelete(fMD5);
}
} else if (t.BeginsWith("uuid:")) {
t.Replace(0, 5, "");
if (t.Length() > 0) fUUID = new TUUID(t);
} else if (t.BeginsWith("tree:")) {
t.Replace(0, 5, "");
TString nm, se, sf, sl;
Long64_t ent = -1, fst= -1, lst = -1;
Int_t f2 = 0;
if (t.Tokenize(nm, f2, ","))
if (t.Tokenize(se, f2, ","))
if (t.Tokenize(sf, f2, ","))
t.Tokenize(sl, f2, ",");
if (!(nm.IsNull())) {
if (se.IsDigit()) sscanf(se.Data(), "%lld", &ent);
if (sf.IsDigit()) sscanf(sf.Data(), "%lld", &fst);
if (sl.IsDigit()) sscanf(sl.Data(), "%lld", &lst);
TFileInfoMeta *meta = new TFileInfoMeta(nm, "TTree", ent, fst, lst);
RemoveMetaData(meta->GetName());
AddMetaData(meta);
}
} else if (t.BeginsWith("obj:")) {
t.Replace(0, 4, "");
TString nm, cl, se;
Long64_t ent = -1;
Int_t f2 = 0;
if (t.Tokenize(nm, f2, ","))
if (t.Tokenize(cl, f2, ","))
t.Tokenize(se, f2, ",");
if (cl.IsNull()) cl = "TObject";
if (!(nm.IsNull())) {
if (se.IsDigit()) sscanf(se.Data(), "%lld", &ent);
TFileInfoMeta *meta = new TFileInfoMeta(nm, cl, ent);
AddMetaData(meta);
}
} else if (t.BeginsWith("idx:")) {
t.Replace(0, 4, "");
if (t.IsDigit()) sscanf(t.Data(), "%d", &fIndex);
} else {
if (t.BeginsWith("url:")) t.Replace(0, 4, "");
TString u;
Int_t f2 = 0;
while (t.Tokenize(u, f2, ",")) {
if (!(u.IsNull())) AddUrl(u);
}
}
}
}
void TFileInfo::SetUUID(const char *uuid)
{
if (uuid) {
if (fUUID) delete fUUID;
fUUID = new TUUID(uuid);
}
}
TUrl *TFileInfo::GetCurrentUrl() const
{
if (!fCurrentUrl)
const_cast<TFileInfo*>(this)->ResetUrl();
return fCurrentUrl;
}
TUrl *TFileInfo::NextUrl()
{
if (!fUrlList)
return 0;
TUrl *returl = fCurrentUrl;
if (fCurrentUrl)
fCurrentUrl = (TUrl*)fUrlList->After(fCurrentUrl);
return returl;
}
TUrl *TFileInfo::FindByUrl(const char *url, Bool_t withDeflt)
{
TIter nextUrl(fUrlList);
TUrl *urlelement;
TRegexp rg(url);
while ((urlelement = (TUrl*) nextUrl())) {
if (TString(urlelement->GetUrl(withDeflt)).Index(rg) != kNPOS) {
return urlelement;
}
}
return 0;
}
Bool_t TFileInfo::AddUrl(const char *url, Bool_t infront)
{
if (FindByUrl(url))
return kFALSE;
if (!fUrlList) {
fUrlList = new TList;
fUrlList->SetOwner();
}
TUrl *newurl = new TUrl(url, kTRUE);
if (fUrlList->GetSize() == 0)
fCurrentUrl = newurl;
if (infront)
fUrlList->AddFirst(newurl);
else
fUrlList->Add(newurl);
return kTRUE;
}
Bool_t TFileInfo::RemoveUrl(const char *url)
{
TUrl *lurl;
if ((lurl = FindByUrl(url))) {
fUrlList->Remove(lurl);
if (lurl == fCurrentUrl)
ResetUrl();
delete lurl;
return kTRUE;
}
return kFALSE;
}
Bool_t TFileInfo::RemoveUrlAt(Int_t i)
{
TUrl *tUrl;
if ((tUrl = dynamic_cast<TUrl *>(fUrlList->At(i))) != NULL) {
fUrlList->Remove(tUrl);
if (tUrl == fCurrentUrl)
ResetUrl();
delete tUrl;
return kTRUE;
}
return kFALSE;
}
Bool_t TFileInfo::SetCurrentUrl(const char *url)
{
TUrl *lurl;
if ((lurl = FindByUrl(url))) {
fCurrentUrl = lurl;
return kTRUE;
}
return kFALSE;
}
Bool_t TFileInfo::SetCurrentUrl(TUrl *url)
{
if (url && fUrlList && fUrlList->FindObject(url)) {
fCurrentUrl = url;
return kTRUE;
}
return kFALSE;
}
Bool_t TFileInfo::AddMetaData(TObject *meta)
{
if (meta) {
if (!fMetaDataList) {
fMetaDataList = new TList;
fMetaDataList->SetOwner();
}
fMetaDataList->Add(meta);
return kTRUE;
}
return kFALSE;
}
Bool_t TFileInfo::RemoveMetaData(const char *meta)
{
if (fMetaDataList) {
if (!meta || strlen(meta) <= 0) {
SafeDelete(fMetaDataList);
return kTRUE;
} else {
TObject *o = fMetaDataList->FindObject(meta);
if (o) {
fMetaDataList->Remove(o);
delete o;
return kTRUE;
}
}
}
return kFALSE;
}
TFileInfoMeta *TFileInfo::GetMetaData(const char *meta) const
{
if (fMetaDataList) {
TFileInfoMeta *m;
if (!meta || strlen(meta) <= 0)
m = (TFileInfoMeta *) fMetaDataList->First();
else
m = (TFileInfoMeta *) fMetaDataList->FindObject(meta);
if (m) {
TClass *c = m->IsA();
return (c && c->InheritsFrom(TFileInfoMeta::Class())) ? m : 0;
}
}
return 0;
}
Int_t TFileInfo::Compare(const TObject *obj) const
{
Int_t rc = 0;
if (TestBit(TFileInfo::kSortWithIndex)) {
const TFileInfo *fi = dynamic_cast<const TFileInfo *>(obj);
if (!fi) {
rc = -1;
} else {
if (fIndex < fi->fIndex) {
rc = -1;
} else if (fIndex > fi->fIndex) {
rc = 1;
}
}
} else {
if (this == obj) {
rc = 0;
} else if (TFileInfo::Class() != obj->IsA()) {
rc = -1;
} else {
rc = (GetFirstUrl()->Compare(((TFileInfo*)obj)->GetFirstUrl()));
}
}
return rc;
}
void TFileInfo::Print(Option_t *option) const
{
if (GetMD5()) GetMD5()->Final();
TString opt(option);
if (opt.Contains("L", TString::kIgnoreCase)) {
Printf("UUID: %s\nMD5: %s\nSize: %lld\nIndex: %d",
GetUUID() ? GetUUID()->AsString() : "undef",
GetMD5() ? GetMD5()->AsString() : "undef",
GetSize(), GetIndex());
TIter next(fUrlList);
TUrl *u;
Printf(" === URLs ===");
while ((u = (TUrl*)next()))
Printf(" URL: %s", u->GetUrl());
TIter nextm(fMetaDataList);
TObject *m = 0;
while ((m = (TObject*) nextm())) {
Printf(" === Meta Data Object ===");
m->Print();
}
} else {
TString out("current-url-undef -|-|- md5-undef");
if (GetCurrentUrl()) out.ReplaceAll("current-url-undef", GetCurrentUrl()->GetUrl());
TString deft;
if (opt.Contains("T:")) deft = opt(opt.Index("T:")+2, opt.Length());
TFileInfoMeta *meta = 0;
if (fMetaDataList && !deft.IsNull()) meta = (TFileInfoMeta *) fMetaDataList->FindObject(deft);
if (fMetaDataList && !meta) meta = (TFileInfoMeta *) fMetaDataList->First();
if (meta) out.ReplaceAll("-|-|-", TString::Format("%s|%s|%lld", meta->GetName(),
meta->GetTitle(), meta->GetEntries()));
if (GetMD5())
out.ReplaceAll("md5-undef", TString::Format("%s", GetMD5()->AsString()));
Printf("%s", out.Data());
}
}
TFileInfoMeta::TFileInfoMeta(const char *objPath, const char *objClass,
Long64_t entries, Long64_t first, Long64_t last,
Long64_t totbytes, Long64_t zipbytes)
: TNamed(objPath, objClass), fEntries(entries), fFirst(first),
fLast(last), fTotBytes(totbytes), fZipBytes(zipbytes)
{
TString p = objPath;
if (!p.BeginsWith("/")) {
p.Prepend("/");
SetName(p);
}
TClass *c = TClass::GetClass(objClass);
fIsTree = (c && c->InheritsFrom("TTree")) ? kTRUE : kFALSE;
ResetBit(TFileInfoMeta::kExternal);
}
TFileInfoMeta::TFileInfoMeta(const char *objPath, const char *objDir,
const char *objClass, Long64_t entries,
Long64_t first, Long64_t last,
Long64_t totbytes, Long64_t zipbytes)
: TNamed(objPath, objClass), fEntries(entries), fFirst(first),
fLast(last), fTotBytes(totbytes), fZipBytes(zipbytes)
{
TString sdir = objDir;
if (!sdir.BeginsWith("/"))
sdir.Prepend("/");
if (!sdir.EndsWith("/"))
sdir += "/";
sdir += objPath;
SetName(sdir);
TClass *c = TClass::GetClass(objClass);
fIsTree = (c && c->InheritsFrom("TTree")) ? kTRUE : kFALSE;
ResetBit(TFileInfoMeta::kExternal);
}
TFileInfoMeta::TFileInfoMeta(const TFileInfoMeta &m)
: TNamed(m.GetName(), m.GetTitle())
{
fEntries = m.fEntries;
fFirst = m.fFirst;
fLast = m.fLast;
fIsTree = m.fIsTree;
fTotBytes = m.fTotBytes;
fZipBytes = m.fZipBytes;
ResetBit(TFileInfoMeta::kExternal);
if (m.TestBit(TFileInfoMeta::kExternal)) SetBit(TFileInfoMeta::kExternal);
}
const char *TFileInfoMeta::GetDirectory() const
{
return gSystem->DirName(GetName());
}
const char *TFileInfoMeta::GetObject() const
{
return gSystem->BaseName(GetName());
}
void TFileInfoMeta::Print(Option_t * ) const
{
Printf(" Name: %s\n Class: %s\n Entries: %lld\n"
" First: %lld\n Last: %lld",
fName.Data(), fTitle.Data(), fEntries, fFirst, fLast);
}