Classes for handling the new hits structures
authorkowal2 <kowal2@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 1 Nov 2000 16:01:26 +0000 (16:01 +0000)
committerkowal2 <kowal2@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 1 Nov 2000 16:01:26 +0000 (16:01 +0000)
14 files changed:
CONTAINERS/AliArrayBranch.cxx [new file with mode: 0644]
CONTAINERS/AliArrayBranch.h [new file with mode: 0644]
CONTAINERS/AliArrayVT.cxx [new file with mode: 0644]
CONTAINERS/AliArrayVT.h [new file with mode: 0644]
CONTAINERS/AliClassInfo.cxx [new file with mode: 0644]
CONTAINERS/AliClassInfo.h [new file with mode: 0644]
CONTAINERS/AliDataType.cxx [new file with mode: 0644]
CONTAINERS/AliDataType.h [new file with mode: 0644]
CONTAINERS/AliMemArray.cxx [new file with mode: 0644]
CONTAINERS/AliMemArray.h [new file with mode: 0644]
CONTAINERS/AliObjectArray.cxx [new file with mode: 0644]
CONTAINERS/AliObjectArray.h [new file with mode: 0644]
CONTAINERS/TArrayOfArray.cxx [new file with mode: 0644]
CONTAINERS/TArrayOfArray.h [new file with mode: 0644]

diff --git a/CONTAINERS/AliArrayBranch.cxx b/CONTAINERS/AliArrayBranch.cxx
new file mode 100644 (file)
index 0000000..616ffce
--- /dev/null
@@ -0,0 +1,1023 @@
+/**************************************************************************
+ * 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;
+}
+
+
diff --git a/CONTAINERS/AliArrayBranch.h b/CONTAINERS/AliArrayBranch.h
new file mode 100644 (file)
index 0000000..9dd653f
--- /dev/null
@@ -0,0 +1,83 @@
+#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
diff --git a/CONTAINERS/AliArrayVT.cxx b/CONTAINERS/AliArrayVT.cxx
new file mode 100644 (file)
index 0000000..6948ceb
--- /dev/null
@@ -0,0 +1,41 @@
+/**************************************************************************
+ * 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)
diff --git a/CONTAINERS/AliArrayVT.h b/CONTAINERS/AliArrayVT.h
new file mode 100644 (file)
index 0000000..2b45269
--- /dev/null
@@ -0,0 +1,47 @@
+#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
+
diff --git a/CONTAINERS/AliClassInfo.cxx b/CONTAINERS/AliClassInfo.cxx
new file mode 100644 (file)
index 0000000..8b1a9aa
--- /dev/null
@@ -0,0 +1,233 @@
+/**************************************************************************
+ * 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;
+}
+
+
+
+
+
+
+
+
diff --git a/CONTAINERS/AliClassInfo.h b/CONTAINERS/AliClassInfo.h
new file mode 100644 (file)
index 0000000..c07b091
--- /dev/null
@@ -0,0 +1,53 @@
+#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
+
diff --git a/CONTAINERS/AliDataType.cxx b/CONTAINERS/AliDataType.cxx
new file mode 100644 (file)
index 0000000..2fbb3e0
--- /dev/null
@@ -0,0 +1,176 @@
+/**************************************************************************
+ * 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;
+  }
+}
diff --git a/CONTAINERS/AliDataType.h b/CONTAINERS/AliDataType.h
new file mode 100644 (file)
index 0000000..e65dc62
--- /dev/null
@@ -0,0 +1,36 @@
+#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
+
diff --git a/CONTAINERS/AliMemArray.cxx b/CONTAINERS/AliMemArray.cxx
new file mode 100644 (file)
index 0000000..0b55757
--- /dev/null
@@ -0,0 +1,408 @@
+/**************************************************************************
+ * 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;  
+}
+
+
+
+
+
+
diff --git a/CONTAINERS/AliMemArray.h b/CONTAINERS/AliMemArray.h
new file mode 100644 (file)
index 0000000..b005c72
--- /dev/null
@@ -0,0 +1,103 @@
+#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
diff --git a/CONTAINERS/AliObjectArray.cxx b/CONTAINERS/AliObjectArray.cxx
new file mode 100644 (file)
index 0000000..8632d99
--- /dev/null
@@ -0,0 +1,154 @@
+/**************************************************************************
+ * 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);
+    }
+  }
+}
+
+
+
+
+
diff --git a/CONTAINERS/AliObjectArray.h b/CONTAINERS/AliObjectArray.h
new file mode 100644 (file)
index 0000000..91a08de
--- /dev/null
@@ -0,0 +1,52 @@
+#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
+
diff --git a/CONTAINERS/TArrayOfArray.cxx b/CONTAINERS/TArrayOfArray.cxx
new file mode 100644 (file)
index 0000000..4230368
--- /dev/null
@@ -0,0 +1,135 @@
+/**************************************************************************
+ * 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;
+}
diff --git a/CONTAINERS/TArrayOfArray.h b/CONTAINERS/TArrayOfArray.h
new file mode 100644 (file)
index 0000000..9c895c4
--- /dev/null
@@ -0,0 +1,67 @@
+#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
+  
+