#include "TInterpreter.h"
#include "TMethodCall.h"
#include "TMethod.h"
#include "TClass.h"
#include "TROOT.h"
#include "Strlen.h"
#include "G__ci.h"
#include "Api.h"
#include "TVirtualMutex.h"
#include "TCint.h"
ClassImp(TMethodCall)
TMethodCall::TMethodCall()
{
fFunc = 0;
fOffset = 0;
fClass = 0;
fMetPtr = 0;
fMethod = "";
fParams = "";
fProto = "";
fDtorOnly = kFALSE;
fRetType = kNone;
}
TMethodCall::TMethodCall(TClass *cl, const char *method, const char *params)
{
fFunc = 0;
Init(cl, method, params);
}
TMethodCall::TMethodCall(const char *function, const char *params)
{
fFunc = 0;
Init(function, params);
}
TMethodCall::TMethodCall(const TMethodCall &orig) : TObject(orig)
{
fFunc = orig.fFunc ? new G__CallFunc(*orig.fFunc) : 0;
fOffset = orig.fOffset;
fClass = orig.fClass;
fMethod = orig.fMethod;
fParams = orig.fParams;
fProto = orig.fProto;
fDtorOnly = orig.fDtorOnly;
fRetType = orig.fRetType;
fMetPtr = 0;
}
TMethodCall &TMethodCall::operator=(const TMethodCall &rhs)
{
if (this != &rhs) {
delete fFunc;
fFunc = rhs.fFunc ? new G__CallFunc(*rhs.fFunc) : 0;
fOffset = rhs.fOffset;
fClass = rhs.fClass;
fMethod = rhs.fMethod;
fParams = rhs.fParams;
fProto = rhs.fProto;
fDtorOnly = rhs.fDtorOnly;
fRetType = rhs.fRetType;
delete fMetPtr;
fMetPtr = 0;
}
return *this;
}
TMethodCall::~TMethodCall()
{
delete fFunc;
delete fMetPtr;
}
TObject *TMethodCall::Clone(const char *) const
{
TObject *newobj = new TMethodCall(*this);
return newobj;
}
static TClass *R__FindScope(const char *function, UInt_t &pos, G__ClassInfo &cinfo)
{
if (function) {
UInt_t nested = 0;
for(int i=strlen(function); i>=0; --i) {
switch(function[i]) {
case '<': --nested; break;
case '>': ++nested; break;
case ':':
if (nested==0) {
if (i>2 && function[i-1]==':') {
TString scope(function);
scope[i-1] = 0;
pos = i+1;
TClass *cl = TClass::GetClass(scope);
if (!cl) cinfo.Init(scope);
return cl;
}
}
break;
}
}
}
return 0;
}
void TMethodCall::Init(TClass *cl, const char *method, const char *params)
{
G__ClassInfo cinfo;
if (!cl) {
UInt_t pos = 0;
cl = R__FindScope(method,pos,cinfo);
method = method+pos;
}
InitImplementation(method,params,0,cl,cinfo);
}
void TMethodCall::Init(const char *function, const char *params)
{
UInt_t pos = 0;
G__ClassInfo cinfo;
TClass *cl = R__FindScope(function,pos,cinfo);
InitImplementation(function+pos, params, 0, cl, cinfo);
}
void TMethodCall::InitImplementation(const char *methodname, const char *params,
const char *proto, TClass *cl,
const G__ClassInfo &cinfo)
{
if (!fFunc)
fFunc = new G__CallFunc;
else
fFunc->Init();
fClass = cl;
fMetPtr = 0;
fMethod = methodname;
fParams = params ? params : "";
fProto = proto ? proto : "";
fDtorOnly = kFALSE;
fRetType = kNone;
G__ClassInfo *scope = 0;
G__ClassInfo global;
if (cl) scope = cl->GetClassInfo();
else scope = (G__ClassInfo*)&cinfo;
if (!scope) return;
R__LOCKGUARD2(gCINTMutex);
if (params && params[0]) {
fFunc->SetFunc(scope, (char *)methodname, (char *)params, &fOffset);
} else if (proto && proto[0]) {
fFunc->SetFuncProto(scope, (char *)methodname, (char *)proto, &fOffset);
} else {
fFunc->SetFunc(scope, (char *)methodname, "", &fOffset);
}
}
void TMethodCall::InitWithPrototype(TClass *cl, const char *method, const char *proto)
{
G__ClassInfo cinfo;
if (!cl) {
UInt_t pos = 0;
cl = R__FindScope(method,pos,cinfo);
method = method+pos;
}
InitImplementation(method, 0, proto, cl, cinfo);
}
void TMethodCall::InitWithPrototype(const char *function, const char *proto)
{
UInt_t pos = 0;
G__ClassInfo cinfo;
TClass *cl = R__FindScope(function,pos,cinfo);
InitImplementation(function+pos, 0, proto, cl, cinfo);
}
Bool_t TMethodCall::IsValid() const
{
return fFunc ? fFunc->IsValid() : kFALSE;
}
TFunction *TMethodCall::GetMethod()
{
if (!fMetPtr) {
if (fClass) {
if (fProto == "")
fMetPtr = fClass->GetMethod(fMethod.Data(), fParams.Data());
else
fMetPtr = fClass->GetMethodWithPrototype(fMethod.Data(), fProto.Data());
TMethod *met = dynamic_cast<TMethod*>(fMetPtr);
if (met) fMetPtr = new TMethod(*met);
} else {
if (fProto == "")
fMetPtr = gROOT->GetGlobalFunction(fMethod.Data(), fParams.Data(), kTRUE);
else
fMetPtr = gROOT->GetGlobalFunctionWithPrototype(fMethod.Data(), fProto.Data(), kTRUE);
if (fMetPtr) fMetPtr = new TFunction(*fMetPtr);
}
}
return fMetPtr;
}
void TMethodCall::Execute(void *object)
{
R__LOCKGUARD2(gCINTMutex);
void *address = 0;
if (object) address = (void*)((Long_t)object + fOffset);
G__settemplevel(1);
if (fDtorOnly) {
Long_t saveglobalvar = G__getgvp();
G__setgvp((Long_t)address);
fFunc->Exec(address);
G__setgvp(saveglobalvar);
} else
fFunc->Exec(address);
G__settemplevel(-1);
}
void TMethodCall::Execute(void *object, const char *params)
{
R__LOCKGUARD2(gCINTMutex);
fFunc->SetArgs((char *)params);
void *address = 0;
if (object) address = (void*)((Long_t)object + fOffset);
G__settemplevel(1);
fFunc->Exec(address);
G__settemplevel(-1);
}
void TMethodCall::Execute(void *object, Long_t &retLong)
{
R__LOCKGUARD2(gCINTMutex);
void *address = 0;
if (object) address = (void*)((Long_t)object + fOffset);
G__settemplevel(1);
retLong = fFunc->ExecInt(address);
G__settemplevel(-1);
}
void TMethodCall::Execute(void *object, const char *params, Long_t &retLong)
{
R__LOCKGUARD2(gCINTMutex);
fFunc->SetArgs((char *)params);
void *address = 0;
if (object) address = (void*)((Long_t)object + fOffset);
G__settemplevel(1);
retLong = fFunc->ExecInt(address);
G__settemplevel(-1);
}
void TMethodCall::Execute(void *object, Double_t &retDouble)
{
R__LOCKGUARD2(gCINTMutex);
void *address = 0;
if (object) address = (void*)((Long_t)object + fOffset);
G__settemplevel(1);
retDouble = fFunc->ExecDouble(address);
G__settemplevel(-1);
}
void TMethodCall::Execute(void *object, const char *params, Double_t &retDouble)
{
R__LOCKGUARD2(gCINTMutex);
fFunc->SetArgs((char *)params);
void *address = 0;
if (object) address = (void*)((Long_t)object + fOffset);
G__settemplevel(1);
retDouble = fFunc->ExecDouble(address);
G__settemplevel(-1);
}
void TMethodCall::Execute(void *object, char **retText)
{
R__LOCKGUARD2(gCINTMutex);
void *address = 0;
if (object) address = (void*)((Long_t)object + fOffset);
G__settemplevel(1);
*retText =(char*) (fFunc->ExecInt(address));
G__settemplevel(-1);
}
void TMethodCall::Execute(void *object, const char *params, char **retText)
{
R__LOCKGUARD2(gCINTMutex);
fFunc->SetArgs((char *)params);
void *address = 0;
if (object) address = (void*)((Long_t)object + fOffset);
G__settemplevel(1);
*retText =(char*)(fFunc->ExecInt(address));
G__settemplevel(-1);
}
TMethodCall::EReturnType TMethodCall::ReturnType()
{
if ( fRetType == kNone) {
TFunction *func = GetMethod();
if (func == 0) {
fRetType = kOther;
Error("ReturnType","Unknown method");
return kOther;
}
Int_t nstar = 0;
const char* returntype = func->GetReturnTypeName();
while (*returntype) {
if (*returntype == '*') nstar++;
returntype++;
}
G__TypedefInfo type(gInterpreter->TypeName(func->GetReturnTypeName()));
const char *name = type.TrueName();
Bool_t isEnum = kFALSE;
if (!strcmp("(unknown)",name)) {
G__TypeInfo type(func->GetReturnTypeName());
name = type.TrueName();
if (type.Property()&kIsEnum) {
isEnum = kTRUE;
}
}
if ((nstar==1) &&
(!strcmp("unsigned char", name) || !strcmp("char", name) ||
!strcmp("UChar_t", name) || !strcmp("Char_t", name) ||
!strcmp("const unsigned char", name) || !strcmp("const char", name) ||
!strcmp("const UChar_t", name) || !strcmp("const Char_t", name) ||
!strcmp("unsigned char*", name) || !strcmp("char*", name) ||
!strcmp("UChar_t*", name) || !strcmp("Char_t*", name) ||
!strcmp("const unsigned char*", name) || !strcmp("const char*", name) ||
!strcmp("const UChar_t*", name) || !strcmp("const Char_t*", name)))
fRetType = kString;
else if (!strcmp("unsigned int", name) || !strcmp("int", name) ||
!strcmp("unsigned long", name) || !strcmp("long", name) ||
!strcmp("unsigned long long", name) || !strcmp("long long", name) ||
!strcmp("unsigned short", name) || !strcmp("short", name) ||
!strcmp("unsigned char", name) || !strcmp("char", name) ||
!strcmp("UInt_t", name) || !strcmp("Int_t", name) ||
!strcmp("ULong_t", name) || !strcmp("Long_t", name) ||
!strcmp("ULong64_t", name) || !strcmp("Long_t64", name) ||
!strcmp("UShort_t", name) || !strcmp("Short_t", name) ||
!strcmp("UChar_t", name) || !strcmp("Char_t", name) ||
!strcmp("Bool_t", name) || !strcmp("bool", name) ||
strstr(name, "enum"))
fRetType = kLong;
else if (!strcmp("float", name) || !strcmp("double", name) ||
!strcmp("Float_t", name) || !strcmp("Double_t", name))
fRetType = kDouble;
else if (isEnum)
fRetType = kLong;
else
fRetType = kOther;
}
return fRetType;
}
void TMethodCall::SetParamPtrs(void *paramArr, Int_t nparam)
{
R__LOCKGUARD2(gCINTMutex);
fFunc->SetArgArray((Long_t *)paramArr, nparam);
}
void TMethodCall::ResetParam()
{
fFunc->ResetArg();
}
void TMethodCall::SetParam(Long_t l)
{
fFunc->SetArg(l);
}
void TMethodCall::SetParam(Double_t d)
{
fFunc->SetArg(d);
}
void TMethodCall::SetParam(Long64_t ll)
{
fFunc->SetArg(ll);
}
void TMethodCall::SetParam(ULong64_t ull)
{
fFunc->SetArg(ull);
}
Last update: Thu Jan 17 09:00:11 2008
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.