Logo ROOT   6.16/01
Reference Guide
TTableDescriptor.cxx
Go to the documentation of this file.
1// @(#)root/table:$Id$
2// Author: Valery Fine 09/08/99 (E-mail: fine@bnl.gov)
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <stdlib.h>
13
14#include "TTableDescriptor.h"
15#include "TTable.h"
16#include "TClass.h"
17#include "TDataMember.h"
18#include "TDataType.h"
19#include "Ttypes.h"
20#include "TInterpreter.h"
21
22#include "TError.h"
23
24//______________________________________________________________________________
25//
26// TTableDescriptor - run-time descriptor of the TTable object rows.
27//______________________________________________________________________________
28
30// TString TTableDescriptor::fgCommentsName = TTableDescriptor::SetCommentsSetName();
33
34////////////////////////////////////////////////////////////////////////////////
35///return column descriptor
36
38{
39 return fgColDescriptors;
40}
41
42////////////////////////////////////////////////////////////////////////////////
43///set table descriptor
44
46{
47 fgColDescriptors = list;
48}
49
50////////////////////////////////////////////////////////////////////////////////
51///set comments name
52
54{
56}
57
58
59////////////////////////////////////////////////////////////////////////////////
60/// The custom Streamer for this table
61
62void TTableDescriptor::Streamer(TBuffer &R__b)
63{
65 TTable::Streamer(R__b);
66}
67
68////////////////////////////////////////////////////////////////////////////////
69///to be documented
70
72 : TTable("tableDescriptor",sizeof(tableDescriptor_st)), fRowClass(0),fSecondDescriptor(0)
73{
74 if (parentTable) {
75 TClass *classPtr = parentTable->GetRowClass();
76 Init(classPtr);
77 }
78 else MakeZombie();
79}
80
81////////////////////////////////////////////////////////////////////////////////
82/// Create a descriptor of the C-structure defined by TClass
83/// TClass *classPtr must be a valid pointer to TClass object for
84/// "plain" C_struture only !!!
85
87 : TTable("tableDescriptor",sizeof(tableDescriptor_st)),fRowClass(0),fSecondDescriptor(0)
88{
89 Init(classPtr);
90}
91////////////////////////////////////////////////////////////////////////////////
92/// class destructor
93
95{
96#ifdef NORESTRICTIONS
97 if (!IsZombie()) {
98 for (Int_t i=0;i<GetNRows();i++) {
100 if (name) delete [] name;
101 UInt_t *indxArray = (UInt_t *)IndexArray(i);
102 if (indxArray) delete [] indxArray;
103 }
104 }
105#endif
106 if (fSecondDescriptor != this) {
107 delete fSecondDescriptor;
109 }
110}
111
112////////////////////////////////////////////////////////////////////////////////
113/// Append one row pointed by "c" to the descriptor
114
116{
117 if (!c) return -1;
118 TDataSet *cmnt = MakeCommentField();
119 R__ASSERT(cmnt!=0);
120
121 return TTable::AddAt(c);
122}
123////////////////////////////////////////////////////////////////////////////////
124///Add one row pointed by "c" to the "i"-th row of the descriptor
125
126void TTableDescriptor::AddAt(const void *c, Int_t i)
127{
128 if (c) {
130#ifdef NORESTRICTIONS
131 const char *comment = element->fColumnName && element->fColumnName[0] ? element->fColumnName : "N/A";
132#else
133 const char *comment = element->fColumnName[0] ? element->fColumnName : "N/A";
134#endif
135 AddAt(*(tableDescriptor_st *)c,comment,i);
136 }
137}
138
139////////////////////////////////////////////////////////////////////////////////
140/// Add one dataset to the descriptor.
141/// There is no new implementation here.
142/// One needs it to avoid the "hidden method" compilation warning
143
145{
146 TTable::AddAt(dataset,idx);
147}
148
149////////////////////////////////////////////////////////////////////////////////
150/// Add the descriptor element followed by its commentText
151/// at the indx-th position of the descriptor (counted from zero)
152
153void TTableDescriptor::AddAt(const tableDescriptor_st &element,const char *commentText,Int_t indx)
154{
155 TTable::AddAt(&element,indx);
156 TDataSet *cmnt = MakeCommentField();
157 R__ASSERT(cmnt!=0);
158 TDataSet *comment = new TDataSet(element.fColumnName);
159 comment->SetTitle(commentText);
160 cmnt->AddAtAndExpand(comment,indx);
161}
162
163////////////////////////////////////////////////////////////////////////////////
164/// Create a list of leaf to be useful for TBranch::TBranch ctor
165
167{
168 const Char_t typeMapTBranch[]="\0FIISDiisbBC";
169 Int_t maxRows = NumberOfColumns();
170 TString string;
171 for (Int_t i=0;i<maxRows;i++){
172 if (i) string += ":";
173 UInt_t nDim = Dimensions(i);
174
175 UInt_t totalSize = 1;
176 UInt_t k = 0;
177
178 if (nDim) {
179 const UInt_t *indx = IndexArray(i);
180 if (!indx){
181 string = "";
182 Error("CreateLeafList()","Can not create leaflist for arrays");
183 return string;
184 }
185 for (k=0;k< nDim; k++) totalSize *= indx[k];
186 }
187 const Char_t *colName = ColumnName(i);
188 if (totalSize > 1) {
189 for ( k = 0; k < totalSize; k++) {
190 Char_t buf[10];
191 snprintf(buf,10,"_%d",k);
192 string += colName;
193 string += buf;
194 if (k==0) {
195 string += "/";
196 string += typeMapTBranch[ColumnType(i)];
197 }
198 if (k != totalSize -1) string += ":";
199 }
200 } else {
201 string += ColumnName(i);
202 string += "/";
203 string += typeMapTBranch[ColumnType(i)];
204 }
205 }
206 return string;
207}
208
209////////////////////////////////////////////////////////////////////////////////
210/// Create a descriptor of the C-structure defined by TClass
211/// TClass *classPtr must be a valid pointer to TClass object for
212/// "plain" C_structure only !!!
213
215{
217 SetType("tableDescriptor");
218 if (classPtr) {
219 fRowClass = classPtr; // remember my row class
220 SetName(classPtr->GetName());
221 LearnTable(classPtr);
222 }
223 else
224 MakeZombie();
225}
226////////////////////////////////////////////////////////////////////////////////
227///to be documented
228
229void TTableDescriptor::LearnTable(const TTable *parentTable)
230{
231 if (!parentTable) {
232 MakeZombie();
233 return;
234 }
235 LearnTable(parentTable->GetRowClass());
236}
237
238////////////////////////////////////////////////////////////////////////////////
239///
240/// LearnTable() creates an array of the descriptors for elements of the row
241///
242/// It creates a descriptor of the C-structure defined by TClass
243/// TClass *classPtr must be a valid pointer to TClass object for
244/// "plain" C-structure only !!!
245///
246/// This is to introduce an artificial restriction demanded by STAR database group
247///
248/// 1. the name may be 31 symbols at most
249/// 2. the number the dimension is 3 at most
250///
251/// To lift this restriction one has to provide -DNORESTRICTIONS CPP symbol and
252/// recompile code (and debug code NOW!)
253///
254
256{
257 if (!classPtr) return;
258
259 if (!(classPtr->GetNdata())) return;
260
261 Char_t *varname;
262
263 tableDescriptor_st elementDescriptor;
264
266 Int_t columnIndex = 0;
267 TIter next(classPtr->GetListOfDataMembers());
268 TDataMember *member = 0;
269 while ( (member = (TDataMember *) next()) ) {
270 memset(&elementDescriptor,0,sizeof(tableDescriptor_st));
271 varname = (Char_t *) member->GetName();
272#ifdef NORESTRICTIONS
273// This is remove to introduce an artificial restriction demanded by STAR infrastructure group
274 elementDescriptor.fColumnName = StrDup(varname);
275#else
276 elementDescriptor.fColumnName[0] = '\0';
277 strncat(elementDescriptor.fColumnName,varname,sizeof(elementDescriptor.fColumnName)-1);
278#endif
279 // define index
280 if (member->IsaPointer() ) {
281 elementDescriptor.fTypeSize = sizeof(void *);
282 const char *typeName = member->GetTypeName();
283 elementDescriptor.fType = TTable::GetTypeId(typeName);
284 } else {
285 TDataType *memberType = member->GetDataType();
286 R__ASSERT(memberType!=0);
287 elementDescriptor.fTypeSize = memberType->Size();
288 elementDescriptor.fType = TTable::GetTypeId(memberType->GetTypeName());
289 }
290 Int_t globalIndex = 1;
291 if (elementDescriptor.fType != kNAN) {
292 Int_t dim = 0;
293 if ( (dim = member->GetArrayDim()) ) {
294 elementDescriptor.fDimensions = dim;
295#ifdef NORESTRICTIONS
296 elementDescriptor.fIndexArray = new UInt_t(dim);
297#else
298 UInt_t maxDim = sizeof(elementDescriptor.fIndexArray)/sizeof(UInt_t);
299 if (UInt_t(dim) > maxDim) {
300 Error("LearnTable","Too many dimenstions - %d", dim);
301 dim = maxDim;
302 }
303#endif
304 for( Int_t indx=0; indx < dim; indx++ ){
305 elementDescriptor.fIndexArray[indx] = member->GetMaxIndex(indx);
306 globalIndex *= elementDescriptor.fIndexArray[indx];
307 }
308 }
309 }
310 else Error("LearnTable","Wrong data type for <%s> structure",classPtr->GetName());
311 elementDescriptor.fSize = globalIndex * (elementDescriptor.fTypeSize);
312 elementDescriptor.fOffset = member->GetOffset();
313 AddAt(elementDescriptor,member->GetTitle(),columnIndex); columnIndex++;
314 }
315}
316
317////////////////////////////////////////////////////////////////////////////////
318////////////////////////////////////////////////////////////
319///
320/// MakeDescriptor(const char *structName) - static method
321/// structName - the name of the C structure
322/// to create descriptor of
323/// return a new instance of the TTableDescriptor or 0
324/// if the "structName is not present with the dictionary
325///
326////////////////////////////////////////////////////////////
327
329{
330 TTableDescriptor *dsc = 0;
331 TClass *cl = TClass::GetClass(structName, kTRUE);
332// TClass *cl = new TClass(structName,1,0,0);
333 R__ASSERT(cl!=0);
334 dsc = new TTableDescriptor(cl);
335 return dsc;
336}
337////////////////////////////////////////////////////////////////////////////////
338/// Instantiate a comment dataset if any
339
341 TDataSet *comments = FindByName(fgCommentsName.Data());
342 if (!comments && createFlag)
343 comments = new TDataSet(fgCommentsName.Data(),this,kTRUE);
344 return comments;
345}
346////////////////////////////////////////////////////////////////////////////////
347/// "Schema evolution"
348/// Method updates the offsets with a new ones from another descriptor
349///
350
352{
353 Int_t maxColumns = NumberOfColumns();
354 Int_t mismathes = 0;
355
356 if ( (UInt_t(maxColumns) == newDescriptor->NumberOfColumns())
357 && (memcmp(GetArray(),newDescriptor->GetArray(),sizeof(tableDescriptor_st)*GetNRows()) == 0)
358 ) return mismathes; // everything fine for sure !
359
360 // Something wrong here, we have to check things piece by piece
361 for (Int_t colCounter=0; colCounter < maxColumns; colCounter++) {
362 Int_t colNewIndx = newDescriptor->ColumnByName(ColumnName(colCounter));
363 // look for analog
364 EColumnType newType = colNewIndx >=0 ? newDescriptor->ColumnType(colNewIndx): kNAN;
365#ifdef __STAR__
366 if (newType == kInt) newType = kLong;
367 else if (newType == kUInt) newType = kULong;
368#endif
369 if ( colNewIndx >=0
370 && Dimensions(colCounter) == newDescriptor->Dimensions(colNewIndx)
371 && ColumnType(colCounter) == newType) {
372 Bool_t same = kFALSE;
373 if ( Dimensions(colCounter)) {
374 for (UInt_t d = 0; d < Dimensions(colCounter); d++) {
375 if (IndexArray(colCounter)[d] != newDescriptor->IndexArray(colNewIndx)[d]){ same = kTRUE; break; }
376 }
377 }
378 SetOffset(newDescriptor->Offset(colNewIndx),colCounter);
379 if (colNewIndx != colCounter) {
380 Printf("Schema evolution: \t%d column of the \"%s\" table has been moved to %d-th column\n",
381 colCounter,ColumnName(colCounter),colNewIndx);
382 mismathes++;
383 } else if (same) {
384 Printf("Schema evolution: \t%d column \"%s\" size has been changed\n",
385 colNewIndx, ColumnName(colCounter));
386 mismathes++;
387 }
388 } else {
389 Printf("Schema evolution: \t%d column \"%s\" of %d type has been lost\n",
390 colCounter,ColumnName(colCounter),ColumnType(colCounter));
391 Printf(" Indx = %d, name = %s \n", colNewIndx, ColumnName(colCounter));
392 SetOffset(UInt_t(-1),colCounter);
393 mismathes++;
394 }
395 }
396 if (!mismathes && UInt_t(maxColumns) != newDescriptor->NumberOfColumns()) {
397 mismathes++;
398 Printf("Warning: One extra column has been introduced\n");
399 }
400 return mismathes;
401}
402
403////////////////////////////////////////////////////////////////////////////////
404/// Find the column index but the column name
405
407{
408 const tableDescriptor_st *elementDescriptor = ((TTableDescriptor *)this)->GetTable();
409 Int_t i = -1;
410 if (!elementDescriptor) return i;
411 Int_t nRows = GetNRows();
412 char *bracket = 0;
413 if (nRows) {
414 char *name = StrDup(columnName);
415 if ((bracket = strchr(name,'[')) ) *bracket = 0;
416 for (i=0; i < nRows; i++,elementDescriptor++)
417 if (strcmp(name,elementDescriptor->fColumnName) == 0) break;
418 delete [] name;
419 }
420 if (i==nRows) i = -1;
421 // Check array
422 if (bracket && !Dimensions(i)) {
423 i = -1;
424 Warning("ColumnByName","%s column contains a scalar value",columnName);
425 }
426 return i;
427}
428
429////////////////////////////////////////////////////////////////////////////////
430/// Return offset of the column defined by "columnName"
431/// Take in account index if provided
432/// Can not handle multidimensional indeces yet.
433
434Int_t TTableDescriptor::Offset(const Char_t *columnName) const
435{
436 Int_t offset = -1;
437 if (columnName) {
438 Int_t indx = ColumnByName(columnName);
439 if (indx >= 0 ) {
440 offset = Offset(indx);
441 const char *openBracket = 0;
442 if ( (openBracket = strchr(columnName,'[')) )
443 offset += atoi(openBracket+1)*TypeSize(indx);
444 }
445 }
446 return offset;
447}
448
449////////////////////////////////////////////////////////////////////////////////
450///to be documented
451
453{
454 Int_t indx = ColumnByName(columnName);
455 if (indx >= 0 ) indx = ColumnSize(indx);
456 return indx;
457}
458
459////////////////////////////////////////////////////////////////////////////////
460///to be documented
461
463{
464 Int_t indx = ColumnByName(columnName);
465 if (indx >= 0 ) indx = TypeSize(indx);
466 return indx;
467}
468
469////////////////////////////////////////////////////////////////////////////////
470///to be documented
471
473{
474 Int_t indx = ColumnByName(columnName);
475 if (indx >= 0 ) indx = Dimensions(indx);
476 return indx;
477}
478
479////////////////////////////////////////////////////////////////////////////////
480///to be documented
481
483{
484 Int_t indx = ColumnByName(columnName);
485 if (indx >= 0 ) indx = ColumnType(indx);
486 return EColumnType(indx);
487}
488////////////////////////////////////////////////////////////////////////////////
489///to be documented
490
492{
493 Int_t fullRowSize = 0;
494 if (RowClass() ) fullRowSize = RowClass()->Size();
495 else {
496 // Calculate the size myslef.
497 Int_t iLastRows = GetNRows()-1;
498 if (iLastRows >=0) fullRowSize = Offset(iLastRows) + ColumnSize(iLastRows);
499 }
500 return fullRowSize;
501}
502
#define d(i)
Definition: RSha256.hxx:102
#define c(i)
Definition: RSha256.hxx:101
int Int_t
Definition: RtypesCore.h:41
char Char_t
Definition: RtypesCore.h:29
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define R__ASSERT(e)
Definition: TError.h:96
#define Printf
Definition: TGeoToOCC.h:18
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2465
TableClassImp(TTableDescriptor, tableDescriptor_st)
#define snprintf
Definition: civetweb.c:1540
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:75
Int_t GetNdata()
Return the number of data members of this class Note that in case the list of data members is not yet...
Definition: TClass.cxx:4407
TList * GetListOfDataMembers(Bool_t load=kTRUE)
Return list containing the TDataMembers of a class.
Definition: TClass.cxx:3615
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5466
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2885
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:31
Int_t GetMaxIndex(Int_t dim) const
Return maximum index for array dimension "dim".
Long_t GetOffset() const
Get offset from "this".
Int_t GetArrayDim() const
Return number of array dimensions.
Bool_t IsaPointer() const
Return true if data member is a pointer.
TDataType * GetDataType() const
Definition: TDataMember.h:74
const char * GetTypeName() const
Get type of data member, e,g.: "class TDirectory*" -> "TDirectory".
virtual void AddAtAndExpand(TDataSet *dataset, Int_t idx=0)
!!!! Under construction !!!!! Add TDataSet object at the "idx" position in ds or at the end of the da...
Definition: TDataSet.cxx:254
virtual TDataSet * FindByName(const char *name, const char *path="", Option_t *opt="") const
Full description see: TDataSetIter::Find.
Definition: TDataSet.cxx:378
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:44
TString GetTypeName()
Get basic type of typedef, e,g.
Definition: TDataType.cxx:149
Int_t Size() const
Get size of basic typedef'ed type.
Definition: TDataType.cxx:366
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
void MakeZombie()
Definition: TObject.h:49
Basic string class.
Definition: TString.h:131
const char * Data() const
Definition: TString.h:364
const Char_t * ColumnName(Int_t columnIndex) const
UInt_t Offset(Int_t columnIndex) const
UInt_t NumberOfColumns() const
TString CreateLeafList() const
Create a list of leaf to be useful for TBranch::TBranch ctor.
virtual void Init(TClass *classPtr)
Create a descriptor of the C-structure defined by TClass TClass *classPtr must be a valid pointer to ...
Int_t ColumnByName(const Char_t *columnName=0) const
Find the column index but the column name.
UInt_t TypeSize(Int_t columnIndex) const
virtual TTableDescriptor * GetDescriptorPointer() const
return column descriptor
UInt_t ColumnSize(Int_t columnIndex) const
const UInt_t * IndexArray(Int_t columnIndex) const
virtual void SetDescriptorPointer(TTableDescriptor *list)
set table descriptor
Int_t Sizeof() const
to be documented
static void SetCommentsSetName(const char *name=".comments")
set comments name
TTableDescriptor * fSecondDescriptor
TDataSet * MakeCommentField(Bool_t createFlag=kTRUE)
Instantiate a comment dataset if any.
TTable::EColumnType ColumnType(Int_t columnIndex) const
UInt_t Dimensions(Int_t columnIndex) const
void SetOffset(UInt_t offset, Int_t column)
TClass * RowClass() const
static TTableDescriptor * fgColDescriptors
void LearnTable(const TTable *parentTable)
to be documented
virtual ~TTableDescriptor()
class destructor
virtual Int_t UpdateOffsets(const TTableDescriptor *newDesciptor)
virtual Int_t AddAt(const void *c)
Append one row pointed by "c" to the descriptor.
static TTableDescriptor * MakeDescriptor(const char *structName)
MakeDescriptor(const char *structName) - static method structName - the name of the C structure to cr...
static TString fgCommentsName
Definition: TTable.h:48
virtual Int_t AddAt(const void *c)
Add the "row" at the GetNRows() position, and reallocate the table if neccesary, and return the row i...
Definition: TTable.cxx:1121
void * GetArray() const
Definition: TTable.h:280
EColumnType
Definition: TTable.h:82
@ kLong
Definition: TTable.h:82
@ kInt
Definition: TTable.h:82
@ kULong
Definition: TTable.h:83
@ kUInt
Definition: TTable.h:82
@ kNAN
Definition: TTable.h:82
friend class TDataSet
Definition: TTable.h:49
virtual void SetType(const char *const type)
to be documented
Definition: TTable.cxx:1972
void * ReAllocate()
Reallocate this table leaving only (used rows)+1 allocated GetTableSize() = GetNRows() + 1 returns a ...
Definition: TTable.cxx:1221
virtual Long_t GetNRows() const
Returns the number of the used rows for the wrapped table.
Definition: TTable.cxx:1387
static EColumnType GetTypeId(const char *typeName)
return the Id of the C basic type by given name return kNAN if the name provided fits no knwn basic n...
Definition: TTable.cxx:291
virtual TClass * GetRowClass() const
to be documented
Definition: TTable.cxx:1374
unsigned int fDimensions
unsigned int fIndexArray[3]
unsigned int fOffset
unsigned int fTypeSize
unsigned int fSize