#ifndef __HZIP__
#define __HZIP__
#include "TObject.h"
#include "TFile.h"
#include "TSystem.h"
#include "TString.h"
#include "TRegexp.h"
#include "TArchiveFile.h"
#include "TArchiveFile.h"
#include "TList.h"
#include "TObjString.h"
#include "TObjArray.h"
#include "TChain.h"
#include "TChainElement.h"
#include <wordexp.h>
#include <iomanip>
#include <iostream>
#include <fstream>
using namespace std;
class HZip : public TObject {
public:
HZip(){};
virtual ~HZip(){};
static TObjArray* glob(TString pattern)
{
wordexp_t file_list;
Char_t** file;
TObjArray* filenames = NULL;
if (pattern.IsNull())
return NULL;
if (::wordexp( pattern.Data(), &file_list, 0 ))
{
::wordfree( &file_list );
return NULL;
}
file = file_list.we_wordv;
filenames = new TObjArray;
for (UInt_t i = 0; i < file_list.we_wordc; i++)
{
if (!gSystem->AccessPathName( file[i] ))
filenames->Add( new TObjString( file[i] ) );
}
::wordfree( &file_list );
if (filenames->GetEntries() == 0)
{
delete filenames;
filenames = NULL;
}
return filenames;
}
static TObjArray* readFileList(TString listfile)
{
if(gSystem->AccessPathName(listfile)){
printf("Error: readFile() : list file does not exist!");
return NULL;
}
Char_t line[1000];
ifstream inp;
TObjArray* filenames = new TObjArray;
inp.open(listfile.Data());
TString name;
while(!inp.eof()){
inp.getline (line, 1000);
name = line;
if(gSystem->AccessPathName(name)){
printf("Error: readFileList() : file %s does not exist!",name.Data());
continue;
}
filenames->Add( new TObjString( name ) );
}
inp.close();
if (filenames->GetEntries() == 0) {
delete filenames;
filenames = NULL;
}
return filenames;
}
static Bool_t chainToTObjArray(TChain* chain=0,TObjArray* filenames=0)
{
if(chain == 0){
printf("Error: chainToTObjArray() : TChain pointer is NULL!");
return kFALSE;
}
if(filenames == 0){
printf("Error: chainToTObjArray() : TObjArray pointer is NULL!");
return kFALSE;
}
TObjArray* elements = chain->GetListOfFiles();
Int_t nfiles = elements->GetEntries();
for(Int_t i=0;i<nfiles;i++){
TChainElement* element = (TChainElement*)elements->At(i);
filenames->Add( new TObjString( element->GetTitle() ) );
}
return kTRUE;
}
static Bool_t exists(TString name,Bool_t silent=kFALSE,Bool_t isZip=kTRUE)
{
if(isZip && name.EndsWith(".zip") == 0) {
if(!silent) printf("Error: File %s does not end with .zip\n!",name.Data());
return kFALSE;
}
if(gSystem->AccessPathName(name.Data()) != 0) {
if(!silent) printf("Error: File %s does not exist\n!",name.Data());
return kFALSE;
}
return kTRUE;
}
static Bool_t splitName(TString fullname, TString& zipname,TString& membername)
{
if(fullname.Contains(".zip#") != 0){
zipname = fullname;
zipname.Remove(zipname.First('#'));
membername = fullname;
membername.Replace(0,membername.First('#') + 1,"");
return kTRUE;
}
printf("Error: isInside() : Filename does not contain .zip#membername!\n");
return kFALSE;
}
static Bool_t isInside(TString name, Bool_t print=kFALSE)
{
TString zipname;
TString membername;
if(!HZip::splitName(name,zipname,membername)) { return kFALSE; }
if(!HZip::exists(zipname)) return kFALSE;
Bool_t found = kFALSE;
TFile* fzip = TFile::Open(zipname.Data());
if(fzip) {
TArchiveFile* archive = fzip->GetArchive();
if(archive){
TObjArray* members = archive->GetMembers();
if(members->FindObject(membername.Data()) == 0) {
if(print) printf("Info: isInside() : File %s not found ind zipfile %s\n",membername.Data(),zipname.Data());
found = kFALSE;
} else {
if(print) printf("Info: isInside() : File %s found ind zipfile %s\n" ,membername.Data(),zipname.Data());
found = kTRUE;
}
} else {
printf("Error: isInside() : Retrieved NULL pointer for Archive!\n");
}
fzip->Close();
delete fzip;
}
return found;
}
static Bool_t isInside(TString zipname, TString membername ,Bool_t print=kFALSE)
{
TString name = zipname + "#" + membername;
return isInside(name,print);
}
static Int_t list(TString name, TString filter=".*",Int_t size=0,Int_t time=0)
{
if(!HZip::exists(name)) return 0;
TFile* fzip = TFile::Open(name.Data());
if(fzip) {
TArchiveFile* archive = fzip->GetArchive();
if(archive){
cout<<"-------------------------------------------------------------------------------"<<endl;
cout<<"Listing all file inside zip file "<<name.Data()<<" (matching "<<filter.Data()<<") :"<<endl;
TObjArray* members = archive->GetMembers();
TString fname = "";
TRegexp expr(filter);
Int_t ct = 0;
for(Int_t i = 0; i < members->GetEntries(); i++){
TArchiveMember* member = (TArchiveMember*) members->At(i);
fname = member->GetName();
if(fname(expr) != ""){
cout<<setw(5)<<ct
<<" size " <<setw(12)<<member->GetCompressedSize()
<<" mod time "<<member->GetModTime().AsString()
<<" "<<member->GetName()<<endl;
ct++;
}
}
cout<<"-------------------------------------------------------------------------------"<<endl;
return ct;
} else {
printf("Error: list() : Retrived NULL pointer for Archive!\n");
}
fzip->Close();
delete fzip;
}
return 0;
}
static Int_t getList(TString name,TList* list,TString filter=".*",Int_t size=0,Int_t time=0)
{
if(!HZip::exists(name)) return 0;
TFile* fzip = TFile::Open(name.Data());
if(fzip) {
TArchiveFile* archive = fzip->GetArchive();
if(archive){
TObjArray* members = archive->GetMembers();
TString fname = "";
TRegexp expr(filter);
Int_t ct = 0;
for(Int_t i = 0; i < members->GetEntries(); i++){
TArchiveMember* member = (TArchiveMember*) members->At(i);
fname = member->GetName();
if(fname(expr) != ""){
list->Add(new TObjString(member->GetName()));
ct++;
}
}
return ct;
} else {
printf("Error: list() : Retrived NULL pointer for Archive!\n");
}
fzip->Close();
delete fzip;
}
return 0;
}
static Bool_t makeChain(TString zipname,TChain* chain = 0,TString filter=".*",Int_t size=0,Int_t time=0)
{
if(chain == 0){
printf("Error: makeChain() : TChain pointer is NULL!");
return kFALSE;
}
TList* list = new TList();
HZip::getList(zipname,list,filter,size,time);
HZip::list(zipname,filter,size,time);
TObjString* member;
TIterator* iter = list->MakeIterator();
while((member = (TObjString*)iter->Next()) != 0){
TString membername = member->GetString();
TString fullname = zipname + "#" + membername;
chain->Add(fullname.Data());
}
delete iter;
delete list;
return kTRUE;
}
static Bool_t makeChainGlob(TString expressionzip,TChain* chain = 0,TString filter=".*",Int_t size=0,Int_t time=0)
{
if(chain == 0){
printf("Error: makeChainGlob() : TChain pointer is NULL!");
return kFALSE;
}
TObjArray* files = HZip::glob(expressionzip);
Int_t nfiles = files->GetEntries();
if(nfiles == 0) return kFALSE;
for(Int_t j=0;j<nfiles;j++){
TString fna = ((TObjString*)(files->At(j)))->GetString();
HZip::makeChain(fna,chain,filter,size,time);
}
delete files;
return kTRUE;
}
static Bool_t makeChainList(TString listfile,TChain* chain = 0,TString filter=".*",Int_t size=0,Int_t time=0)
{
if(chain == 0){
printf("Error: makeChainList() : TChain pointer is NULL!");
return kFALSE;
}
if(gSystem->AccessPathName(listfile)){
printf("Error: makeChainList() : list file does not exist!");
return kFALSE;
}
Char_t line[1000];
ifstream inp;
inp.open(listfile.Data());
TString name;
while(!inp.eof()){
inp.getline (line, 1000);
name = line;
if(gSystem->AccessPathName(name)){
printf("Error: makeChainList() : file %s does not exist!",name.Data());
continue;
}
HZip::makeChain(name,chain,filter,size,time);
}
inp.close();
return kTRUE;
}
static Bool_t addFile(TString zipname,TString membername, Int_t mode=0)
{
TString zipName = zipname;
zipName.ReplaceAll(".zip","");
TString cmd = Form("zip -j -g -n .root %s %s 1>/dev/null",zipName.Data(),membername.Data());
if(!HZip::exists(membername,kFALSE,kFALSE)) return kFALSE;
if(!HZip::exists(zipname,kTRUE))
{
Int_t rc = gSystem->Exec(cmd.Data());
if(rc == 0) {
cout<<"adding: "<<membername.Data()<<" (new)"<<endl;
return kTRUE;
}
else {
printf("Error: addFile() : zip returned with error!\n");
return kFALSE;
}
} else {
Bool_t inside = HZip::isInside(zipname + "#" + membername);
if(mode == 2){
Int_t rc = gSystem->Exec(cmd.Data());
if(rc == 0) {
if(!inside){
cout<<"adding: "<<membername.Data()<<" (added)"<<endl;
} else {
cout<<"adding: "<<membername.Data()<<" (replace)"<<endl;
}
return kTRUE; }
else {
printf("Error: addFile() : zip returned with error!\n");
return kFALSE;
}
} else {
if(!HZip::isInside(zipname + "#" + membername)){
Int_t rc = gSystem->Exec(cmd.Data());
if(rc == 0) {
cout<<"adding: "<<membername.Data()<<" (new)"<<endl;
return kTRUE;
}
else {
printf("Error: addFile() : zip returned with error!\n");
return kFALSE;
}
} else {
if (mode == 0) {
printf("Error: addFile() : Member = %s already existing inside zipfile %s\n!",membername.Data(),zipname.Data());
return kFALSE;
} else {
cout<<"adding: "<<membername.Data()<<" (replace)"<<endl;
return kTRUE;
}
}
}
}
return kFALSE;
}
static Bool_t addFiles(TString zipname,TList* list, Int_t mode=0)
{
cout<<"-------------------------------------------------------------------------------"<<endl;
cout<<"Adding files to file "<<zipname.Data()<<" :"<<endl;
TObjString* member;
TIterator* iter = list->MakeIterator();
while((member = (TObjString*)iter->Next()) != 0){
TString membername = member->GetString();
if(!addFile(zipname,membername,mode)) {
delete iter;
cout<<"-------------------------------------------------------------------------------"<<endl;
return kFALSE;
}
}
cout<<"-------------------------------------------------------------------------------"<<endl;
delete iter;
return kTRUE;
}
static Bool_t test(TString zipname){
TString cmd = Form("unzip -t %s",zipname.Data());
Int_t rc = gSystem->Exec(cmd.Data());
if(rc == 0) { return kTRUE; }
else {
printf("Error: test() : zip returned with error!");
return kFALSE;
}
}
static Bool_t unzip(TString zipname,TString outDir=""){
TString cmd;
if(outDir != "") cmd = Form("unzip %s -d %s",zipname.Data(),outDir.Data());
else cmd = Form("unzip %s" ,zipname.Data());
Int_t rc = gSystem->Exec(cmd.Data());
if(rc == 0) { return kTRUE; }
else {
printf("Error: unzip() : zip returned with error!");
return kFALSE;
}
}
ClassDef(HZip,0);
};
#endif