00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TStructViewer.h"
00013 #include "TStructNodeProperty.h"
00014 #include "TStructViewerGUI.h"
00015 #include "TStructNode.h"
00016
00017 #include <TDataMember.h>
00018 #include <TVirtualCollectionProxy.h>
00019 #include <TClassEdit.h>
00020 #include <vector>
00021
00022 ClassImp(TStructViewer);
00023
00024 class TA {
00025 public:
00026 virtual ~TA() {}
00027 };
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 TStructViewer::TStructViewer(void* ptr, const char * clname)
00068 {
00069
00070
00071 fPointer = NULL;
00072 fPointerClass = NULL;
00073 fTopNode = NULL;
00074
00075
00076 fColors.Add(new TStructNodeProperty("+", 17));
00077
00078
00079 fGUI = new TStructViewerGUI(this, NULL, &fColors);
00080
00081 SetPointer(ptr, clname);
00082 }
00083
00084
00085 TStructViewer::~TStructViewer()
00086 {
00087
00088
00089 Reset();
00090 fColors.SetOwner();
00091 fColors.Clear();
00092 }
00093
00094
00095 void TStructViewer::AddNode(TStructNode* node, ULong_t size)
00096 {
00097
00098
00099 TList* list = (TList*)fLevelArray[node->GetLevel()];
00100
00101 if(!list) {
00102 fLevelArray[node->GetLevel()] = list = new TList();
00103 }
00104 list->Add(node);
00105
00106
00107 fLevelMembersCount(node->GetLevel())++;
00108
00109 fLevelSize(node->GetLevel()) += size;
00110 }
00111
00112
00113 void TStructViewer::CountMembers(TClass* cl, TStructNode* parent, void* pointer)
00114 {
00115
00116
00117 if(!cl) {
00118 return;
00119 }
00120
00121 if (cl->InheritsFrom(TClass::Class())) {
00122 return;
00123 }
00124
00125
00126
00127
00128
00129 cl->BuildRealData(parent->GetPointer());
00130 TIter it(cl->GetListOfDataMembers());
00131 TDataMember* dm;
00132 while ((dm = (TDataMember*) it() ))
00133 {
00134
00135 parent->SetAllMembersCount(parent->GetAllMembersCount() + 1);
00136 parent->SetMembersCount(parent->GetMembersCount() + 1);
00137
00138 if (dm->Property() & kIsStatic) {
00139 continue;
00140 }
00141
00142
00143 void* ptr = NULL;
00144
00145 if(dm->IsaPointer()) {
00146 TString trueTypeName = dm->GetTrueTypeName();
00147
00148
00149 if(trueTypeName.EndsWith("**")) {
00150 continue;
00151 }
00152
00153 if (!pointer) {
00154 continue;
00155 }
00156
00157 void** pptr = (void**)((ULong_t)pointer + dm->GetOffset());
00158 ptr = *pptr;
00159
00160 if (!ptr) {
00161 continue;
00162 }
00163
00164 if(fPointers.GetValue((ULong_t)ptr)) {
00165 continue;
00166 } else {
00167 fPointers.Add((ULong_t)ptr, (ULong_t)ptr);
00168 }
00169
00170 ULong_t size = 0;
00171 if (TClass* cl2 = TClass::GetClass(dm->GetTypeName())) {
00172 size = cl2->Size();
00173 }
00174
00175 if(size == 0) {
00176 size = dm->GetUnitSize();
00177 }
00178
00179 ENodeType type;
00180 if(dm->GetDataType()) {
00181 type = kBasic;
00182 } else {
00183 type = kClass;
00184 }
00185
00186
00187 TStructNode* node = new TStructNode(dm->GetName(), dm->GetTypeName(), ptr, parent, size, type);
00188 AddNode(node, size);
00189
00190 CountMembers(TClass::GetClass(dm->GetTypeName()), node, ptr);
00191
00192
00193 parent->SetTotalSize(parent->GetTotalSize() + node->GetTotalSize() - size);
00194
00195 parent->SetAllMembersCount(parent->GetAllMembersCount() + node->GetAllMembersCount() - 1);
00196 } else {
00197 ptr = (void*)((ULong_t)pointer + dm->GetOffset());
00198
00199 if (!ptr) {
00200 continue;
00201 }
00202 CountMembers(TClass::GetClass(dm->GetTypeName()), parent, ptr);
00203 }
00204
00205
00206
00207
00208 if (dm->IsSTLContainer()) {
00209 parent->SetNodeType(kSTLCollection);
00210
00211
00212 TClass* stlClass = TClass::GetClass(dm->GetTypeName());
00213 if (!stlClass) {
00214 continue;
00215 }
00216
00217 TVirtualCollectionProxy* proxy = stlClass->GetCollectionProxy();
00218 if (!proxy) {
00219 continue;
00220 }
00221 TVirtualCollectionProxy::TPushPop helper(proxy, ptr);
00222
00223 UInt_t count = proxy->Size();
00224 parent->SetMembersCount(parent->GetMembersCount() + count);
00225
00226 if (!proxy->HasPointers() || proxy->GetType() != kNoType_t) {
00227 parent->SetTotalSize(parent->GetTotalSize() + count * proxy->Sizeof());
00228 parent->SetAllMembersCount(parent->GetAllMembersCount() + count);
00229 } else {
00230 TClass* clProxy = proxy->GetValueClass();
00231 TString name;
00232 TString typeName;
00233
00234 ULong_t size = 0;
00235 if (clProxy) {
00236 name = clProxy->GetName();
00237 typeName = clProxy->GetName();
00238 size = clProxy->Size();
00239 } else {
00240 continue;
00241 }
00242
00243
00244 if (size == 0) {
00245 size = proxy->Sizeof();
00246 }
00247
00248
00249 Bool_t ptp = kFALSE;
00250 std::vector<std::string> parts;
00251 int loc;
00252 TClassEdit::GetSplit(dm->GetTypeName(), parts, loc);
00253 std::vector<std::string>::const_iterator iPart = parts.begin();
00254 while (iPart != parts.end() && *iPart == "")
00255 ++iPart;
00256 if (iPart != parts.end() && *iPart != dm->GetTypeName()) {
00257 for (std::vector<std::string>::const_iterator iP = iPart,
00258 iPE = parts.end(); iP != iPE; ++iP) {
00259 if (TString(TClassEdit::ResolveTypedef(iP->c_str(), true).c_str()).EndsWith("**")){
00260 ptp = kTRUE;
00261 break;
00262 }
00263 }
00264 }
00265 if (ptp) {
00266 continue;
00267 }
00268
00269
00270 void* element;
00271 for (UInt_t i = 0; i < count ; i++) {
00272 element = *(void**)proxy->At(i);
00273
00274 if (!element) {
00275 continue;
00276 }
00277 if (clProxy->InheritsFrom(TObject::Class())) {
00278 name = ((TObject*) element)->GetName();
00279 }
00280
00281
00282 TStructNode* node = new TStructNode(name, typeName, element, parent, size, kClass);
00283
00284 AddNode(node, size);
00285
00286 parent->SetMembersCount(parent->GetMembersCount() + 1);
00287
00288 CountMembers(clProxy, node, element);
00289 parent->SetTotalSize(parent->GetTotalSize() + node->GetTotalSize());
00290 parent->SetAllMembersCount(parent->GetAllMembersCount() + node->GetAllMembersCount());
00291 }
00292 }
00293 }
00294 }
00295
00296
00297
00298
00299
00300 if(cl->InheritsFrom(TCollection::Class())) {
00301
00302 parent->SetNodeType(kCollection);
00303
00304
00305 if (!pointer) {
00306 return;
00307 }
00308
00309 TIter it2((TCollection*)pointer);
00310 TObject* item;
00311
00312 while((item = it2())) {
00313
00314 ULong_t size = 0;
00315 if (TClass* cl3 = item->IsA()){
00316 size = cl3->Size();
00317 }
00318
00319
00320 if (size == 0) {
00321 size = sizeof(item);
00322 }
00323
00324
00325 TStructNode* node = new TStructNode(item->GetName(), item->ClassName(), item, parent, size, kClass);
00326
00327 AddNode(node, size);
00328
00329 parent->SetMembersCount(parent->GetMembersCount() + 1);
00330
00331 CountMembers(item->IsA(), node, item);
00332
00333 parent->SetTotalSize(parent->GetTotalSize() + node->GetTotalSize());
00334 parent->SetAllMembersCount(parent->GetAllMembersCount() + node->GetAllMembersCount());
00335 }
00336 }
00337 }
00338
00339
00340 void TStructViewer::Draw(Option_t *option)
00341 {
00342
00343
00344 TString opt(option);
00345 if(opt == "count") {
00346
00347 } else if (opt == "size") {
00348
00349 }
00350
00351
00352 if (fTopNode) {
00353 fGUI->SetNodePtr(fTopNode);
00354 } else {
00355
00356 }
00357 }
00358
00359
00360 TCanvas* TStructViewer::GetCanvas()
00361 {
00362
00363
00364 return fGUI->GetCanvas();
00365 }
00366
00367
00368 TGMainFrame* TStructViewer::GetFrame()
00369 {
00370
00371
00372 return fGUI;
00373 }
00374
00375 void* TStructViewer::GetPointer() const
00376 {
00377
00378
00379 return fPointer;
00380 }
00381
00382
00383 TExMap TStructViewer::GetLevelMembersCount() const
00384 {
00385
00386
00387 return fLevelMembersCount;
00388 }
00389
00390
00391 TExMap TStructViewer::GetLevelSize() const
00392 {
00393
00394
00395 return fLevelSize;
00396 }
00397
00398
00399 Bool_t TStructViewer::GetLinksVisibility() const
00400 {
00401
00402
00403 return fGUI->GetLinksVisibility();
00404 }
00405
00406
00407 void TStructViewer::Prepare()
00408 {
00409
00410 if (fTopNode) {
00411 Reset();
00412 }
00413
00414 ULong_t size = fPointerClass->Size();
00415
00416 TString name = "Main pointer";
00417 if (fPointerClass->InheritsFrom(TObject::Class())) {
00418 name = ((TObject*) fPointer)->GetName();
00419 }
00420 fTopNode = new TStructNode(name, fPointerClass->GetName(), fPointer, NULL, size, kClass);
00421 AddNode(fTopNode, size);
00422 CountMembers(fPointerClass, fTopNode, fPointer);
00423 }
00424
00425
00426 void TStructViewer::Reset()
00427 {
00428
00429
00430 TList* lst;
00431 TIter it(&fLevelArray);
00432 while ((lst = (TList*) it() )) {
00433 lst->SetOwner();
00434 lst->Clear();
00435 }
00436
00437
00438 fLevelMembersCount.Clear();
00439 fLevelSize.Clear();
00440 fPointers.Clear();
00441 fLevelArray.Clear();
00442
00443 fTopNode = NULL;
00444 }
00445
00446
00447 void TStructViewer::SetColor(TString name, Int_t color)
00448 {
00449
00450
00451 TIter it(&fColors);
00452 TStructNodeProperty* prop;
00453 while ((prop = (TStructNodeProperty*) it() )) {
00454 if (name == prop->GetName()) {
00455 prop->SetColor(TColor::GetColor(color));
00456 fGUI->Update();
00457
00458 return;
00459 }
00460 }
00461
00462
00463 prop = new TStructNodeProperty(name.Data(), color);
00464 fColors.Add(prop);
00465 fColors.Sort();
00466 }
00467
00468
00469 void TStructViewer::SetLinksVisibility(Bool_t val)
00470 {
00471
00472
00473 fGUI->SetLinksVisibility(val);
00474 }
00475
00476
00477 void TStructViewer::SetPointer(void* ptr, const char* clname)
00478 {
00479
00480
00481 if (ptr) {
00482 TA* a = (TA*) ptr;
00483 if (clname) {
00484 fPointerClass = TClass::GetClass(clname);
00485 } else {
00486 fPointerClass = TClass::GetClass(typeid(*a));
00487 }
00488
00489 if (!fPointerClass) {
00490 return;
00491 }
00492
00493 fPointer = ptr;
00494 Prepare();
00495 fGUI->SetNodePtr(fTopNode);
00496 }
00497 }
00498
00499
00500 TColor TStructViewer::GetColor(const char* typeName)
00501 {
00502
00503
00504 TIter it(&fColors);
00505 TStructNodeProperty* prop;
00506 while((prop = (TStructNodeProperty*) it())) {
00507 if (!strcmp(prop->GetName(), typeName)) {
00508 return prop->GetColor();
00509 }
00510 }
00511
00512 return TColor();
00513 }