1#include "TRestReflector.h"
3#include "TEmulatedCollectionProxy.h"
4#include "TRestStringHelper.h"
6#include "TStreamerInfo.h"
62 if (
cl ==
nullptr && dt.size == 0) {
63 cout <<
"In TRestReflector::TRestReflector() : unrecognized type: \"" << _type <<
"\"" << endl;
69 size =
cl == 0 ? dt.size :
cl->Size();
70 type =
cl == 0 ? dt.name :
cl->GetName();
94 cout <<
"In TRestReflector::Destroy() : cannot free on stack memory!" << endl;
110 for (
unsigned char j = 0; j < bytepreline && i <
size; j++) {
113 save << std::uppercase << std::setfill(
'0') << std::setw(2) << std::hex
114 << ((*(
address + i)) & 0xff) <<
" ";
117 cout << save.str() << endl;
126 if (
address ==
nullptr)
return "null";
128 if (converter !=
nullptr) {
129 return converter->ToString(
address);
131 return Form(
"Type: %s, Address: %p",
type.c_str(),
address);
136 if (
type ==
"string") {
140 if (converter !=
nullptr) {
141 converter->ParseString(
address, str);
143 cout <<
"Method for parsing string to " <<
type <<
" has not been registered!" << endl;
152 if (
cl->GetCollectionProxy() &&
dynamic_cast<TEmulatedCollectionProxy*
>(
cl->GetCollectionProxy())) {
162 if (
type ==
"" ||
size == 0 ||
cl ==
nullptr) {
163 cout <<
"Error in CreateDictionary: object is zombie!" << endl;
167 int pos = ((string)
type).find(
"<");
169 string basetype = ((string)
type).substr(0, pos);
170 vector<string> stltypes{
"vector",
"list",
"map",
"set",
"array",
"deque"};
172 for (
auto stltype : stltypes) {
173 if (basetype == stltype) {
178 cout <<
"Error in CreateDictionary: unknown type \"" <<
type <<
"\"" << endl;
183 typeformatted =
Replace(typeformatted,
"<",
"_");
184 typeformatted =
Replace(typeformatted,
",",
"_");
187 string sofilename = REST_USER_PATH + (string)
"/AddonDict/Dict_" + typeformatted +
".so";
191 cout <<
"Loading external dictionary for: \"" <<
type <<
"\":" << endl;
192 cout << sofilename << endl;
197 cout <<
"Error in CreateDictionary: cannot create dictionary, path not writeable!" << endl;
198 cout <<
"path: \"" << REST_USER_PATH <<
"\"" << endl;
199 cout <<
"This is possible in case you are using public installation of REST, install one by your "
204 int z = system(Form(
"mkdir -p %s/AddonDict", REST_USER_PATH.c_str()));
206 cout <<
"mkdir failed to create directory" << endl;
210 string linkdeffilename = REST_USER_PATH + (string)
"/AddonDict/LinkDef.h";
211 ofstream ofs(linkdeffilename);
212 ofs <<
"#include <map>" << endl;
213 ofs <<
"#include <vector>" << endl;
214 ofs <<
"#include <map>" << endl;
215 ofs <<
"#include <set>" << endl;
216 ofs <<
"#include <list>" << endl;
217 ofs <<
"#include <array>" << endl;
218 ofs <<
"#ifdef __ROOTCLING__" << endl;
219 ofs <<
"#pragma link C++ class " <<
type <<
";" << endl;
220 ofs <<
"#endif" << endl;
223 string cxxfilename = REST_USER_PATH + (string)
"/AddonDict/" + typeformatted +
".cxx";
225 cout <<
"Creating external dictionary for: \"" <<
type <<
"\":" << endl;
226 cout << sofilename << endl;
229 int a = system(Form(
"rootcling -f %s -c %s", cxxfilename.c_str(), linkdeffilename.c_str()));
231 cout <<
"rootcling failed to generate dictionary" << endl;
236 system(Form(
"gcc %s `root-config --cflags` "
237 "`root-config --libs` -lGui -lGeom -lGdml -lMinuit -L/usr/lib64 "
238 "-lstdc++ -shared -fPIC -o %s",
239 cxxfilename.c_str(), sofilename.c_str()));
248 cout <<
"gcc failed to generate library for the dictionary" << endl;
253 gSystem->Load(sofilename.c_str());
254 RESTListOfClasses_typeid.clear();
255 RESTListOfClasses_typename.clear();
275 cout <<
"In TRestReflector::CloneTo() : the ptr is zombie! " << endl;
280 cout <<
"In TRestReflector::CloneTo() : type doesn't match! (This :" << from.
type
281 <<
", Target : " << to.
type <<
")" << endl;
286 if (converter !=
nullptr) {
289 cout <<
"Method for cloning type: \"" << from.
type <<
"\" has not been registered!" << endl;
310 TDataMember* mem =
cl->GetDataMember(
name.c_str());
311 if (mem ==
nullptr) {
313 TVirtualStreamerInfo* vs =
cl->GetStreamerInfo();
314 TObjArray* ses = vs->GetElements();
315 int n = ses->GetLast() + 1;
316 for (
int i = 0; i < n; i++) {
317 TStreamerElement* ele = (TStreamerElement*)ses->At(i);
318 string type = ele->GetTypeName();
319 if (
type ==
"BASE") {
320 char* addr =
address + ele->GetOffset();
321 type = ele->GetClass()->GetName();
326 char* addr =
address + mem->GetOffset();
327 string type = mem->GetTypeName();
338 TList* list =
cl->GetListOfDataMembers();
340 TDataMember* mem = (TDataMember*)list->At(ID);
341 char* addr =
address + mem->GetOffset();
342 string type = mem->GetTypeName();
343 string name = mem->GetName();
353 vector<string> dataMembers;
356 TVirtualStreamerInfo* vs =
cl->GetStreamerInfo();
357 TObjArray* ses = vs->GetElements();
358 int n = ses->GetLast() + 1;
359 for (
int i = 0; i < n; i++) {
360 TStreamerElement* ele = (TStreamerElement*)ses->At(i);
361 string type = ele->GetTypeName();
362 if (
type ==
"BASE") {
363 char* addr =
address + ele->GetOffset();
364 type = ele->GetClass()->GetName();
367 dataMembers.insert(dataMembers.end(), baseDataMembers.begin(), baseDataMembers.end());
372 TList* list =
cl->GetListOfDataMembers();
373 for (
int i = 0; i < list->GetSize(); i++) {
374 TDataMember* mem = (TDataMember*)list->At(i);
375 string name = mem->GetName();
377 dataMembers.push_back(
name);
393 return cl->GetNdata();
void ParseString(std::string str)
Set the value of the wrapped object from std::string.
void Assembly()
Assembly a new object, and save its address. The old object will be destroied if not null.
std::string ToString()
Convert the wrapped object to std::string.
TRestReflector()
Default constructor.
std::string GetDataMemberValueString(std::string name)
Get the value of datamember as std::string.
std::string type
Type of the wrapped object.
int size
Size of the object.
std::vector< std::string > GetListOfDataMembers()
Get a list of the class's datamembers as a std::vector of std::string, including those from base clas...
char * address
Address of the wrapped object.
TClass * cl
Pointer to the corresponding TClass helper, if the wrapped object is in class type.
bool is_data_type
Pointer to the corresponding TDataType helper, if the wrapped object is in data type.
void operator>>(TRestReflector to)
Deep copy the content of the wrapped object to to.
int GetNumberOfDataMembers()
Get the number of data members of a class.
TRestReflector GetDataMember(std::string name)
Find the class's datamember as TRestReflector object, including those from base class.
std::string name
Name field.
void PrintMemory(int bytepreline=16)
Print the Hex memory std::map of the wrappered object.
void Destroy()
Destroy the current object. It will make the class to be zombie.
const std::type_info * typeinfo
value of typeid(T).name() of the wrapped object
bool IsZombie()
If this object type wrapper is invalid.
bool onheap
If on heap, we can call Destroy() to TRestReflector. True only when initialized from Assembly()
int InitDictionary()
Prepare the ROOT dictionary for this type.
This namespace serves for the reflection functionality.
TRestReflector WrapType(std::string typeName)
Wrap information an object of type: typeName, memory is not allocated.
TClass * GetClassQuick(std::string type)
void CloneAny(TRestReflector from, TRestReflector to)
Deep copy the content of object from to to
TRestReflector Assembly(std::string typeName)
Assembly an object of type: typeName, returning the allocated memory address and size.
std::string RemoveWhiteSpaces(std::string in)
Returns the input string removing all white spaces.
std::string Replace(std::string in, std::string thisString, std::string byThisString, size_t fromPosition=0, Int_t N=0)
Replace every occurences of thisSring by byThisString inside string in.