Converters.cxx

Go to the documentation of this file.
00001 // @(#)root/pyroot:$Id: Converters.cxx 37357 2010-12-06 22:22:35Z wlav $
00002 // Author: Wim Lavrijsen, Jan 2005
00003 
00004 // Bindings
00005 #include "PyROOT.h"
00006 #include "PyStrings.h"
00007 #include "Converters.h"
00008 #include "ObjectProxy.h"
00009 #include "PyBufferFactory.h"
00010 #include "TCustomPyTypes.h"
00011 #include "Utility.h"
00012 #include "RootWrapper.h"
00013 
00014 // ROOT
00015 #include "TClass.h"
00016 #include "TClassEdit.h"
00017 
00018 // CINT
00019 #include "Api.h"
00020 
00021 // Standard
00022 #include <limits.h>
00023 #include <string.h>
00024 #include <utility>
00025 #include <sstream>
00026 
00027 
00028 //- data ______________________________________________________________________
00029 PyROOT::ConvFactories_t PyROOT::gConvFactories;
00030 
00031 
00032 //- base converter implementation ---------------------------------------------
00033 PyObject* PyROOT::TConverter::FromMemory( void* )
00034 {
00035 // could happen if no derived class override
00036    PyErr_SetString( PyExc_TypeError, "unknown type can not be converted from memory" );
00037    return 0;
00038 }
00039 
00040 //_____________________________________________________________________________
00041 Bool_t PyROOT::TConverter::ToMemory( PyObject*, void* )
00042 {
00043 // could happen if no derived class override
00044    PyErr_SetString( PyExc_TypeError, "unknown type can not be converted to memory" );
00045    return kFALSE;
00046 }
00047 
00048 
00049 //- helper macro's ------------------------------------------------------------
00050 #define PYROOT_IMPLEMENT_BASIC_CONVERTER( name, type, stype, F1, F2 )         \
00051 PyObject* PyROOT::T##name##Converter::FromMemory( void* address )             \
00052 {                                                                             \
00053    return F1( (stype)*((type*)address) );                                     \
00054 }                                                                             \
00055                                                                               \
00056 Bool_t PyROOT::T##name##Converter::ToMemory( PyObject* value, void* address ) \
00057 {                                                                             \
00058    type s = (type)F2( value );                                                \
00059    if ( s == (type)-1 && PyErr_Occurred() )                                   \
00060       return kFALSE;                                                          \
00061    *((type*)address) = (type)s;                                               \
00062    return kTRUE;                                                              \
00063 }
00064 
00065 #define PYROOT_IMPLEMENT_BASIC_REF_CONVERTER( name )                          \
00066 PyObject* PyROOT::T##name##Converter::FromMemory( void* )                     \
00067 {                                                                             \
00068    return 0;                                                                  \
00069 }                                                                             \
00070                                                                               \
00071 Bool_t PyROOT::T##name##Converter::ToMemory( PyObject*, void* )               \
00072 {                                                                             \
00073    return kFALSE;                                                             \
00074 }
00075 
00076 
00077 //_____________________________________________________________________________
00078 #define PYROOT_IMPLEMENT_BASIC_CHAR_CONVERTER( name, type, low, high )        \
00079 Bool_t PyROOT::T##name##Converter::SetArg(                                    \
00080       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )       \
00081 {                                                                             \
00082 /* convert <pyobject> to C++ <<type>>, set arg for call, allow int -> char */ \
00083    if ( PyROOT_PyUnicode_Check( pyobject ) ) {                                \
00084       if ( PyROOT_PyUnicode_GET_SIZE( pyobject ) == 1 ) {                     \
00085          para.fl = (Long_t)PyROOT_PyUnicode_AsString( pyobject )[0];          \
00086          if ( func )                                                          \
00087             func->SetArg( para.fl );                                          \
00088       } else {                                                                \
00089          PyErr_Format( PyExc_TypeError,                                       \
00090             #type" expected, got string of size "PY_SSIZE_T_FORMAT, PyROOT_PyUnicode_GET_SIZE( pyobject ) );\
00091          return kFALSE;                                                       \
00092       }                                                                       \
00093    } else {                                                                   \
00094       para.fl = PyLong_AsLong( pyobject );                                    \
00095       if ( para.fl == -1 && PyErr_Occurred() ) {                              \
00096          return kFALSE;                                                       \
00097       } else if ( ! ( low <= para.fl && para.fl <= high ) ) {                 \
00098          PyErr_Format( PyExc_ValueError,                                      \
00099             "integer to character: value %ld not in range [%d,%d]", para.fl, low, high );\
00100          return kFALSE;                                                       \
00101       } else if ( func )                                                      \
00102          func->SetArg( para.fl );                                             \
00103    }                                                                          \
00104    return kTRUE;                                                              \
00105 }                                                                             \
00106                                                                               \
00107 PyObject* PyROOT::T##name##Converter::FromMemory( void* address )             \
00108 {                                                                             \
00109    return PyROOT_PyUnicode_FromFormat( "%c", *((type*)address) );             \
00110 }                                                                             \
00111                                                                               \
00112 Bool_t PyROOT::T##name##Converter::ToMemory( PyObject* value, void* address ) \
00113 {                                                                             \
00114    if ( PyROOT_PyUnicode_Check( value ) ) {                                   \
00115       const char* buf = PyROOT_PyUnicode_AsString( value );                   \
00116       if ( PyErr_Occurred() )                                                 \
00117          return kFALSE;                                                       \
00118       int len = strlen( buf );                                                \
00119       if ( len != 1 ) {                                                       \
00120          PyErr_Format( PyExc_TypeError, #type" expected, got string of size %d", len );\
00121          return kFALSE;                                                       \
00122       }                                                                       \
00123       *((type*)address) = (type)buf[0];                                       \
00124    } else {                                                                   \
00125       Long_t l = PyLong_AsLong( value );                                      \
00126       if ( l == -1 && PyErr_Occurred() )                                      \
00127          return kFALSE;                                                       \
00128       if ( ! ( low <= l && l <= high ) ) {                                    \
00129          PyErr_Format( PyExc_ValueError, \
00130             "integer to character: value %ld not in range [%d,%d]", l, low, high );\
00131          return kFALSE;                                                       \
00132       }                                                                       \
00133       *((type*)address) = (type)l;                                            \
00134    }                                                                          \
00135    return kTRUE;                                                              \
00136 }
00137 
00138 
00139 //- converters for built-ins --------------------------------------------------
00140 Bool_t PyROOT::TLongConverter::SetArg(
00141       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00142 {
00143 // convert <pyobject> to C++ long, set arg for call
00144 #if PY_VERSION_HEX >= 0x02070000
00145 // p2.7 silently converts floats to long ...
00146    if ( ! (PyLong_Check( pyobject ) || PyInt_Check( pyobject )) )
00147       return kFALSE;
00148 #endif
00149    para.fl = PyLong_AsLong( pyobject );
00150    if ( para.fl == -1 && PyErr_Occurred() )
00151       return kFALSE;
00152    else if ( func )
00153       func->SetArg( para.fl );
00154    return kTRUE;
00155 }
00156 
00157 PYROOT_IMPLEMENT_BASIC_CONVERTER( Long, Long_t, Long_t, PyLong_FromLong, PyLong_AsLong )
00158 
00159 //____________________________________________________________________________
00160 Bool_t PyROOT::TLongRefConverter::SetArg(
00161       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00162 {
00163 // convert <pyobject> to C++ long&, set arg for call
00164    if ( ! TCustomInt_CheckExact( pyobject ) ) {
00165       if ( PyInt_Check( pyobject ) )
00166          PyErr_SetString( PyExc_TypeError, "use ROOT.Long for pass-by-ref of longs" );
00167       return kFALSE;
00168    }
00169 
00170 #if PY_VERSION_HEX < 0x03000000
00171    para.fl = (Long_t)&((PyIntObject*)pyobject)->ob_ival;
00172    if ( func )
00173       func->SetArgRef( (Long_t&)((PyIntObject*)pyobject)->ob_ival );
00174    return kTRUE;
00175 #else
00176    para.fl = 0; func = 0;
00177    return kFALSE; // there no longer is a PyIntObject in p3
00178 #endif
00179 }
00180 
00181 PYROOT_IMPLEMENT_BASIC_REF_CONVERTER( LongRef )
00182 
00183 //____________________________________________________________________________
00184 Bool_t PyROOT::TConstLongRefConverter::SetArg(
00185       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00186 {
00187 // convert <pyobject> to C++ const long&, set arg for call using buffer
00188    para.fl = fBuffer = PyLong_AsLong( pyobject );
00189    if ( para.fl == -1 && PyErr_Occurred() )
00190       return kFALSE;
00191    else if ( func )
00192       func->SetArgRef( fBuffer );
00193    return kTRUE;
00194 }
00195 
00196 //____________________________________________________________________________
00197 Bool_t PyROOT::TIntRefConverter::SetArg(
00198       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00199 {
00200 // convert <pyobject> to C++ (pseudo)int&, set arg for call
00201    if ( ! TCustomInt_CheckExact( pyobject ) ) {
00202       if ( PyInt_Check( pyobject ) )
00203          PyErr_SetString( PyExc_TypeError, "use ROOT.Long for pass-by-ref of ints" );
00204       return kFALSE;
00205    }
00206 
00207 #if PY_VERSION_HEX < 0x03000000
00208    para.fl = (Long_t)&((PyIntObject*)pyobject)->ob_ival;
00209    if ( func ) {
00210       G__value v;
00211       v.ref = (long)&((PyIntObject*)pyobject)->ob_ival;
00212       G__letint(&v,'i',para.fl);
00213       func->SetArg( v );
00214    }
00215 
00216    return kTRUE;
00217 #else
00218    para.fl = 0; func = 0;
00219    return kFALSE; // there no longer is a PyIntObject in p3
00220 #endif
00221 }
00222 
00223 PYROOT_IMPLEMENT_BASIC_REF_CONVERTER( IntRef )
00224 
00225 //____________________________________________________________________________
00226 Bool_t PyROOT::TBoolConverter::SetArg(
00227       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00228 {
00229 // convert <pyobject> to C++ bool, allow int/long -> bool, set arg for call
00230    para.fl = PyLong_AsLong( pyobject );
00231    if ( ! ( para.fl == 0 || para.fl == 1 ) ) {
00232       PyErr_SetString( PyExc_TypeError, "boolean value should be bool, or integer 1 or 0" );
00233       return kFALSE;
00234    }
00235 
00236    if ( func )
00237       func->SetArg( para.fl );
00238    return kTRUE;
00239 }
00240 
00241 PYROOT_IMPLEMENT_BASIC_CONVERTER( Bool, Bool_t, Long_t, PyInt_FromLong, PyInt_AsLong )
00242 
00243 //____________________________________________________________________________
00244 PYROOT_IMPLEMENT_BASIC_CHAR_CONVERTER( Char,  Char_t,  CHAR_MIN, CHAR_MAX  )
00245 PYROOT_IMPLEMENT_BASIC_CHAR_CONVERTER( UChar, UChar_t,        0, UCHAR_MAX )
00246 
00247 //____________________________________________________________________________
00248 PYROOT_IMPLEMENT_BASIC_CONVERTER( Short,  Short_t,  Long_t, PyInt_FromLong,  PyInt_AsLong )
00249 PYROOT_IMPLEMENT_BASIC_CONVERTER( UShort, UShort_t, Long_t, PyInt_FromLong,  PyInt_AsLong )
00250 PYROOT_IMPLEMENT_BASIC_CONVERTER( Int,    Int_t,    Long_t, PyInt_FromLong,  PyInt_AsLong )
00251 
00252 //____________________________________________________________________________
00253 Bool_t PyROOT::TULongConverter::SetArg(
00254       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00255 {
00256 // convert <pyobject> to C++ unsigned long, set arg for call
00257    para.ful = PyLongOrInt_AsULong( pyobject );
00258    if ( PyErr_Occurred() )
00259       return kFALSE;
00260    else if ( func )
00261       func->SetArg( para.ful );
00262    return kTRUE;
00263 }
00264 
00265 PyObject* PyROOT::TULongConverter::FromMemory( void* address )
00266 {
00267 // construct python object from C++ unsigned long read at <address>
00268    return PyLong_FromUnsignedLong( *((ULong_t*)address) );
00269 }
00270 
00271 Bool_t PyROOT::TULongConverter::ToMemory( PyObject* value, void* address )
00272 {
00273 // convert <value> to C++ unsigned long, write it at <address>
00274    ULong_t u = PyLongOrInt_AsULong( value );
00275    if ( PyErr_Occurred() )
00276       return kFALSE;
00277    *((ULong_t*)address) = u;
00278    return kTRUE;
00279 }
00280 
00281 //____________________________________________________________________________
00282 PyObject* PyROOT::TUIntConverter::FromMemory( void* address )
00283 {
00284 // construct python object from C++ unsigned int read at <address>
00285    return PyLong_FromUnsignedLong( *((UInt_t*)address) );
00286 }
00287 
00288 Bool_t PyROOT::TUIntConverter::ToMemory( PyObject* value, void* address )
00289 {
00290 // convert <value> to C++ unsigned int, write it at <address>
00291    ULong_t u = PyLongOrInt_AsULong( value );
00292    if ( PyErr_Occurred() )
00293       return kFALSE;
00294 
00295    if ( u > (ULong_t)UINT_MAX ) {
00296       PyErr_SetString( PyExc_OverflowError, "value too large for unsigned int" );
00297       return kFALSE;
00298    }
00299 
00300    *((UInt_t*)address) = (UInt_t)u;
00301    return kTRUE;
00302 }
00303 
00304 //____________________________________________________________________________
00305 Bool_t PyROOT::TDoubleConverter::SetArg(
00306       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00307 {
00308 // convert <pyobject> to C++ double, set arg for call
00309    para.fd = PyFloat_AsDouble( pyobject );
00310    if ( para.fd == -1.0 && PyErr_Occurred() )
00311       return kFALSE;
00312    else if ( func )
00313       func->SetArg( para.fd );
00314    return kTRUE;
00315 }
00316 
00317 PYROOT_IMPLEMENT_BASIC_CONVERTER( Double, Double_t, Double_t, PyFloat_FromDouble, PyFloat_AsDouble )
00318 PYROOT_IMPLEMENT_BASIC_CONVERTER( Float,  Float_t,  Double_t, PyFloat_FromDouble, PyFloat_AsDouble )
00319 
00320 //____________________________________________________________________________
00321 Bool_t PyROOT::TDoubleRefConverter::SetArg(
00322       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00323 {
00324 // convert <pyobject> to C++ double&, set arg for call
00325    if ( ! TCustomFloat_CheckExact( pyobject ) ) {
00326       if ( PyFloat_Check( pyobject ) )
00327          PyErr_SetString( PyExc_TypeError, "use ROOT.Double for pass-by-ref of doubles" );
00328       return kFALSE;
00329    }
00330 
00331    para.fl = (Long_t)&((PyFloatObject*)pyobject)->ob_fval;
00332    if ( func )
00333       func->SetArgRef( ((PyFloatObject*)pyobject)->ob_fval );
00334    return kTRUE;
00335 }
00336 
00337 PYROOT_IMPLEMENT_BASIC_REF_CONVERTER( DoubleRef )
00338 
00339 //____________________________________________________________________________
00340 Bool_t PyROOT::TConstDoubleRefConverter::SetArg(
00341       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00342 {
00343 // convert <pyobject> to C++ const double&, set arg for call using buffer
00344    para.fd = fBuffer = PyFloat_AsDouble( pyobject );
00345    if ( para.fd == -1.0 && PyErr_Occurred() )
00346       return kFALSE;
00347    else if ( func )
00348       func->SetArgRef( fBuffer );
00349    return kTRUE;
00350 }
00351 
00352 //____________________________________________________________________________
00353 Bool_t PyROOT::TVoidConverter::SetArg( PyObject*, TParameter&, G__CallFunc*, Long_t )
00354 {
00355 // can't happen (unless a type is mapped wrongly), but implemented for completeness
00356    PyErr_SetString( PyExc_SystemError, "void/unknown arguments can\'t be set" );
00357    return kFALSE;
00358 }
00359 
00360 //____________________________________________________________________________
00361 Bool_t PyROOT::TMacroConverter::SetArg( PyObject*, TParameter&, G__CallFunc*, Long_t )
00362 {
00363 // C++ macro's are not acceptable function args (but their values could be)
00364    PyErr_SetString( PyExc_SystemError, "macro arguments can\'t be set" );
00365    return kFALSE;
00366 }
00367 
00368 PyObject* PyROOT::TMacroConverter::FromMemory( void* address )
00369 {
00370 // no info available from ROOT/meta; go directly to CINT for the type info
00371    G__DataMemberInfo dmi;
00372    while ( dmi.Next() ) {    // using G__ClassInfo().GetDataMember() would cause overwrite
00373 
00374       if ( (Long_t)address == dmi.Offset() ) {
00375       // for now, only handle int, double, and C-string
00376          switch ( dmi.Type()->Type() ) {
00377          case 'p':
00378             return PyInt_FromLong( (Long_t) *(Int_t*)address );
00379          case 'P':
00380             return PyFloat_FromDouble( (double) *(Double_t*)address );
00381          case 'T':
00382             return PyROOT_PyUnicode_FromString( *(char**)address );
00383          default:
00384          // type unknown/not implemented
00385             PyErr_SetString( PyExc_NotImplementedError, "macro value could not be converted" );
00386             return 0;
00387          }
00388       }
00389    }
00390 
00391 // type unknown/not implemented
00392    PyErr_SetString( PyExc_AttributeError, "requested macro not found" );
00393    return 0;
00394 }
00395 
00396 //____________________________________________________________________________
00397 Bool_t PyROOT::TLongLongConverter::SetArg(
00398       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00399 {
00400 // convert <pyobject> to C++ long long, set arg for call
00401 
00402    if ( PyFloat_Check( pyobject ) ) {
00403    // special case: float implements nb_int, but allowing rounding conversions
00404    // interferes with overloading
00405       PyErr_SetString( PyExc_ValueError, "can not convert float to long long" );
00406       return kFALSE;
00407    }
00408 
00409    para.fll = PyLong_AsLongLong( pyobject );
00410    if ( PyErr_Occurred() )
00411       return kFALSE;
00412    else if ( func )
00413       func->SetArg( para.fll );
00414    return kTRUE;
00415 }
00416 
00417 PyObject* PyROOT::TLongLongConverter::FromMemory( void* address )
00418 {
00419 // construct python object from C++ long long read at <address>
00420    return PyLong_FromLongLong( *(Long64_t*)address );
00421 }
00422 
00423 Bool_t PyROOT::TLongLongConverter::ToMemory( PyObject* value, void* address )
00424 {
00425 // convert <value> to C++ long long, write it at <address>
00426    Long64_t ll = PyLong_AsLongLong( value );
00427    if ( ll == -1 && PyErr_Occurred() )
00428       return kFALSE;
00429    *((Long64_t*)address) = ll;
00430    return kTRUE;
00431 }
00432 
00433 //____________________________________________________________________________
00434 Bool_t PyROOT::TULongLongConverter::SetArg(
00435       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00436 {
00437 // convert <pyobject> to C++ unsigned long long, set arg for call
00438    para.full = PyLongOrInt_AsULong64( pyobject );
00439    if ( PyErr_Occurred() )
00440       return kFALSE;
00441    else if ( func )
00442       func->SetArg( para.full );
00443    return kTRUE;
00444 }
00445 
00446 PyObject* PyROOT::TULongLongConverter::FromMemory( void* address )
00447 {
00448 // construct python object from C++ unsigned long long read at <address>
00449    return PyLong_FromUnsignedLongLong( *(ULong64_t*)address );
00450 }
00451 
00452 Bool_t PyROOT::TULongLongConverter::ToMemory( PyObject* value, void* address )
00453 {
00454 // convert <value> to C++ unsigned long long, write it at <address>
00455    Long64_t ull = PyLongOrInt_AsULong64( value );
00456    if ( PyErr_Occurred() )
00457       return kFALSE;
00458    *((ULong64_t*)address) = ull;
00459    return kTRUE;
00460 }
00461 
00462 //____________________________________________________________________________
00463 Bool_t PyROOT::TCStringConverter::SetArg(
00464       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00465 {
00466 // construct a new string and copy it in new memory
00467    const char* s = PyROOT_PyUnicode_AsStringChecked( pyobject );
00468    if ( PyErr_Occurred() )
00469       return kFALSE;
00470 
00471    fBuffer = s;
00472    para.fv = (void*)fBuffer.c_str();
00473 
00474 // verify (too long string will cause truncation, no crash)
00475    if ( fMaxSize < (UInt_t)fBuffer.size() )
00476       PyErr_Warn( PyExc_RuntimeWarning, (char*)"string too long for char array (truncated)" );
00477    else if ( fMaxSize != UINT_MAX )
00478       fBuffer.resize( fMaxSize, '\0' );      // padd remainder of buffer as needed
00479 
00480 // set the value and declare success
00481    if ( func )
00482       func->SetArg( reinterpret_cast< Long_t >( fBuffer.c_str() ) );
00483    return kTRUE;
00484 }
00485 
00486 PyObject* PyROOT::TCStringConverter::FromMemory( void* address )
00487 {
00488 // construct python object from C++ const char* read at <address>
00489    if ( address && *(char**)address ) {
00490       if ( fMaxSize != UINT_MAX ) {          // need to prevent reading beyond boundary
00491          std::string buf( *(char**)address, fMaxSize );
00492          return PyROOT_PyUnicode_FromString( buf.c_str() );
00493       }
00494 
00495       return PyROOT_PyUnicode_FromString( *(char**)address );
00496    }
00497 
00498 // empty string in case there's no address
00499    Py_INCREF( PyStrings::gEmptyString );
00500    return PyStrings::gEmptyString;
00501 }
00502 
00503 Bool_t PyROOT::TCStringConverter::ToMemory( PyObject* value, void* address )
00504 {
00505 // convert <value> to C++ const char*, write it at <address>
00506    const char* s = PyROOT_PyUnicode_AsStringChecked( value );
00507    if ( PyErr_Occurred() )
00508       return kFALSE;
00509 
00510 // verify (too long string will cause truncation, no crash)
00511    if ( fMaxSize < (UInt_t)PyROOT_PyUnicode_GET_SIZE( value ) )
00512       PyErr_Warn( PyExc_RuntimeWarning, (char*)"string too long for char array (truncated)" );
00513 
00514    if ( fMaxSize != UINT_MAX )
00515       strncpy( *(char**)address, s, fMaxSize );   // padds remainder
00516    else
00517       // coverity[secure_coding] - can't help it, it's intentional.
00518       strcpy( *(char**)address, s );
00519 
00520    return kTRUE;
00521 }
00522 
00523 
00524 //- pointer/array conversions -------------------------------------------------
00525 namespace {
00526 
00527    inline Bool_t CArraySetArg(
00528       PyObject* pyobject, PyROOT::TParameter& para, G__CallFunc* func, char tc, int size )
00529    {
00530       int buflen = PyROOT::Utility::GetBuffer( pyobject, tc, size, para.fv );
00531       if ( ! para.fv || buflen == 0 )
00532          return kFALSE;
00533       else if ( func )
00534          func->SetArg( para.fl );
00535       return kTRUE;
00536    }
00537 
00538 } // unnamed namespace
00539 
00540 
00541 //____________________________________________________________________________
00542 Bool_t PyROOT::TNonConstCStringConverter::SetArg(
00543       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00544 {
00545 // attempt base class first (i.e. passing a string), but if that fails, try a buffer
00546    if ( this->TCStringConverter::SetArg( pyobject, para, func ) )
00547       return kTRUE;
00548 
00549 // apparently failed, try char buffer
00550    PyErr_Clear();
00551    return CArraySetArg( pyobject, para, func, 'c', sizeof(char) );
00552 }
00553 
00554 
00555 //____________________________________________________________________________
00556 Bool_t PyROOT::TVoidArrayConverter::GetAddressSpecialCase( PyObject* pyobject, void*& address )
00557 {
00558 // (1): "null pointer"
00559    if ( pyobject == Py_None ) {
00560       address = (void*)0;
00561       return kTRUE;
00562    }
00563 
00564 // (2): allow integer zero to act as a null pointer, no deriveds
00565    if ( PyInt_CheckExact( pyobject ) || PyLong_CheckExact( pyobject ) ) {
00566       Long_t val = (Long_t)PyLong_AsLong( pyobject );
00567       if ( val == 0l ) {
00568          address = (void*)val;
00569          return kTRUE;
00570       }
00571 
00572       return kFALSE;
00573    }
00574 
00575 // (3): opaque CObject from somewhere
00576    if ( PyCObject_Check( pyobject ) ) {
00577       address = (void*)PyCObject_AsVoidPtr( pyobject );
00578       return kTRUE;
00579    }
00580 
00581    return kFALSE;
00582 }
00583 
00584 //____________________________________________________________________________
00585 Bool_t PyROOT::TVoidArrayConverter::SetArg(
00586       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t user )
00587 {
00588 // just convert pointer if it is a ROOT object
00589    if ( ObjectProxy_Check( pyobject ) ) {
00590    // depending on memory policy, some objects are no longer owned when passed to C++
00591       if ( ! fKeepControl && user != Utility::kStrict )
00592          ((ObjectProxy*)pyobject)->Release();
00593 
00594    // set pointer (may be null) and declare success
00595       para.fv = ((ObjectProxy*)pyobject)->GetObject();
00596       if ( func )
00597          func->SetArg( para.fl );
00598       return kTRUE;
00599    }
00600 
00601 // handle special cases
00602    if ( GetAddressSpecialCase( pyobject, para.fv ) ) {
00603       if ( func )
00604          func->SetArg( para.fl );
00605       return kTRUE;
00606    }
00607 
00608 // final try: attempt to get buffer
00609    int buflen = Utility::GetBuffer( pyobject, '*', 1, para.fv, kFALSE );
00610 
00611 // ok if buffer exists (can't perform any useful size checks)
00612    if ( para.fv && buflen != 0 ) {
00613       if ( func )
00614          func->SetArg( para.fl );
00615       return kTRUE;
00616    }
00617 
00618 // give up
00619    return kFALSE;
00620 }
00621 
00622 //____________________________________________________________________________
00623 PyObject* PyROOT::TVoidArrayConverter::FromMemory( void* address )
00624 {
00625 // nothing sensible can be done, just return <address> as pylong
00626    return PyLong_FromLong( (Long_t)address );
00627 }
00628 
00629 //____________________________________________________________________________
00630 Bool_t PyROOT::TVoidArrayConverter::ToMemory( PyObject* value, void* address )
00631 {
00632 // just convert pointer if it is a ROOT object
00633    if ( ObjectProxy_Check( value ) ) {
00634    // depending on memory policy, some objects are no longer owned when passed to C++
00635       if ( ! fKeepControl && Utility::gMemoryPolicy != Utility::kStrict )
00636          ((ObjectProxy*)value)->Release();
00637 
00638    // set pointer (may be null) and declare success
00639       *(void**)address = ((ObjectProxy*)value)->GetObject();
00640       return kTRUE;
00641    }
00642 
00643 // handle special cases
00644    void* ptr = 0;
00645    if ( GetAddressSpecialCase( value, ptr ) ) {
00646       *(void**)address = ptr;
00647       return kTRUE;
00648    }
00649 
00650 // final try: attempt to get buffer
00651    void* buf = 0;
00652    int buflen = Utility::GetBuffer( value, '*', 1, buf, kFALSE );
00653    if ( ! buf || buflen == 0 )
00654       return kFALSE;
00655 
00656    *(void**)address = buf;
00657    return kTRUE;
00658 }
00659 
00660 //____________________________________________________________________________
00661 #define PYROOT_IMPLEMENT_ARRAY_CONVERTER( name, type, code )                 \
00662 Bool_t PyROOT::T##name##ArrayConverter::SetArg(                              \
00663       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )      \
00664 {                                                                            \
00665    return CArraySetArg( pyobject, para, func, code, sizeof(type) );          \
00666 }                                                                            \
00667                                                                              \
00668 PyObject* PyROOT::T##name##ArrayConverter::FromMemory( void* address )       \
00669 {                                                                            \
00670    return BufFac_t::Instance()->PyBuffer_FromMemory( *(type**)address, fSize );\
00671 }                                                                            \
00672                                                                              \
00673 Bool_t PyROOT::T##name##ArrayConverter::ToMemory( PyObject* value, void* address )\
00674 {                                                                            \
00675    void* buf = 0;                                                            \
00676    int buflen = Utility::GetBuffer( value, code, sizeof(type), buf );        \
00677    if ( ! buf || buflen == 0 )                                               \
00678       return kFALSE;                                                         \
00679    if ( 0 <= fSize ) {                                                       \
00680       if ( fSize < buflen/(int)sizeof(type) ) {                              \
00681          PyErr_SetString( PyExc_ValueError, "buffer too large for value" );  \
00682          return kFALSE;                                                      \
00683       }                                                                      \
00684       memcpy( *(type**)address, buf, 0 < buflen ? ((size_t) buflen) : sizeof(type) );\
00685    } else                                                                    \
00686       *(type**)address = (type*)buf;                                         \
00687    return kTRUE;                                                             \
00688 }
00689 
00690 //____________________________________________________________________________
00691 PYROOT_IMPLEMENT_ARRAY_CONVERTER( Short,  Short_t,  'h' )
00692 PYROOT_IMPLEMENT_ARRAY_CONVERTER( UShort, UShort_t, 'H' )
00693 PYROOT_IMPLEMENT_ARRAY_CONVERTER( Int,    Int_t,    'i' )
00694 PYROOT_IMPLEMENT_ARRAY_CONVERTER( UInt,   UInt_t,   'I' )
00695 PYROOT_IMPLEMENT_ARRAY_CONVERTER( Long,   Long_t,   'l' )
00696 PYROOT_IMPLEMENT_ARRAY_CONVERTER( ULong,  ULong_t,  'L' )
00697 PYROOT_IMPLEMENT_ARRAY_CONVERTER( Float,  Float_t,  'f' )
00698 PYROOT_IMPLEMENT_ARRAY_CONVERTER( Double, Double_t, 'd' )
00699 
00700 //____________________________________________________________________________
00701 Bool_t PyROOT::TLongLongArrayConverter::SetArg(
00702       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t user )
00703 {
00704 // convert <pyobject> to C++ long long*, set arg for call
00705    PyObject* pytc = PyObject_GetAttr( pyobject, PyStrings::gTypeCode );
00706    if ( pytc != 0 ) {              // iow, this array has a known type, but there's no
00707       Py_DECREF( pytc );           // such thing for long long in module array
00708       return kFALSE;
00709    }
00710 
00711    return TVoidArrayConverter::SetArg( pyobject, para, func, user );
00712 }
00713 
00714 
00715 //- converters for special cases ----------------------------------------------
00716 #define PYROOT_IMPLEMENT_STRING_AS_PRIMITIVE_CONVERTER( name, strtype, DF1 )  \
00717 PyROOT::T##name##Converter::T##name##Converter() :                            \
00718       TRootObjectConverter( TClass::GetClass( #strtype ) ) {}                 \
00719                                                                               \
00720 Bool_t PyROOT::T##name##Converter::SetArg(                                    \
00721       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t user )  \
00722 {                                                                             \
00723    if ( PyROOT_PyUnicode_Check( pyobject ) ) {                                \
00724       fBuffer = PyROOT_PyUnicode_AsString( pyobject );                        \
00725       para.fv = &fBuffer;                                                     \
00726       if ( func )                                                             \
00727          func->SetArg( para.fl );                                             \
00728       return kTRUE;                                                           \
00729    }                                                                          \
00730                                                                               \
00731    if ( ! ( PyInt_Check( pyobject ) || PyLong_Check( pyobject ) ) )           \
00732       return TRootObjectConverter::SetArg( pyobject, para, func, user );      \
00733                                                                               \
00734    return kFALSE;                                                             \
00735 }                                                                             \
00736                                                                               \
00737 PyObject* PyROOT::T##name##Converter::FromMemory( void* address )             \
00738 {                                                                             \
00739    if ( address )                                                             \
00740       return PyROOT_PyUnicode_FromString( ((strtype*)address)->DF1() );       \
00741    Py_INCREF( PyStrings::gEmptyString );                                      \
00742    return PyStrings::gEmptyString;                                            \
00743 }                                                                             \
00744                                                                               \
00745 Bool_t PyROOT::T##name##Converter::ToMemory( PyObject* value, void* address ) \
00746 {                                                                             \
00747    if ( PyROOT_PyUnicode_Check( value ) ) {                                   \
00748       *((strtype*)address) = PyROOT_PyUnicode_AsString( value );              \
00749       return kTRUE;                                                           \
00750    }                                                                          \
00751                                                                               \
00752    return TRootObjectConverter::ToMemory( value, address );                   \
00753 }
00754 
00755 PYROOT_IMPLEMENT_STRING_AS_PRIMITIVE_CONVERTER( TString,   TString,     Data )
00756 PYROOT_IMPLEMENT_STRING_AS_PRIMITIVE_CONVERTER( STLString, std::string, c_str )
00757 
00758 //____________________________________________________________________________
00759 Bool_t PyROOT::TRootObjectConverter::SetArg(
00760       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t user )
00761 {
00762 // convert <pyobject> to C++ instance*, set arg for call
00763    if ( ! ObjectProxy_Check( pyobject ) ) {
00764       if ( GetAddressSpecialCase( pyobject, para.fv ) ) {
00765          if ( func )
00766             func->SetArg( para.fl );         // allow special cases such as NULL
00767          return kTRUE;
00768       }
00769 
00770    // not a PyROOT object (TODO: handle SWIG etc.)
00771       return kFALSE;
00772    }
00773 
00774    ObjectProxy* pyobj = (ObjectProxy*)pyobject;
00775    if ( pyobj->ObjectIsA() && pyobj->ObjectIsA()->GetBaseClass( fClass.GetClass() ) ) {
00776    // depending on memory policy, some objects need releasing when passed into functions
00777       if ( ! KeepControl() && user != Utility::kStrict )
00778          ((ObjectProxy*)pyobject)->Release();
00779 
00780    // calculate offset between formal and actual arguments
00781       para.fv = pyobj->GetObject();
00782       G__ClassInfo* clFormalInfo = (G__ClassInfo*)fClass->GetClassInfo();
00783       G__ClassInfo* clActualInfo = (G__ClassInfo*)pyobj->ObjectIsA()->GetClassInfo();
00784       Long_t offset = 0;
00785       if ( clFormalInfo && clActualInfo && clFormalInfo != clActualInfo )
00786          offset = G__isanybase( clFormalInfo->Tagnum(), clActualInfo->Tagnum(), para.fl );
00787 
00788    // set pointer (may be null) and declare success
00789       para.fl += offset;
00790       if ( func )
00791          func->SetArg( para.fl );
00792       return kTRUE;
00793 
00794    } else if ( ! fClass.GetClass()->GetClassInfo() ) {
00795    // assume "user knows best" to allow anonymous pointer passing
00796       para.fv = pyobj->GetObject();
00797       if ( func )
00798          func->SetArg( para.fl );
00799       return kTRUE;
00800    }
00801 
00802    return kFALSE;
00803 }
00804 
00805 //____________________________________________________________________________
00806 PyObject* PyROOT::TRootObjectConverter::FromMemory( void* address )
00807 {
00808 // construct python object from C++ instance read at <address>
00809    return BindRootObject( address, fClass, kFALSE );
00810 }
00811 
00812 //____________________________________________________________________________
00813 Bool_t PyROOT::TRootObjectConverter::ToMemory( PyObject* value, void* address )
00814 {
00815 // convert <value> to C++ instance, write it at <address>
00816    if ( ! ObjectProxy_Check( value ) ) {
00817       void* ptr = 0;
00818       if ( GetAddressSpecialCase( value, ptr ) ) {
00819          *(void**)address = ptr;             // allow special cases such as NULL
00820          return kTRUE;
00821       }
00822 
00823    // not a PyROOT object (TODO: handle SWIG etc.)
00824       return kFALSE;
00825    }
00826 
00827    if ( ((ObjectProxy*)value)->ObjectIsA()->GetBaseClass( fClass.GetClass() ) ) {
00828    // depending on memory policy, some objects need releasing when passed into functions
00829       if ( ! KeepControl() && Utility::gMemoryPolicy != Utility::kStrict )
00830          ((ObjectProxy*)value)->Release();
00831 
00832    // TODO: fix this, as this is sooo wrong ...
00833       memcpy( (void*)address, ((ObjectProxy*)value)->GetObject(), fClass->Size() );
00834       return kTRUE;
00835    }
00836 
00837    return kFALSE;
00838 }
00839 
00840 //____________________________________________________________________________
00841 Bool_t PyROOT::TRootObjectPtrConverter::SetArg(
00842       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t user )
00843 {
00844 // convert <pyobject> to C++ instance**, set arg for call
00845    if ( ! ObjectProxy_Check( pyobject ) )
00846       return kFALSE;              // not a PyROOT object (TODO: handle SWIG etc.)
00847 
00848    if ( ((ObjectProxy*)pyobject)->ObjectIsA()->GetBaseClass( fClass.GetClass() ) ) {
00849    // depending on memory policy, some objects need releasing when passed into functions
00850       if ( ! KeepControl() && user != Utility::kStrict )
00851          ((ObjectProxy*)pyobject)->Release();
00852 
00853    // set pointer (may be null) and declare success
00854       para.fv = &((ObjectProxy*)pyobject)->fObject;
00855       if ( func )
00856          func->SetArg( para.fl );
00857       return kTRUE;
00858    }
00859 
00860    return kFALSE;
00861 }
00862 
00863 //____________________________________________________________________________
00864 PyObject* PyROOT::TRootObjectPtrConverter::FromMemory( void* address )
00865 {
00866 // construct python object from C++ instance* read at <address>
00867    return BindRootObject( address, fClass, kTRUE );
00868 }
00869 
00870 //____________________________________________________________________________
00871 Bool_t PyROOT::TRootObjectPtrConverter::ToMemory( PyObject* value, void* address )
00872 {
00873 // convert <value> to C++ instance*, write it at <address>
00874    if ( ! ObjectProxy_Check( value ) )
00875       return kFALSE;              // not a PyROOT object (TODO: handle SWIG etc.)
00876 
00877    if ( ((ObjectProxy*)value)->ObjectIsA()->GetBaseClass( fClass.GetClass() ) ) {
00878    // depending on memory policy, some objects need releasing when passed into functions
00879       if ( ! KeepControl() && Utility::gMemoryPolicy != Utility::kStrict )
00880          ((ObjectProxy*)value)->Release();
00881 
00882    // set pointer (may be null) and declare success
00883       *(void**)address = ((ObjectProxy*)value)->GetObject();
00884       return kTRUE;
00885    }
00886 
00887    return kFALSE;
00888 }
00889 
00890 //____________________________________________________________________________
00891 Bool_t PyROOT::TVoidPtrRefConverter::SetArg(
00892       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00893 {
00894 // convert <pyobject> to C++ void*&, set arg for call
00895    if ( ObjectProxy_Check( pyobject ) ) {
00896       para.fv = &((ObjectProxy*)pyobject)->fObject;
00897       if ( func )
00898          func->SetArg( para.fl );       // this assumes that CINT will treat void*& as void**
00899       return kTRUE;
00900    }
00901 
00902    return kFALSE;
00903 }
00904 
00905 //____________________________________________________________________________
00906 Bool_t PyROOT::TVoidPtrPtrConverter::SetArg(
00907       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00908 {
00909 // convert <pyobject> to C++ void**, set arg for call
00910    if ( ObjectProxy_Check( pyobject ) ) {
00911    // this is a ROOT object, take and set its address
00912       para.fv = &((ObjectProxy*)pyobject)->fObject;
00913       if ( func )
00914          func->SetArg( para.fl );
00915       return kTRUE;
00916    }
00917 
00918 // buffer objects are allowed under "user knows best"
00919    int buflen = Utility::GetBuffer( pyobject, '*', 1, para.fv, kFALSE );
00920 
00921 // ok if buffer exists (can't perform any useful size checks)
00922    if ( para.fv && buflen != 0 ) {
00923       if ( func )
00924          func->SetArg( para.fl );
00925       return kTRUE;
00926    }
00927 
00928    return kFALSE;
00929 }
00930 
00931 //____________________________________________________________________________
00932 PyObject* PyROOT::TVoidPtrPtrConverter::FromMemory( void* address )
00933 {
00934 // read a void** from address; since this is unknown, long is used (user can cast)
00935    return PyLong_FromLong( (long)*((long**)address) );
00936 }
00937 
00938 //____________________________________________________________________________
00939 Bool_t PyROOT::TPyObjectConverter::SetArg(
00940       PyObject* pyobject, TParameter& para, G__CallFunc* func, Long_t )
00941 {
00942 // by definition: set and declare success
00943    para.fv = pyobject;
00944    if ( func )
00945       func->SetArg( para.fl );
00946    return kTRUE;
00947 }
00948 
00949 PyObject* PyROOT::TPyObjectConverter::FromMemory( void* address )
00950 {
00951 // construct python object from C++ PyObject* read at <address>
00952    PyObject* pyobject = *((PyObject**)address);
00953 
00954    if ( ! pyobject ) {
00955       Py_INCREF( Py_None );
00956       return Py_None;
00957    }
00958 
00959    Py_INCREF( pyobject );
00960    return pyobject;
00961 }
00962 
00963 Bool_t PyROOT::TPyObjectConverter::ToMemory( PyObject* value, void* address )
00964 {
00965 // no conversion needed, write <value> at <address>
00966    Py_INCREF( value );
00967    *((PyObject**)address) = value;
00968    return kTRUE;
00969 }
00970 
00971 
00972 //- factories -----------------------------------------------------------------
00973 PyROOT::TConverter* PyROOT::CreateConverter( const std::string& fullType, Long_t user )
00974 {
00975 // The matching of the fulltype to a converter factory goes through up to five levels:
00976 //   1) full, exact match
00977 //   2) match of decorated, unqualified type
00978 //   3) accept const ref as by value
00979 //   4) accept ref as pointer
00980 //   5) generalized cases (covers basically all ROOT classes)
00981 //
00982 // If all fails, void is used, which will generate a run-time warning when used.
00983 
00984 // resolve typedefs etc.
00985    G__TypeInfo ti( fullType.c_str() );
00986    std::string resolvedType = ti.TrueName();
00987    if ( ! ti.IsValid() )
00988       resolvedType = fullType;     // otherwise, resolvedType will be "(unknown)"
00989 
00990 // an exactly matching converter is preferred
00991    ConvFactories_t::iterator h = gConvFactories.find( resolvedType );
00992    if ( h != gConvFactories.end() )
00993       return (h->second)( user );
00994 
00995 //-- nothing? ok, collect information about the type and possible qualifiers/decorators
00996    const std::string& cpd = Utility::Compound( resolvedType );
00997    std::string realType   = TClassEdit::ShortType( resolvedType.c_str(), 1 );
00998 
00999 // accept unqualified type (as python does not know about qualifiers)
01000    h = gConvFactories.find( realType + cpd );
01001    if ( h != gConvFactories.end() )
01002       return (h->second)( user );
01003 
01004 //-- nothing? collect qualifier information
01005    Bool_t isConst = ti.Property() & G__BIT_ISCONSTANT;
01006 
01007 // accept const <type>& as converter by value (as python copies most types)
01008    if ( isConst && cpd == "&" ) {
01009       h = gConvFactories.find( realType );
01010       if ( h != gConvFactories.end() )
01011          return (h->second)( user );
01012    }
01013 
01014 //-- still nothing? try pointer instead of ref, if ref
01015    if ( cpd == "&" ) {
01016       h = gConvFactories.find( realType + "*" );
01017       if ( h != gConvFactories.end() )
01018          return (h->second)( user );
01019    }
01020 
01021 //-- still nothing? use a generalized converter
01022    Bool_t control = cpd == "&" || isConst;
01023 
01024 // converters for known/ROOT classes and default (void*)
01025    TConverter* result = 0;
01026    if ( TClass* klass = TClass::GetClass( realType.c_str() ) ) {
01027       if ( cpd == "**" || cpd == "*&" || cpd == "&*" )
01028          result = new TRootObjectPtrConverter( klass, control );
01029       else if ( cpd == "*" )
01030          result = new TRootObjectConverter( klass, control );
01031       else if ( cpd == "&" )
01032          result = new TStrictRootObjectConverter( klass, control );
01033       else if ( cpd == "" )               // by value
01034          result = new TStrictRootObjectConverter( klass, kTRUE );
01035 
01036    } else if ( ti.Property() & G__BIT_ISENUM ) {
01037    // special case (CINT): represent enums as unsigned integers
01038       if ( cpd == "&" )
01039          h = gConvFactories.find( "long&" );
01040       else
01041          h = gConvFactories.find( "UInt_t" );
01042    }
01043 
01044    if ( ! result && h != gConvFactories.end() )
01045    // converter factory available, use it to create converter
01046       result = (h->second)( user );
01047    else if ( ! result ) {
01048       if ( cpd != "" ) {
01049          std::stringstream s;
01050          s << "creating converter for unknown type \"" << fullType << "\"" << std::ends;
01051          PyErr_Warn( PyExc_RuntimeWarning, (char*)s.str().c_str() );
01052          result = new TVoidArrayConverter();       // "user knows best"
01053       } else
01054          result = new TVoidConverter();            // fails on use
01055    }
01056 
01057    return result;
01058 }
01059 
01060 //____________________________________________________________________________
01061 #define PYROOT_BASIC_CONVERTER_FACTORY( name )                               \
01062 TConverter* Create##name##Converter( Long_t )                                \
01063 {                                                                            \
01064    return new T##name##Converter();                                          \
01065 }
01066 
01067 #define PYROOT_ARRAY_CONVERTER_FACTORY( name )                               \
01068 TConverter* Create##name##Converter( Long_t user )                           \
01069 {                                                                            \
01070    return new T##name##Converter( (Int_t)user );                             \
01071 }
01072 
01073 //____________________________________________________________________________
01074 namespace {
01075 
01076    using namespace PyROOT;
01077 
01078 // use macro rather than template for portability ...
01079    PYROOT_BASIC_CONVERTER_FACTORY( Bool )
01080    PYROOT_BASIC_CONVERTER_FACTORY( Char )
01081    PYROOT_BASIC_CONVERTER_FACTORY( UChar )
01082    PYROOT_BASIC_CONVERTER_FACTORY( Short )
01083    PYROOT_BASIC_CONVERTER_FACTORY( UShort )
01084    PYROOT_BASIC_CONVERTER_FACTORY( Int )
01085    PYROOT_BASIC_CONVERTER_FACTORY( IntRef )
01086    PYROOT_BASIC_CONVERTER_FACTORY( UInt )
01087    PYROOT_BASIC_CONVERTER_FACTORY( Long )
01088    PYROOT_BASIC_CONVERTER_FACTORY( LongRef )
01089    PYROOT_BASIC_CONVERTER_FACTORY( ConstLongRef )
01090    PYROOT_BASIC_CONVERTER_FACTORY( ULong )
01091    PYROOT_BASIC_CONVERTER_FACTORY( Float )
01092    PYROOT_BASIC_CONVERTER_FACTORY( Double )
01093    PYROOT_BASIC_CONVERTER_FACTORY( DoubleRef )
01094    PYROOT_BASIC_CONVERTER_FACTORY( ConstDoubleRef )
01095    PYROOT_BASIC_CONVERTER_FACTORY( Void )
01096    PYROOT_BASIC_CONVERTER_FACTORY( Macro )
01097    PYROOT_BASIC_CONVERTER_FACTORY( LongLong )
01098    PYROOT_BASIC_CONVERTER_FACTORY( ULongLong )
01099    PYROOT_ARRAY_CONVERTER_FACTORY( CString )
01100    PYROOT_ARRAY_CONVERTER_FACTORY( NonConstCString )
01101    PYROOT_ARRAY_CONVERTER_FACTORY( ShortArray )
01102    PYROOT_ARRAY_CONVERTER_FACTORY( UShortArray )
01103    PYROOT_ARRAY_CONVERTER_FACTORY( IntArray )
01104    PYROOT_ARRAY_CONVERTER_FACTORY( UIntArray )
01105    PYROOT_ARRAY_CONVERTER_FACTORY( LongArray )
01106    PYROOT_ARRAY_CONVERTER_FACTORY( ULongArray )
01107    PYROOT_ARRAY_CONVERTER_FACTORY( FloatArray )
01108    PYROOT_ARRAY_CONVERTER_FACTORY( DoubleArray )
01109    PYROOT_BASIC_CONVERTER_FACTORY( VoidArray )
01110    PYROOT_BASIC_CONVERTER_FACTORY( LongLongArray )
01111    PYROOT_BASIC_CONVERTER_FACTORY( TString )
01112    PYROOT_BASIC_CONVERTER_FACTORY( STLString )
01113    PYROOT_BASIC_CONVERTER_FACTORY( VoidPtrRef )
01114    PYROOT_BASIC_CONVERTER_FACTORY( VoidPtrPtr )
01115    PYROOT_BASIC_CONVERTER_FACTORY( PyObject )
01116 
01117 // converter factories for ROOT types
01118    typedef std::pair< const char*, ConverterFactory_t > NFp_t;
01119 
01120    NFp_t factories_[] = {
01121    // factories for built-ins
01122       NFp_t( "bool",               &CreateBoolConverter               ),
01123       NFp_t( "char",               &CreateCharConverter               ),
01124       NFp_t( "unsigned char",      &CreateUCharConverter              ),
01125       NFp_t( "short",              &CreateShortConverter              ),
01126       NFp_t( "unsigned short",     &CreateUShortConverter             ),
01127       NFp_t( "int",                &CreateIntConverter                ),
01128       NFp_t( "int&",               &CreateIntRefConverter             ),
01129       NFp_t( "const int&",         &CreateIntConverter                ),
01130       NFp_t( "unsigned int",       &CreateUIntConverter               ),
01131       NFp_t( "UInt_t", /* enum */  &CreateUIntConverter               ),
01132       NFp_t( "long",               &CreateLongConverter               ),
01133       NFp_t( "long&",              &CreateLongRefConverter            ),
01134       NFp_t( "const long&",        &CreateConstLongRefConverter       ),
01135       NFp_t( "unsigned long",      &CreateULongConverter              ),
01136       NFp_t( "long long",          &CreateLongLongConverter           ),
01137       NFp_t( "unsigned long long", &CreateULongLongConverter          ),
01138       NFp_t( "float",              &CreateFloatConverter              ),
01139       NFp_t( "double",             &CreateDoubleConverter             ),
01140       NFp_t( "double&",            &CreateDoubleRefConverter          ),
01141       NFp_t( "const double&",      &CreateConstDoubleRefConverter     ),
01142       NFp_t( "void",               &CreateVoidConverter               ),
01143       NFp_t( "#define",            &CreateMacroConverter              ),
01144 
01145    // pointer/array factories
01146       NFp_t( "unsigned char*",     &CreateCStringConverter            ),
01147       NFp_t( "short*",             &CreateShortArrayConverter         ),
01148       NFp_t( "unsigned short*",    &CreateUShortArrayConverter        ),
01149       NFp_t( "int*",               &CreateIntArrayConverter           ),
01150       NFp_t( "unsigned int*",      &CreateUIntArrayConverter          ),
01151       NFp_t( "long*",              &CreateLongArrayConverter          ),
01152       NFp_t( "unsigned long*",     &CreateULongArrayConverter         ),
01153       NFp_t( "float*",             &CreateFloatArrayConverter         ),
01154       NFp_t( "double*",            &CreateDoubleArrayConverter        ),
01155       NFp_t( "long long*",         &CreateLongLongArrayConverter      ),
01156       NFp_t( "void*",              &CreateVoidArrayConverter          ),
01157 
01158    // factories for special cases
01159       NFp_t( "const char*",        &CreateCStringConverter            ),
01160       NFp_t( "char*",              &CreateNonConstCStringConverter    ),
01161       NFp_t( "TString",            &CreateTStringConverter            ),
01162       NFp_t( "TString&",           &CreateTStringConverter            ),
01163       NFp_t( "std::string",        &CreateSTLStringConverter          ),
01164       NFp_t( "string",             &CreateSTLStringConverter          ),
01165       NFp_t( "const std::string&", &CreateSTLStringConverter          ),
01166       NFp_t( "const string&",      &CreateSTLStringConverter          ),
01167       NFp_t( "void*&",             &CreateVoidPtrRefConverter         ),
01168       NFp_t( "void**",             &CreateVoidPtrPtrConverter         ),
01169       NFp_t( "PyObject*",          &CreatePyObjectConverter           ),
01170       NFp_t( "_object*",           &CreatePyObjectConverter           ),
01171       NFp_t( "FILE*",              &CreateVoidArrayConverter          )
01172    };
01173 
01174    struct InitConvFactories_t {
01175    public:
01176       InitConvFactories_t()
01177       {
01178          int nf = sizeof( factories_ ) / sizeof( factories_[ 0 ] );
01179          for ( int i = 0; i < nf; ++i ) {
01180             gConvFactories[ factories_[ i ].first ] = factories_[ i ].second;
01181          }
01182       }
01183    } initConvFactories_;
01184 
01185 } // unnamed namespace

Generated on Tue Jul 5 14:10:12 2011 for ROOT_528-00b_version by  doxygen 1.5.1