Removing warnings (Sun)
[u/mrichter/AliRoot.git] / CONTAINERS / AliArrayBranch.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 #include "TROOT.h"
19 #include "AliArrayBranch.h"
20 #include "TFile.h"
21 #include "TTree.h" 
22 #include "TBasket.h"
23 #include "TClass.h"
24 #include "TRealData.h"
25 #include "TDataType.h"
26 #include "TDataMember.h"
27
28 #include "TBranch.h"
29 #include "TBranchClones.h"
30 #include "TLeaf.h"
31 #include "TLeafB.h"
32 #include "TLeafC.h"
33 #include "TLeafF.h"
34 #include "TLeafD.h"
35 #include "TLeafI.h"
36 #include "TLeafS.h"
37 #include "TLeafObject.h"
38
39 #include "AliObjectArray.h"
40 #include "AliDataType.h"
41
42 //-----------------------------------------------------
43 // A Branch for the case of an array of clone objects. 
44 //-----------------------------------------------------
45
46 //*KEND.
47
48 R__EXTERN TTree *gTree;
49
50 ClassImp(AliArraySubBranch)
51 ClassImp(AliArrayBranch)
52 ClassImp(AliObjectBranch)
53 ClassImp(AliTree)
54
55
56
57   Int_t AliArraySubBranch::GetEntryExport(Int_t entry, Int_t /*getall*/, AliObjectArray *list, Int_t nentries)
58 {
59 //*-*-*-*-*-*Read all leaves of entry and return total number of bytes*-*-*
60 //*-* export buffers to real objects in the AliObjectArray list.
61 //*-*
62
63    if (TestBit(kDoNotProcess)) return 0;
64    if (fReadEntry == entry) return 1;
65    if (entry < 0 || entry >= fEntryNumber) return 0;
66    Int_t nbytes;
67    Int_t first  = fBasketEntry[fReadBasket];
68    Int_t last;
69    if (fReadBasket == fWriteBasket) last = fEntryNumber - 1;
70    else                             last = fBasketEntry[fReadBasket+1] - 1;
71 //
72 //      Are we still in the same ReadBasket?
73    if (entry < first || entry > last) {
74       fReadBasket = TMath::BinarySearch(fWriteBasket+1, fBasketEntry, entry);
75       first       = fBasketEntry[fReadBasket];
76    }
77
78 //     We have found the basket containing this entry.
79 //     make sure basket buffers are in memory.
80    TBasket *basket = GetBasket(fReadBasket);
81    if (!basket) return 0;
82    TBuffer *buf    = basket->GetBufferRef();
83 //     Set entry offset in buffer and read data from all leaves
84    if (!buf->IsReading()) {
85       basket->SetReadMode();
86    }
87 //   Int_t bufbegin = basket->GetEntryPointer(entry-first);
88    Int_t bufbegin;
89    Int_t *entryOffset = basket->GetEntryOffset();
90    if (entryOffset) bufbegin = entryOffset[entry-first];
91    else             bufbegin = basket->GetKeylen() + (entry-first)*basket->GetNevBufSize();
92    buf->SetBufferOffset(bufbegin);
93
94    TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
95    //   leaf->ReadBasketExport(*buf,list,nentries);  //!!! MI
96    ReadBasketExport(*buf,leaf, list,nentries);
97    nbytes = buf->Length() - bufbegin;
98    fReadEntry = entry;
99
100    return nbytes;
101 }
102
103 void AliArraySubBranch::ReadBasketExport(TBuffer &b, TLeaf *leaf, AliObjectArray *list, Int_t n)
104 {
105   //
106   // 
107   Int_t len    = leaf->GetLenStatic();
108   Int_t offset = leaf->GetOffset();
109   void *value  = leaf->GetValuePointer();
110
111   //8bit integer
112   if (leaf->IsA()==TLeafB::Class()){   
113     Int_t j = 0;
114     for (Int_t i=0;i<n;i++) {
115       memcpy((char*)list->UncheckedAt(i) + offset,&((Char_t*)value)[j], len);
116       j += len;
117     } 
118   } 
119   //variable length string.
120   if (leaf->IsA()==TLeafC::Class()){  
121     UChar_t len;
122     b >> len;
123     if (len) {
124       if (len >= len) len = len-1;
125       b.ReadFastArray((Char_t*)value,len);
126       ((Char_t*)value)[len] = 0;
127     } else {
128       value = 0;
129     }    
130     Int_t j = 0;
131     for (Int_t i=0;i<n;i++) {
132       memcpy((char*)list->UncheckedAt(i) + offset,&((Char_t*)value)[j], 1);
133       j += len;
134     }
135   }
136   //double
137   if (leaf->IsA()==TLeafD::Class()){   
138     b.ReadFastArray(((Double_t*)value),n*len);    
139     Int_t j = 0;
140     for (Int_t i=0;i<n;i++) {
141       memcpy((char*)list->UncheckedAt(i) + offset,&((Double_t*)value)[j], 8*len);
142       j += len;
143    }
144   }
145   //float
146   if (leaf->IsA()==TLeafF::Class()){   
147     if (n*len == 1) {
148       b >> ((Float_t*)value)[0];
149     } else {
150       b.ReadFastArray(((Float_t*)value),n*len);
151     }
152     
153     Float_t *val = (Float_t*)value;
154     for (Int_t i=0;i<n;i++) {
155       char *first = (char*)list->UncheckedAt(i);
156       Float_t *ff = (Float_t*)&first[offset];
157       for (Int_t j=0;j<len;j++) {
158         ff[j] = val[j];
159       }
160       val += len;
161     }
162     return;
163   }
164   //int2
165   if (leaf->IsA()==TLeafS::Class()){       
166     if (n*len == 1) {
167       b >> ((Short_t*)value)[0];
168     } else {
169       b.ReadFastArray(((Short_t*)value),n*len);
170     }
171     Short_t *val = (Short_t*)value;
172     for (Int_t i=0;i<n;i++) {
173       char *first = (char*)list->UncheckedAt(i);
174       Short_t *ii = (Short_t*)&first[offset];
175       for (Int_t j=0;j<len;j++) {
176         ii[j] = val[j];
177       }
178       val += len;
179     }    
180     return;
181   }     
182   //int4
183   if (leaf->IsA()==TLeafI::Class()){       
184     if (n*len == 1) {
185       b >> ((Int_t*)value)[0];
186     } else {
187       b.ReadFastArray(((Int_t*)value),n*len);
188     }
189     Int_t *val = (Int_t*)value;
190     for (Int_t i=0;i<n;i++) {
191       char *first = (char*)list->UncheckedAt(i);
192       Int_t *ii = (Int_t*)&first[offset];
193       for (Int_t j=0;j<len;j++) {
194         ii[j] = val[j];
195       }
196       val += len;
197     }    
198     return;
199   }      
200 }
201
202
203 //______________________________________________________________________________
204 AliArrayBranch::AliArrayBranch(): TBranch()
205 {
206 //*-*-*-*-*-*Default constructor for BranchClones*-*-*-*-*-*-*-*-*-*
207 //*-*        ====================================
208
209    fList        = 0;
210    fRead        = 0;
211    fN           = 0;
212    fNdataMax    = 0;
213    fBranchCount = 0;
214 }
215
216
217 //______________________________________________________________________________
218 AliArrayBranch::AliArrayBranch(const Text_t *name, void *pointer, TTree * tree,  Int_t basketsize, Int_t compress)
219     :TBranch()
220 {
221 //*-*-*-*-*-*-*-*-*-*-*-*-*Create a BranchClones*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
222 //*-*                      =====================
223 //
224    char leaflist[80];
225    char branchname[80];
226    char branchcount[64];
227    fTree       = tree;
228    gTree       = tree; // MI because some bug in ROOT I didn't obtain proper gTree
229    // it is necesary to set gTree because oder subranchces  defined below need it
230    SetName(name);
231    if (compress == -1) {
232       TFile *bfile = fTree->GetDirectory()->GetFile();
233       if (bfile) compress = bfile->GetCompressionLevel();
234    }
235    char *cpointer  = (char*)pointer;
236    char **ppointer = (char**)(cpointer);
237    fList     = (AliObjectArray*)(*ppointer);
238    fAddress  = cpointer;
239    fRead     = 0;
240    fN        = 0;
241    fNdataMax = 0;
242
243    AliClassInfo *clinfo = fList->GetClassInfo();
244    if (!clinfo) return;
245    fClassName = clinfo->GetName();   
246    
247 //*-*- Create a branch to store the array count
248    if (basketsize < 100) basketsize = 100;
249    sprintf(leaflist,"%s_/I",name);
250    sprintf(branchcount,"%s_",name);
251    fBranchCount = new TBranch(branchcount,&fN,leaflist,basketsize);
252    fBranchCount->SetBit(kIsClone);
253    TLeaf *leafcount = (TLeaf*)fBranchCount->GetListOfLeaves()->UncheckedAt(0);
254
255 //*-*-  Create the first basket
256
257    fDirectory  = fTree->GetDirectory();
258    fFileName   = "";
259
260    TBasket *basket = new TBasket(branchcount,fTree->GetName(),this);
261    fBaskets.Add(basket);
262
263 //*-*- Loop on all public data members of the class and its base classes
264
265    TClass *cl = fList->GetClass();
266    if (cl){
267      if (!cl->GetListOfRealData())  cl->BuildRealData();
268      
269      const char *itype = 0;
270      TRealData *rd;
271      TIter      next(cl->GetListOfRealData());
272      while ((rd = (TRealData *) next())) {
273        TDataMember *member = rd->GetDataMember();
274        if (!member->IsBasic()) {
275          Warning("BranchClones","Cannot process member:%s",member->GetName());
276          continue;
277        }
278        if (!member->IsPersistent()) continue; //do not process members with a ! as the first
279        // character in the comment field
280        TDataType *membertype = member->GetDataType();
281        Int_t type = membertype->GetType();
282        if (type == 0) {
283          Warning("BranchClones","Cannot process member:%s",member->GetName());
284          continue;
285        }
286        if (type == 1)  itype = "B";
287        if (type == 11) itype = "b";
288        if (type == 3)  itype = "I";
289        if (type == 5)  itype = "F";
290        if (type == 8)  itype = "D";
291        if (type == 13) itype = "i";
292        if (type == 2)  itype = "S";
293        if (type == 12) itype = "s";
294        
295        
296        Int_t arraydim = member->GetArrayDim();
297        if (arraydim!=1){
298          //   OLD Version 
299          sprintf(leaflist,"%s[%s]/%s",member->GetName(),branchcount,itype);
300          Int_t comp = compress;
301          if (type == 5) comp--;
302          sprintf(branchname,"%s.%s",name,rd->GetName());
303          TBranch *branch  = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
304          branch->SetBit(kIsClone);
305          TObjArray *leaves = branch->GetListOfLeaves();
306          TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
307          leaf->SetOffset(rd->GetThisOffset());
308          leaf->SetLeafCount(leafcount);
309          Int_t arraydim = member->GetArrayDim();
310          if (arraydim) {
311            Int_t maxindex = member->GetMaxIndex(arraydim-1);
312            leaf->SetLen(maxindex);
313          }
314          fBranches.Add(branch);
315        }
316        else
317          for (Int_t i=0;i< member->GetMaxIndex(0);i++){
318            const char * dmname = member->GetName() ;
319            char  bname[200];
320            Int_t j=0;
321            while ( (dmname[j]!='[') && (dmname[j]!=0) ){
322              bname[j]=dmname[j];
323              j++;
324            }
325            bname[j]=0;
326            sprintf(leaflist,"%s(%d)[%s]/%s",bname,i,branchcount,itype);
327            Int_t comp = compress;
328            if (type == 5) comp--;
329            sprintf(branchname,"%s.%s(%d)",name,bname,i);
330            TBranch *branch  = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
331            branch->SetBit(kIsClone);
332            TObjArray *leaves = branch->GetListOfLeaves();
333            TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
334            leaf->SetOffset(rd->GetThisOffset()+membertype->Size()*i);
335            leaf->SetLeafCount(leafcount);
336            fBranches.Add(branch);
337          }                
338        
339      }     
340    }
341    else if (clinfo->IsA()->InheritsFrom("AliDataType")){ //branch for basic type
342      Int_t type = (((AliDataType*)clinfo)->GetDataType())->GetType();
343      const char *itype = 0;
344      if (type <=0) 
345        Warning("BranchClones","Cannot process member:%s",clinfo->GetName());       
346      else{
347      
348        if (type == 1)  itype = "B";
349        if (type == 11) itype = "b";
350        if (type == 3)  itype = "I";
351        if (type == 5)  itype = "F";
352        if (type == 8)  itype = "D";
353        if (type == 13) itype = "i";
354        if (type == 2)  itype = "S";
355        if (type == 12) itype = "s";
356        sprintf(leaflist,"%s[%s]/%s",name,branchcount,itype);
357        Int_t comp = compress;
358        if (type == 5) comp--;
359        sprintf(branchname,"%s",clinfo->GetName());       
360        TBranch *branch  = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
361        branch->SetBit(kIsClone);
362        TObjArray *leaves = branch->GetListOfLeaves();
363        TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
364        leaf->SetOffset(0);
365        leaf->SetLeafCount(leafcount);
366        fBranches.Add(branch);  
367      }
368    }
369
370 }
371
372
373 //______________________________________________________________________________
374 AliArrayBranch::~AliArrayBranch()
375 {
376 //*-*-*-*-*-*Default destructor for a BranchClones*-*-*-*-*-*-*-*-*-*-*-*
377 //*-*        =====================================
378
379    delete fBranchCount;
380    fBranchCount = 0;
381    fBranches.Delete();
382    fList = 0;
383 }
384
385
386 //______________________________________________________________________________
387 void AliArrayBranch::Browse(TBrowser *b)
388 {
389    fBranches.Browse( b );
390 }
391
392 //______________________________________________________________________________
393 Int_t AliArrayBranch::Fill()
394 {
395 //*-*-*-*-*Loop on all Branches of this BranchClones to fill Basket buffer*-*
396 //*-*      ===============================================================
397
398    Int_t i;
399    Int_t nbytes = 0;
400    Int_t nbranches = fBranches.GetEntriesFast();
401    char **ppointer = (char**)(fAddress);
402    if (ppointer == 0) return 0;
403    fList = (AliObjectArray*)(*ppointer);
404    //   fN    = fList->GetEntriesFast();
405    fN    = fList->GetSize();
406    fEntries++;
407
408    if (fN > fNdataMax) {
409       fNdataMax = fList->GetSize();
410       char branchcount[64];
411       sprintf(branchcount,"%s_",GetName());
412       TLeafI *leafi = (TLeafI*)fBranchCount->GetLeaf(branchcount);
413       leafi->SetMaximum(fNdataMax);
414       for (i=0;i<nbranches;i++)  {
415          TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
416          TObjArray *leaves = branch->GetListOfLeaves();
417          TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
418          leaf->SetAddress();
419       }
420    }
421    nbytes += fBranchCount->Fill();
422    for (i=0;i<nbranches;i++)  {
423       TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
424       TObjArray *leaves = branch->GetListOfLeaves();
425       TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
426       // leaf->Import(fList, fN);   // MI
427       Import(leaf,fN);              // MI change
428       nbytes += branch->Fill();
429    }
430    return nbytes;
431 }
432
433 //______________________________________________________________________________
434 Int_t AliArrayBranch::GetEntry(Int_t entry, Int_t getall)
435 {
436 //*-*-*-*-*Read all branches of a BranchClones and return total number of bytes
437 //*-*      ====================================================================
438
439    if (TestBit(kDoNotProcess) && !getall) return 0;
440    Int_t nbytes = fBranchCount->GetEntry(entry);
441    TLeaf *leafcount = (TLeaf*)fBranchCount->GetListOfLeaves()->UncheckedAt(0);
442    fN = Int_t(leafcount->GetValue());
443    if (fN <= 0) return 0;
444
445    TBranch *branch;
446    Int_t nbranches = fBranches.GetEntriesFast();
447
448      // if fList exists, create clonesarray objects
449    if (fList) {
450      //fList->ExpandCreateFast(fN);   //MI  
451      fList->Resize(fN);    //MI change 
452      for (Int_t i=0;i<nbranches;i++)  {
453        branch = (TBranch*)fBranches.UncheckedAt(i);  
454        nbytes += ((AliArraySubBranch*)branch)->GetEntryExport(entry, getall, fList, fN);  // !!!MI
455       }
456    } else {
457       for (Int_t i=0;i<nbranches;i++)  {
458          branch = (TBranch*)fBranches.UncheckedAt(i);
459          nbytes += branch->GetEntry(entry, getall);
460       }
461    }
462   return nbytes;
463 }
464
465 //______________________________________________________________________________
466 void AliArrayBranch::Print(Option_t *option) const
467 {
468 //*-*-*-*-*-*-*-*-*-*-*-*Print TBranch parameters*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
469 //*-*                    ========================
470
471    fBranchCount->Print(option);
472    Int_t i;
473    Int_t nbranches = fBranches.GetEntriesFast();
474    for (i=0;i<nbranches;i++)  {
475       TBranch *branch = (TBranch*)fBranches[i];
476       branch->Print(option);
477    }
478 }
479
480 //______________________________________________________________________________
481 void AliArrayBranch::Reset(Option_t *option)
482 {
483 //*-*-*-*-*-*-*-*Reset a Branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
484 //*-*            ====================
485 //
486 //    Existing buffers are deleted
487 //    Entries, max and min are reset
488 //
489
490    fEntries        = 0;
491    fTotBytes       = 0;
492    fZipBytes       = 0;
493    Int_t i;
494    Int_t nbranches = fBranches.GetEntriesFast();
495    for (i=0;i<nbranches;i++)  {
496       TBranch *branch = (TBranch*)fBranches[i];
497       branch->Reset(option);
498    }
499    fBranchCount->Reset();
500
501
502 //______________________________________________________________________________
503 void  AliArrayBranch::SetAddress(void *add)  
504 {
505 //*-*-*-*-*-*-*-*Set address of this branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
506 //*-*            ====================
507 //*-*
508
509    fReadEntry = -1;
510    fAddress = (char*)add;
511    char **ppointer = (char**)(fAddress);
512    if ( (*ppointer)==0 ) {  //MI change 
513      *ppointer = (char*) new AliObjectArray(fClassName);
514      fAddress = (char*)ppointer;
515    }
516    fList = (AliObjectArray*)(*ppointer);
517    fBranchCount->SetAddress(&fN);
518
519 }
520
521 //______________________________________________________________________________
522 void AliArrayBranch::SetBasketSize(Int_t buffsize)
523 {
524 //*-*-*-*-*-*-*-*Reset basket size for all subbranches of this branchclones
525 //*-*            ==========================================================
526 //
527
528    fBasketSize = buffsize;
529    Int_t i;
530    Int_t nbranches = fBranches.GetEntriesFast();
531    for (i=0;i<nbranches;i++)  {
532       TBranch *branch = (TBranch*)fBranches[i];
533       branch->SetBasketSize(buffsize);
534    }
535 }
536
537 //_______________________________________________________________________
538 void AliArrayBranch::Streamer(TBuffer &b)
539 {
540 //*-*-*-*-*-*-*-*-*Stream a class object*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
541 //*-*              =========================================
542    if (b.IsReading()) {
543       b.ReadVersion();  //Version_t v = b.ReadVersion();
544       TNamed::Streamer(b);
545       b >> fCompress;
546       b >> fBasketSize;
547       b >> fEntryOffsetLen;
548       b >> fMaxBaskets;
549       b >> fWriteBasket;
550       b >> fEntryNumber;
551       b >> fEntries;
552       b >> fTotBytes;
553       b >> fZipBytes;
554       b >> fOffset;
555       b >> fBranchCount;
556       fClassName.Streamer(b);
557       fBranches.Streamer(b);
558       fTree = gTree;
559       TBranch *branch;
560       TLeaf *leaf;
561       Int_t nbranches = fBranches.GetEntriesFast();
562       for (Int_t i=0;i<nbranches;i++)  {
563          branch = (TBranch*)fBranches[i];
564          branch->SetBit(kIsClone);
565          leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(0);
566          leaf->SetOffset(0);
567       }
568       fRead = 1;
569
570       AliClassInfo *clinfo = AliClassInfo::FindClassInfo(fClassName);
571       if (!clinfo) {
572         AliObjectArray tmp(fClassName); 
573         //MI change - object array to construct class description
574         clinfo = AliClassInfo::FindClassInfo(fClassName);
575       }
576       if (!clinfo) return;
577       
578       TClass *cl = clinfo->GetClass();
579       //      if (!cl) {
580       //   Warning("Streamer","Unknow class: %s. Cannot read BranchClones: %s",
581       //      fClassName.Data(),GetName());
582       //   return;
583       //}
584       if (cl){
585
586         if (!cl->GetListOfRealData())  cl->BuildRealData();
587         char branchname[80];
588         TRealData *rd;
589         TIter      next(cl->GetListOfRealData());
590         while ((rd = (TRealData *) next())) {
591           TDataMember *member = rd->GetDataMember();
592           if (!member->IsBasic())      continue;
593           if (!member->IsPersistent()) continue;
594           TDataType *membertype = member->GetDataType();
595           if (membertype->GetType() == 0) continue; 
596          //MI change - for array spliting
597           Int_t arraydim = member->GetArrayDim();
598           if (arraydim==1){
599             for (Int_t i=0;i< member->GetMaxIndex(0);i++){
600               const char * dmname = member->GetName() ;
601               char  bname[200];
602               Int_t j=0;
603               while ( (dmname[j]!='[') && (dmname[j]!=0) ){
604                 bname[j]=dmname[j];
605                 j++;
606               }
607               bname[j]=0;
608               sprintf(branchname,"%s.%s(%d)",GetName(),bname,i);
609               branch  = (TBranch*)fBranches.FindObject(branchname);
610               if (!branch) continue;
611               TObjArray *leaves = branch->GetListOfLeaves();
612               leaf = (TLeaf*)leaves->UncheckedAt(0);
613               leaf->SetOffset(rd->GetThisOffset()+membertype->Size()*i);
614             }
615           }
616           sprintf(branchname,"%s.%s",GetName(),rd->GetName());
617           branch  = (TBranch*)fBranches.FindObject(branchname);
618           if (!branch) continue;
619           TObjArray *leaves = branch->GetListOfLeaves();
620           leaf = (TLeaf*)leaves->UncheckedAt(0);
621           leaf->SetOffset(rd->GetThisOffset());         
622         }
623
624       }
625       else if (clinfo->IsA()->InheritsFrom("AliDataType")){ //branch for basic type
626         char branchname[100];
627         sprintf(branchname,"%s",clinfo->GetName());  
628         branch  = (TBranch*)fBranches.FindObject(branchname);
629         if (branch){
630           TObjArray *leaves = branch->GetListOfLeaves();
631           leaf = (TLeaf*)leaves->UncheckedAt(0);
632           leaf->SetOffset(0);
633         }   
634       }
635    }
636    else{
637         
638       b.WriteVersion(AliArrayBranch::IsA());
639       TNamed::Streamer(b);
640       b << fCompress;
641       b << fBasketSize;
642       b << fEntryOffsetLen;
643       b << fMaxBaskets;
644       b << fWriteBasket;
645       b << fEntryNumber;
646       b << fEntries;
647       b << fTotBytes;
648       b << fZipBytes;
649       b << fOffset;
650       b << fBranchCount;
651       fClassName.Streamer(b);
652       fBranches.Streamer(b);
653    }
654 }
655
656
657
658 void AliArrayBranch::Import(TLeaf * leaf, Int_t n)
659 {
660
661   const Int_t kIntUndefined = -9999;
662   Int_t j = 0;
663   char *clone;
664   Int_t len    = leaf->GetLenStatic();
665   Int_t offset = leaf->GetOffset();
666   void *value  = leaf->GetValuePointer();
667   //
668   for (Int_t i=0;i<n;i++) {
669     clone = (char*)fList->UncheckedAt(i);
670     //8bit int
671     if (leaf->IsA()==TLeafB::Class()){  
672       memcpy(&((Char_t*)value)[j],clone + offset, len);
673     }
674     //var size
675     if (leaf->IsA()==TLeafC::Class()){  
676       memcpy(&((Char_t*)value)[j],clone + offset, 1);
677     }
678     //double
679     if (leaf->IsA()==TLeafD::Class()){  
680       if (clone) memcpy(&((Double_t*)value)[j],clone + offset, 8*len);
681       else       memcpy(&((Double_t*)value)[j],&kIntUndefined,  8*len);      
682     }
683     //float
684     if (leaf->IsA()==TLeafF::Class()){   
685       if (clone) memcpy(&((Float_t*)value)[j],clone + offset, 4*len);
686       else       memcpy(&((Float_t*)value)[j],&kIntUndefined,  4*len);     
687     }    
688     //int
689     if (leaf->IsA()==TLeafI::Class()){  
690       if (clone) memcpy(&((Int_t*)value)[j],clone + offset, 4*len);
691       else       memcpy(&((Int_t*)value)[j],&kIntUndefined,  4*len);
692     }
693    //short
694     if (leaf->IsA()==TLeafS::Class()){  
695       if (clone) memcpy(&((Short_t*)value)[j],clone + offset, 2*len);
696       else       memcpy(&((Short_t*)value)[j],&kIntUndefined,  2*len);
697     }     
698     j += len;  
699   }
700   //
701 }
702
703 AliObjectBranch::AliObjectBranch(const Text_t *name, const Text_t *classname, void *addobj,
704                                  TTree * tree, 
705                                  Int_t basketsize, Int_t splitlevel, Int_t compress): TBranchObject()
706 {
707 //*-*-*-*-*-*-*-*-*-*-*-*-*Create a BranchObject*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
708 //*-*                      =====================
709 //
710    TClass *cl      = gROOT->GetClass(classname);
711    fTree =tree;  //MI change
712    if (!cl) {
713       Error("TBranchObject","Cannot find class:%s",classname);
714       return;
715    }
716    if (!cl->GetListOfRealData())  cl->BuildRealData();
717    Int_t bufsize=basketsize; //MI ?
718    SetName(name);
719    SetTitle(name);
720    fCompress = compress;
721    if (compress == -1) {
722      TFile *bfile = fTree->GetDirectory()->GetFile(); //MI chnge fTrre - gTree
723       if (bfile) fCompress = bfile->GetCompressionLevel();
724    }
725    if (basketsize < 100) basketsize = 100;
726    fBasketSize     = basketsize;
727    fAddress        = (char*)addobj;
728    fClassName      = classname;
729    fBasketEntry    = new Int_t[fMaxBaskets];
730    fBasketBytes    = new Int_t[fMaxBaskets];
731    fBasketSeek     = new Seek_t[fMaxBaskets];
732    fOldObject      = 0;
733
734    fBasketEntry[0] = fEntryNumber;
735    fBasketBytes[0] = 0;
736
737    TLeaf *leaf     = new TLeafObject(name,classname);
738    leaf->SetBranch(this);
739    leaf->SetAddress(addobj);
740    fNleaves = 1;
741    fLeaves.Add(leaf);
742    fTree->GetListOfLeaves()->Add(leaf);  //MI change fTree-gTree
743
744 // Set the bit kAutoDelete to specify that when reading
745 // in TLeafObject::ReadBasket, the object should be deleted
746 // before calling Streamer.
747 // It is foreseen to not set this bit in a future version.
748    SetAutoDelete(kTRUE);
749
750 //*-*-  Create the first basket
751    //   fTree       = gTree;  //MI change - no need anymore 
752    fDirectory  = fTree->GetDirectory();
753    fFileName   = "";
754
755    if (!splitlevel){
756      TBasket *basket = new TBasket(name,fTree->GetName(),this);
757      fBaskets.Add(basket);
758      return;
759    }
760
761    //
762    // 
763    TBranch * branch =this;
764    TObjArray *blist = branch->GetListOfBranches();
765    const char *rdname;
766    const char *dname;
767    char branchname[64];
768    if (!cl->GetListOfRealData()) cl->BuildRealData();
769    char **apointer = (char**)(addobj);
770    TObject *obj = (TObject*)(*apointer);
771    Bool_t delobj = kFALSE;
772    if (!obj) {
773       obj = (TObject*)cl->New();
774       delobj = kTRUE;
775    }
776 //*-*- Loop on all public data members of the class and its base classes
777    Int_t lenName = strlen(name);
778    Int_t isDot = 0;
779    if (name[lenName-1] == '.') isDot = 1;
780    TBranch *branch1 = 0;
781    TRealData *rd;
782    TIter      next(cl->GetListOfRealData());
783    while ((rd = (TRealData *) next())) {
784       TDataMember *dm = rd->GetDataMember();
785       if (!dm->IsPersistent()) continue; //do not process members with a ! as the first
786                                          // character in the comment field
787       rdname = rd->GetName();
788       dname  = dm->GetName();
789
790   //  Next line now commented, functionality to process arrays is now implemented
791   //  the statement is left to show how to use Property() and kIsArray
792   //     if (dm->Property() & kIsArray) continue;
793
794       TDataType *dtype = dm->GetDataType();
795       Int_t code = 0;
796       if (dtype) code = dm->GetDataType()->GetType();
797
798 //*-*- Encode branch name. Use real data member name
799       sprintf(branchname,"%s",rdname);
800       if (isDot) {
801          if (dm->IsaPointer()) sprintf(branchname,"%s%s",name,&rdname[1]);
802          else                  sprintf(branchname,"%s%s",name,&rdname[0]);
803       }
804       char leaflist[64];
805       Int_t offset    = rd->GetThisOffset();
806       char *pointer   = (char*)obj + offset;
807       if (dm->IsaPointer()) {
808          TClass *clobj = 0;
809          if (!dm->IsBasic()) clobj = gROOT->GetClass(dm->GetTypeName());
810          if (clobj && !strcmp("TClonesArray",clobj->GetName())) {
811             char *cpointer  =(char*)pointer;
812             char **ppointer =(char**)cpointer;
813             TClonesArray *list = (TClonesArray*)(*ppointer);
814             if (splitlevel != 100) {
815                if (isDot) branch1 = new TBranchClones(&branchname[0],pointer,bufsize);
816                else       branch1 = new TBranchClones(&branchname[1],pointer,bufsize);
817                blist->Add(branch1);
818             } else {
819                if (isDot) branch1 = new TBranchObject(&branchname[0],list->ClassName(),pointer,bufsize);
820                else       branch1 = new TBranchObject(&branchname[1],list->ClassName(),pointer,bufsize);
821                blist->Add(branch1);
822             }
823          }
824          else
825            if (clobj && !strcmp("AliObjectArray",clobj->GetName())) {
826              char *cpointer  =(char*)pointer;
827              char **ppointer =(char**)cpointer;
828              TClonesArray *list = (TClonesArray*)(*ppointer);
829              if (splitlevel != 100) {
830                if (isDot) branch1 = new AliArrayBranch(&branchname[0],pointer,fTree,bufsize,compress);
831                else       branch1 = new AliArrayBranch(&branchname[1],pointer,fTree,bufsize,compress);
832                blist->Add(branch1);
833              } else {
834                if (isDot) branch1 = new AliObjectBranch(&branchname[0],list->ClassName(),pointer,fTree,bufsize);
835                else       branch1 = new AliObjectBranch(&branchname[1],list->ClassName(),pointer,fTree,bufsize);
836                blist->Add(branch1);
837              }
838            }
839            else {
840              if (!clobj) {
841                if (code != 1) continue;
842                sprintf(leaflist,"%s/%s",dname,"C");
843                branch1 = new TBranch(branchname,pointer,leaflist,bufsize);
844                branch1->SetTitle(dname);
845                blist->Add(branch1);
846              } else {
847                if (!clobj->InheritsFrom(TObject::Class())) continue;
848                //branch1 = new TBranchObject(dname,clobj->GetName(),pointer,bufsize,0); //MI change
849                branch1 = new AliObjectBranch(dname,clobj->GetName(),pointer,fTree,bufsize,splitlevel);
850                if (isDot) branch1->SetName(&branchname[0]);
851                else       branch1->SetName(&branchname[1]);  //do not use the first character (*)
852                blist->Add(branch1);
853              }
854            }
855       }else {
856 //*-*-------------Data Member is a basic data type----------
857         if (dm->IsBasic()) {
858           if      (code ==  1) sprintf(leaflist,"%s/%s",rdname,"B");
859           else if (code == 11) sprintf(leaflist,"%s/%s",rdname,"b");
860           else if (code ==  2) sprintf(leaflist,"%s/%s",rdname,"S");
861           else if (code == 12) sprintf(leaflist,"%s/%s",rdname,"s");
862           else if (code ==  3) sprintf(leaflist,"%s/%s",rdname,"I");
863           else if (code == 13) sprintf(leaflist,"%s/%s",rdname,"i");
864           else if (code ==  5) sprintf(leaflist,"%s/%s",rdname,"F");
865           else if (code ==  8) sprintf(leaflist,"%s/%s",rdname,"D");
866           else {
867             printf("Cannot create branch for rdname=%s, code=%d\n",branchname, code);
868             leaflist[0] = 0;
869           }
870           branch1 = new TBranch(branchname,pointer,leaflist,bufsize);
871           branch1->SetTitle(rdname);
872           blist->Add(branch1);
873         }
874       }
875       if (branch1) branch1->SetOffset(offset);
876       else Warning("Branch","Cannot process member:%s",rdname);      
877    }
878    if (delobj) delete obj;
879 }
880
881
882
883 //______________________________________________________________________________
884 void AliObjectBranch::SetAddress(void *add)
885 {
886 //*-*-*-*-*-*-*-*Set address of this branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
887 //*-*            ====================
888 //
889
890    //special case when called from code generated by TTree::MakeClass
891    if (Long_t(add) == -1) {
892       SetBit(kWarn);
893       return;
894    }
895    fReadEntry = -1;
896    Int_t nbranches = fBranches.GetEntriesFast();
897    TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
898    if (leaf) leaf->SetAddress(add);
899    TBranch *branch;
900    fAddress = (char*)add;
901    char *pointer   = fAddress;
902    void **ppointer = (void**)add;
903    TObject *obj = (TObject*)(*ppointer);
904    TClass *cl = gROOT->GetClass(fClassName.Data());
905    if (!obj && cl) {
906       obj = (TObject*)cl->New();
907       *ppointer = (void*)obj;
908    }
909    Int_t i, offset;
910    if (!cl) {
911       for (i=0;i<nbranches;i++)  {
912          branch  = (TBranch*)fBranches[i];
913          pointer = (char*)obj;
914          branch->SetAddress(pointer);
915       }
916       return;
917    }
918    if (!cl->GetListOfRealData())  cl->BuildRealData();
919    char *fullname = new char[200];
920    const char *bname = GetName();
921    Int_t lenName = strlen(bname);
922    Int_t isDot = 0;
923    if (bname[lenName-1] == '.') isDot = 1;
924    const char *rdname;
925    TRealData *rd;
926    TIter      next(cl->GetListOfRealData());
927    while ((rd = (TRealData *) next())) {
928       TDataMember *dm = rd->GetDataMember();
929       if (!dm->IsPersistent()) continue;
930       rdname = rd->GetName();
931       TDataType *dtype = dm->GetDataType();
932       Int_t code = 0;
933       if (dtype) code = dm->GetDataType()->GetType();
934       offset  = rd->GetThisOffset();
935       pointer = (char*)obj + offset;
936       branch  = 0;
937       if (dm->IsaPointer()) {
938          TClass *clobj = 0;
939          if (!dm->IsBasic()) clobj = gROOT->GetClass(dm->GetTypeName());
940          if (clobj && !strcmp("TClonesArray",clobj->GetName())) {
941             if (isDot) sprintf(fullname,"%s%s",bname,&rdname[1]);
942             else       sprintf(fullname,"%s",&rdname[1]);
943             branch = (TBranch*)fBranches.FindObject(fullname);
944          }
945          else
946            if (clobj && !strcmp("AliObjectArray",clobj->GetName())) {
947              if (isDot) sprintf(fullname,"%s%s",bname,&rdname[1]);
948              else       sprintf(fullname,"%s",&rdname[1]);
949              branch = (TBranch*)fBranches.FindObject(fullname);
950            }
951          else {
952             if (!clobj) {
953                if (code != 1) continue;
954                if (isDot) sprintf(fullname,"%s%s",bname,&rdname[0]);
955                else       sprintf(fullname,"%s",&rdname[0]);
956                branch = (TBranch*)fBranches.FindObject(fullname);
957             } else {
958                if (!clobj->InheritsFrom(TObject::Class())) continue;
959                if (isDot) sprintf(fullname,"%s%s",bname,&rdname[1]);
960                else       sprintf(fullname,"%s",&rdname[1]);
961                branch = (TBranch*)fBranches.FindObject(fullname);
962             }
963          }
964       } else {
965          if (dm->IsBasic()) {
966             if (isDot) sprintf(fullname,"%s%s",bname,&rdname[0]);
967             else       sprintf(fullname,"%s",&rdname[0]);
968             branch = (TBranch*)fBranches.FindObject(fullname);
969          }
970       }
971       if(branch) branch->SetAddress(pointer);
972    }
973    delete [] fullname;
974 }
975
976
977
978
979
980 AliTree::AliTree(const char *name,const char *title, Int_t maxvirtualsize):
981   TTree(name,title,maxvirtualsize)
982 {
983   //
984   //default constructor for AliTree
985   gTree =this;
986 }
987
988 TBranch * AliTree::AliBranch(const char *name, void *clonesaddress, Int_t bufsize, Int_t splitlevel,
989                              Int_t compres)
990 {
991   if (clonesaddress == 0) return 0;
992   char *cpointer =(char*)clonesaddress;
993   char **ppointer =(char**)cpointer;
994   AliObjectArray *list = (AliObjectArray*)(*ppointer);
995   if (list == 0) return 0;
996   gTree = this;
997   if (splitlevel) {
998     TBranch *branch = new AliArrayBranch(name,clonesaddress,this,bufsize, compres);
999     fBranches.Add(branch);
1000     return branch;
1001   } else {
1002     TBranchObject *branch = new TBranchObject(name,list->ClassName(),clonesaddress,bufsize,0);
1003     fBranches.Add(branch);
1004     return branch;
1005   }
1006 }
1007
1008 TBranch* AliTree::AliBranch(const char *name, const char *classname, void *addobj, 
1009                      Int_t bufsize, Int_t splitlevel)
1010 {
1011   gTree = this;
1012   TClass *cl = gROOT->GetClass(classname);
1013   if (!cl) {
1014     Error("BranchObject","Cannot find class:%s",classname);
1015     return 0;
1016   }
1017   TBranch * branch = new AliObjectBranch(name,classname,addobj, this, bufsize,splitlevel);
1018   fBranches.Add(branch);
1019   return branch;
1020 }
1021
1022