162 ClassImp(TDataMember);
169 TDataMember::TDataMember(DataMemberInfo_t *info, TClass *cl) : TDictionary()
182 if (!fInfo && !fClass)
return;
192 void TDataMember::Init(
bool afterReading)
197 if (!fInfo || !gInterpreter->DataMemberInfo_IsValid(fInfo))
return;
199 fFullTypeName = TClassEdit::GetLong64_Name(gCling->DataMemberInfo_TypeName(fInfo));
200 fTrueTypeName = TClassEdit::GetLong64_Name(gCling->DataMemberInfo_TypeTrueName(fInfo));
201 fTypeName = TClassEdit::GetLong64_Name(gCling->TypeName(fTrueTypeName));
202 SetName(gCling->DataMemberInfo_Name(fInfo));
203 t = gCling->DataMemberInfo_Title(fInfo);
209 if (t && t[0] !=
'!') SetBit(kObjIsPersistent);
211 if (IsBasic() || IsEnum()) {
213 const char *name = GetFullTypeName();
214 if (strcmp(name,
"unsigned char") != 0 &&
215 strncmp(name,
"unsigned short",
sizeof (
"unsigned short")) != 0 &&
216 strcmp(name,
"unsigned int") != 0 &&
217 strncmp(name,
"unsigned long",
sizeof (
"unsigned long")) != 0)
219 name = GetTypeName();
220 fDataType = gROOT->GetType(name);
225 fDataType = gROOT->GetType(name,kTRUE);
228 fDataType = gROOT->GetType(
"Int_t", kTRUE);
258 const char *ptr1 = 0;
266 strlcpy(cmt,GetTitle(),2048);
268 if ((opt_ptr=strstr(cmt,
"*OPTION={"))) {
274 ptr1 = R__STRTOK_R(opt_ptr,
"{}", &rest);
276 Fatal(
"TDataMember",
"Internal error, found \"*OPTION={\" but not \"{}\" in %s.",GetTitle());
279 ptr1 = R__STRTOK_R(
nullptr,
"{}", &rest);
281 Fatal(
"TDataMember",
"Internal error, found \"*OPTION={\" but not \"{}\" in %s.",GetTitle());
286 strlcpy(opt,ptr1,2048);
297 ptr1 = R__STRTOK_R((
char *)(cnt++ ?
nullptr : opt),
";", &rest);
299 Int_t nch = strlen(ptr1)+1;
301 strlcpy(tok,ptr1,nch);
302 tokens[token_cnt]=tok;
308 for (i=0;i<token_cnt;i++) {
309 if (strstr(tokens[i],
"GetMethod")) {
310 ptr1 = R__STRTOK_R(tokens[i],
"\"", &rest);
312 Fatal(
"TDataMember",
"Internal error, found \"GetMethod\" but not \"\\\"\" in %s.",GetTitle());
315 ptr1 = R__STRTOK_R(
nullptr,
"\"", &rest);
317 Fatal(
"TDataMember",
"Internal error, found \"GetMethod\" but not \"\\\"\" in %s.",GetTitle());
321 if (!afterReading && GetClass()->GetMethod(ptr1,
""))
323 fValueGetter =
new TMethodCall(GetClass(),ptr1,
"");
328 if (strstr(tokens[i],
"SetMethod")) {
329 ptr1 = R__STRTOK_R(tokens[i],
"\"", &rest);
331 Fatal(
"TDataMember",
"Internal error, found \"SetMethod\" but not \"\\\"\" in %s.",GetTitle());
334 ptr1 = R__STRTOK_R(
nullptr,
"\"", &rest);
336 Fatal(
"TDataMember",
"Internal error, found \"SetMethod\" but not \"\\\"\" in %s.",GetTitle());
339 if (GetClass()->GetMethod(ptr1,
"1"))
341 fValueSetter =
new TMethodCall(GetClass(),ptr1,
"1");
348 std::unique_ptr<TList> optionlist{
new TList()};
350 for (i=0;i<token_cnt;i++) {
351 if (strstr(tokens[i],
"Items")) {
352 ptr1 = R__STRTOK_R(tokens[i],
"()", &rest);
354 Fatal(
"TDataMember",
"Internal error, found \"Items\" but not \"()\" in %s.",GetTitle());
357 ptr1 = R__STRTOK_R(
nullptr,
"()", &rest);
359 Fatal(
"TDataMember",
"Internal error, found \"Items\" but not \"()\" in %s.",GetTitle());
364 strlcpy(opts,ptr1,2048);
372 ptr1 = R__STRTOK_R(opt_cnt++ ?
nullptr : opts,
",", &rest);
374 TOptionListItem *it =
new TOptionListItem(
this,1,0,0,ptr1,
"");
385 fOptions =
new TList();
387 TIter next(optionlist.get());
389 TOptionListItem *it = 0;
390 TOptionListItem *it1 = 0;
391 while ((it=(TOptionListItem*)next())) {
394 Bool_t islabel = (ptr1[0]==
'\"');
395 ptr2 = R__STRTOK_R((
char *)ptr1,
"=\"", &rest);
396 ptr3 = R__STRTOK_R(
nullptr,
"=\"", &rest);
399 it1=
new TOptionListItem(
this,-9999,0,0,ptr3,ptr2);
404 Long_t l = std::strtol(ptr1, &strtolResult, 10);
405 bool isnumber = (strtolResult != ptr1);
408 TGlobal *enumval = gROOT->GetGlobal(ptr1, kTRUE);
410 Int_t *value = (Int_t *)(enumval->GetAddress());
412 l = (Long_t)(*value);
413 }
else if (IsEnum()) {
414 TObject *obj = fClass->GetListOfDataMembers(
false)->FindObject(ptr1);
416 l = ((TEnumConstant *)obj)->GetValue();
418 l = gInterpreter->Calc(Form(
"%s;", ptr1));
420 Fatal(
"TDataMember",
"Internal error, couldn't recognize enum/global value %s.", ptr1);
424 it1 =
new TOptionListItem(
this,l,0,0,ptr3,ptr1);
428 optionlist->Remove(it);
436 for (i=0;i<token_cnt;i++)
if(tokens[i])
delete [] tokens[i];
439 }
else if (IsEnum()) {
440 fOptions =
new TList();
441 if (TEnum* enumDict = TEnum::GetEnum(GetTypeName()) ){
442 TIter iEnumConst(enumDict->GetConstants());
443 while (TEnumConstant* enumConst = (TEnumConstant*)iEnumConst()) {
445 =
new TOptionListItem(
this, enumConst->GetValue(),0,0,
446 enumConst->GetName(),enumConst->GetName());
452 }
else if (!strncmp(GetFullTypeName(),
"Bool_t",6)){
454 fOptions =
new TList();
455 TOptionListItem *it =
new TOptionListItem(
this,1,0,0,
"ON",0);
457 it =
new TOptionListItem(
this,0,0,0,
"Off",0);
467 TDataMember::TDataMember(
const TDataMember& dm) :
469 fInfo(gCling->DataMemberInfo_FactoryCopy(dm.fInfo)),
471 fDataType(dm.fDataType),
473 fSTLCont(dm.fSTLCont),
474 fProperty(dm.fProperty),
475 fArrayDim(dm.fArrayDim),
476 fArrayMaxIndex( dm.fArrayDim ? new Int_t[dm.fArrayDim] : 0),
477 fArrayIndex(dm.fArrayIndex),
478 fTypeName(dm.fTypeName),
479 fFullTypeName(dm.fFullTypeName),
480 fTrueTypeName(dm.fTrueTypeName),
483 fOptions(dm.fOptions ? (TList*)dm.fOptions->Clone() : 0)
485 for(Int_t d = 0; d < fArrayDim; ++d)
486 fArrayMaxIndex[d] = dm.fArrayMaxIndex[d];
492 TDataMember& TDataMember::operator=(
const TDataMember& dm)
495 gCling->DataMemberInfo_Delete(fInfo);
504 TDictionary::operator=(dm);
505 fInfo= gCling->DataMemberInfo_FactoryCopy(dm.fInfo);
507 fDataType=dm.fDataType;
509 fSTLCont=dm.fSTLCont;
510 fProperty=dm.fProperty;
511 fArrayDim = dm.fArrayDim;
512 fArrayMaxIndex = dm.fArrayDim ?
new Int_t[dm.fArrayDim] : 0;
513 for(Int_t d = 0; d < fArrayDim; ++d)
514 fArrayMaxIndex[d] = dm.fArrayMaxIndex[d];
515 fArrayIndex = dm.fArrayIndex;
516 fTypeName=dm.fTypeName;
517 fFullTypeName=dm.fFullTypeName;
518 fTrueTypeName=dm.fTrueTypeName;
519 fOptions = dm.fOptions ? (TList*)dm.fOptions->Clone() : 0;
527 TDataMember::~TDataMember()
529 delete [] fArrayMaxIndex;
530 gCling->DataMemberInfo_Delete(fInfo);
542 Int_t TDataMember::GetArrayDim()
const
544 if (fArrayDim<0 && fInfo) {
545 R__LOCKGUARD(gInterpreterMutex);
546 TDataMember *dm =
const_cast<TDataMember*
>(
this);
547 dm->fArrayDim = gCling->DataMemberInfo_ArrayDim(fInfo);
550 dm->fArrayMaxIndex =
new Int_t[fArrayDim];
551 for(Int_t dim = 0; dim < dm->fArrayDim; ++dim) {
552 dm->fArrayMaxIndex[dim] = gCling->DataMemberInfo_MaxIndex(fInfo,dim);
564 const char *TDataMember::GetArrayIndex()
const
566 if (!IsaPointer())
return "";
567 if (fArrayIndex.Length()==0 && fInfo) {
568 R__LOCKGUARD(gInterpreterMutex);
569 TDataMember *dm =
const_cast<TDataMember*
>(
this);
570 const char* val = gCling->DataMemberInfo_ValidArrayIndex(fInfo);
571 if (val) dm->fArrayIndex = val;
572 else dm->fArrayIndex.Append((Char_t)0);
579 TDictionary::DeclId_t TDataMember::GetDeclId()
const
581 if (fInfo)
return gInterpreter->GetDeclId(fInfo);
588 Int_t TDataMember::GetMaxIndex(Int_t dim)
const
590 if (fArrayDim<0 && fInfo) {
591 return gCling->DataMemberInfo_MaxIndex(fInfo,dim);
593 if (dim < 0 || dim >= fArrayDim)
return -1;
594 return fArrayMaxIndex[dim];
601 const char *TDataMember::GetTypeName()
const
603 if (fProperty==(-1)) Property();
604 return fTypeName.Data();
610 const char *TDataMember::GetFullTypeName()
const
612 if (fProperty==(-1)) Property();
614 return fFullTypeName.Data();
620 const char *TDataMember::GetTrueTypeName()
const
622 return fTrueTypeName.Data();
628 Long_t TDataMember::GetOffset()
const
630 if (fOffset>=0)
return fOffset;
632 R__LOCKGUARD(gInterpreterMutex);
634 if (fClass->GetDeclFileLine() < 0) {
635 ((TDataMember*)
this)->fOffset = gCling->DataMemberInfo_Offset(fInfo);
643 dmbracket.Form(
"%s[",GetName());
644 fClass->BuildRealData();
645 TIter next(fClass->GetListOfRealData());
648 while ((rdm = (TRealData*)next())) {
649 char *rdmc = (
char*)rdm->GetName();
652 if (this->IsaPointer() && rdmc[0] ==
'*') rdmc++;
654 if (rdm->GetDataMember() !=
this)
continue;
655 if (strcmp(rdmc,GetName()) == 0) {
656 offset = rdm->GetThisOffset();
659 if (strcmp(rdm->GetName(),GetName()) == 0) {
660 if (rdm->IsObject()) {
661 offset = rdm->GetThisOffset();
665 if (strstr(rdm->GetName(),dmbracket.Data())) {
666 offset = rdm->GetThisOffset();
670 ((TDataMember*)
this)->fOffset = offset;
677 Long_t TDataMember::GetOffsetCint()
const
679 if (fOffset>=0)
return fOffset;
681 R__LOCKGUARD(gInterpreterMutex);
682 TDataMember *dm =
const_cast<TDataMember*
>(
this);
684 if (dm->IsValid())
return gCling->DataMemberInfo_Offset(dm->fInfo);
692 Int_t TDataMember::GetUnitSize()
const
694 if (IsaPointer())
return sizeof(
void*);
695 if (IsEnum() )
return sizeof(Int_t);
696 if (IsBasic() )
return GetDataType()->Size();
698 TClass *cl = TClass::GetClass(GetTypeName());
699 if (!cl) cl = TClass::GetClass(GetTrueTypeName());
700 if ( cl)
return cl->Size();
702 Warning(
"GetUnitSize",
"Can not determine sizeof(%s)",GetTypeName());
709 Bool_t TDataMember::IsBasic()
const
711 if (fProperty == -1) Property();
712 return (fProperty & kIsFundamental) ? kTRUE : kFALSE;
718 Bool_t TDataMember::IsEnum()
const
720 if (fProperty == -1) Property();
721 return (fProperty & kIsEnum) ? kTRUE : kFALSE;
727 Bool_t TDataMember::IsaPointer()
const
729 if (fProperty == -1) Property();
730 return (fProperty & kIsPointer) ? kTRUE : kFALSE;
736 int TDataMember::IsSTLContainer()
738 if (fSTLCont != -1)
return fSTLCont;
739 R__LOCKGUARD(gInterpreterMutex);
740 fSTLCont = TClassEdit::UnderlyingIsSTLCont(GetTrueTypeName());
749 Bool_t TDataMember::IsValid()
751 if (fOffset >= 0)
return kTRUE;
754 if (!fInfo && UpdateInterpreterStateMarker()) {
755 DeclId_t newId = gInterpreter->GetDataMember(fClass->GetClassInfo(), fName);
757 DataMemberInfo_t *info
758 = gInterpreter->DataMemberInfo_Factory(newId, fClass->GetClassInfo());
762 TListOfDataMembers *lst =
dynamic_cast<TListOfDataMembers*
>(fClass->GetListOfDataMembers());
773 Long_t TDataMember::Property()
const
775 if (fProperty!=(-1))
return fProperty;
777 R__LOCKGUARD(gInterpreterMutex);
778 TDataMember *t = (TDataMember*)
this;
780 if (!fInfo || !gCling->DataMemberInfo_IsValid(fInfo))
return 0;
781 int prop = gCling->DataMemberInfo_Property(fInfo);
782 int propt = gCling->DataMemberInfo_TypeProperty(fInfo);
783 t->fProperty = prop|propt;
785 t->fFullTypeName = TClassEdit::GetLong64_Name(gCling->DataMemberInfo_TypeName(fInfo));
786 t->fTrueTypeName = TClassEdit::GetLong64_Name(gCling->DataMemberInfo_TypeTrueName(fInfo));
787 t->fTypeName = TClassEdit::GetLong64_Name(gCling->TypeName(fTrueTypeName));
789 t->fName = gCling->DataMemberInfo_Name(fInfo);
790 t->fTitle = gCling->DataMemberInfo_Title(fInfo);
798 TList *TDataMember::GetOptions()
const
810 TMethodCall *TDataMember::GetterMethod(TClass *cl)
812 if (!fValueGetter || cl) {
814 R__LOCKGUARD(gInterpreterMutex);
816 if (!cl) cl = fClass;
819 TString methodname = fValueGetter->GetMethodName();
821 fValueGetter =
new TMethodCall(cl, methodname.Data(),
"");
829 const char *dataname = GetName();
832 gettername.Form(
"Get%s", dataname+1);
833 if (GetClass()->GetMethod(gettername,
""))
834 return fValueGetter =
new TMethodCall(cl, gettername,
"");
835 gettername.Form(
"Is%s", dataname+1);
836 if (GetClass()->GetMethod(gettername,
""))
837 return fValueGetter =
new TMethodCall(cl, gettername,
"");
838 gettername.Form(
"Has%s", dataname+1);
839 if (GetClass()->GetMethod(gettername,
""))
840 return fValueGetter =
new TMethodCall(cl, gettername,
"");
854 TMethodCall *TDataMember::SetterMethod(TClass *cl)
856 if (!fValueSetter || cl) {
858 R__LOCKGUARD(gInterpreterMutex);
860 if (!cl) cl = fClass;
864 TString methodname = fValueSetter->GetMethodName();
865 TString params = fValueSetter->GetParams();
867 fValueSetter =
new TMethodCall(cl, methodname.Data(), params.Data());
875 const char *dataname = GetName();
878 settername.Form(
"Set%s", dataname+1);
879 if (strstr(settername,
"Is")) settername.Form(
"Set%s", dataname+3);
880 if (GetClass()->GetMethod(settername,
"1"))
881 fValueSetter =
new TMethodCall(cl, settername,
"1");
883 if (GetClass()->GetMethod(settername,
"true"))
884 fValueSetter =
new TMethodCall(cl, settername,
"true");
897 Bool_t TDataMember::Update(DataMemberInfo_t *info)
899 R__LOCKGUARD(gInterpreterMutex);
901 if (fInfo) gCling->DataMemberInfo_Delete(fInfo);
902 SafeDelete(fValueSetter);
903 SafeDelete(fValueGetter);
906 SafeDelete(fOptions);
914 delete [] fArrayMaxIndex;
932 void TDataMember::Streamer(TBuffer& b) {
934 b.ReadClassBuffer(Class(),
this);
938 if (fProperty & kIsStatic) {
950 b.WriteClassBuffer(Class(),
this);
957 TOptionListItem::TOptionListItem(TDataMember *d, Long_t val, Long_t valmask,
958 Long_t tglmask,
const char *name,
const char *label)
962 fValueMaskBit = valmask;
963 fToggleMaskBit = tglmask;