#include <assert.h>
#ifdef WIN32
# include <float.h>
#endif
#include "Riosfwd.h"
#include "Riostream.h"
#include "TROOT.h"
#include "TBaseClass.h"
#include "TSystem.h"
#include "TBuffer.h"
#include "TMath.h"
#include "TClass.h"
#include "TBrowser.h"
#include "TString.h"
#include "Api.h"
#include "TDataSetIter.h"
#include "TTable.h"
#include "TTableDescriptor.h"
#include "TColumnView.h"
#include "TGaxis.h"
#include "TH1.h"
#include "TH2.h"
#include "TProfile.h"
#include "TVirtualPad.h"
#include "TEventList.h"
#include "TPolyMarker.h"
#include "TView.h"
#include "TGaxis.h"
#include "TPolyMarker3D.h"
#include "THLimitsFinder.h"
#include "TTableMap.h"
static TH1 *gCurrentTableHist = 0;
static const char *gDtorName = "dtor";
static   Int_t         gNbins[4] = {100,100,100,100};     
static   Float_t       gVmin[4]  = {0,0,0,0};             
static   Float_t       gVmax[4]  = {20,20,20,20};         
const char *TTable::fgTypeName[] = {
   "NAN", "float", "int", "long", "short", "double",
   "unsigned int", "unsigned long","unsigned short",
   "unsigned char", "char", "Ptr_t"
};
static void ArrayLayout(UInt_t *layout,const UInt_t *size, Int_t dim)
{
  
  
  
  
  
  
  
  
  
  
  
  
   if (dim && layout && size) {
      if (++layout[dim-1] >= size[dim-1]) {
         layout[dim-1] = 0;
         dim--;
         ArrayLayout(layout,size, dim);
      }
   }
}
ClassImp(TTable)
TTableDescriptor *TTable::GetTableDescriptors() const {
 
   assert(0);
   return new TTableDescriptor(this);
}
void TTable::AsString(void *buf, EColumnType type, Int_t width,ostream &out) const
{
  
  
  
  
  
  
  
  
   switch (type) {
      case kFloat:
         out << dec  << setw(width) << setprecision(width-3) << *(float *)buf;
         break;
      case kInt:
         out << dec  <<  setw(width) << *(int *)buf;
         break;
      case kLong:
         out << dec  << setw(width) << *(long *)buf;
         break;
      case kShort:
         out << dec  << setw(width) << *(short *)buf;
         break;
      case kDouble:
         out << dec  << setw(width) << setprecision(width-3) << *(double *)buf;
         break;
      case kUInt:
         out << dec  << setw(width) << *(unsigned int *)buf;
         break;
      case kULong:
         out << dec  << setw(width) << *(unsigned long *)buf;
         break;
      case kUShort:
         out  << setw(width) << "0x" << hex << *(unsigned short *)buf;
         break;
      case kUChar:
         out  << setw(width) << "0x" << hex << int(*(unsigned char *)buf);
         break;
      case kChar:
         out << setw(width) << *(char *)buf;
         break;
      case kBool:
         out << setw(width) << *(bool *)buf;
         break;
      case kPtr:
         out << "->" << setw(width) << *(void **)buf;
         break;
      default:
         out << "\"NaN\"";
         break;
   };
}
const void *TTable::At(Int_t i) const
{
 
   if (!BoundsOk("TTable::At", i)) {
       Warning("TTable::At","%s.%s",GetName(),GetType());
      i = 0;
   }
   return (const void *)(fTable+i*fSize);
}
Int_t TTable::CopyRows(const TTable *srcTable, Long_t srcRow, Long_t dstRow, Long_t nRows, Bool_t expand)
{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
   assert(!TestBit(kIsNotOwn));
   if (!(srcTable && srcTable->GetNRows()) || srcRow > srcTable->GetNRows()-1   )   return 0;
   if (strcmp(GetType(),srcTable->GetType())) {
      
      if (!nRows) nRows = srcTable->GetNRows();
      Long_t tSize = GetTableSize();
      Long_t extraRows = (tSize - dstRow) - nRows;
      if (extraRows < 0) {
         if (expand) {
            ReAllocate(tSize - extraRows);
            extraRows = 0;
         }
         nRows += extraRows;
      }
      if (dstRow+nRows > GetNRows()) SetNRows(dstRow+nRows);
      ::memmove((*this)[dstRow],(*srcTable)[srcRow],(size_t)GetRowSize()*nRows);
      return nRows;
   } else
      Error("CopyRows",
           "This table is <%s> but the src table has a wrong type <%s>",GetType()
           ,srcTable->GetType());
   return 0;
}
void TTable::DeleteRows(Long_t indx, UInt_t nRows)
{
  
  
  
  
  
   if (CopyRows(this, indx+nRows, indx, GetNRows()-indx-nRows))
      SetUsedRows(GetNRows() - nRows);
}
TH1  *TTable::Draw(TCut varexp, TCut selection, Option_t *option, Int_t nentries, Int_t firstentry)
{
   return TTable::Draw(varexp.GetTitle(), selection.GetTitle(), option, nentries, firstentry);
}
TH1 *TTable::Draw(const Text_t *varexp00, const Text_t *selection, Option_t *option,Int_t nentries, Int_t firstentry)
{
   if (GetNRows() == 0 || varexp00 == 0 || varexp00[0]==0) return 0;
   TString  opt;
   const char *hdefault = "htemp";
   Int_t i,j,action;
   Int_t hkeep = 0;
   opt = option;
   opt.ToLower();
   Text_t *varexp0 = StrDup(varexp00);
   Text_t *hname = strstr(varexp0,">>");
   TH1 *oldh1 = 0;
   TEventList *elist = 0;
   Bool_t profile = kFALSE;
   gCurrentTableHist = 0;
   if (hname) {
      *hname  = 0;
      hname += 2;
      hkeep  = 1;
      i = strcspn(varexp0,">>");
      Bool_t hnameplus = kFALSE;
      while (*hname == ' ') hname++;
      if (*hname == '+') {
         hnameplus = kTRUE;
         hname++;
         while (*hname == ' ') hname++;
         j = strlen(hname)-1;
         while (j) {
            if (hname[j] != ' ') break;
            hname[j] = 0;
            j--;
         }
      }
      if (i) {
         oldh1 = (TH1*)gDirectory->Get(hname);
         if (oldh1 && !hnameplus) oldh1->Reset();
      } else {
         elist = (TEventList*)gDirectory->Get(hname);
         if (!elist) {
            elist = new TEventList(hname,selection,1000,0);
         }
         if (elist && !hnameplus) elist->Reset();
      }
   }
   if (!hname || *hname==0) {
      hkeep  = 0;
      if (gDirectory) {
         oldh1 = (TH1*)gDirectory->Get(hdefault);
         if (oldh1 ) { oldh1->Delete(); oldh1 = 0;}
      }
   }
   
   const Char_t *expressions[] ={varexp0,0,0,0,selection};
   Int_t maxExpressions = sizeof(expressions)/sizeof(Char_t *);
   Char_t *nextColon    = varexp0;
   Int_t colIndex       = 1;
   while ((nextColon = strchr(nextColon,':')) && ( colIndex < maxExpressions - 1 ) ) {
      *nextColon = 0;
      nextColon++;
      expressions[colIndex] = nextColon;
      colIndex++;
   }
   expressions[colIndex] = selection;
   Printf(" Draw %s for <%s>\n", varexp00, selection);
   Char_t *exprFileName = MakeExpression(expressions,colIndex+1);
   if (!exprFileName) {
      delete [] varexp0;
      return 0;
   }
   Int_t dimension = colIndex;
   TString title = expressions[0];
   for (i=1;i<colIndex;i++) {
      title += ":";
      title += expressions[i];
   }
   Int_t nsel = strlen(selection);
   if (nsel > 1) {
      if (nsel < 80-title.Length()) {
         title += "{";
         title += selection;
         title += "}";
      } else
         title += "{...}";
   }
   const Char_t *htitle = title.Data();
   if (oldh1) {
      Int_t mustdelete = 0;
      if (oldh1->InheritsFrom("TProfile")) profile = kTRUE;
      if (opt.Contains("prof")) {
         if (!profile) mustdelete = 1;
      } else {
         if (oldh1->GetDimension() != dimension) mustdelete = 1;
      }
      if (mustdelete) {
         Warning("Draw","Deleting old histogram with different dimensions");
         delete oldh1; oldh1 = 0;
      }
   }
   if (!gPad && !opt.Contains("goff") && dimension > 0) {
      gROOT->MakeDefCanvas();
   }
   if (dimension == 1) {
      action = 1;
      if (!oldh1) {
         gNbins[0] = 100;
         if (gPad && opt.Contains("same")) {
            TH1 *oldhtemp = (TH1*)gPad->FindObject(hdefault);
            if (oldhtemp) {
               gNbins[0] = oldhtemp->GetXaxis()->GetNbins();
               gVmin[0]  = oldhtemp->GetXaxis()->GetXmin();
               gVmax[0]  = oldhtemp->GetXaxis()->GetXmax();
            } else {
               gVmin[0]  = gPad->GetUxmin();
               gVmax[0]  = gPad->GetUxmax();
            }
         } else {
            action = -1;
         }
      }
      TH1F *h1;
      if (oldh1) {
         h1 = (TH1F*)oldh1;
         gNbins[0] = h1->GetXaxis()->GetNbins();  
      } else {
         h1 = new TH1F(hname,htitle,gNbins[0],gVmin[0],gVmax[0]);
         if (!hkeep) {
            h1->SetBit(kCanDelete);
            h1->SetDirectory(0);
         }
         if (opt.Length() && opt[0] == 'e') h1->Sumw2();
      }
      EntryLoop(exprFileName,action, h1, nentries, firstentry, option);
      if (!opt.Contains("goff")) h1->Draw(option);
   } else if (dimension == 2) {
      action = 2;
      if (!opt.Contains("same") && gPad)  gPad->Clear();
      if (!oldh1 || !opt.Contains("same")) {
         gNbins[0] = 40;
         gNbins[1] = 40;
         if (opt.Contains("prof")) gNbins[1] = 100;
         if (opt.Contains("same")) {
            TH1 *oldhtemp = (TH1*)gPad->FindObject(hdefault);
            if (oldhtemp) {
               gNbins[1] = oldhtemp->GetXaxis()->GetNbins();
               gVmin[1]  = oldhtemp->GetXaxis()->GetXmin();
               gVmax[1]  = oldhtemp->GetXaxis()->GetXmax();
               gNbins[0] = oldhtemp->GetYaxis()->GetNbins();
               gVmin[0]  = oldhtemp->GetYaxis()->GetXmin();
               gVmax[0]  = oldhtemp->GetYaxis()->GetXmax();
            } else {
               gNbins[1] = 40;
               gVmin[1]  = gPad->GetUxmin();
               gVmax[1]  = gPad->GetUxmax();
               gNbins[0] = 40;
               gVmin[0]  = gPad->GetUymin();
               gVmax[0]  = gPad->GetUymax();
            }
         } else {
            action = -2;
         }
      }
      if (profile || opt.Contains("prof")) {
         TProfile *hp;
         if (oldh1) {
            action = 4;
            hp = (TProfile*)oldh1;
         } else {
            if (action < 0) action = -4;
            if (opt.Contains("profs"))
               hp = new TProfile(hname,htitle,gNbins[1],gVmin[1], gVmax[1],"s");
            else
               hp = new TProfile(hname,htitle,gNbins[1],gVmin[1], gVmax[1],"");
            if (!hkeep) {
               hp->SetBit(kCanDelete);
               hp->SetDirectory(0);
            }
         }
         EntryLoop(exprFileName,action,hp,nentries, firstentry, option);
         if (!opt.Contains("goff")) hp->Draw(option);
      } else {
         TH2F *h2;
         if (oldh1) {
            h2 = (TH2F*)oldh1;
         } else {
            h2 = new TH2F(hname,htitle,gNbins[1],gVmin[1], gVmax[1], gNbins[0], gVmin[0], gVmax[0]);
            if (!hkeep) {
               const Int_t kNoStats = BIT(9);
               h2->SetBit(kCanDelete);
               h2->SetBit(kNoStats);
               h2->SetDirectory(0);
            }
         }
         Int_t noscat = strlen(option);
         if (opt.Contains("same")) noscat -= 4;
         if (noscat) {
            EntryLoop(exprFileName,action,h2,nentries, firstentry, option);
 
            if (!opt.Contains("goff")) h2->Draw(option);
         } else {
            action = 12;
            if (!oldh1 && !opt.Contains("same")) action = -12;
            EntryLoop(exprFileName,action,h2,nentries, firstentry, option);
            if (oldh1 && !opt.Contains("goff")) h2->Draw(option);
         }
      }
   } else if (dimension == 3) {
      action = 13;
      if (!opt.Contains("same")) action = -13;
      EntryLoop(exprFileName,action,0,nentries, firstentry, option);
   } else {
      action = 5;
      EntryLoop(exprFileName,action,elist,nentries, firstentry, option);
   }
   delete [] exprFileName;
   delete [] varexp0;
   return gCurrentTableHist;
}
static void FindGoodLimits(Int_t nbins, Int_t &newbins, Float_t &xmin, Float_t &xmax)
{
   Double_t binlow,binhigh,binwidth;
   Int_t n;
   Double_t dx = 0.1*(xmax-xmin);
   Double_t umin = xmin - dx;
   Double_t umax = xmax + dx;
   if (umin < 0 && xmin >= 0) umin = 0;
   if (umax > 0 && xmax <= 0) umax = 0;
#if ROOT_VERSION_CODE >= ROOT_VERSION(3,03,5)
   THLimitsFinder::Optimize(umin,umax,nbins,binlow,binhigh,n,binwidth,"");
#else
   TGaxis::Optimize(umin,umax,nbins,binlow,binhigh,n,binwidth,"");
#endif
   if (binwidth <= 0 || binwidth > 1.e+39) {
      xmin = -1;
      xmax = 1;
   } else {
      xmin    = binlow;
      xmax    = binhigh;
   }
   newbins = nbins;
}
Bool_t TTable::EntryLoop(const Char_t *exprFileName,Int_t &action, TObject *obj
                          ,Int_t nentries, Int_t firstentry, Option_t *option)
{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
   Double_t rmin[3],rmax[3];
   switch(G__loadfile((Char_t *)exprFileName)) {
      case G__LOADFILE_SUCCESS:
      case G__LOADFILE_DUPLICATE:
         break;
      default:
         Error("EntryLoop","Error: loading file %s",exprFileName);
         G__unloadfile((Char_t *)exprFileName);
         return kFALSE; 
   }
   
   
   
   const Char_t *funcName = "SelectionQWERTY";
#define BYTECODE
#ifdef BYTECODE
   const Char_t *argtypes = "Float_t *,float **, int&, int& ";
   Long_t offset;
   G__ClassInfo globals;
   G__MethodInfo func = globals.GetMethod(funcName,argtypes,&offset);
   
   struct G__bytecodefunc *pbc = func.GetBytecode();
   if(!pbc) {
      Error("EntryLoop","Bytecode compilation %s",funcName);
      G__unloadfile((Char_t *)exprFileName);
      return kFALSE; 
   }
#endif
   
   int i;
   int nRows =  GetNRows();
   TTableDescriptor    *tabsDsc   = GetRowDescriptors();
   tableDescriptor_st  *descTable = tabsDsc->GetTable();
   Float_t  results[]    = {1,1,1,1,1};
   Char_t **addressArray = (Char_t **)new ULong_t[tabsDsc->GetNRows()];
   Char_t *thisTable     = (Char_t *)GetArray();
#ifdef BYTECODE
   G__CallFunc callfunc;
   callfunc.SetBytecode(pbc);
   callfunc.SetArg((long)(&results[0]));   
   callfunc.SetArg((long)(addressArray));  
   callfunc.SetArg((long)(&i));            
   callfunc.SetArg((long)(&nRows));        
#else
   char buf[200];
   sprintf(buf,"%s((Float_t*)(%ld),(void**)(%ld),*(int*)(%ld),*(int*)(%ld))"
             ,funcName
             ,(long int)results,(long int)addressArray,(long int)(&i),(long int)(&nRows));
#endif
   
#ifdef BYTECODE
#  define CALLMETHOD callfunc.Exec(0);
#else
#  define CALLMETHOD G__calc(buf);
#endif
#define TAKEACTION_BEGIN                                                                    \
            descTable = tabsDsc->GetTable();                                                \
            for (i=0; i < tabsDsc->GetNRows(); i++,descTable++ )                            \
               addressArray[i] = addressEntry + descTable->fOffset;                         \
            for(i=firstentry;i<lastEntry;i++) {                                             \
            CALLMETHOD
#define TAKEACTION_END  for (int j=0; j < tabsDsc->GetNRows(); j++ ) addressArray[j] += rSize;}
   if (firstentry < nRows ) {
      Long_t rSize         = GetRowSize();
      Char_t *addressEntry = thisTable + rSize*firstentry;
      Int_t lastEntry = TMath::Min(UInt_t(firstentry+nentries),UInt_t(nRows));
      if (action < 0) {
         gVmin[0] = gVmin[1] = gVmin[2] = 1e30;
         gVmax[0] = gVmax[1] = gVmax[2] = -gVmin[0];
      }
      Int_t nchans = 0;
      switch ( action ) {
         case -1: {
            TAKEACTION_BEGIN
            if (results[1]) {
               if (gVmin[0] > results[0]) gVmin[0] = results[0];
               if (gVmax[0] < results[0]) gVmax[0] = results[0];
            }
            TAKEACTION_END
            nchans = gNbins[0];
            if (gVmin[0] >= gVmax[0]) { gVmin[0] -= 1; gVmax[0] += 1;}
            FindGoodLimits(nchans,gNbins[0],gVmin[0],gVmax[0]);
            ((TH1 *)obj)->SetBins(gNbins[0],gVmin[0],gVmax[0]);
         }
         case  1:
            TAKEACTION_BEGIN
            if (results[1]) ((TH1 *)obj)->Fill(Axis_t(results[0]),Stat_t(results[1]));
            TAKEACTION_END
            gCurrentTableHist = ((TH1 *)obj);
            break;
         case  -2:
            TAKEACTION_BEGIN
            if (results[2]) {
               if (gVmin[0] > results[1]) gVmin[0] = results[1];
               if (gVmax[0] < results[1]) gVmax[0] = results[1];
               if (gVmin[1] > results[0]) gVmin[1] = results[0];
               if (gVmax[1] < results[0]) gVmax[1] = results[0];
            }
            TAKEACTION_END
            nchans = gNbins[0];
            if (gVmin[0] >= gVmax[0]) { gVmin[0] -= 1; gVmax[0] += 1;}
            FindGoodLimits(nchans,gNbins[0],gVmin[0],gVmax[0]);
            if (gVmin[1] >= gVmax[1]) { gVmin[1] -= 1; gVmax[1] += 1;}
            FindGoodLimits(nchans,gNbins[1],gVmin[1],gVmax[1]);
            ((TH1*)obj)->SetBins(gNbins[1],gVmin[1],gVmax[1],gNbins[0],gVmin[0],gVmax[0]);
         case   2:
            if (obj->IsA() == TH2F::Class()) {
               TAKEACTION_BEGIN
               if (results[2]) ((TH2F*)obj)->Fill(Axis_t(results[0]),Axis_t(results[1]),Stat_t(results[2]));
               TAKEACTION_END
            } else if (obj->IsA() == TH2S::Class()) {
               TAKEACTION_BEGIN
               if (results[2]) ((TH2S*)obj)->Fill(Axis_t(results[0]),Axis_t(results[1]),Stat_t(results[2]));
               TAKEACTION_END
            } else if (obj->IsA() == TH2C::Class()) {
               TAKEACTION_BEGIN
               if (results[2]) ((TH2C*)obj)->Fill(Axis_t(results[0]),Axis_t(results[1]),Stat_t(results[2]));
               TAKEACTION_END
            } else if (obj->IsA() == TH2D::Class()) {
               TAKEACTION_BEGIN
               if (results[2]) ((TH2D*)obj)->Fill(Axis_t(results[0]),Axis_t(results[1]),Stat_t(results[2]));
               TAKEACTION_END
            }
            gCurrentTableHist =  ((TH1 *)obj);
            break;
         case -4:
            TAKEACTION_BEGIN
            if (results[2]) {
               if (gVmin[0] > results[1]) gVmin[0] = results[1];
               if (gVmax[0] < results[1]) gVmax[0] = results[1];
               if (gVmin[1] > results[0]) gVmin[1] = results[0];
               if (gVmax[1] < results[0]) gVmax[1] = results[0];
            }
            TAKEACTION_END
            nchans = gNbins[1];
            if (gVmin[1] >= gVmax[1]) { gVmin[1] -= 1; gVmax[1] += 1;}
            FindGoodLimits(nchans,gNbins[1],gVmin[1],gVmax[1]);
            ((TProfile*)obj)->SetBins(gNbins[1],gVmin[1],gVmax[1]);
         case  4:
            TAKEACTION_BEGIN
            if (results[2]) ((TProfile*)obj)->Fill(Axis_t(results[0]),Axis_t(results[1]),Stat_t(results[2]));
            TAKEACTION_END
            break;
         case -12:
            TAKEACTION_BEGIN
            if (results[2]) {
               if (gVmin[0] > results[1]) gVmin[0] = results[1];
               if (gVmax[0] < results[1]) gVmax[0] = results[1];
               if (gVmin[1] > results[0]) gVmin[1] = results[0];
               if (gVmax[1] < results[0]) gVmax[1] = results[0];
            }
            TAKEACTION_END
            nchans = gNbins[0];
            if (gVmin[0] >= gVmax[0]) { gVmin[0] -= 1; gVmax[0] += 1;}
            FindGoodLimits(nchans,gNbins[0],gVmin[0],gVmax[0]);
            if (gVmin[1] >= gVmax[1]) { gVmin[1] -= 1; gVmax[1] += 1;}
            FindGoodLimits(nchans,gNbins[1],gVmin[1],gVmax[1]);
            ((TH2F*)obj)->SetBins(gNbins[1],gVmin[1],gVmax[1],gNbins[0],gVmin[0],gVmax[0]);
         case  12: {
            if (!strstr(option,"same") && !strstr(option,"goff")) {
               ((TH2F*)obj)->DrawCopy(option);
               gPad->Update();
            }
            Float_t *x = new Float_t[lastEntry-firstentry]; 
            Float_t *y = new Float_t[lastEntry-firstentry]; 
            Float_t u, v;
            Float_t umin = gPad->GetUxmin();
            Float_t umax = gPad->GetUxmax();
            Float_t vmin = gPad->GetUymin();
            Float_t vmax = gPad->GetUymax();
            Int_t pointIndex = 0;
            TAKEACTION_BEGIN
            if (results[2]) {
               u = gPad->XtoPad(results[0]);
               v = gPad->YtoPad(results[1]);
               if (u < umin) u = umin;
               if (u > umax) u = umax;
               if (v < vmin) v = vmin;
               if (v > vmax) v = vmax;
               x[pointIndex] = u;
               y[pointIndex] = v;
               pointIndex++;
            }
            TAKEACTION_END
            if (pointIndex && !strstr(option,"goff")) {
               TPolyMarker *pm = new TPolyMarker(pointIndex,x,y);
               pm->Draw();
               pm->SetBit(kCanDelete);
            }
            if (!((TH2F*)obj)->TestBit(kCanDelete))
               if (pointIndex)
                  for(i=0;i<pointIndex;i++) ((TH2F*)obj)->Fill(x[i], y[i]);
            delete [] x; delete [] y;
            gCurrentTableHist = ((TH1*)obj);
            }
            break;
         case -13:
            TAKEACTION_BEGIN
            if (results[3]) {
               if (gVmin[0] > results[2]) gVmin[0] = results[2];
               if (gVmax[0] < results[2]) gVmax[0] = results[2];
               if (gVmin[1] > results[1]) gVmin[1] = results[1];
               if (gVmax[1] < results[1]) gVmax[1] = results[1];
               if (gVmin[2] > results[0]) gVmin[2] = results[0];
               if (gVmax[2] < results[0]) gVmax[2] = results[0];
            }
            TAKEACTION_END
            rmin[0] = gVmin[2]; rmin[1] = gVmin[1]; rmin[2] = gVmin[0];
            rmax[0] = gVmax[2]; rmax[1] = gVmax[1]; rmax[2] = gVmax[0];
            gPad->Clear();
            gPad->Range(-1,-1,1,1);
            TView::CreateView(1,rmin,rmax);
         case 13: {
            TPolyMarker3D *pm3d = new TPolyMarker3D(lastEntry-firstentry);
            pm3d->SetBit(kCanDelete);
            TAKEACTION_BEGIN
            if (results[3]) pm3d->SetNextPoint(results[0],results[1],results[2]);
            TAKEACTION_END
            pm3d->Draw();
         }
         break;
         default:
            Error("EntryLoop","unknown action \"%d\" for table <%s>", action, GetName());
            break;
      };
   }
   G__unloadfile((Char_t *)exprFileName);
   delete [] addressArray;
   return kTRUE;
}
TTable::TTable(const Text_t *name, Int_t size) : TDataSet(name),
         fSize(size),fN(0), fTable(0),fMaxIndex(0)
{
   
   if (size == 0) Warning("TTable(0)","Wrong table format");
}
TTable::TTable(const Text_t *name, Int_t n,Int_t size) : TDataSet(name),
        fSize(size),fN(0),fTable(0),fMaxIndex(0)
{
   
   if (n > 0) Set(n);
}
TTable::TTable(const Text_t *name, Int_t n, Char_t *table,Int_t size) : TDataSet(name),
         fSize(size),fN(0),fTable(0),fMaxIndex(0)
{
   
   Set(n, table);
}
TTable::TTable(const Text_t *name, const Text_t *type, Int_t n, Char_t *array, Int_t size)
         : TDataSet(name),fSize(size),fTable(0),fMaxIndex(0)
{
   
   fTable = array;
   SetType(type);
   SetfN(n);
}
TTable::TTable(const TTable &table):TDataSet(table)
{
   
   fTable    = 0;
   SetUsedRows(table.GetNRows());
   fSize     = table.GetRowSize();
   SetfN(table.fN);
   Set(table.fN, table.fTable);
}
TTable &TTable::operator=(const TTable &rhs)
{
   
   
   
   if (strcmp(GetType(),rhs.GetType()) == 0) {
      if (this != &rhs && rhs.GetNRows() >0 ){
         Set(rhs.GetNRows(), rhs.fTable);
         SetUsedRows(rhs.GetNRows());
      }
   } else
      Error("operator=","Can not copy <%s> table into <%s> table", rhs.GetType(),GetType());
   return *this;
}
TTable::~TTable()
{
   
   Delete();
}
void TTable::Adopt(Int_t n, void *arr)
{
   
   
   Clear();
   SetfN(n); SetUsedRows(n);
   fTable = (char *)arr;
}
Int_t TTable::AddAt(const void *row)
{
  
  
  
  
  
   Int_t gap = GetTableSize() - GetNRows();
   
   if (gap < 1) ReAllocate(GetTableSize() + TMath::Max(1,Int_t(0.3*GetTableSize())));
   Int_t indx = GetNRows();
   AddAt(row,indx);
   return indx;
}
void TTable::AddAt(const void *row, Int_t i)
{
   
   
   
   
   
   if (!BoundsOk("TTable::AddAt", i))
      i = 0;
   if (row) memcpy(fTable+i*fSize,row,fSize);
   else memset(fTable+i*fSize,127,fSize);
   SetUsedRows(TMath::Max((Int_t)i+1,Int_t(fMaxIndex)));
}
void TTable::CopyStruct(Char_t *dest, const Char_t *src)
{
 
 
   ::memcpy(dest,src,fSize*fN);
}
void TTable::CopySet(TTable &array)
{
   
   array.Set(fN);
   CopyStruct(array.fTable,fTable);
}
const Char_t *TTable::GetColumnComment(Int_t columnIndex) const {
   
   TDataSetIter nextComment(GetRowDescriptors()->MakeCommentField(kFALSE));
   TDataSet *nxc = 0;
   for (int i=0; i<= columnIndex; i++) nxc = nextComment();
   return nxc ? nxc->GetTitle() : 0;
}
Long_t TTable::AppendRows(const void *row, UInt_t nRows)
{
   
   
   
   
   Long_t size = 0;
   if (!TestBit(kIsNotOwn) && row && nRows ) {
      Int_t indx = GetNRows();
      ReAllocate(nRows);
      
      ::memmove(fTable+indx*fSize,row,fSize*nRows);
      size = GetSize();
   }
   return TestBit(kIsNotOwn) ? 0 : GetSize();
}
Long_t TTable::InsertRows(const void *row, Long_t indx, UInt_t nRows)
{
  
  
  
  
  
  
  
  
  
  
  
  
  
   Long_t nShifted = 0;
   if (nRows > 0) {
      
      nShifted = CopyRows(this, indx, indx+nRows, GetNRows()+nRows);
      
      ::memmove(fTable+indx*fSize,row,fSize*nRows);
   }
   return nShifted;
}
void *TTable::ReAllocate()
{
  
  
  
  
  
   ReAlloc(GetNRows()+1);
   return (void *)fTable;
}
void *TTable::ReAllocate(Int_t newsize)
{
  
  
  
  
  
   if (newsize > fN) ReAlloc(newsize);
   return (void *)fTable;
}
void TTable::ReAlloc(Int_t newsize)
{
  
   if (!TestBit(kIsNotOwn) && newsize > 0) {
      void *arr = 0;
      Int_t sleepCounter = 0;
      while (!(arr =  realloc(fTable,fSize*newsize))) {
         sleepCounter++;
         Warning("ReAlloc",
              "Not enough memory to Reallocate %d bytes for table <%s::%s>. Please cancel some jobs",
              newsize, GetType(),GetName());
         gSystem->Sleep(1000*600);
         if (sleepCounter > 30) {
            Error("ReAlloc","I can not wait anymore. Good bye");
            assert(0);
         }
      }
      SetfN(newsize);
      fTable = (char *)arr;
   }
}
Char_t *TTable::Create()
{
   
   
   if (!fTable) {
      void *ptr = 0;
      Int_t sleepCounter = 0;
      while (!(ptr = malloc(fSize*fN))) {
         sleepCounter++;
         Warning("Create",
            "Not enough memory to allocate %d rows for table <%s::%s>. Please cancel some jobs",
            fN, GetType(),GetName());
         gSystem->Sleep(1000*600);
         if (sleepCounter > 30){
            Error("Create","I can not wait anymore. Good bye");
            assert(0);
         }
      }
      fTable = (Char_t *)ptr;
      
      memset(fTable,0,fSize*fN);
   }
   return fTable;
}
void TTable::Browse(TBrowser *b){
   
   if (!b) return;
   TDataSet::Browse(b);
   Int_t nrows = TMath::Min(Int_t(GetNRows()),6);
   if (nrows == 0) nrows = 1;
   Print(0,nrows);
   
   UInt_t nCol = GetNumberOfColumns();
   for (UInt_t i = 0;i<nCol;i++){
      TColumnView *view = 0;
      UInt_t nDim = GetDimensions(i);
      const Char_t *colName = GetColumnName(i);
      if (!nDim) { 
         
         
         if( GetColumnType(i)== kPtr) {
            UInt_t offset = GetOffset(i);
            TTableMap *m = *(TTableMap **)(((char *)GetArray())+offset);
            if (m) {
               TString nameMap = "*";
               nameMap += m->Table()->GetName();
               b->Add(m,nameMap.Data());
            }
         } else {
            view = new TColumnView(GetColumnName(i),this);
            view->SetBit(kCanDelete);
            b->Add(view,view->GetName());
         }
      } else {     
         const UInt_t *indx = GetIndexArray(i);
         UInt_t totalSize = 1;
         UInt_t k;
         for (k=0;k<nDim; k++) totalSize *= indx[k];
         for (k=0;k<totalSize;k++) {
            char *buffer =  new char[strlen(colName)+13];
            sprintf(buffer,"%s[%d]",colName,k);
            view = new TColumnView(buffer,this);
            view->SetBit(kCanDelete);
            b->Add(view,view->GetName());
            delete [] buffer;
         }
      }
   }
}
void TTable::Clear(Option_t *opt)
{
   
   
   if (!fTable) return;
   Bool_t dtor = kFALSE;
   dtor = opt && (strcmp(opt,gDtorName)==0);
   if (!opt || !opt[0] || dtor ) {
      if (! TestBit(kIsNotOwn)) {
         if (!dtor) ResetMap();
         free(fTable);
      }
      fTable    = 0;
      fMaxIndex = 0;
      SetfN(0);
      return;
   }
}
void TTable::Delete(Option_t *opt)
{
   
   
   
   
   
   Clear(gDtorName);
   TDataSet::Delete(opt);
}
TClass  *TTable::GetRowClass() const
{
   
   TClass *cl = 0;
   TTableDescriptor *dsc = GetRowDescriptors();
   if (dsc) cl = dsc->RowClass();
   else Error("GetRowClass()","Table descriptor of <%s::%s> table lost",
             GetName(),GetType());
   return cl;
}
Long_t TTable::GetNRows() const {
   return fMaxIndex;
}
Long_t TTable::GetRowSize() const {
   return fSize;
}
Long_t TTable::GetTableSize() const {
   return fN;
}
void TTable::Fit(const Text_t *formula ,const Text_t *varexp, const Text_t *selection,Option_t *option ,Option_t *goption,Int_t nentries, Int_t firstentry)
{
   Int_t nch = strlen(option) + 10;
   char *opt = new char[nch];
   if (option) sprintf(opt,"%sgoff",option);
   else        strcpy(opt,"goff");
   Draw(varexp,selection,opt,nentries,firstentry);
   delete [] opt;
   TH1 *hfit = gCurrentTableHist;
   if (hfit) {
      Printf("hname=%s, formula=%s, option=%s, goption=%s\n",hfit->GetName(),formula,option,goption);
      
      Bool_t canDeleteBit = hfit->TestBit(kCanDelete);
      if (canDeleteBit)  hfit->ResetBit(kCanDelete);
      hfit->Fit(formula,option,goption);
      if (TestBit(canDeleteBit))   hfit->SetBit(kCanDelete);
   }
   else      Printf("ERROR hfit=0\n");
}
const Char_t *TTable::GetType() const
{
   return GetTitle();
}
Bool_t TTable::IsFolder() const {
   
   
   
   
   
   return kTRUE; 
#if 0
   
   return
   (fList && fList->Last() ? kTRUE : kFALSE)
   ||
     (GetNRows() > 0);
#endif
}
Int_t TTable::NaN()
{
   EColumnType code;
   char const *cell,*colname,*table;
   double word;
   int icol,irow,colsize,wordsize,nwords,iword,nerr,offset;
   TTableDescriptor *rowDes = GetRowDescriptors();
   assert(rowDes!=0);
   table = (const char*)GetArray();
   int ncols = rowDes->GetNumberOfColumns();
   int lrow  = GetRowSize();
   int nrows = GetNRows  ();
   nerr =0;
   for (icol=0; icol < ncols; icol++) {
      code = rowDes->GetColumnType(icol);
      if (code!=kFloat && code!=kDouble) continue;
      offset   = rowDes->GetOffset    (icol);
      colsize  = rowDes->GetColumnSize(icol);
      wordsize = rowDes->GetTypeSize  (icol);
      nwords = colsize/wordsize;
      for (irow=0; irow < nrows; irow++) { 
         cell = table + offset + irow*lrow;
         for (iword=0;iword<nwords; iword++,cell+=wordsize) { 
            word = (code==kDouble) ? *(double*)cell : *(float*)cell;
            if (TMath::Finite(word))     continue;
            nerr++; colname = rowDes->GetColumnName(icol);
            Warning("NaN"," Table %s.%s.%d\n",GetName(),colname,irow);
         }
      }
   }
   return nerr;
}
TTable *TTable::New(const Char_t *name, const Char_t *type, void *array, UInt_t size)
{
  
   TTable *table = 0;
   if (type && name) {
      TString tableType(type);
      TString t = tableType.Strip();
      const Char_t *classprefix="St_";
      const Int_t extralen = strlen(classprefix) + 1;
      Char_t *classname = new Char_t[strlen(t.Data())+extralen];
      strcpy(classname,classprefix);
      strcat(classname,t.Data());
      TClass *cl = TClass::GetClass(classname);
      if (cl) {
         table = (TTable *)cl->New();
         if (table) {
            table->SetTablePointer(array);
            table->SetName(name);
            table->SetfN(size);
            table->SetUsedRows(size);
         }
      }
      delete [] classname;
   }
   return table;
}
Bool_t TTable::OutOfBoundsError(const char *where, Int_t i) const
{
   
   Error(where, "index %d out of bounds (size: %d, this: 0x%08x)", i, fN, this);
   return kFALSE;
}
Char_t *TTable::Print(Char_t *strbuf,Int_t lenbuf) const
{
   
   Int_t iOut = 0;
   TTableDescriptor *dscT = GetRowDescriptors();
   if (!dscT ) {
      Error("Print"," No dictionary entry for <%s> structure", GetTitle());
      if (lenbuf>0) iOut += sprintf(strbuf+iOut," *** Errror ***");
      return strbuf;
   }
   TROOT::IndentLevel();
   if (lenbuf>0) {
      
      Char_t *typenam =  new Char_t [strlen(dscT->GetName())+1];
      strcpy(typenam,dscT->GetName());
      
      Char_t *last = strrchr(typenam,'_');
      
      Char_t *eon = 0;
      if (last) eon = strstr(last,"_st");
      
      if (eon) *eon = '\0';
      iOut += sprintf(strbuf+iOut,"struct %s {",typenam);
      delete [] typenam;
   } else {
      cout << "struct " << dscT->GetName() << " {" << endl;
   }
   TTableDescriptor::iterator dsc  = dscT->begin();
   TTableDescriptor::iterator dscE = dscT->end();
   TDataSetIter nextComment(dscT->MakeCommentField(kFALSE));
   for (;dsc != dscE; dsc++) {
      TROOT::IndentLevel();
      TString name = GetTypeName(EColumnType((*dsc).fType));
      if (lenbuf>0) {
         
         name.ReplaceAll("unsigned char","octet");
         name.ReplaceAll("int","long");
         iOut += sprintf(strbuf+iOut," %s %s",name.Data(),(*dsc).fColumnName);
      } else
         cout << '\t'<< name.Data() << '\t'<< (*dsc).fColumnName;
      Int_t indx;
      Int_t dim = (*dsc).fDimensions;
      for  (indx = 0; indx < dim; indx++) {
         if (lenbuf>0)
            iOut += sprintf(strbuf+iOut,"[%d]",(*dsc).fIndexArray[indx]);
         else
            cout <<  "[" << dec << (*dsc).fIndexArray[indx]<<"]";
      }
      
      TDataSet *nxc = nextComment();
      if (lenbuf>0)
         iOut += sprintf(strbuf+iOut, ";");
      else {
         const char *title = nxc ? nxc->GetTitle() : " ";
         cout << ";\t//" << title << endl;
      }
   } 
   TROOT::IndentLevel();
   if (lenbuf>0)
      iOut += sprintf(strbuf+iOut, "}");
   else
      cout << "}" << endl;
   return strbuf;
}
const Char_t *TTable::PrintHeader() const
{
  
   cout << endl << " ---------------------------------------------------------------------------------------" << endl
        <<  " " << Path()
                <<"  Allocated rows: "<<fN
                <<"\t Used rows: "<<fMaxIndex
                <<"\t Row size: "      << fSize << " bytes"
        <<endl;
   return 0;
}
const Char_t *TTable::Print(Int_t row, Int_t rownumber, const Char_t *, const Char_t *) const
{
  
  
  
  
  
  
  
  
  
  
  
   
   Int_t const width = 8;
   Int_t rowStep = 10; 
   Int_t rowNumber = rownumber;
   if (row  > Int_t(GetSize()) || GetSize() == UInt_t(0))  {
      PrintHeader();
      cout  << " ======================================================================================" << endl
           << "   There are " << GetSize() << " allocated rows for this table only"                     << endl
             << " ======================================================================================" << endl;
      return 0;
   }
   if (rowNumber > Int_t(GetSize()-row)) rowNumber = GetSize()-row;
   if (!rowNumber) return 0;
   rowStep = TMath::Min(rowStep,rowNumber);
   Int_t cdate = 0;
   Int_t ctime = 0;
   UInt_t *cdatime = 0;
   Bool_t isdate = kFALSE;
   TTableDescriptor *dscT = GetRowDescriptors();
   if (!dscT ) return 0;
   
   const Char_t  *startRow = (const Char_t *)GetArray() + row*GetRowSize();
   Int_t rowCount = rowNumber;
   Int_t thisLoopLenth = 0;
   const Char_t  *nextRow = 0;
   while (rowCount) {
      PrintHeader();
      if  (GetNRows() == 0) {
         cout  << " ======================================================================================" << endl
               << "   There is NO filled row in this table"                                                 << endl
               << " ======================================================================================" << endl;
         return 0;
      }
      cout << " Table: " << dscT->GetName()<< "\t";
      for (Int_t j = row+rowNumber-rowCount; j<row+rowNumber-rowCount+rowStep && j < row+rowNumber ;j++) {
         Int_t hW = width-2;
         if (j>=10) hW -= (int)TMath::Log10(float(j))-1;
         cout  << setw(hW) << "["<<j<<"]";
         cout  << " :" ;
      }
      cout << endl
      <<       " ======================================================================================" << endl;
      TTableDescriptor::iterator member = dscT->begin();
      TTableDescriptor::iterator   dscE = dscT->end();
      TDataSetIter nextComment(dscT->MakeCommentField(kFALSE));
      for (; member != dscE; member++){
         TString membertype = GetTypeName(EColumnType((*member).fType));
         isdate = kFALSE;
         if (strcmp((*member).fColumnName,"fDatime") == 0 && membertype == "UInt_t")
                                                                                   isdate = kTRUE;
         cout << membertype.Data();
         
         Int_t dim = (*member).fDimensions;
         Int_t indx = 0;
         UInt_t *arrayLayout = 0;
         if (dim) {
            arrayLayout = new UInt_t[dim];
            memset(arrayLayout,0,dim*sizeof(Int_t));
         }
         Int_t arrayLength  = 1;
         while (indx < dim ){ 
            arrayLength *= (*member).fIndexArray[indx];
            indx++;
         }
         
         Int_t offset = (*member).fOffset;
         Int_t thisStepRows;
         thisLoopLenth = TMath::Min(rowCount,rowStep);
         Int_t indexOffset;
         Bool_t breakLoop = kFALSE;
         for (indexOffset=0; indexOffset < arrayLength && !breakLoop; indexOffset++) {
            nextRow = startRow;
            if (!indexOffset) cout << "\t" << (*member).fColumnName;
            else              cout << "\t" << setw(strlen((*member).fColumnName)) << " ";
            if (dim) {
               for (Int_t i=0;i<dim;i++) cout << "["<<dec<<arrayLayout[i]<<"]";
               ArrayLayout(arrayLayout,(*member).fIndexArray,dim);
            }
            cout << "\t";
            if ( strlen((*member).fColumnName)+3*dim < 8) cout << "\t";
            for (thisStepRows = 0;thisStepRows < thisLoopLenth; thisStepRows++,nextRow += GetRowSize()) {
               const char *pointer = nextRow + offset  + indexOffset*(*member).fTypeSize;
               if (isdate) {
                  cdatime = (UInt_t*)pointer;
                  TDatime::GetDateTime(cdatime[0],cdate,ctime);
                  cout << cdate << "/" << ctime;
               } else if ((*member).fType == kChar && dim == 1) {
                  char charbuffer[11];
                  strncpy(charbuffer,pointer,TMath::Min(10,arrayLength));
                  charbuffer[10] = 0;
                  cout << "\"" << charbuffer;
                  if (arrayLength > 10)
                     cout << " . . . ";
                  cout << "\"";
                  breakLoop = kTRUE;
               } else {
                  AsString((void *)pointer,EColumnType((*member).fType),width,cout);
                  cout << " :";
               }
            }
            
            if (indexOffset==0) {
               TDataSet *nxc = nextComment();
               cout << " " << (const char *)(nxc ? nxc->GetTitle() : "no comment");
            }
            cout << endl;
         }
         if (arrayLayout) delete [] arrayLayout;
      }
      rowCount -= thisLoopLenth;
      startRow  = nextRow;
   }
   cout << "---------------------------------------------------------------------------------------" << endl;
   return 0;
}
void TTable::PrintContents(Option_t *) const
{
   
   TDataSet::PrintContents();
   TROOT::IndentLevel();
   Printf("\tclass %s: public TTable\t --> Allocated rows: %d\t Used rows: %d\t Row size: %d bytes\n",
         IsA()->GetName(),int(fN),int(fMaxIndex),int(fSize));
}
void TTable::Project(const Text_t *hname, const Text_t *varexp, const Text_t *selection, Option_t *option,Int_t nentries, Int_t firstentry)
{
   Int_t nch = strlen(hname) + strlen(varexp);
   char *var = new char[nch+5];
   sprintf(var,"%s>>%s",varexp,hname);
   nch = strlen(option) + 10;
   char *opt = new char[nch];
   if (option) sprintf(opt,"%sgoff",option);
   else        strcpy(opt,"goff");
   Draw(var,selection,opt,nentries,firstentry);
   delete [] var;
   delete [] opt;
}
Int_t TTable::Purge(Option_t *opt)
{
   
   ReAllocate();
   return TDataSet::Purge(opt);
}
void TTable::SavePrimitive(ostream &out, Option_t * )
{
   UInt_t arrayLayout[10],arraySize[10];
   const unsigned char *pointer=0,*startRow=0;
   int i,rowCount;unsigned char ic;
   out << "TDataSet *CreateTable() { " << endl;
   Int_t rowNumber =  GetNRows();
   TTableDescriptor *dscT = GetRowDescriptors();
   if (!rowNumber || !dscT ) {
      out << "// The output table was bad-defined!" << endl
          << " fprintf(stderr, \"Bad table found. Please remove me\\n\");" << endl
          << " return 0; } "    << endl;
      return;
   }
   startRow = (const UChar_t *)GetArray();
   assert(startRow!=0);
   const Char_t *rowId = "row";
   const Char_t *tableId = "tableSet";
   const char *className = IsA()->GetName();
   out << "// -----------------------------------------------------------------" << endl;
   out << "// "   << Path()
       << " Allocated rows: "<< rowNumber
       <<"  Used rows: "<<      rowNumber
       <<"  Row size: " << fSize << " bytes"                 << endl;
   out << "// "  << " Table: " << dscT->GetName()<<"[0]--> "
       << dscT->GetName()<<"["<<rowNumber-1 <<"]"            << endl;
   out << "// ====================================================================" << endl;
   out << "// ------  Test whether this table share library was loaded ------"      << endl;
   out << "  if (!TClass::GetClass(\"" << className << "\")) return 0;"    << endl;
   out <<    dscT->GetName() << " " << rowId << ";" << endl
       <<  className << " *" << tableId << " = new "
       <<  className
       << "(\""<<GetName()<<"\"," << GetNRows() << ");" << endl
       << "//" <<endl ;
   TDataSetIter nextComment(dscT->MakeCommentField(kFALSE));
   for (rowCount=0;rowCount<rowNumber; rowCount++,startRow += fSize, nextComment.Reset()) {     
      out << "memset(" << "&" << rowId << ",0," << tableId << "->GetRowSize()" << ");" << endl ;
   TTableDescriptor::iterator member  = dscT->begin();
   TTableDescriptor::iterator   dscE  = dscT->end();
   for (; member != dscE; member++) {  
      TString memberType = GetTypeName(EColumnType((*member).fType));
      TString memberName((*member).fColumnName);
       
      TDataSet *nxc = nextComment();
      TString memberTitle(nxc ? nxc->GetTitle() : "no comment");
      Int_t offset = (*member).fOffset;
      int mayBeName = 0;
      if (memberName.Index("name",0,TString::kIgnoreCase)>=0) mayBeName=1999;
      if (memberName.Index("file",0,TString::kIgnoreCase)>=0) mayBeName=1999;
      int typeSize = (*member).fTypeSize;
      Int_t dim = (*member).fDimensions;
      if (dim) memset(arrayLayout,0,dim*sizeof(Int_t));
      Int_t arrayLength  = 1;
      for (int indx=0;indx < dim ;indx++){
         arraySize[indx] =  (*member).fIndexArray[indx];;
         arrayLength *= arraySize[indx];
      }
      int charLen = (memberType.CompareTo("char")==0);
      if (charLen) {    
         charLen=arrayLength;
         pointer = startRow + offset;
         if (mayBeName) {
            charLen = strlen((const char*)pointer)+1;
            if (charLen>arrayLength) charLen = arrayLength;
         } else {
            for(;charLen && !pointer[charLen-1];charLen--){;}
            if (!charLen) charLen=1;
         }
         out << " memcpy(&" << rowId << "." << (const char*)memberName;
         out << ",\"";
         for (int ii=0; ii<charLen;ii++) {
            ic = pointer[ii];
            if (ic && (isalnum(ic)
             || strchr("!#$%&()*+-,./:;<>=?@{}[]_|~",ic))) {
               out << ic;
            } else {                                      
               out << "\\x" << setw(2) << setfill('0') << hex << (unsigned)ic ;
               out << setw(1) << setfill(' ') << dec;
            }
         }
         out << "\"," << dec << charLen << ");";
         out << "// " << (const char*)memberTitle << endl;
         continue;
      } 
      Int_t indexOffset;
      for (indexOffset=0; indexOffset < arrayLength ; indexOffset++) {
         out << setw(3) << " " ;
         out << " " << rowId << "." << (const char*)memberName;
         if (dim) {
            for (i=0;i<dim;i++) {out << "["<<dec<<arrayLayout[i]<<"]";}
            ArrayLayout(arrayLayout,arraySize,dim);}
            out << "\t = ";
            pointer = startRow + offset  + indexOffset*typeSize;
            AsString((void *)pointer,EColumnType((*member).fType),10,out);
            if (indexOffset==0)  out << "; // " << (const char*)memberTitle;
            out << ";" << endl;
         }
      }
      out << tableId << "->AddAt(&" << rowId <<");" << endl;
   }
   out << "// ----------------- end of code ---------------" << endl
       << " return (TDataSet *)tableSet;" << endl
       << "}"  << endl;
   return;
}
void TTable::Set(Int_t n)
{
   
   if (n < 0) return;
   if (fN != n)  Clear();
   SetfN(n);
   if (fN == 0) return;
   Create();
   if (TTable::GetNRows()) Reset();
}
void TTable::SetTablePointer(void *table)
{
   
   if (fTable) free(fTable);
   fTable = (Char_t *)table;
}
void TTable::SetType(const Text_t *const type)
{
   
   SetTitle(type);
}
static Char_t *GetExpressionFileName()
{
   
   const Char_t *tempDirs =  gSystem->Getenv("TEMP");
   if (!tempDirs)  tempDirs =  gSystem->Getenv("TMP");
   if (!tempDirs) tempDirs = "/tmp";
   if (gSystem->AccessPathName(tempDirs)) tempDirs = ".";
   if (gSystem->AccessPathName(tempDirs)) return 0;
   Char_t buffer[16];
   sprintf(buffer,"C.%d.tmp",gSystem->GetPid());
   TString fileName = "Selection.";
   fileName += buffer;
   return  gSystem->ConcatFileName(tempDirs,fileName.Data());
}
Char_t *TTable::MakeExpression(const Char_t *expressions[],Int_t nExpressions)
{
  
  
  
  
  
  
  
  
   const Char_t *typeNames[] = {"NAN","float", "int",  "long",  "short",         "double"
                                ,"unsigned int","unsigned long", "unsigned short","unsigned char"
                                ,"char", "TTableMap &"};
   const char *resID     = "results";
   const char *addressID = "address";
   Char_t *fileName = GetExpressionFileName();
   if (!fileName) {
      Error("MakeExpression","Can not create a temporary file");
      return 0;
   }
   ofstream str;
   str.open(fileName);
   if (str.bad() ) {
      Error("MakeExpression","Can not open the temporary file <%s>",fileName);
      delete [] fileName;
      return 0;
   }
   TTableDescriptor *dsc = GetRowDescriptors();
   const tableDescriptor_st *descTable  = dsc->GetTable();
   
   str << "void SelectionQWERTY(float *"<<resID<<", float **"<<addressID<< ", int& i$, int& n$ )"   << endl;
   str << "{"                                                        << endl;
   int i = 0;
   for (i=0; i < dsc->GetNRows(); i++,descTable++ ) {
      
      const Char_t *columnName = descTable->fColumnName;
      const Char_t *type = 0;
      
      for (Int_t exCount = 0; exCount < nExpressions; exCount++) {
         if (expressions[exCount] && expressions[exCount][0] && strstr(expressions[exCount],columnName)) goto LETSTRY;
      }
      continue;
LETSTRY:
      Bool_t isScalar = !(descTable->fDimensions);
      Bool_t isFloat = descTable->fType == kFloat;
      type = typeNames[descTable->fType];
      str << type << " ";
      if (!isScalar)  str << "*";
      str << columnName << " = " ;
      if (isScalar)   str << "*(";
      if (!isFloat)   str << "(" << type << "*)";
      str << addressID << "[" << i << "]";
      if (isScalar)   str << ")" ;
      str << ";" << endl;
   }
   
   for (i=0; i < nExpressions; i++ ) {
      if (expressions[i] && expressions[i][0])
         str << " "<<resID<<"["<<i<<"]=(float)(" << expressions[i] << ");"  << endl;
   };
   str << "}" << endl;
   str.close();
   
   if (str.good()) return fileName;
   delete [] fileName;
   return 0;
}
void TTable::Reset(Int_t c)
{
   
   
   if (fTable) {
      ResetMap(kTRUE);
      ::memset(fTable,c,fSize*fN);
      if (c) ResetMap(kFALSE);
   }
}
void TTable::ResetMap(Bool_t wipe)
{
   
   
   
   
   piterator links     = pbegin();
   piterator lastLinks = pend();
   for (;links != lastLinks;links++) {
      TTableMap **mp = (TTableMap **)(*links);
      if (wipe) delete *mp;
      *mp = 0;
   }
}
void TTable::Set(Int_t n, Char_t *array)
{
   
   
   if (n < 0) return;
   if (fN < n) Clear();
   SetfN(n);
   if (fN == 0) return;
   Create();
   CopyStruct(fTable,array);
   fMaxIndex = n;
}
void TTable::StreamerTable(TBuffer &b,Version_t version)
{
   
   if (b.IsReading()) {
      TDataSet::Streamer(b);
      b >> fN;
      StreamerHeader(b,version);
      
      Set(fMaxIndex);
   } else {
      TDataSet::Streamer(b);
      b << fN;
      StreamerHeader(b,version);
   }
}
void TTable::StreamerHeader(TBuffer &b, Version_t version)
{
   
   if (b.IsReading()) {
      Long_t rbytes;
      if (version) { }   
#ifdef __STAR__
      if (version < 3) {
         
         
         
         
         long len = b.Length() + (20+4) + (20+4) + 4;
         b.SetBufferOffset(len);
      }
#endif
      b >> fMaxIndex;         
      b >> rbytes;            
      if (GetRowSize() == -1) fSize = rbytes;
      if (rbytes - GetRowSize()) {
         Warning("StreamerHeader","Schema evolution warning: row size mismatch: expected %d, read %d bytes\n",GetRowSize(),rbytes);
      }
#ifdef __STAR__
      if (version < 3) {
         
         
         
         long len = b.Length() + (4) + (4);
         b.SetBufferOffset(len);
      }
#endif
   } else {
      b << fMaxIndex;         
      b << fSize;             
   }
}
Int_t TTable::SetfN(Long_t len)
{
   
   fN = len;
   return fN;
}
#ifdef StreamElelement
#define __StreamElelement__ StreamElelement
#undef StreamElelement
#endif
#define StreamElementIn(type)  case TTableDescriptor::_NAME2_(k,type):        \
 if (evolutionOn) {                                  \
     if (nextCol->fDimensions)  {                    \
       if (nextCol->fOffset != UInt_t(-1)) {         \
          R__b.ReadFastArray((_NAME2_(type,_t) *)(row+nextCol->fOffset),nextCol->fSize/sizeof(_NAME2_(type,_t)));   \
       } else {                                        \
           _NAME2_(type,_t) *readPtrV = new _NAME2_(type,_t)[nextCol->fSize/sizeof(_NAME2_(type,_t))];              \
           R__b.ReadFastArray((_NAME2_(type,_t) *)(row+nextCol->fOffset),nextCol->fSize/sizeof(_NAME2_(type,_t)));  \
           delete [] readPtrV;                       \
           readPtrV = 0;                             \
       }                                             \
     }                                               \
     else  {                                         \
       _NAME2_(type,_t) skipBuffer;                  \
       _NAME2_(type,_t) *readPtr =  (_NAME2_(type,_t) *)(row+nextCol->fOffset); \
       if (nextCol->fOffset == UInt_t(-1)) readPtr = &skipBuffer;               \
       R__b >> *readPtr;                             \
     }                                               \
 } else {                                            \
   if (nextCol->fDimensions)  {                      \
     R__b.ReadFastArray  ((_NAME2_(type,_t) *)(row+nextCol->fOffset),nextCol->fSize/sizeof(_NAME2_(type,_t)));  \
   } else                                                       \
     R__b >> *(_NAME2_(type,_t) *)(row+nextCol->fOffset);       \
 }                                                              \
 break
#define StreamElementOut(type) case TTableDescriptor::_NAME2_(k,type):    \
 if (nextCol->fDimensions)                                    \
    R__b.WriteFastArray((_NAME2_(type,_t) *)(row+nextCol->fOffset), nextCol->fSize/sizeof(_NAME2_(type,_t))); \
 else                                                         \
    R__b << *(_NAME2_(type,_t) *)(row+nextCol->fOffset);      \
 break
TTableDescriptor  *TTable::GetRowDescriptors() const
{
   
   TTableDescriptor *dsc = 0;
   if (IsA()) dsc = GetDescriptorPointer();
   if (!dsc) {
      Error("GetRowDescriptors()","%s has no dictionary !",GetName());
      dsc = GetTableDescriptors();
      ((TTableDescriptor *)this)->SetDescriptorPointer(dsc);
   }
   return dsc;
}
TTableDescriptor *TTable::GetDescriptorPointer() const
{
   
   assert(0);
   return 0;
}
void TTable::SetDescriptorPointer(TTableDescriptor *)
{
   
   assert(0);
}
void TTable::Streamer(TBuffer &R__b)
{
   
   TTableDescriptor *ioDescriptor = GetRowDescriptors();
   TTableDescriptor *currentDescriptor = ioDescriptor;
   Version_t R__v = 0;
   if (R__b.IsReading()) {
      
      R__v = R__b.ReadVersion();
      Bool_t evolutionOn = kFALSE;
      if (R__v>=2) {
         if (IsA() != TTableDescriptor::Class()) {
            if (R__v>3) {
               R__b >> ioDescriptor;
            } else {  
               ioDescriptor =  new TTableDescriptor();
               ioDescriptor->Streamer(R__b);
            }
            if (!currentDescriptor) {
               currentDescriptor = ioDescriptor;
               SetDescriptorPointer(currentDescriptor);
            }
            if (currentDescriptor->fSecondDescriptor != ioDescriptor) {
               
               delete currentDescriptor->fSecondDescriptor;
               currentDescriptor->fSecondDescriptor = ioDescriptor;
            }
            
            evolutionOn = (Bool_t)ioDescriptor->UpdateOffsets(currentDescriptor);
         }
      }
      TTable::StreamerTable(R__b,R__v);
      if (fMaxIndex <= 0) return;
      char *row= fTable;
      Int_t maxColumns = ioDescriptor->NumberOfColumns();
      Int_t rowSize = GetRowSize();
      if (evolutionOn) Reset(0); 
      for (Int_t indx=0;indx<fMaxIndex;indx++,row += rowSize) {
         tableDescriptor_st *nextCol = ioDescriptor->GetTable();
         for (Int_t colCounter=0; colCounter < maxColumns; colCounter++,nextCol++) {
            
            switch(nextCol->fType) {
               StreamElementIn(Float);
               StreamElementIn(Int);
               StreamElementIn(Long);
               StreamElementIn(Short);
               StreamElementIn(Double);
               StreamElementIn(UInt);
               StreamElementIn(ULong);
               StreamElementIn(UChar);
               StreamElementIn(Char);
               StreamElementIn(Bool);
               case TTableDescriptor::kPtr: {
                  Ptr_t readPtr;
                  R__b >> readPtr;
                  if (evolutionOn) {
                     
                     
                     if (nextCol->fOffset == UInt_t(-1)) delete readPtr; 
                     else *(Ptr_t *)(row+nextCol->fOffset) = readPtr;
                  } else {
                     *(Ptr_t *)(row+nextCol->fOffset) = readPtr;
               }
               break;
                                       }
               default:
               break;
            };
         }
      }
   } else {
      TSeqCollection *save = fList;
      R__b.WriteVersion(TTable::IsA());
      
      if (IsA() != TTableDescriptor::Class()) {
         if ( Class_Version()>3 ) {
            R__b << ioDescriptor;
         } else {  
            ioDescriptor->Streamer(R__b);
         }
      } else {
         if ( Class_Version()<=3 ) fList = 0;
      }
      TTable::StreamerTable(R__b);
      if (fMaxIndex <= 0) return;
      char *row= fTable;
      Int_t maxColumns = ioDescriptor->NumberOfColumns();
      Int_t rowSize = GetRowSize();
      for (Int_t indx=0;indx<fMaxIndex;indx++,row += rowSize) {
         tableDescriptor_st *nextCol = ioDescriptor->GetTable();
         for (Int_t colCounter=0; colCounter < maxColumns; colCounter++,nextCol++) {
            
            switch(nextCol->fType) {
               StreamElementOut(Float);
               StreamElementOut(Int);
               StreamElementOut(Long);
               StreamElementOut(Short);
               StreamElementOut(Double);
               StreamElementOut(UInt);
               StreamElementOut(ULong);
               StreamElementOut(UChar);
               StreamElementOut(Char);
               StreamElementOut(Bool);
               case TTableDescriptor::kPtr:
                  R__b << *(Ptr_t *)(row+nextCol->fOffset);
                  break;
               default:
                  break;
            };
         }
      }
      fList = save;
   }
}
#ifdef __StreamElelement__
#define StreamElelement __StreamElelement__
#undef __StreamElelement__
#endif
void TTable::Update()
{
   
}
void TTable::Update(TDataSet *set, UInt_t opt)
{
 
 
   if (set->HasData()) {
      
      if (strcmp(GetTitle(),set->GetTitle()) == 0 ) {
         TTable *table =  (TTable *)set;
         Adopt(table->GetSize(),table->GetArray());
         
         
         
         SetUsedRows(table->GetNRows());
         
         table->SetBit(kIsNotOwn);
         
         ResetBit(kIsNotOwn);
      } else
         Error("Update",
             "This table is <%s> but the updating one has a wrong type <%s>",GetTitle(),set->GetTitle());
   }
   TDataSet::Update(set,opt);
}
const char *TTable::TableDictionary(const char *className,const char *structName,TTableDescriptor *&ColDescriptors)
{
   
   
   if (className){};
   TClass *r = TClass::GetClass(structName,1);
   ColDescriptors = new TTableDescriptor(r);
   return structName;
}
 
Int_t        TTable::GetColumnIndex(const Char_t *columnName) const {return GetRowDescriptors()->ColumnByName(columnName);}
const Char_t *TTable::GetColumnName(Int_t columnIndex) const {return GetRowDescriptors()->ColumnName(columnIndex); }
const UInt_t *TTable::GetIndexArray(Int_t columnIndex) const {return GetRowDescriptors()->IndexArray(columnIndex); }
UInt_t       TTable::GetNumberOfColumns()              const {return GetRowDescriptors()->NumberOfColumns();       }
UInt_t       TTable::GetOffset(Int_t columnIndex)      const {return GetRowDescriptors()->Offset(columnIndex); }
Int_t        TTable::GetOffset(const Char_t *columnName) const {return GetRowDescriptors()->Offset(columnName); }
UInt_t       TTable::GetColumnSize(Int_t columnIndex)  const {return GetRowDescriptors()->ColumnSize(columnIndex); }
Int_t        TTable::GetColumnSize(const Char_t *columnName) const {return GetRowDescriptors()->ColumnSize(columnName); }
UInt_t       TTable::GetTypeSize(Int_t columnIndex)    const {return GetRowDescriptors()->TypeSize(columnIndex); }
Int_t        TTable::GetTypeSize(const Char_t *columnName) const {return GetRowDescriptors()->TypeSize(columnName); }
UInt_t       TTable::GetDimensions(Int_t columnIndex)  const {return GetRowDescriptors()->Dimensions(columnIndex); }
Int_t        TTable::GetDimensions(const Char_t *columnName) const {return GetRowDescriptors()->Dimensions(columnName); }
TTable::EColumnType  TTable::GetColumnType(Int_t columnIndex)  const {return GetRowDescriptors()->ColumnType(columnIndex); }
TTable::EColumnType  TTable::GetColumnType(const Char_t *columnName) const {return GetRowDescriptors()->ColumnType(columnName); }
TTable::piterator::piterator(const TTable *t,EColumnType type): fCurrentRowIndex(0),fCurrentColIndex(0),fCurrentRowPtr(0)
{
   
   Int_t sz = 0;
   if (t) sz = t->GetNRows();
   if (sz) {
      fRowSize       = t->GetRowSize();
      fCurrentRowPtr = (const Char_t *)t->GetArray();
      TTableDescriptor    *tabsDsc       = t->GetRowDescriptors();
      TTableDescriptor::iterator ptr     = tabsDsc->begin();
      TTableDescriptor::iterator lastPtr = tabsDsc->end();
      UInt_t i =0;
      for( i = 0; ptr != lastPtr; ptr++,i++)
         if ( tabsDsc->ColumnType(i) == type ) fPtrs.push_back(tabsDsc->Offset(i));
      if (fPtrs.size()==0) {
         MakeEnd(t->GetNRows());
      } else {
         column();
      }
   } else {
      MakeEnd(0);
   }
} 
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.