--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+#include "TROOT.h"
+#include "AliArrayBranch.h"
+#include "TFile.h"
+#include "TTree.h"
+#include "TBasket.h"
+#include "TClass.h"
+#include "TRealData.h"
+#include "TDataType.h"
+#include "TDataMember.h"
+
+#include "TBranch.h"
+#include "TBranchClones.h"
+#include "TLeaf.h"
+#include "TLeafB.h"
+#include "TLeafC.h"
+#include "TLeafF.h"
+#include "TLeafD.h"
+#include "TLeafI.h"
+#include "TLeafS.h"
+#include "TLeafObject.h"
+
+#include "AliObjectArray.h"
+#include "AliDataType.h"
+
+//-----------------------------------------------------
+// A Branch for the case of an array of clone objects.
+//-----------------------------------------------------
+
+//*KEND.
+
+R__EXTERN TTree *gTree;
+
+ClassImp(AliArraySubBranch)
+ClassImp(AliArrayBranch)
+ClassImp(AliObjectBranch)
+ClassImp(AliTree)
+
+
+
+Int_t AliArraySubBranch::GetEntryExport(Int_t entry, Int_t getall, AliObjectArray *list, Int_t nentries)
+{
+//*-*-*-*-*-*Read all leaves of entry and return total number of bytes*-*-*
+//*-* export buffers to real objects in the AliObjectArray list.
+//*-*
+
+ if (TestBit(kDoNotProcess)) return 0;
+ if (fReadEntry == entry) return 1;
+ if (entry < 0 || entry >= fEntryNumber) return 0;
+ Int_t nbytes;
+ Int_t first = fBasketEntry[fReadBasket];
+ Int_t last;
+ if (fReadBasket == fWriteBasket) last = fEntryNumber - 1;
+ else last = fBasketEntry[fReadBasket+1] - 1;
+//
+// Are we still in the same ReadBasket?
+ if (entry < first || entry > last) {
+ fReadBasket = TMath::BinarySearch(fWriteBasket+1, fBasketEntry, entry);
+ first = fBasketEntry[fReadBasket];
+ }
+
+// We have found the basket containing this entry.
+// make sure basket buffers are in memory.
+ TBasket *basket = GetBasket(fReadBasket);
+ if (!basket) return 0;
+ TBuffer *buf = basket->GetBufferRef();
+// Set entry offset in buffer and read data from all leaves
+ if (!buf->IsReading()) {
+ basket->SetReadMode();
+ }
+// Int_t bufbegin = basket->GetEntryPointer(entry-first);
+ Int_t bufbegin;
+ Int_t *entryOffset = basket->GetEntryOffset();
+ if (entryOffset) bufbegin = entryOffset[entry-first];
+ else bufbegin = basket->GetKeylen() + (entry-first)*basket->GetNevBufSize();
+ buf->SetBufferOffset(bufbegin);
+
+ TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
+ // leaf->ReadBasketExport(*buf,list,nentries); //!!! MI
+ ReadBasketExport(*buf,leaf, list,nentries);
+ nbytes = buf->Length() - bufbegin;
+ fReadEntry = entry;
+
+ return nbytes;
+}
+
+void AliArraySubBranch::ReadBasketExport(TBuffer &b, TLeaf *leaf, AliObjectArray *list, Int_t n)
+{
+ //
+ //
+ Int_t len = leaf->GetLenStatic();
+ Int_t offset = leaf->GetOffset();
+ void *value = leaf->GetValuePointer();
+
+ //8bit integer
+ if (leaf->IsA()==TLeafB::Class()){
+ Int_t j = 0;
+ for (Int_t i=0;i<n;i++) {
+ memcpy((char*)list->UncheckedAt(i) + offset,&((Char_t*)value)[j], len);
+ j += len;
+ }
+ }
+ //variable length string.
+ if (leaf->IsA()==TLeafC::Class()){
+ UChar_t len;
+ b >> len;
+ if (len) {
+ if (len >= len) len = len-1;
+ b.ReadFastArray((Char_t*)value,len);
+ ((Char_t*)value)[len] = 0;
+ } else {
+ value = 0;
+ }
+ Int_t j = 0;
+ for (Int_t i=0;i<n;i++) {
+ memcpy((char*)list->UncheckedAt(i) + offset,&((Char_t*)value)[j], 1);
+ j += len;
+ }
+ }
+ //double
+ if (leaf->IsA()==TLeafD::Class()){
+ b.ReadFastArray(((Double_t*)value),n*len);
+ Int_t j = 0;
+ for (Int_t i=0;i<n;i++) {
+ memcpy((char*)list->UncheckedAt(i) + offset,&((Double_t*)value)[j], 8*len);
+ j += len;
+ }
+ }
+ //float
+ if (leaf->IsA()==TLeafF::Class()){
+ if (n*len == 1) {
+ b >> ((Float_t*)value)[0];
+ } else {
+ b.ReadFastArray(((Float_t*)value),n*len);
+ }
+
+ Float_t *val = (Float_t*)value;
+ for (Int_t i=0;i<n;i++) {
+ char *first = (char*)list->UncheckedAt(i);
+ Float_t *ff = (Float_t*)&first[offset];
+ for (Int_t j=0;j<len;j++) {
+ ff[j] = val[j];
+ }
+ val += len;
+ }
+ return;
+ }
+ //int2
+ if (leaf->IsA()==TLeafS::Class()){
+ if (n*len == 1) {
+ b >> ((Short_t*)value)[0];
+ } else {
+ b.ReadFastArray(((Short_t*)value),n*len);
+ }
+ Short_t *val = (Short_t*)value;
+ for (Int_t i=0;i<n;i++) {
+ char *first = (char*)list->UncheckedAt(i);
+ Short_t *ii = (Short_t*)&first[offset];
+ for (Int_t j=0;j<len;j++) {
+ ii[j] = val[j];
+ }
+ val += len;
+ }
+ return;
+ }
+ //int4
+ if (leaf->IsA()==TLeafI::Class()){
+ if (n*len == 1) {
+ b >> ((Int_t*)value)[0];
+ } else {
+ b.ReadFastArray(((Int_t*)value),n*len);
+ }
+ Int_t *val = (Int_t*)value;
+ for (Int_t i=0;i<n;i++) {
+ char *first = (char*)list->UncheckedAt(i);
+ Int_t *ii = (Int_t*)&first[offset];
+ for (Int_t j=0;j<len;j++) {
+ ii[j] = val[j];
+ }
+ val += len;
+ }
+ return;
+ }
+}
+
+
+//______________________________________________________________________________
+AliArrayBranch::AliArrayBranch(): TBranch()
+{
+//*-*-*-*-*-*Default constructor for BranchClones*-*-*-*-*-*-*-*-*-*
+//*-* ====================================
+
+ fList = 0;
+ fRead = 0;
+ fN = 0;
+ fNdataMax = 0;
+ fBranchCount = 0;
+}
+
+
+//______________________________________________________________________________
+AliArrayBranch::AliArrayBranch(const Text_t *name, void *pointer, TTree * tree, Int_t basketsize, Int_t compress)
+ :TBranch()
+{
+//*-*-*-*-*-*-*-*-*-*-*-*-*Create a BranchClones*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+//*-* =====================
+//
+ char leaflist[80];
+ char branchname[80];
+ char branchcount[64];
+ fTree = tree;
+ gTree = tree; // MI because some bug in ROOT I didn't obtain proper gTree
+ // it is necesary to set gTree because oder subranchces defined below need it
+ SetName(name);
+ if (compress == -1) {
+ TFile *bfile = fTree->GetDirectory()->GetFile();
+ if (bfile) compress = bfile->GetCompressionLevel();
+ }
+ char *cpointer = (char*)pointer;
+ char **ppointer = (char**)(cpointer);
+ fList = (AliObjectArray*)(*ppointer);
+ fAddress = cpointer;
+ fRead = 0;
+ fN = 0;
+ fNdataMax = 0;
+
+ AliClassInfo *clinfo = fList->GetClassInfo();
+ if (!clinfo) return;
+ fClassName = clinfo->GetName();
+
+//*-*- Create a branch to store the array count
+ if (basketsize < 100) basketsize = 100;
+ sprintf(leaflist,"%s_/I",name);
+ sprintf(branchcount,"%s_",name);
+ fBranchCount = new TBranch(branchcount,&fN,leaflist,basketsize);
+ fBranchCount->SetBit(kIsClone);
+ TLeaf *leafcount = (TLeaf*)fBranchCount->GetListOfLeaves()->UncheckedAt(0);
+
+//*-*- Create the first basket
+
+ fDirectory = fTree->GetDirectory();
+ fFileName = "";
+
+ TBasket *basket = new TBasket(branchcount,fTree->GetName(),this);
+ fBaskets.Add(basket);
+
+//*-*- Loop on all public data members of the class and its base classes
+
+ TClass *cl = fList->GetClass();
+ if (cl){
+ if (!cl->GetListOfRealData()) cl->BuildRealData();
+
+ const char *itype = 0;
+ TRealData *rd;
+ TIter next(cl->GetListOfRealData());
+ while ((rd = (TRealData *) next())) {
+ TDataMember *member = rd->GetDataMember();
+ if (!member->IsBasic()) {
+ Warning("BranchClones","Cannot process member:%s",member->GetName());
+ continue;
+ }
+ if (!member->IsPersistent()) continue; //do not process members with a ! as the first
+ // character in the comment field
+ TDataType *membertype = member->GetDataType();
+ Int_t type = membertype->GetType();
+ if (type == 0) {
+ Warning("BranchClones","Cannot process member:%s",member->GetName());
+ continue;
+ }
+ if (type == 1) itype = "B";
+ if (type == 11) itype = "b";
+ if (type == 3) itype = "I";
+ if (type == 5) itype = "F";
+ if (type == 8) itype = "D";
+ if (type == 13) itype = "i";
+ if (type == 2) itype = "S";
+ if (type == 12) itype = "s";
+
+
+ Int_t arraydim = member->GetArrayDim();
+ if (arraydim!=1){
+ // OLD Version
+ sprintf(leaflist,"%s[%s]/%s",member->GetName(),branchcount,itype);
+ Int_t comp = compress;
+ if (type == 5) comp--;
+ sprintf(branchname,"%s.%s",name,rd->GetName());
+ TBranch *branch = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
+ branch->SetBit(kIsClone);
+ TObjArray *leaves = branch->GetListOfLeaves();
+ TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
+ leaf->SetOffset(rd->GetThisOffset());
+ leaf->SetLeafCount(leafcount);
+ Int_t arraydim = member->GetArrayDim();
+ if (arraydim) {
+ Int_t maxindex = member->GetMaxIndex(arraydim-1);
+ leaf->SetLen(maxindex);
+ }
+ fBranches.Add(branch);
+ }
+ else
+ for (Int_t i=0;i< member->GetMaxIndex(0);i++){
+ const char * dmname = member->GetName() ;
+ char bname[200];
+ Int_t j=0;
+ while ( (dmname[j]!='[') && (dmname[j]!=0) ){
+ bname[j]=dmname[j];
+ j++;
+ }
+ bname[j]=0;
+ sprintf(leaflist,"%s(%d)[%s]/%s",bname,i,branchcount,itype);
+ Int_t comp = compress;
+ if (type == 5) comp--;
+ sprintf(branchname,"%s.%s(%d)",name,bname,i);
+ TBranch *branch = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
+ branch->SetBit(kIsClone);
+ TObjArray *leaves = branch->GetListOfLeaves();
+ TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
+ leaf->SetOffset(rd->GetThisOffset()+membertype->Size()*i);
+ leaf->SetLeafCount(leafcount);
+ fBranches.Add(branch);
+ }
+
+ }
+ }
+ else if (clinfo->IsA()->InheritsFrom("AliDataType")){ //branch for basic type
+ Int_t type = (((AliDataType*)clinfo)->GetDataType())->GetType();
+ char *itype = 0;
+ if (type <=0)
+ Warning("BranchClones","Cannot process member:%s",clinfo->GetName());
+ else{
+
+ if (type == 1) itype = "B";
+ if (type == 11) itype = "b";
+ if (type == 3) itype = "I";
+ if (type == 5) itype = "F";
+ if (type == 8) itype = "D";
+ if (type == 13) itype = "i";
+ if (type == 2) itype = "S";
+ if (type == 12) itype = "s";
+ sprintf(leaflist,"%s[%s]/%s",name,branchcount,itype);
+ Int_t comp = compress;
+ if (type == 5) comp--;
+ sprintf(branchname,"%s",clinfo->GetName());
+ TBranch *branch = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
+ branch->SetBit(kIsClone);
+ TObjArray *leaves = branch->GetListOfLeaves();
+ TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
+ leaf->SetOffset(0);
+ leaf->SetLeafCount(leafcount);
+ fBranches.Add(branch);
+ }
+ }
+
+}
+
+
+//______________________________________________________________________________
+AliArrayBranch::~AliArrayBranch()
+{
+//*-*-*-*-*-*Default destructor for a BranchClones*-*-*-*-*-*-*-*-*-*-*-*
+//*-* =====================================
+
+ delete fBranchCount;
+ fBranchCount = 0;
+ fBranches.Delete();
+ fList = 0;
+}
+
+
+//______________________________________________________________________________
+void AliArrayBranch::Browse(TBrowser *b)
+{
+ fBranches.Browse( b );
+}
+
+//______________________________________________________________________________
+Int_t AliArrayBranch::Fill()
+{
+//*-*-*-*-*Loop on all Branches of this BranchClones to fill Basket buffer*-*
+//*-* ===============================================================
+
+ Int_t i;
+ Int_t nbytes = 0;
+ Int_t nbranches = fBranches.GetEntriesFast();
+ char **ppointer = (char**)(fAddress);
+ if (ppointer == 0) return 0;
+ fList = (AliObjectArray*)(*ppointer);
+ // fN = fList->GetEntriesFast();
+ fN = fList->GetSize();
+ fEntries++;
+
+ if (fN > fNdataMax) {
+ fNdataMax = fList->GetSize();
+ char branchcount[64];
+ sprintf(branchcount,"%s_",GetName());
+ TLeafI *leafi = (TLeafI*)fBranchCount->GetLeaf(branchcount);
+ leafi->SetMaximum(fNdataMax);
+ for (i=0;i<nbranches;i++) {
+ TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
+ TObjArray *leaves = branch->GetListOfLeaves();
+ TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
+ leaf->SetAddress();
+ }
+ }
+ nbytes += fBranchCount->Fill();
+ for (i=0;i<nbranches;i++) {
+ TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
+ TObjArray *leaves = branch->GetListOfLeaves();
+ TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
+ // leaf->Import(fList, fN); // MI
+ Import(leaf,fN); // MI change
+ nbytes += branch->Fill();
+ }
+ return nbytes;
+}
+
+//______________________________________________________________________________
+Int_t AliArrayBranch::GetEntry(Int_t entry, Int_t getall)
+{
+//*-*-*-*-*Read all branches of a BranchClones and return total number of bytes
+//*-* ====================================================================
+
+ if (TestBit(kDoNotProcess) && !getall) return 0;
+ Int_t nbytes = fBranchCount->GetEntry(entry);
+ TLeaf *leafcount = (TLeaf*)fBranchCount->GetListOfLeaves()->UncheckedAt(0);
+ fN = Int_t(leafcount->GetValue());
+ if (fN <= 0) return 0;
+
+ TBranch *branch;
+ Int_t nbranches = fBranches.GetEntriesFast();
+
+ // if fList exists, create clonesarray objects
+ if (fList) {
+ //fList->ExpandCreateFast(fN); //MI
+ fList->Resize(fN); //MI change
+ for (Int_t i=0;i<nbranches;i++) {
+ branch = (TBranch*)fBranches.UncheckedAt(i);
+ nbytes += ((AliArraySubBranch*)branch)->GetEntryExport(entry, getall, fList, fN); // !!!MI
+ }
+ } else {
+ for (Int_t i=0;i<nbranches;i++) {
+ branch = (TBranch*)fBranches.UncheckedAt(i);
+ nbytes += branch->GetEntry(entry, getall);
+ }
+ }
+ return nbytes;
+}
+
+//______________________________________________________________________________
+void AliArrayBranch::Print(Option_t *option)
+{
+//*-*-*-*-*-*-*-*-*-*-*-*Print TBranch parameters*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+//*-* ========================
+
+ fBranchCount->Print(option);
+ Int_t i;
+ Int_t nbranches = fBranches.GetEntriesFast();
+ for (i=0;i<nbranches;i++) {
+ TBranch *branch = (TBranch*)fBranches[i];
+ branch->Print(option);
+ }
+}
+
+//______________________________________________________________________________
+void AliArrayBranch::Reset(Option_t *option)
+{
+//*-*-*-*-*-*-*-*Reset a Branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+//*-* ====================
+//
+// Existing buffers are deleted
+// Entries, max and min are reset
+//
+
+ fEntries = 0;
+ fTotBytes = 0;
+ fZipBytes = 0;
+ Int_t i;
+ Int_t nbranches = fBranches.GetEntriesFast();
+ for (i=0;i<nbranches;i++) {
+ TBranch *branch = (TBranch*)fBranches[i];
+ branch->Reset(option);
+ }
+ fBranchCount->Reset();
+}
+
+//______________________________________________________________________________
+void AliArrayBranch::SetAddress(void *add)
+{
+//*-*-*-*-*-*-*-*Set address of this branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+//*-* ====================
+//*-*
+
+ fReadEntry = -1;
+ fAddress = (char*)add;
+ char **ppointer = (char**)(fAddress);
+ if ( (*ppointer)==0 ) { //MI change
+ *ppointer = (char*) new AliObjectArray(fClassName);
+ fAddress = (char*)ppointer;
+ }
+ fList = (AliObjectArray*)(*ppointer);
+ fBranchCount->SetAddress(&fN);
+
+}
+
+//______________________________________________________________________________
+void AliArrayBranch::SetBasketSize(Int_t buffsize)
+{
+//*-*-*-*-*-*-*-*Reset basket size for all subbranches of this branchclones
+//*-* ==========================================================
+//
+
+ fBasketSize = buffsize;
+ Int_t i;
+ Int_t nbranches = fBranches.GetEntriesFast();
+ for (i=0;i<nbranches;i++) {
+ TBranch *branch = (TBranch*)fBranches[i];
+ branch->SetBasketSize(buffsize);
+ }
+}
+
+//_______________________________________________________________________
+void AliArrayBranch::Streamer(TBuffer &b)
+{
+//*-*-*-*-*-*-*-*-*Stream a class object*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+//*-* =========================================
+ if (b.IsReading()) {
+ b.ReadVersion(); //Version_t v = b.ReadVersion();
+ TNamed::Streamer(b);
+ b >> fCompress;
+ b >> fBasketSize;
+ b >> fEntryOffsetLen;
+ b >> fMaxBaskets;
+ b >> fWriteBasket;
+ b >> fEntryNumber;
+ b >> fEntries;
+ b >> fTotBytes;
+ b >> fZipBytes;
+ b >> fOffset;
+ b >> fBranchCount;
+ fClassName.Streamer(b);
+ fBranches.Streamer(b);
+ fTree = gTree;
+ TBranch *branch;
+ TLeaf *leaf;
+ Int_t nbranches = fBranches.GetEntriesFast();
+ for (Int_t i=0;i<nbranches;i++) {
+ branch = (TBranch*)fBranches[i];
+ branch->SetBit(kIsClone);
+ leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(0);
+ leaf->SetOffset(0);
+ }
+ fRead = 1;
+
+ AliClassInfo *clinfo = AliClassInfo::FindClassInfo(fClassName);
+ if (!clinfo) {
+ AliObjectArray tmp(fClassName);
+ //MI change - object array to construct class description
+ clinfo = AliClassInfo::FindClassInfo(fClassName);
+ }
+ if (!clinfo) return;
+
+ TClass *cl = clinfo->GetClass();
+ // if (!cl) {
+ // Warning("Streamer","Unknow class: %s. Cannot read BranchClones: %s",
+ // fClassName.Data(),GetName());
+ // return;
+ //}
+ if (cl){
+
+ if (!cl->GetListOfRealData()) cl->BuildRealData();
+ char branchname[80];
+ TRealData *rd;
+ TIter next(cl->GetListOfRealData());
+ while ((rd = (TRealData *) next())) {
+ TDataMember *member = rd->GetDataMember();
+ if (!member->IsBasic()) continue;
+ if (!member->IsPersistent()) continue;
+ TDataType *membertype = member->GetDataType();
+ if (membertype->GetType() == 0) continue;
+ //MI change - for array spliting
+ Int_t arraydim = member->GetArrayDim();
+ if (arraydim==1){
+ for (Int_t i=0;i< member->GetMaxIndex(0);i++){
+ const char * dmname = member->GetName() ;
+ char bname[200];
+ Int_t j=0;
+ while ( (dmname[j]!='[') && (dmname[j]!=0) ){
+ bname[j]=dmname[j];
+ j++;
+ }
+ bname[j]=0;
+ sprintf(branchname,"%s.%s(%d)",GetName(),bname,i);
+ branch = (TBranch*)fBranches.FindObject(branchname);
+ if (!branch) continue;
+ TObjArray *leaves = branch->GetListOfLeaves();
+ leaf = (TLeaf*)leaves->UncheckedAt(0);
+ leaf->SetOffset(rd->GetThisOffset()+membertype->Size()*i);
+ }
+ }
+ sprintf(branchname,"%s.%s",GetName(),rd->GetName());
+ branch = (TBranch*)fBranches.FindObject(branchname);
+ if (!branch) continue;
+ TObjArray *leaves = branch->GetListOfLeaves();
+ leaf = (TLeaf*)leaves->UncheckedAt(0);
+ leaf->SetOffset(rd->GetThisOffset());
+ }
+
+ }
+ else if (clinfo->IsA()->InheritsFrom("AliDataType")){ //branch for basic type
+ char branchname[100];
+ sprintf(branchname,"%s",clinfo->GetName());
+ branch = (TBranch*)fBranches.FindObject(branchname);
+ if (branch){
+ TObjArray *leaves = branch->GetListOfLeaves();
+ leaf = (TLeaf*)leaves->UncheckedAt(0);
+ leaf->SetOffset(0);
+ }
+ }
+ }
+ else{
+
+ b.WriteVersion(AliArrayBranch::IsA());
+ TNamed::Streamer(b);
+ b << fCompress;
+ b << fBasketSize;
+ b << fEntryOffsetLen;
+ b << fMaxBaskets;
+ b << fWriteBasket;
+ b << fEntryNumber;
+ b << fEntries;
+ b << fTotBytes;
+ b << fZipBytes;
+ b << fOffset;
+ b << fBranchCount;
+ fClassName.Streamer(b);
+ fBranches.Streamer(b);
+ }
+}
+
+
+
+void AliArrayBranch::Import(TLeaf * leaf, Int_t n)
+{
+
+ const Int_t kIntUndefined = -9999;
+ Int_t j = 0;
+ char *clone;
+ Int_t len = leaf->GetLenStatic();
+ Int_t fOffset = leaf->GetOffset();
+ void *value = leaf->GetValuePointer();
+ //
+ for (Int_t i=0;i<n;i++) {
+ clone = (char*)fList->UncheckedAt(i);
+ //8bit int
+ if (leaf->IsA()==TLeafB::Class()){
+ memcpy(&((Char_t*)value)[j],clone + fOffset, len);
+ }
+ //var size
+ if (leaf->IsA()==TLeafC::Class()){
+ memcpy(&((Char_t*)value)[j],clone + fOffset, 1);
+ }
+ //double
+ if (leaf->IsA()==TLeafD::Class()){
+ if (clone) memcpy(&((Double_t*)value)[j],clone + fOffset, 8*len);
+ else memcpy(&((Double_t*)value)[j],&kIntUndefined, 8*len);
+ }
+ //float
+ if (leaf->IsA()==TLeafF::Class()){
+ if (clone) memcpy(&((Float_t*)value)[j],clone + fOffset, 4*len);
+ else memcpy(&((Float_t*)value)[j],&kIntUndefined, 4*len);
+ }
+ //int
+ if (leaf->IsA()==TLeafI::Class()){
+ if (clone) memcpy(&((Int_t*)value)[j],clone + fOffset, 4*len);
+ else memcpy(&((Int_t*)value)[j],&kIntUndefined, 4*len);
+ }
+ //short
+ if (leaf->IsA()==TLeafS::Class()){
+ if (clone) memcpy(&((Short_t*)value)[j],clone + fOffset, 2*len);
+ else memcpy(&((Short_t*)value)[j],&kIntUndefined, 2*len);
+ }
+ j += len;
+ }
+ //
+}
+
+AliObjectBranch::AliObjectBranch(const Text_t *name, const Text_t *classname, void *addobj,
+ TTree * tree,
+ Int_t basketsize, Int_t splitlevel, Int_t compress): TBranchObject()
+{
+//*-*-*-*-*-*-*-*-*-*-*-*-*Create a BranchObject*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+//*-* =====================
+//
+ TClass *cl = gROOT->GetClass(classname);
+ fTree =tree; //MI change
+ if (!cl) {
+ Error("TBranchObject","Cannot find class:%s",classname);
+ return;
+ }
+ if (!cl->GetListOfRealData()) cl->BuildRealData();
+ Int_t bufsize=basketsize; //MI ?
+ SetName(name);
+ SetTitle(name);
+ fCompress = compress;
+ if (compress == -1) {
+ TFile *bfile = fTree->GetDirectory()->GetFile(); //MI chnge fTrre - gTree
+ if (bfile) fCompress = bfile->GetCompressionLevel();
+ }
+ if (basketsize < 100) basketsize = 100;
+ fBasketSize = basketsize;
+ fAddress = (char*)addobj;
+ fClassName = classname;
+ fBasketEntry = new Int_t[fMaxBaskets];
+ fBasketBytes = new Int_t[fMaxBaskets];
+ fBasketSeek = new Seek_t[fMaxBaskets];
+ fOldObject = 0;
+
+ fBasketEntry[0] = fEntryNumber;
+ fBasketBytes[0] = 0;
+
+ TLeaf *leaf = new TLeafObject(name,classname);
+ leaf->SetBranch(this);
+ leaf->SetAddress(addobj);
+ fNleaves = 1;
+ fLeaves.Add(leaf);
+ fTree->GetListOfLeaves()->Add(leaf); //MI change fTree-gTree
+
+// Set the bit kAutoDelete to specify that when reading
+// in TLeafObject::ReadBasket, the object should be deleted
+// before calling Streamer.
+// It is foreseen to not set this bit in a future version.
+ SetAutoDelete(kTRUE);
+
+//*-*- Create the first basket
+ // fTree = gTree; //MI change - no need anymore
+ fDirectory = fTree->GetDirectory();
+ fFileName = "";
+
+ if (!splitlevel){
+ TBasket *basket = new TBasket(name,fTree->GetName(),this);
+ fBaskets.Add(basket);
+ return;
+ }
+
+ //
+ //
+ TBranch * branch =this;
+ TObjArray *blist = branch->GetListOfBranches();
+ const char *rdname;
+ const char *dname;
+ char branchname[64];
+ if (!cl->GetListOfRealData()) cl->BuildRealData();
+ char **apointer = (char**)(addobj);
+ TObject *obj = (TObject*)(*apointer);
+ Bool_t delobj = kFALSE;
+ if (!obj) {
+ obj = (TObject*)cl->New();
+ delobj = kTRUE;
+ }
+//*-*- Loop on all public data members of the class and its base classes
+ Int_t lenName = strlen(name);
+ Int_t isDot = 0;
+ if (name[lenName-1] == '.') isDot = 1;
+ TBranch *branch1 = 0;
+ TRealData *rd;
+ TIter next(cl->GetListOfRealData());
+ while ((rd = (TRealData *) next())) {
+ TDataMember *dm = rd->GetDataMember();
+ if (!dm->IsPersistent()) continue; //do not process members with a ! as the first
+ // character in the comment field
+ rdname = rd->GetName();
+ dname = dm->GetName();
+
+ // Next line now commented, functionality to process arrays is now implemented
+ // the statement is left to show how to use Property() and kIsArray
+ // if (dm->Property() & kIsArray) continue;
+
+ TDataType *dtype = dm->GetDataType();
+ Int_t code = 0;
+ if (dtype) code = dm->GetDataType()->GetType();
+
+//*-*- Encode branch name. Use real data member name
+ sprintf(branchname,"%s",rdname);
+ if (isDot) {
+ if (dm->IsaPointer()) sprintf(branchname,"%s%s",name,&rdname[1]);
+ else sprintf(branchname,"%s%s",name,&rdname[0]);
+ }
+ char leaflist[64];
+ Int_t offset = rd->GetThisOffset();
+ char *pointer = (char*)obj + offset;
+ if (dm->IsaPointer()) {
+ TClass *clobj = 0;
+ if (!dm->IsBasic()) clobj = gROOT->GetClass(dm->GetTypeName());
+ if (clobj && !strcmp("TClonesArray",clobj->GetName())) {
+ char *cpointer =(char*)pointer;
+ char **ppointer =(char**)cpointer;
+ TClonesArray *list = (TClonesArray*)(*ppointer);
+ if (splitlevel != 2) {
+ if (isDot) branch1 = new TBranchClones(&branchname[0],pointer,bufsize);
+ else branch1 = new TBranchClones(&branchname[1],pointer,bufsize);
+ blist->Add(branch1);
+ } else {
+ if (isDot) branch1 = new TBranchObject(&branchname[0],list->ClassName(),pointer,bufsize);
+ else branch1 = new TBranchObject(&branchname[1],list->ClassName(),pointer,bufsize);
+ blist->Add(branch1);
+ }
+ }
+ else
+ if (clobj && !strcmp("AliObjectArray",clobj->GetName())) {
+ char *cpointer =(char*)pointer;
+ char **ppointer =(char**)cpointer;
+ TClonesArray *list = (TClonesArray*)(*ppointer);
+ if (splitlevel != 2) {
+ if (isDot) branch1 = new AliArrayBranch(&branchname[0],pointer,fTree,bufsize,compress);
+ else branch1 = new AliArrayBranch(&branchname[1],pointer,fTree,bufsize,compress);
+ blist->Add(branch1);
+ } else {
+ if (isDot) branch1 = new AliObjectBranch(&branchname[0],list->ClassName(),pointer,fTree,bufsize);
+ else branch1 = new AliObjectBranch(&branchname[1],list->ClassName(),pointer,fTree,bufsize);
+ blist->Add(branch1);
+ }
+ }
+ else {
+ if (!clobj) {
+ if (code != 1) continue;
+ sprintf(leaflist,"%s/%s",dname,"C");
+ branch1 = new TBranch(branchname,pointer,leaflist,bufsize);
+ branch1->SetTitle(dname);
+ blist->Add(branch1);
+ } else {
+ if (!clobj->InheritsFrom(TObject::Class())) continue;
+ //branch1 = new TBranchObject(dname,clobj->GetName(),pointer,bufsize,0); //MI change
+ branch1 = new AliObjectBranch(dname,clobj->GetName(),pointer,fTree,bufsize,splitlevel);
+ if (isDot) branch1->SetName(&branchname[0]);
+ else branch1->SetName(&branchname[1]); //do not use the first character (*)
+ blist->Add(branch1);
+ }
+ }
+ }else {
+//*-*-------------Data Member is a basic data type----------
+ if (dm->IsBasic()) {
+ if (code == 1) sprintf(leaflist,"%s/%s",rdname,"B");
+ else if (code == 11) sprintf(leaflist,"%s/%s",rdname,"b");
+ else if (code == 2) sprintf(leaflist,"%s/%s",rdname,"S");
+ else if (code == 12) sprintf(leaflist,"%s/%s",rdname,"s");
+ else if (code == 3) sprintf(leaflist,"%s/%s",rdname,"I");
+ else if (code == 13) sprintf(leaflist,"%s/%s",rdname,"i");
+ else if (code == 5) sprintf(leaflist,"%s/%s",rdname,"F");
+ else if (code == 8) sprintf(leaflist,"%s/%s",rdname,"D");
+ else {
+ printf("Cannot create branch for rdname=%s, code=%d\n",branchname, code);
+ leaflist[0] = 0;
+ }
+ branch1 = new TBranch(branchname,pointer,leaflist,bufsize);
+ branch1->SetTitle(rdname);
+ blist->Add(branch1);
+ }
+ }
+ if (branch1) branch1->SetOffset(offset);
+ else Warning("Branch","Cannot process member:%s",rdname);
+ }
+ if (delobj) delete obj;
+}
+
+
+
+//______________________________________________________________________________
+void AliObjectBranch::SetAddress(void *add)
+{
+//*-*-*-*-*-*-*-*Set address of this branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+//*-* ====================
+//
+
+ //special case when called from code generated by TTree::MakeClass
+ if (Long_t(add) == -1) {
+ SetBit(kWarn);
+ return;
+ }
+ fReadEntry = -1;
+ Int_t nbranches = fBranches.GetEntriesFast();
+ TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
+ if (leaf) leaf->SetAddress(add);
+ TBranch *branch;
+ fAddress = (char*)add;
+ char *pointer = fAddress;
+ void **ppointer = (void**)add;
+ TObject *obj = (TObject*)(*ppointer);
+ TClass *cl = gROOT->GetClass(fClassName.Data());
+ if (!obj && cl) {
+ obj = (TObject*)cl->New();
+ *ppointer = (void*)obj;
+ }
+ Int_t i, offset;
+ if (!cl) {
+ for (i=0;i<nbranches;i++) {
+ branch = (TBranch*)fBranches[i];
+ pointer = (char*)obj;
+ branch->SetAddress(pointer);
+ }
+ return;
+ }
+ if (!cl->GetListOfRealData()) cl->BuildRealData();
+ char *fullname = new char[200];
+ const char *bname = GetName();
+ Int_t lenName = strlen(bname);
+ Int_t isDot = 0;
+ if (bname[lenName-1] == '.') isDot = 1;
+ const char *rdname;
+ TRealData *rd;
+ TIter next(cl->GetListOfRealData());
+ while ((rd = (TRealData *) next())) {
+ TDataMember *dm = rd->GetDataMember();
+ if (!dm->IsPersistent()) continue;
+ rdname = rd->GetName();
+ TDataType *dtype = dm->GetDataType();
+ Int_t code = 0;
+ if (dtype) code = dm->GetDataType()->GetType();
+ offset = rd->GetThisOffset();
+ pointer = (char*)obj + offset;
+ branch = 0;
+ if (dm->IsaPointer()) {
+ TClass *clobj = 0;
+ if (!dm->IsBasic()) clobj = gROOT->GetClass(dm->GetTypeName());
+ if (clobj && !strcmp("TClonesArray",clobj->GetName())) {
+ if (isDot) sprintf(fullname,"%s%s",bname,&rdname[1]);
+ else sprintf(fullname,"%s",&rdname[1]);
+ branch = (TBranch*)fBranches.FindObject(fullname);
+ }
+ else
+ if (clobj && !strcmp("AliObjectArray",clobj->GetName())) {
+ if (isDot) sprintf(fullname,"%s%s",bname,&rdname[1]);
+ else sprintf(fullname,"%s",&rdname[1]);
+ branch = (TBranch*)fBranches.FindObject(fullname);
+ }
+ else {
+ if (!clobj) {
+ if (code != 1) continue;
+ if (isDot) sprintf(fullname,"%s%s",bname,&rdname[0]);
+ else sprintf(fullname,"%s",&rdname[0]);
+ branch = (TBranch*)fBranches.FindObject(fullname);
+ } else {
+ if (!clobj->InheritsFrom(TObject::Class())) continue;
+ if (isDot) sprintf(fullname,"%s%s",bname,&rdname[1]);
+ else sprintf(fullname,"%s",&rdname[1]);
+ branch = (TBranch*)fBranches.FindObject(fullname);
+ }
+ }
+ } else {
+ if (dm->IsBasic()) {
+ if (isDot) sprintf(fullname,"%s%s",bname,&rdname[0]);
+ else sprintf(fullname,"%s",&rdname[0]);
+ branch = (TBranch*)fBranches.FindObject(fullname);
+ }
+ }
+ if(branch) branch->SetAddress(pointer);
+ }
+ delete [] fullname;
+}
+
+
+
+
+
+AliTree::AliTree(const char *name,const char *title, Int_t maxvirtualsize):
+ TTree(name,title,maxvirtualsize)
+{
+ //
+ //default constructor for AliTree
+ gTree =this;
+}
+
+TBranch * AliTree::AliBranch(const char *name, void *clonesaddress, Int_t bufsize, Int_t splitlevel,
+ Int_t compres)
+{
+ if (clonesaddress == 0) return 0;
+ char *cpointer =(char*)clonesaddress;
+ char **ppointer =(char**)cpointer;
+ AliObjectArray *list = (AliObjectArray*)(*ppointer);
+ if (list == 0) return 0;
+ gTree = this;
+ if (splitlevel) {
+ TBranch *branch = new AliArrayBranch(name,clonesaddress,this,bufsize, compres);
+ fBranches.Add(branch);
+ return branch;
+ } else {
+ TBranchObject *branch = new TBranchObject(name,list->ClassName(),clonesaddress,bufsize,0);
+ fBranches.Add(branch);
+ return branch;
+ }
+}
+
+TBranch* AliTree::AliBranch(const char *name, const char *classname, void *addobj,
+ Int_t bufsize, Int_t splitlevel)
+{
+ gTree = this;
+ TClass *cl = gROOT->GetClass(classname);
+ if (!cl) {
+ Error("BranchObject","Cannot find class:%s",classname);
+ return 0;
+ }
+ TBranch * branch = new AliObjectBranch(name,classname,addobj, this, bufsize,splitlevel);
+ fBranches.Add(branch);
+ return branch;
+}
+
+
--- /dev/null
+#ifndef ALIARRAYBRANCH_H
+#define ALIARRAYBRANCH_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+
+//////////////////////////////////////////////////////////////////////////
+// //
+// AliArrayBranch //
+// //
+// A Branch for the case of an array of clone objects. //
+//////////////////////////////////////////////////////////////////////////
+
+
+#include "TBranch.h"
+#include "TTree.h"
+#include "TBranchObject.h"
+class AliObjectArray;
+
+class AliArraySubBranch : public TBranch {
+public:
+ AliArraySubBranch(){;}
+ AliArraySubBranch(const char* name, void* address, const char* leaflist, Int_t basketsize = 32000,
+ Int_t compress = -1):TBranch(name, address, leaflist, basketsize, compress){;}
+ virtual Int_t GetEntryExport(Int_t entry, Int_t getall, AliObjectArray* list, Int_t n);
+ virtual void ReadBasketExport(TBuffer &b, TLeaf *leaf, AliObjectArray *list, Int_t n);
+ ClassDef(AliArraySubBranch,1) //Branch in case of an array of clone objects
+};
+
+class AliArrayBranch : public TBranch {
+
+private:
+ void Import(TLeaf * leaf, Int_t n); //integer fill leef buffer
+protected:
+ AliObjectArray *fList; //Pointer to the clonesarray
+ Int_t fRead; //flag = 1 if clonesarray has been read
+ Int_t fN; //Number of elements in ClonesArray
+ Int_t fNdataMax; //Maximum value of fN
+ TString fClassName; //name of the class of the objets in the ClonesArray
+ TBranch *fBranchCount; //Branch with clones count
+
+public:
+ AliArrayBranch();
+ AliArrayBranch(const Text_t *name, void *clonesaddress, TTree * tree, Int_t basketsize=32000,Int_t compress=-1);
+ virtual ~AliArrayBranch();
+
+ virtual void Browse(TBrowser *b);
+ virtual Int_t Fill();
+ virtual Int_t GetEntry(Int_t entry=0, Int_t getall = 0);
+ virtual Int_t GetN() {return fN;}
+ AliObjectArray *GetList() {return fList;}
+ Bool_t IsFolder() {return kTRUE;}
+ virtual void Print(Option_t *option="");
+ virtual void Reset(Option_t *option="");
+ virtual void SetAddress(void *add);
+ virtual void SetBasketSize(Int_t buffsize);
+ virtual Bool_t IsFolder() const {return kTRUE;}
+ ClassDef(AliArrayBranch,1) //Branch in case of an array of clone objects
+};
+
+
+class AliObjectBranch: public TBranchObject{
+public:
+ AliObjectBranch():TBranchObject(){;}
+ AliObjectBranch(const Text_t *name, const Text_t *classname, void *addobj, TTree * tree,
+ Int_t basketsize=32000, Int_t splitlevel = 0, Int_t compress=-1);
+ void SetAddress(void *add);
+ ClassDef(AliObjectBranch,1)
+};
+
+class AliTree : public TTree {
+public:
+ AliTree():TTree(){;}
+ AliTree(const char *name,const char *title, Int_t maxvirtualsize=0);
+ TBranch* AliBranch(const char *name, void *clonesaddress, Int_t bufsize =32000,
+ Int_t splitlevel=1,Int_t compres=1);
+ TBranch* AliBranch(const char *name, const char *classname, void *addobj,
+ Int_t bufsize=32000, Int_t splitlevel=1);
+ ClassDef(AliTree,1)
+};
+
+#endif
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+///////////////////////////////////////////////////////////////////////////////
+// //
+// AliArrayVT //
+//
+//
+// //
+/*
+
+
+*/
+//Begin_Html
+/*
+
+<img src="../gif/AliObjectArray.gif">
+*/
+//End_Html
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+
+
+
+ClassImp(AliArrayVT)
--- /dev/null
+#ifndef ALIARRAYVT_H
+#define ALIARRAYVT_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+
+
+class AliArrayVT: public TObject{
+ //
+ //function object
+ //for AliObjectArray
+ //
+public:
+ AliArrayVT(){cmp=0; mkbuffer=0; delbuffer=0; stream=0; dump=0;fClass=0;}
+
+ int Compare(void* p1, void* p2) { return (*cmp)(p1,p2);}
+ char * MakeBuffer(UInt_t size) { return (*mkbuffer)(size);}
+ void DeleteBuffer(void * p) { return (*delbuffer)(p);}
+ void CTORBuffer(void *p, const UInt_t size) { return (*ctorbuffer)(p,size);}
+ void DTORBuffer(void * p, const UInt_t size) { return (*dtorbuffer)(p,size);}
+ void ObjectCTOR(void *p) { return (*objectctor)(p);}
+ void ObjectDTOR(void * p) { return (*objectdtor)(p);}
+ void StreamObject(TBuffer& b, void * object) {return (*stream)(b, object);}
+ void StreamBuffer(TBuffer& b, const void *object, UInt_t size) {return (*streamb)(b,object,size);}
+ void ClassDump(void *p) { return (*dump)(p);}
+public:
+ int (*cmp)(void*, void*);
+ char* (*mkbuffer)(UInt_t );
+ void (*delbuffer)(void*);
+ void (*objectctor)(void*);
+ void (*objectdtor)(void*);
+ void (*ctorbuffer)(void*, UInt_t size);
+ void (*dtorbuffer)(void*, UInt_t size);
+
+ void (*stream)(TBuffer &, void *);
+ void (*streamb)(TBuffer &, const void *,UInt_t);
+ void (*dump)(void*);
+ TString fClassName; //class name of the object
+ TClass * fClass; //class type of the object
+ UInt_t fSize; //size of object
+ ClassDef(AliArrayVT,0)
+};
+
+#endif //ALIARRAYVT
+
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+///////////////////////////////////////////////////////////////////////////////
+// //
+// AliClassInfo //
+// //
+//Defined to make unified interface to primitive types (in Root described by //
+// TDataType) and TClass. //
+// Additional virtual function (comparing to ROOT TClass) neccesary //
+// for AliContainers //
+// virtual void CTORBuffer(void * pointer, UInt_t size=1) //
+// should construct buffer of size =size objects at position pointer //
+// virtual void DTORBuffer(void * pointer, UInt_t size=1) //
+// should destruct buffer of size =size objects at position pointer //
+// virtual void StreamBuffer(TBuffer& b, const void *object, UInt_t size) //
+// stream buffer of objects `
+//Begin_Html
+//<img src="../gif/AliClassInfo.gif">
+//End_Html
+// //
+// //
+///////////////////////////////////////////////////////////////////////////////
+
+
+#include "AliClassInfo.h"
+#include "TMath.h"
+#include "TClass.h"
+
+#include "TROOT.h"
+#include "iostream.h"
+
+ClassImp(AliClassInfo)
+
+
+TList AliClassInfo::fgList; // list of loaded class
+
+AliClassInfo * AliClassInfo::FindClassInfo(const char * name)
+{
+ //
+ TIter next(&fgList);
+ TString sname(name);
+ AliClassInfo * info;
+ while ((info = (AliClassInfo *) next()))
+ if (info->GetName()==sname) return info;
+ return 0;
+}
+
+
+
+AliClassInfo * AliClassInfo::GenerClassInfo(const char * classname)
+{
+ //
+ // Set class information fClassInfo according class name
+ //
+ char name[100];
+ AliClassInfo *info=0;
+ sprintf(name,"AliClassType%s",classname);
+ info = AliClassInfo::FindClassInfo(classname);
+ if (info) return info;
+ //
+ if ( (!info) && (gROOT->GetType(classname),kTRUE)){
+ //if data type information exist
+ char line[100];
+ // sprintf(line,"(*((AliClassInfo**)%p))= new AliDataType(\"%s\");",
+ // &info,classname);
+ sprintf(line,"new AliDataType(\"%s\");",
+ classname);
+
+ //cout<<line<<"\n";
+ gROOT->ProcessLine(line);
+ info = AliClassInfo::FindClassInfo(classname);
+ }
+ if (info) return info;
+
+ TClass * cl = gROOT->GetClass(classname);
+ // if exist root class information
+ if ( (!info) && (gROOT->GetClass(classname))){ //is it class?
+ char chinter[1000];
+ sprintf(chinter,"%s.C",classname);
+ GenerClassInfoCode(classname,kTRUE,cl->GetDeclFileName(),chinter);
+ info = AliClassInfo::FindClassInfo(classname);
+ }
+ if (!info){
+ TClass * cl = new TClass(classname,0);
+ if (cl->Size()>0){ //if root information doesn't exist
+ //but exist cint information
+ char chinclude[1000];
+ sprintf(chinclude,"%s.h",classname);
+ char chinter[1000];
+ sprintf(chinter,"%s.C",classname);
+ GenerClassInfoCode(classname,kTRUE,chinclude,chinter);
+ }
+ }
+
+ return info;
+}
+
+
+
+void AliClassInfo::GenerClassInfoCode(const char * clname, Bool_t load,
+ const char *incpath, const char *outfile)
+{
+
+ // gener temporary file - name
+
+ FILE *fout = fopen(outfile,"w");
+ if (!clname){
+ cerr<<"Class not specified\n";
+ return ;
+ }
+ char buff[1000];
+ const char *pchar =incpath;
+ //replace with /0
+ char * pchar2 =buff;
+ fprintf(fout,"#include \"AliClassInfo.h\"\n");
+
+ if (incpath==0) {}
+ else{
+ // proces headers - header separated by
+ pchar =incpath;
+ pchar2 =buff;
+ //
+ while (*pchar==' ') pchar++;
+ while (*pchar) {
+ if (*pchar!=' ') *pchar2++ = *pchar;
+ else
+ if (*(pchar2-1)!=0) *pchar2++=0;
+ pchar++;
+ }
+ *pchar2=0;
+ Int_t index = pchar2-buff;
+ for (Int_t i=0;i<index;i++)
+ if ( (i==0) ||(buff[i-1]==0))
+ fprintf(fout,"#include \"%s\"\n",&buff[i]);
+ }
+ //process classes
+ pchar =clname;
+ pchar2 =buff;
+ while (*pchar==' ') pchar++;
+ while (*pchar) {
+ if (*pchar!=' ') *pchar2++ = *pchar;
+ else
+ if (*(pchar2-1)!=0) *pchar2++=0;
+ pchar++;
+ }
+ *pchar2=0;
+ Int_t index = pchar2-buff;
+ for (Int_t i=0;i<index;i++)
+ if ( (i==0) ||(buff[i-1]==0))
+ GenerClassInterface(&buff[i],fout);
+
+ fclose(fout);
+ //
+
+ if (load) {
+ char line[100];
+ // gSystem->Rename("/tmp/root_tmpinterinter"
+ sprintf(line,".L %s+",outfile);
+ cout<<line<<"\nGenerating class Interface \n";
+ cout<<line<<"\n*****************************\n";
+ gROOT->ProcessLine(line);
+ cout<<line<<"\n*****************************\n";
+ cout<<line<<"\nClass Interface generated \n";
+ }
+}
+
+
+
+Bool_t AliClassInfo::GenerClassInterface(const char * clname, FILE * fout)
+{
+ // TClass * cl = gROOT->GetClass("AliLHit",kTRUE);
+ fprintf(fout,"\n/************************************************/\n");
+ fprintf(fout,"/* Automaticaly generated interface for class \n");
+ fprintf(fout," %s \n",clname);
+ fprintf(fout,"**************************************************/\n");
+ fprintf(fout,"\n\n");
+ //constructor
+ fprintf(fout,"class AliClass%s : public AliClassInfo {\n",clname);
+ fprintf(fout,"public:\n");
+ fprintf(fout,"\tAliClass%s(){\n",clname);
+ fprintf(fout,"\t SetName(\"%s\");\n",clname);
+ fprintf(fout,"\t SetTitle(\"Interface for %s class \");\n",clname);
+ fprintf(fout,"\t fgList.Add(this);\n");
+ fprintf(fout,"\t fSize = sizeof(%s);\n\t}\n",clname);
+ //
+ fprintf(fout,"\tconst char * GetClassName(){ return \"%s\";}\n",clname);
+ //
+ fprintf(fout,"\tvirtual TClass* GetClass(){return %s::Class();}\n",clname);
+ //placement constructor interface
+ fprintf(fout,"\tvoid CTORBuffer(void * pointer, UInt_t size=1)\n\t{\n");
+ fprintf(fout,"\t %s * last = &((%s*)pointer)[size];\n",clname,clname);
+ fprintf(fout,"\t %s * p = (%s*)pointer;\n",clname,clname);
+ fprintf(fout,"\t while (p!=last) new (p++)%s;\n\t}\n",clname);
+ //placement destructor interface
+ fprintf(fout,"\tvoid DTORBuffer(void * pointer, UInt_t size=1)\n\t{\n");
+ fprintf(fout,"\t %s * last = &((%s*)pointer)[size];\n",clname,clname);
+ fprintf(fout,"\t %s * p = (%s*)pointer;\n",clname,clname);
+ fprintf(fout,"\t while (p!=last) (p++)->~%s();\n\t}\n",clname);
+ //streamer interface
+ fprintf(fout,"\tvoid StreamBuffer(TBuffer &b,const void * pointer, UInt_t size=1)\n\t{\n");
+ fprintf(fout,"\t for (UInt_t i=0;i<size;i++) ((%s*)pointer)[i].Streamer(b);\n\t}\n",clname);
+ //
+ fprintf(fout,"\t void ObjectDump(void *p) {((%s*)p)->Dump();}\n",clname);
+ fprintf(fout,"};\n");
+ //make instance of the class
+ fprintf(fout,"AliClass%s galiclass____%s; \n",clname,clname);
+ return kTRUE;
+}
+
+
+
+
+
+
+
+
+
--- /dev/null
+#ifndef ALICLASSINFO_H
+#define ALICLASSINFO_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+///////////////////////////////////////////////////////////////////////////////
+// //
+// AliClassInfo //
+// //
+// Defined to make unified interface to primitive types (in Root described by//
+// TDataType) and TClass. //
+// //
+// Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk //
+///////////////////////////////////////////////////////////////////////////////
+
+
+#include "TNamed.h"
+class TDataType;
+
+
+
+class AliClassInfo : public TNamed {
+public:
+ AliClassInfo(){;}
+ virtual ~AliClassInfo(){;}
+ virtual void CTORBuffer(void * pointer, UInt_t size=1){;}
+ // {return (*ctorbuffer)(p,size);}
+ virtual void DTORBuffer(void * pointer, UInt_t size=1){;}
+ //{return (*dtorbuffer)(p,size);}
+ virtual void StreamBuffer(TBuffer& b, const void *object, UInt_t size){;}
+ //{return (*streamb)(b,object,size);}
+ virtual void ObjectDump(void *p){;}
+ virtual const char * GetClassName(){ return 0;}
+ virtual TClass * GetClass(){return 0;}
+ virtual TDataType * GetDataType(){return 0;}
+ const UInt_t Size(){return fSize;}
+ static AliClassInfo * FindClassInfo(const char * name);
+ static AliClassInfo * GenerClassInfo(const char * clname);
+ static void GenerClassInfoCode(const char * clname, Bool_t load,
+ const char *incpath, const char *outfile);
+ const TList & GetListOfClass(){return fgList;}
+protected:
+ static Bool_t GenerClassInterface(const char * clname, FILE * fout);
+ static TList fgList; // list of loaded class
+ UInt_t fSize; //size of object
+ ClassDef(AliClassInfo,1)
+};
+
+
+#endif //ALICLASSINFO_H
+
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+///////////////////////////////////////////////////////////////////////////////
+// //
+// AliDataType //
+// //
+// Defined to make unified interface to primitive types (in Root described by//
+// TDataType) and TClass. //
+// //
+///////////////////////////////////////////////////////////////////////////////
+
+
+#include "AliDataType.h"
+#include "AliCTypes.h"
+
+#include "TMath.h"
+#include "TClass.h"
+#include "TDataType.h"
+
+#include "TROOT.h"
+#include "iostream.h"
+
+
+ClassImp(AliDataType)
+
+
+
+AliDataType::AliDataType(const char *name)
+{
+ //
+ // AliData type constructor
+ fDataType = new TDataType(name);
+ if (fDataType->GetType()<0) fDataType= (gROOT->GetType(name,kTRUE));
+ if ((fDataType) && (fDataType->GetType())){
+ fSize = fDataType->Size();
+ // fType = (EDataType) fDataType->GetType();
+ SetTitle(name);
+ SetName(name);
+ fgList.Add(this);
+ }
+}
+
+
+const char * AliDataType::GetClassName()
+{
+ //class name of the object
+ return (fDataType) ? fDataType->GetName():0;
+}
+
+void AliDataType::StreamBuffer(TBuffer& b, const void *object, UInt_t size)
+{
+ //streamer for buffer of objects
+ char * last = &((char*)object)[size*fSize];
+ char * pfirst = (char*)object;
+ char *p;
+ if (b.IsWriting()){
+ switch ((EDataType) fDataType->GetType()){
+ case kChar_t:
+ for (p= pfirst; p<last;p+=fSize) b<<*((Char_t*)p);
+ break;
+ case kShort_t:
+ for (p= pfirst; p<last;p+=fSize) b<<*((Short_t*)p);
+ break;
+ case kInt_t:
+ for (p= pfirst; p<last;p+=fSize) b<<*((Int_t*)p);
+ break;
+ case kLong_t:
+ for (p= pfirst; p<last;p+=fSize) b<<*((Long_t*)p);
+ break;
+ case kUChar_t:
+ for (p= pfirst; p<last;p+=fSize) b<<*((UChar_t*)p);
+ break;
+ case kUShort_t:
+ for (p= pfirst; p<last;p+=fSize) b<<*((UShort_t*)p);
+ break;
+ case kUInt_t:
+ for (p= pfirst; p<last;p+=fSize) b<<*((UInt_t*)p);
+ break;
+ case kFloat_t:
+ for (p= pfirst; p<last;p+=fSize) b<<*((Float_t*)p);
+ break;
+ case kDouble_t:
+ for (p= pfirst; p<last;p+=fSize) b<<*((Double_t*)p);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ switch ((EDataType) fDataType->GetType()){
+ case kChar_t:
+ for (p= pfirst; p<last;p+=fSize) b>>*((Char_t*)p);
+ break;
+ case kShort_t:
+ for (p= pfirst; p<last;p+=fSize) b>>*((Short_t*)p);
+ break;
+ case kInt_t:
+ for (p= pfirst; p<last;p+=fSize) b>>*((Int_t*)p);
+ break;
+ case kLong_t:
+ for (p= pfirst; p<last;p+=fSize) b>>*((Long_t*)p);
+ break;
+ case kUChar_t:
+ for (p= pfirst; p<last;p+=fSize) b>>*((UChar_t*)p);
+ break;
+ case kUShort_t:
+ for (p= pfirst; p<last;p+=fSize) b>>*((UShort_t*)p);
+ break;
+ case kUInt_t:
+ for (p= pfirst; p<last;p+=fSize) b>>*((UInt_t*)p);
+ break;
+ case kFloat_t:
+ for (p= pfirst; p<last;p+=fSize) b>>*((Float_t*)p);
+ break;
+ case kDouble_t:
+ for (p= pfirst; p<last;p+=fSize) b>>*((Double_t*)p);
+ break;
+ default:
+ break;
+ }
+
+}
+
+void AliDataType::ObjectDump(void *p)
+{
+ //
+ // dump object information
+ // assume that object p has type described by AliDataTYPE
+ switch ((EDataType) fDataType->GetType()){
+ case kChar_t:
+ cout<<*((Char_t*)p)<<"\n";
+ break;
+ case kShort_t:
+ cout<<*((Short_t*)p)<<"\n";
+ break;
+ case kInt_t:
+ cout<<*((Int_t*)p)<<"\n";
+ break;
+ case kLong_t:
+ cout<<*((Long_t*)p)<<"\n";
+ break;
+ case kUChar_t:
+ cout<<*((UChar_t*)p)<<"\n";
+ break;
+ case kUShort_t:
+ cout<<*((UShort_t*)p)<<"\n";
+ break;
+ case kUInt_t:
+ cout<<*((UInt_t*)p)<<"\n";
+ break;
+ case kFloat_t:
+ cout<<*((Float_t*)p)<<"\n";
+ break;
+ case kDouble_t:
+ cout<<*((Double_t*)p)<<"\n";
+ break;
+ default:
+ break;
+ }
+}
--- /dev/null
+#ifndef ALIDATATYPE_H
+#define ALIDATATYPE_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// AliDataType //
+// //
+// Defined to make unified interface to primitive types (in Root described by//
+// TDataType) and TClass. //
+// //
+// Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "AliClassInfo.h"
+
+
+class AliDataType : public AliClassInfo {
+public:
+ AliDataType(const char *name);
+ const char * GetClassName();
+ void StreamBuffer(TBuffer& b, const void *object, UInt_t size);
+ void ObjectDump(void *p);
+ TDataType * GetDataType(){return fDataType;}
+protected:
+ AliDataType(const AliDataType & type){;}
+ AliDataType &operator = (const AliDataType & type){return *this;} //assignment operator
+ TDataType * fDataType; //root type information
+ ClassDefT(AliDataType,0)
+};
+
+#endif
+
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+///////////////////////////////////////////////////////////////////////////////
+// //
+// AliMemArray //
+// (Pseudo)Container optimised for fast random access operator[ ].
+// Operator [] time doesn\92t depend on the number of elements in container O(1) -
+// like in standard array or like in STL vector
+// To achieve maximally-fast indexing and iteration in one buffer mode
+// the vector maintains its storage as a single contiguous array of objects (one buffer mode)
+
+// When a vector runs out of pre-allocated storage, in order to maintain it
+// contiguous array it must allocate a whole new (larger) chunk of storage
+// elsewhere and copy the objects to the new storage.
+// void * AliMemArray::Unchecked1DAt(UInt_t i) const
+// return &(((char*)fCont)[fObjectSize*i]);
+
+// In multi buffer mode (like two dimensional array) when a vector runs out of
+// pre-allocated storage we don\92t need to copy whole array only small buffer but operator [] is slower
+// void * AliMemArray::Unchecked2DAt(UInt_t i, UInt_t j) const
+// return &( ((char**)fCont)[i] [j*fObjectSize]);
+// void * AliMemArray::Unchecked2DAt(UInt_t i) const
+// return &( ((char**)fCont)[i/fBufferSize] [(i%fBufferSize)*fObjectSize]) ;
+
+
+//Begin_Html
+//<img src="../gif/AliMemArray.gif">
+//End_Html
+
+
+// Streamer CTORBuffer and DTORBuffer are virtual - should be implemented in derived
+// classes. For example AliObjectArray derived from AliMemArray is general array
+// for objects with defined AliClassInfo information.
+// //
+// //
+// Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk //
+///////////////////////////////////////////////////////////////////////////////
+
+
+
+#include "AliMemArray.h"
+#include "iostream.h"
+#include "TMath.h"
+#include "TError.h"
+
+
+ClassImp(AliMemArray)
+
+
+AliMemArray::AliMemArray()
+{
+ //
+ //default constructor
+ //
+ fCont = 0;
+ fSize = 0;
+ fCapacity=0;
+ fObjectSize = 0;
+ fBufferSize = 0;
+}
+
+AliMemArray::AliMemArray(Int_t objectSize, Int_t buffersize)
+{
+ //
+ // AliMemArray constructor
+ fCont = 0;
+ fSize = 0;
+ fCapacity=0;
+ fObjectSize =objectSize;
+ fBufferSize =buffersize;
+}
+
+AliMemArray::AliMemArray(const AliMemArray & arr)
+{
+ //
+ //copy constructor
+ fCont = arr.fCont;
+ fSize = arr.fSize;
+ fCapacity = arr.fCapacity;
+ fObjectSize = arr.fObjectSize;
+ fBufferSize =arr.fBufferSize;
+
+ if (arr.fBufferSize==0) {
+ fCont = new char[fCapacity*fObjectSize];
+ CopyBuffer(fCont, arr.fCont, fSize);
+ }
+ else{
+ Int_t buffers = fCapacity/fBufferSize;
+ if (fCapacity%fBufferSize) buffers++;
+ void ** table = (void**) new char*[buffers];
+ for (Int_t i=0; i<buffers;i++){
+ table[i] = new char[fBufferSize*fObjectSize];
+ Int_t size = fSize - i*fBufferSize;
+ if (size > (Int_t)fBufferSize) size = fBufferSize;
+ if (size >0) CopyBuffer(table[i], ((void**)arr.fCont)[i],size);
+ }
+ fCont = (void*)table;
+ }
+}
+
+
+void AliMemArray::Swap( AliMemArray &arr)
+{
+ //swap contents of array
+ UInt_t size = arr.fSize;
+ arr.fSize = fSize;
+ fSize = size;
+ UInt_t capacity = arr.fCapacity;
+ arr.fCapacity = fCapacity;
+ fCapacity = capacity;
+ UInt_t objectSize = arr.fObjectSize;
+ arr.fObjectSize = fObjectSize;
+ fObjectSize = objectSize;
+ UInt_t bufferSize = arr.fBufferSize;
+ arr.fBufferSize = fBufferSize;
+ fBufferSize = bufferSize;
+ void * cont = arr.fCont;
+ arr.fCont = fCont;
+ fCont = cont;
+}
+
+void AliMemArray::CopyBuffer(void *dest, void *src, UInt_t size)
+{
+ //
+ //array placement copy constructor
+ memcpy(dest, src,size*fObjectSize);
+}
+
+AliMemArray::~AliMemArray()
+{
+ //
+ //default destructor
+ Delete();
+}
+
+
+void AliMemArray::SetObjectSize(UInt_t bufsize)
+{
+ //
+ //set memory size for one object - it can be changed only when the array is empty
+ if (fCont){
+ ::Error("AliMemArray::SetObjectSize", "forbidden to resize just allocated objects");
+ return;
+ };
+ fBufferSize=bufsize;
+}
+
+AliMemArray & AliMemArray::operator = (const AliMemArray &arr)
+{
+ //
+ //
+ AliMemArray tmparr(arr);
+ Swap(tmparr);
+ return *this;
+}
+
+void AliMemArray::SetBufferSize(UInt_t bufsize)
+{
+ //
+ //set buffer size - it can be changed only when the array is empty
+ if (fCont==0) {
+ fBufferSize = bufsize;
+ return;
+ }
+ if (fBufferSize == bufsize) return;
+
+ if (bufsize==0){
+ char *table = new char[fObjectSize*fCapacity];
+ char * p = table;
+ for (UInt_t i=0; i<fSize; i++,p+=fObjectSize)
+ memcpy(p, At(i), fObjectSize);
+ //delete [](char*)fCont;
+ Delete();
+ fCont = table;
+ fBufferSize = bufsize;
+ }
+ else{
+ Int_t buffers = fCapacity/bufsize;
+ if (fCapacity%bufsize) buffers++;
+ char ** table = new char*[buffers];
+ for (Int_t ibuf=0; ibuf<buffers;ibuf++){
+ table[ibuf] = new char[bufsize*fObjectSize];
+ Int_t size = fSize - ibuf*bufsize;
+ if (size > (Int_t)bufsize) size = bufsize;
+ if (size >0) for ( Int_t ip=0;ip<size;ip++)
+ memcpy(&table[ibuf][ip*fObjectSize], At(ibuf*bufsize+ip), fObjectSize);
+ }
+ // delete [](char**)fCont;
+ Delete();
+ fCont = (void*)table;
+ fBufferSize = bufsize;
+ }
+
+}
+
+
+
+void AliMemArray::Delete(Option_t *)
+{
+ //
+ //delete memory space occupied by the array -
+ //Use this routine when your objects allocate
+ //memory (e.g. objects inheriting from TNamed or containing TStrings
+ //allocate memory). If not you better use Clear() since if is faster.
+ if (fCont){
+ if (fBufferSize) {
+ Delete2D();
+ fSize = 0;
+ fCapacity = 0;
+ return;
+ }
+ DTORBuffer(Unchecked1DAt(0),fSize);
+ delete [] (char*)fCont;
+ fCont = 0;
+ fSize = 0;
+ fCapacity = 0;
+ }
+}
+
+void AliMemArray::Clear(Option_t *)
+{
+ //
+ //clear array -
+ // Only use this routine when your objects don't
+ // allocate memory since it will not call the object dtors.
+ if (fBufferSize){
+ Clear2D();
+ return;
+ }
+ if (fCont){
+ memset(fCont, 0, fSize*fObjectSize);
+ fSize = 0;
+ }
+}
+
+void AliMemArray::Reserve(UInt_t n)
+{
+ //
+ //reserve arrays space
+ //
+ if (fObjectSize<=0) {
+ cout<<"Object length not defined\n";
+ return;
+ }
+ if (n==fCapacity) return;
+
+ if (fBufferSize>0) {
+ Reserve2D(n); //if 2D buffer
+ return;
+ }
+ //
+ if (fCapacity){
+ if (fSize>n) {
+ DTORBuffer(Unchecked1DAt(n),fSize-n);
+ memset(&((char*)fCont)[n*fObjectSize], 0, (fSize-n)*fObjectSize);
+ fSize =n;
+ }
+ fCont = (char*)TStorage::ReAlloc(fCont, n*fObjectSize,fCapacity*fObjectSize);
+ }
+ else fCont = new char[n*fObjectSize];
+
+ if (!fCont) fCapacity = 0;
+ else fCapacity = n;
+}
+
+
+void AliMemArray::Resize(UInt_t n)
+{
+ //
+ //resize buffer
+ //
+ if (fObjectSize<=0) {
+ cout<<"Object length not defined\n";
+ return;
+ }
+ if (fBufferSize>0) {
+ Resize2D(n); //if 2D buffer
+ return;
+ }
+ //
+ if (n>fCapacity) Reserve(n); //reserve automaticaly space if sie >capacity
+ if (fSize>n){
+ DTORBuffer(Unchecked1DAt(n),fSize-n);
+ memset(&((char*)fCont)[n*fObjectSize], 0, (fSize-n)*fObjectSize);
+ }
+ if (fSize<n) CTORBuffer(Unchecked1DAt(fSize),n-fSize);
+ fSize = n;
+ return;
+}
+
+void AliMemArray::Delete2D()
+{
+ //
+ //delete memory space occupied by the array
+ if (!fBufferSize) return;
+
+ Int_t nbuff = (fCapacity/fBufferSize);
+ if ( (fCapacity%fBufferSize)!=0) nbuff++;
+ for (Int_t i=0;i<nbuff;i++) {
+ Int_t size = fSize-i*fBufferSize;
+ if (size>0)
+ DTORBuffer(GetRow(i),UInt_t(size)<fBufferSize? size:fBufferSize);
+ delete [] (char*)GetRow(i);
+ }
+ delete [] (void**)fCont;
+ fCont =0;
+ fSize = 0;
+ fCapacity = 0;
+}
+
+void AliMemArray::Clear2D()
+{
+ //
+ //clear memory space occupied by the array - doesn't call DTOR
+ Int_t nbuff = (fCapacity/fBufferSize);
+ if ( (fCapacity%fBufferSize)!=0) nbuff++;
+ for (Int_t i=0;i<nbuff;i++) memset(GetRow(i), 0, fSize*fObjectSize);
+ fSize = 0;
+}
+
+
+
+
+void AliMemArray::Reserve2D(UInt_t n)
+{
+ //
+ //
+ Int_t buffers = n/fBufferSize;
+ if (n%fBufferSize) buffers++;
+ UInt_t nobjects=buffers*fBufferSize;
+ Int_t oldbuffers = GetNBuffers() ;
+ if (buffers==oldbuffers) return;
+ //
+ void ** table = (void**) new char*[buffers];
+
+ Int_t max = buffers>oldbuffers ? buffers: oldbuffers;
+ for (Int_t i = 0;i<max;i++) {
+ if ( (i<oldbuffers) && (i<buffers)) table[i] = GetRow(i);
+ if ( (i<oldbuffers)&&(i>=buffers) ){
+ Int_t dsize = TMath::Min(Int_t(fSize) - i*Int_t(fBufferSize),Int_t(fBufferSize));
+ if (dsize>0) DTORBuffer(GetRow(i),dsize);
+ delete [] (char*)GetRow(i);
+ }
+ if (i>=oldbuffers)
+ table[i] = new char[fBufferSize*fObjectSize];
+ }
+ if (fSize>nobjects) fSize=nobjects;
+
+ fCapacity = nobjects ;
+ delete [] (void**)fCont;
+ fCont = (void*)table;
+}
+
+
+
+void AliMemArray::Resize2D(UInt_t n)
+{
+ //
+ //
+ if (n>fCapacity) Reserve2D(n); //reserve automaticaly space
+ Int_t buffers = n/fBufferSize;
+ if (n%fBufferSize) buffers++;
+
+ if (fSize>n){ //call destructor if we decrease the size of array
+ Int_t oldbuffer = fSize/fBufferSize;
+
+ for (Int_t i=buffers;i<oldbuffer; i++){
+ Int_t iold= fSize-i*fBufferSize;
+ if (iold>(Int_t)fBufferSize) iold= fBufferSize;
+ Int_t inew= n -i*fBufferSize;
+ if (inew<0) inew =0;
+ DTORBuffer(Unchecked2DAt(i,inew),iold-inew);
+ }
+ }
+ if (fSize<n){ //call constructor if we increase the size of array
+ Int_t oldbuffer = fSize/fBufferSize;
+ for (Int_t i=oldbuffer;i<buffers; i++){
+ Int_t iold = fSize-i*fBufferSize;
+ if (iold<0) iold = 0;
+ Int_t inew = n -i*fBufferSize;
+ if (inew>(Int_t)fBufferSize) inew = fBufferSize;
+ CTORBuffer(Unchecked2DAt(i,iold),inew-iold);
+ }
+ }
+ fSize = n;
+}
+
+
+
+
+
+
--- /dev/null
+#ifndef ALIMEMARRAY_H
+#define ALIMEMARRAY_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+///////////////////////////////////////////////////////////////////////////////
+// //
+// AliMemArray //
+// (Pseudo)Container optimised for fast random access operator[ ]. //
+// Operator [] time doesn\92t depend on the number of elements in container O(1) -
+// like in standard array or like in STL vector
+///////////////////////////////////////////////////////////////////////////////
+#include "TObject.h"
+
+class AliMemArray: public TObject {
+public:
+ AliMemArray();
+ AliMemArray(Int_t objectSize, Int_t buffersize=0);
+ AliMemArray(const AliMemArray & arr);
+ AliMemArray & operator = (const AliMemArray &arr);
+ virtual ~AliMemArray();
+ void Swap(AliMemArray & arr);
+ //
+ inline void * UncheckedAt(UInt_t index) const; //
+ inline void * At(UInt_t i) const ; //controled return pointer to object
+ inline void * Unchecked1DAt(UInt_t i) const; //return pointer to the object
+ inline void * Unchecked2DAt(UInt_t i) const ; //return pointer to the object
+ inline void * Unchecked2DAt(UInt_t i, UInt_t j) const ; //return pointer to the object
+
+ Bool_t Is1D(){return (fBufferSize==0);} //true if 1D array
+ Bool_t Is2D(){return (fBufferSize!=0);} //true if 2D array
+ //
+ const void * GetArray()const {return fCont;} //return pointer to the buffer
+ void * GetRow(UInt_t row)const {return fBufferSize? ((void**)fCont)[row]: fCont;}
+
+ // return pointer to the object
+ //
+ const UInt_t GetCapacity() const {return fCapacity;} //return number of stored objects
+ const UInt_t GetSize() const {return fSize;} //return number of stored objects
+ //
+ void Delete(Option_t *option="");
+ //delete memory space occupated by the array
+ void Clear(Option_t *option="");
+ //clear memory space occupied by the array - doesn't call destructor
+ void Resize(UInt_t n);
+ void Reserve(UInt_t n);
+ //
+ const UInt_t GetBufferSize() const {return fBufferSize;}
+ const UInt_t GetObjectSize() const {return fObjectSize;}
+ const UInt_t GetNBuffers() const {return fBufferSize? fCapacity/fBufferSize :1;}
+ void SetBufferSize(UInt_t bufsize);
+protected :
+ void SetObjectSize(UInt_t size);
+ void Delete2D(); //delete memory space occupated by the array
+ void Clear2D(); //clear memory space occupated by the array
+ void Resize2D(UInt_t n);
+ void Reserve2D(UInt_t n);
+ //
+protected:
+ virtual void CTORBuffer(void *buffer, UInt_t size){;} //array placement constructor
+ virtual void DTORBuffer(void *buffer, UInt_t size){;} //array placement destructor
+ virtual void CopyBuffer(void *src, void *dest, UInt_t size); //array placement copy constructor
+ UInt_t fSize; //total number of valid objects
+ UInt_t fCapacity; //capacity of array
+ UInt_t fObjectSize; // object size
+ UInt_t fBufferSize; //number of object in one full buffer (0 means array in one buffer)
+ //
+private:
+ void * fCont; //!data buffer
+ ClassDef(AliMemArray,0)
+};
+
+void * AliMemArray::Unchecked1DAt(UInt_t i) const
+{
+ return &(((char*)fCont)[fObjectSize*i]);
+}
+
+void * AliMemArray::Unchecked2DAt(UInt_t i, UInt_t j) const
+{
+ return &( ((char**)fCont)[i] [j*fObjectSize]);
+}
+
+//********************************************************************
+void * AliMemArray::Unchecked2DAt(UInt_t i) const
+{
+ //
+ // called in GePointer if we have more then one buffer
+ return &( ((char**)fCont)[i/fBufferSize] [(i%fBufferSize)*fObjectSize]) ;
+}
+
+void * AliMemArray::UncheckedAt(UInt_t i) const
+{
+
+ return (!fBufferSize) ?Unchecked1DAt(i): Unchecked2DAt(i);
+}
+
+void * AliMemArray::At(UInt_t i) const
+{
+ return (i<fSize) ? UncheckedAt(i):0; //controled return pointer to object
+}
+
+#endif
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+///////////////////////////////////////////////////////////////////////////////
+// //
+// AliObjectArray //
+// //
+//AliObjectArray is an array of clone (identical) objects. //
+//In comparison with the TClonesArray objects in this array don't need //
+//to derive from TObject. They also don't need RTTI - type information. //
+// //
+//Objects type information is stored in object fClassInfo (instance of //
+//the AliClassInfo). //
+//Objects in array are stored sequentialy in buffers. Buffer is standart C++ //
+//array of objects. Buffers size is equal for all of the buffers. If we specify
+//fBufferSize==0 objects are stored in one big standart C++ array.
+//
+// Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk //
+//
+//Begin_Html
+/*
+<img src="../gif/AliObjectArray.gif">
+*/
+///////////////////////////////////////////////////////////////////////////////
+
+
+#include "AliObjectArray.h"
+
+ClassImp(AliObjectArray)
+
+AliObjectArray::AliObjectArray():AliMemArray()
+{
+ //
+ //default constructor
+ //
+ fClassInfo = 0;
+}
+
+AliObjectArray::AliObjectArray(const char * classname, Int_t buffersize):AliMemArray()
+{
+ //
+ // AliObject array constructor
+ // Set class information fClassInfo according specified type and set the array size -size
+ // Buufer size fBufferSize
+ fClassInfo = 0;
+ fBufferSize = buffersize;
+ SetClass(classname);
+}
+
+AliObjectArray::AliObjectArray(const AliObjectArray &arr)
+{
+ //
+ //
+ *((AliMemArray*)this) = *((AliMemArray*)&arr);
+ fClassInfo = arr.GetClassInfo();
+}
+
+
+AliObjectArray & AliObjectArray::operator=(const AliObjectArray &arr)
+{
+ //
+ //
+ *((AliMemArray*)this) = *((AliMemArray*)&arr);
+ fClassInfo = arr.GetClassInfo();
+ return (*this);
+}
+
+AliObjectArray::~AliObjectArray()
+{
+ //
+ //default destructor
+ Delete();
+}
+
+Bool_t AliObjectArray::SetClass(const char * classname)
+{
+ //
+ // Set class information fClassInfo according class name
+ //
+ Delete();
+
+ fClassInfo = AliClassInfo::GenerClassInfo(classname);
+ fObjectSize = fClassInfo->Size();
+ return (fClassInfo!=0);
+}
+
+void AliObjectArray::Dump(Int_t i)
+{
+ //dump object at position i
+ if (At(i)) fClassInfo->ObjectDump(At(i));
+ else printf("index %d - out of range\n",i);
+}
+
+void AliObjectArray::Streamer(TBuffer& R__b)
+{
+ //
+ //Stream of the AliVector2D
+ //
+ TString s;
+ if (R__b.IsReading()) {
+ Version_t R__v = R__b.ReadVersion(); if (R__v) { }
+ TObject::Streamer(R__b);
+ s.Streamer(R__b); //read class info
+ if (s!=" ") SetClass(s.Data());
+ else fClassInfo=0;
+ R__b >> fBufferSize;
+ R__b >> fObjectSize;
+ Int_t size;
+ R__b >> size;
+ Resize(size);
+ if (fSize>0){
+ if (fBufferSize==0) fClassInfo->StreamBuffer(R__b, GetArray(), fSize);
+ else
+ for (UInt_t i=0;i<GetNBuffers();i++)
+ fClassInfo->StreamBuffer(R__b, GetRow(i), fBufferSize);
+ }
+ } else {
+ R__b.WriteVersion(AliObjectArray::IsA());
+ TObject::Streamer(R__b);
+ if (fClassInfo) s = fClassInfo->GetClassName();
+ else s=" ";
+ s.Streamer(R__b);
+ R__b << fBufferSize;
+ R__b << fObjectSize;
+ R__b << fSize;
+
+ if (fSize>0){
+ if (fBufferSize==0) fClassInfo->StreamBuffer(R__b, GetArray(), fSize);
+ else
+ for (UInt_t i=0;i<GetNBuffers();i++)
+ fClassInfo->StreamBuffer(R__b, GetRow(i), fBufferSize);
+ }
+ }
+}
+
+
+
+
+
--- /dev/null
+#ifndef ALIOBJECTARRAY_H
+#define ALIOBJECTARRAY_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+/////////////////////////////////////////////////////////////////////////
+// AliObjectArray //
+//AliObjectArray is an array of clone (identical) objects. //
+//In comparison with the TClonesArray objects in this array don't need //
+//to derive from TObject. They also don't need RTTI - type information.//
+//Objects type information is stored in object fClassInfo (instance of //
+//the AliClassInfo). //
+// //
+/////////////////////////////////////////////////////////////////////////
+
+#include "AliClassInfo.h"
+#include "AliMemArray.h"
+class TClass;
+
+class AliObjectArray: public AliMemArray {
+public:
+ AliObjectArray();
+ AliObjectArray(const char * classname, Int_t buffersize=0);
+ AliObjectArray(const AliObjectArray &arr); //copy constructor
+ AliObjectArray & operator = (const AliObjectArray &arr);
+ ~AliObjectArray();
+ Bool_t SetClass(const char * classname);
+ //
+ TClass * GetClass() {return fClassInfo->GetClass();}
+ AliClassInfo * GetClassInfo() const {return fClassInfo;}
+ virtual void Dump(Int_t i);
+ //
+protected :
+ void CTORBuffer(void * buffer, UInt_t size)
+ {fClassInfo->CTORBuffer(buffer,size);} // buffer constructor
+ void DTORBuffer(void * buffer, UInt_t size)
+ {fClassInfo->DTORBuffer(buffer,size);} // buffer constructor
+private:
+ AliClassInfo *fClassInfo; //pointer to containg class info
+ //
+ ClassDef(AliObjectArray,0)
+};
+
+
+
+
+
+
+
+#endif //ALIMEMARRAY_I
+
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/*
+$Log$
+*/
+#include "TArrayOfArray.h"
+#include "iostream.h"
+
+
+
+
+ClassImp(TArrayOfArray)
+ClassImp(TArrayOfArray_vStack)
+ClassImp(TArrayOfArray_vList)
+
+
+TArrayOfArray_vStack::TArrayOfArray_vStack()
+{
+ fIndex = 0;
+ fArray = 0;
+}
+
+TArrayOfArray_vStack::TArrayOfArray_vStack(const char *classname)
+{
+ fIndex = 0;
+ fArray = 0;
+ SetClass(classname);
+}
+
+
+TArrayOfArray_vStack::~TArrayOfArray_vStack()
+{
+ if (fIndex) delete fIndex;
+ if (fArray) delete fArray;
+}
+
+Bool_t TArrayOfArray_vStack::SetClass(const char * classname)
+{
+ //
+ //set class
+ if (fIndex==0) fIndex = new AliObjectArray("Int_t");
+ if (fArray==0) fArray = new AliObjectArray;
+ else fArray->Delete();
+ return fArray->SetClass(classname);
+}
+
+
+void TArrayOfArray_vStack::Clear(Option_t *)
+{
+ //
+ // clear contents
+ //if (fIndex) fIndex->Clear();
+ //if (fArray) fArray->Clear();
+ if (fIndex) fIndex->Resize(0);
+ if (fArray) fArray->Resize(0);
+
+}
+
+void * TArrayOfArray_vStack::At(UInt_t index0, UInt_t index1)
+{
+ //get pointer to the object
+ if ( (fIndex!=0) && (index0+1<fIndex->GetSize())
+ && ((*((UInt_t*)(fIndex->Unchecked1DAt(index0+1)))
+ >(*((UInt_t*)(fIndex->Unchecked1DAt(index0)))+index1)) ) )
+ return Unchecked1DAt(index0,index1);
+ else
+ return 0;
+}
+void TArrayOfArray_vStack::Dump(UInt_t index0, UInt_t index1)
+{
+ void * p = At(index0,index1);
+ if ( (p) && fArray->GetClassInfo()) fArray->GetClassInfo()->ObjectDump(p);
+ else{
+ printf("Index %d,%d out of range\n",index0,index1);
+ cout<<flush;
+ }
+
+}
+
+Int_t TArrayOfArray_vStack::Resize(Int_t index, UInt_t newsize)
+{
+ //expand array with index index to newsize
+ if (index<0) index = fIndex->GetSize()-2;
+ if ((UInt_t)index==(fIndex->GetSize()-2)){
+ Int_t arrindex = *((Int_t*)(fIndex->At(index)));
+ fArray->Resize(arrindex+newsize);
+ *(Int_t*)(fIndex->At(index+1)) = arrindex+newsize;
+ }
+ else{
+ cout<<"out\n";
+ }
+ return 0;
+}
+
+UInt_t TArrayOfArray_vStack::Push(UInt_t size)
+{
+ //make new array with size - return starting index
+ if ( (fIndex==0) || (fArray==0)) return 0;
+ UInt_t index1 = fIndex->GetSize();
+ UInt_t indexa = fArray->GetSize();
+ fArray->Resize(indexa+size);
+ if (index1==0) {
+ fIndex->Resize(2);
+ (*(Int_t*)fIndex->Unchecked1DAt(0))=0;
+ (*(Int_t*)fIndex->Unchecked1DAt(1))=size;
+ return 0;
+ }
+ else{
+ fIndex->Resize(index1+1);
+ (*(Int_t*)fIndex->Unchecked1DAt(index1))=indexa+size;
+ }
+ return index1-1;
+}
+
+Int_t TArrayOfArray_vStack::ArraySize(UInt_t index)
+{
+ //size if subarray with index index
+ if ( (fIndex) && fIndex->GetSize()>index+1)
+ return (*(Int_t*)fIndex->Unchecked1DAt(index+1))-(*(Int_t*)fIndex->Unchecked1DAt(index));
+ else
+ return 0;
+}
--- /dev/null
+#ifndef TARRAYOFARRAY_H
+#define TARRAYOFARRAY_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/* $Id$ */
+#include "TObject.h"
+#include "AliObjectArray.h"
+
+class TArrayOfArray: public TObject {
+public:
+ virtual void * At(UInt_t index0, UInt_t index1)=0;
+ //get pointer to the object
+ virtual void Dump(UInt_t index0, UInt_t index1)=0;
+ virtual Int_t Resize(Int_t index, UInt_t newsize)=0;
+ //expand array with index index to newsize
+ virtual UInt_t Push(UInt_t size)=0;
+ //make new array with size - return starting index
+ virtual Int_t ArraySize(UInt_t index)=0;
+ virtual Int_t GetSize()=0;
+ ClassDef(TArrayOfArray,1)
+};
+
+
+class TArrayOfArray_vStack: public TArrayOfArray{
+public:
+ TArrayOfArray_vStack();
+ TArrayOfArray_vStack(const char *classname);
+ ~TArrayOfArray_vStack();
+ Bool_t SetClass(const char * classname);
+ virtual void Clear(Option_t * opt="");
+ void * Unchecked1DArray(UInt_t index){return fIndex->Unchecked1DAt(index);}
+ void * Unchecked1DAt(UInt_t index0, UInt_t index1);
+ //
+ virtual void * At(UInt_t index0, UInt_t index1);
+ //get pointer to the object
+ virtual void Dump(UInt_t index0, UInt_t index1);
+ virtual Int_t Resize(Int_t index, UInt_t newsize);
+ //expand array with index index to newsize
+ virtual UInt_t Push(UInt_t size);
+ //make new array with size - return starting index
+ virtual Int_t ArraySize(UInt_t index);
+ Int_t ArraySize(){ return fArray->GetSize();}
+ virtual Int_t GetSize(){return (fIndex) ?(Int_t)fIndex->GetSize()-1:0;}
+private:
+ AliObjectArray * fIndex;
+ AliObjectArray * fArray;
+ ClassDef(TArrayOfArray_vStack,1)
+};
+
+class TArrayOfArray_vList: public TArrayOfArray{
+protected:
+ AliObjectArray fIndex;
+ AliObjectArray fSecondaryIndexes;
+ AliObjectArray fArray;
+ ClassDef(TArrayOfArray_vList,1)
+};
+
+inline void * TArrayOfArray_vStack::Unchecked1DAt(UInt_t index0, UInt_t index1)
+{
+ // unchecked return
+ return fArray->Unchecked1DAt(((UInt_t*)fIndex->GetArray())[index0]+index1);
+}
+
+#endif
+
+