1 #include "TRestReflector.h"
3 #include "TEmulatedCollectionProxy.h"
4 #include "TRestStringHelper.h"
5 #include "TRestTools.h"
6 #include "TStreamerInfo.h"
57 TRestReflector::TRestReflector(
void* _address,
const string& _type) {
58 address = (
char*)_address;
62 if (cl ==
nullptr && dt.size == 0) {
63 cout <<
"In TRestReflector::TRestReflector() : unrecognized type: \"" << _type <<
"\"" << endl;
67 typeinfo = cl ==
nullptr ? dt.typeinfo : cl->GetTypeInfo();
68 is_data_type = dt.size > 0;
69 size = cl ==
nullptr ? dt.size : cl->Size();
70 type = cl ==
nullptr ? dt.name : cl->GetName();
75 void TRestReflector::Assembly() {
76 if (!IsZombie() && onheap) {
81 address = (
char*)cl->New();
83 }
else if (is_data_type) {
84 address = (
char*)malloc(size);
85 memset(address, 0, size);
90 void TRestReflector::Destroy()
const {
91 if (address ==
nullptr) {
96 cout <<
"In TRestReflector::Destroy() : cannot free on stack memory!" << endl;
101 cl->Destructor(address);
102 }
else if (is_data_type) {
107 void TRestReflector::PrintMemory(
int bytepreline) {
112 for (
unsigned char j = 0; j < bytepreline && i < size; j++) {
115 save << std::uppercase << std::setfill(
'0') << std::setw(2) << std::hex
116 << ((*(address + i)) & 0xff) <<
" ";
119 cout << save.str() << endl;
126 string TRestReflector::ToString()
const {
127 if (type ==
"string") {
128 return *(
string*)(address);
130 if (address ==
nullptr) {
134 if (converter !=
nullptr) {
135 return converter->ToString(address);
137 return Form(
"Type: %s, Address: %p", type.c_str(), address);
141 void TRestReflector::ParseString(
const string& str)
const {
142 if (type ==
"string") {
143 *(
string*)(address) = str;
146 if (converter !=
nullptr) {
147 converter->ParseString(address, str);
149 cout <<
"Method for parsing string to " << type <<
" has not been registered!" << endl;
154 int TRestReflector::InitDictionary() {
160 if (cl->GetCollectionProxy() &&
dynamic_cast<TEmulatedCollectionProxy*
>(cl->GetCollectionProxy())) {
170 if (type.empty() || size == 0 || cl ==
nullptr) {
171 cout <<
"Error in CreateDictionary: object is zombie!" << endl;
175 int pos = ((string)type).find(
'<');
177 string basetype = ((string)type).substr(0, pos);
178 vector<string> stltypes{
"vector",
"list",
"map",
"set",
"array",
"deque"};
180 for (
auto stltype : stltypes) {
181 if (basetype == stltype) {
186 cout <<
"Error in CreateDictionary: unknown type \"" << type <<
"\"" << endl;
190 string typeformatted =
Replace(type,
">",
"_");
191 typeformatted =
Replace(typeformatted,
"<",
"_");
192 typeformatted =
Replace(typeformatted,
",",
"_");
195 string sofilename = REST_USER_PATH + (string)
"/AddonDict/Dict_" + typeformatted +
".so";
199 cout <<
"Loading external dictionary for: \"" << type <<
"\":" << endl;
200 cout << sofilename << endl;
204 cout <<
"Error in CreateDictionary: cannot create dictionary, path not writeable!" << endl;
205 cout <<
"path: \"" << REST_USER_PATH <<
"\"" << endl;
206 cout <<
"This is possible in case you are using public installation of REST, install one by your "
211 if (system(Form(
"mkdir -p %s/AddonDict", REST_USER_PATH.c_str())) != 0) {
212 cout <<
"mkdir failed to create directory" << endl;
216 string linkdeffilename = REST_USER_PATH + (string)
"/AddonDict/LinkDef.h";
217 ofstream ofs(linkdeffilename);
218 ofs <<
"#include <map>" << endl;
219 ofs <<
"#include <vector>" << endl;
220 ofs <<
"#include <map>" << endl;
221 ofs <<
"#include <set>" << endl;
222 ofs <<
"#include <list>" << endl;
223 ofs <<
"#include <array>" << endl;
224 ofs <<
"#ifdef __ROOTCLING__" << endl;
225 ofs <<
"#pragma link C++ class " << type <<
";" << endl;
226 ofs <<
"#endif" << endl;
229 string cxxfilename = REST_USER_PATH + (string)
"/AddonDict/" + typeformatted +
".cxx";
231 cout <<
"Creating external dictionary for: \"" << type <<
"\":" << endl;
232 cout << sofilename << endl;
234 if (system(Form(
"rootcling -f %s -c %s", cxxfilename.c_str(), linkdeffilename.c_str())) != 0) {
235 cout <<
"rootcling failed to generate dictionary" << endl;
239 if (system(Form(
"gcc %s `root-config --cflags` "
240 "`root-config --libs` -lGui -lGeom -lGdml -lMinuit -L/usr/lib64 "
241 "-lstdc++ -shared -fPIC -o %s",
242 cxxfilename.c_str(), sofilename.c_str())) != 0) {
243 cout <<
"gcc failed to generate library for the dictionary" << endl;
248 gSystem->Load(sofilename.c_str());
249 RESTListOfClasses_typeid.clear();
250 RESTListOfClasses_typename.clear();
252 typeinfo = cl->GetTypeInfo();
256 bool TRestReflector::IsZombie()
const {
257 return (type.empty() || address ==
nullptr || size == 0 || (cl ==
nullptr && !is_data_type));
270 cout <<
"In TRestReflector::CloneTo() : the ptr is zombie! " << endl;
275 cout <<
"In TRestReflector::CloneTo() : type doesn't match! (This :" << from.
type
276 <<
", Target : " << to.
type <<
")" << endl;
281 if (converter !=
nullptr) {
284 cout <<
"Method for cloning type: \"" << from.
type <<
"\" has not been registered!" << endl;
291 if (mem ==
nullptr) {
293 TVirtualStreamerInfo* vs = cl->GetStreamerInfo();
294 TObjArray* ses = vs->GetElements();
295 int n = ses->GetLast() + 1;
296 for (
int i = 0; i < n; i++) {
297 TStreamerElement* ele = (TStreamerElement*)ses->At(i);
298 string type = ele->GetTypeName();
299 if (type ==
"BASE") {
300 char* addr = address + ele->GetOffset();
301 type = ele->GetClass()->GetName();
306 char* addr = address + mem->GetOffset();
307 string type = mem->GetTypeName();
319 if (ID < GetNumberOfDataMembers()) {
320 TDataMember* mem = (TDataMember*)list->At(ID);
321 char* addr = address + mem->GetOffset();
322 string type = mem->GetTypeName();
323 string name = mem->GetName();
332 vector<string> TRestReflector::GetListOfDataMembers()
const {
333 vector<string> dataMembers;
336 TVirtualStreamerInfo* vs = cl->GetStreamerInfo();
337 TObjArray* ses = vs->GetElements();
338 int n = ses->GetLast() + 1;
339 for (
int i = 0; i < n; i++) {
340 TStreamerElement* ele = (TStreamerElement*)ses->At(i);
341 string type = ele->GetTypeName();
342 if (type ==
"BASE") {
343 char* addr = address + ele->GetOffset();
344 type = ele->GetClass()->GetName();
347 dataMembers.insert(dataMembers.end(), baseDataMembers.begin(), baseDataMembers.end());
352 TList* list = cl->GetListOfDataMembers();
353 for (
int i = 0; i < list->GetSize(); i++) {
354 TDataMember* mem = (TDataMember*)list->At(i);
355 string name = mem->GetName();
357 dataMembers.push_back(name);
363 string TRestReflector::GetDataMemberValueString(
const string& name) {
371 int TRestReflector::GetNumberOfDataMembers()
const {
373 return cl->GetNdata();
void Assembly()
Assembly a new object, and save its address. The old object will be destroied if not null.
std::string type
Type of the wrapped object.
char * address
Address of the wrapped object.
std::vector< std::string > GetListOfDataMembers() const
Get a list of the class's datamembers as a std::vector of std::string, including those from base clas...
bool IsZombie() const
If this object type wrapper is invalid.
std::string ToString() const
Convert the wrapped object to std::string.
std::string name
Name field.
const std::type_info * typeinfo
value of typeid(T).name() of the wrapped object
TRestReflector GetDataMember(const std::string &name)
Find the class's datamember as TRestReflector object, including those from base class.
This namespace serves for the reflection functionality.
TClass * GetClassQuick(std::string type)
TRestReflector WrapType(const std::string &typeName)
Wrap information an object of type: typeName, memory is not allocated.
void CloneAny(const TRestReflector &from, const TRestReflector &to)
Deep copy the content of object from to to
TRestReflector Assembly(const 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 any occurences of thisSring by byThisString inside string in.