00001
00002
00003
00004
00005
00006 #ifndef __CXX_Extensions__h
00007 #define __CXX_Extensions__h
00008
00009
00010 #ifdef _MSC_VER
00011
00012
00013 #pragma warning(disable: 4786)
00014 #endif
00015
00016
00017 #include "Version.hxx"
00018 #include "Config.hxx"
00019 #include "Objects.hxx"
00020
00021 extern "C"
00022 {
00023 extern PyObject py_object_initializer;
00024 }
00025
00026 #include <vector>
00027 #include <map>
00028
00029 namespace Py
00030 {
00031 class ExtensionModuleBase;
00032
00033
00034 class ExtensionExceptionType : public Object
00035 {
00036 public:
00037 ExtensionExceptionType();
00038 virtual ~ExtensionExceptionType();
00039
00040
00041 void init( ExtensionModuleBase &module, const std::string& name, ExtensionExceptionType &parent );
00042 void init( ExtensionModuleBase &module, const std::string& name );
00043 };
00044
00045
00046 class MethodTable
00047 {
00048 public:
00049 MethodTable();
00050 virtual ~MethodTable();
00051
00052 void add(const char* method_name, PyCFunction f, const char* doc="", int flag=1);
00053 PyMethodDef* table();
00054
00055 protected:
00056 std::vector<PyMethodDef> t;
00057 PyMethodDef *mt;
00058
00059 static PyMethodDef method (const char* method_name, PyCFunction f, int flags = 1, const char* doc="");
00060
00061 private:
00062
00063
00064
00065 MethodTable(const MethodTable& m);
00066 void operator=(const MethodTable& m);
00067
00068 };
00069
00070 extern "C"
00071 {
00072 typedef PyObject *(*method_varargs_call_handler_t)( PyObject *_self, PyObject *_args );
00073 typedef PyObject *(*method_keyword_call_handler_t)( PyObject *_self, PyObject *_args, PyObject *_dict );
00074 }
00075
00076 template<class T>
00077 class MethodDefExt : public PyMethodDef
00078 {
00079 public:
00080 typedef Object (T::*method_varargs_function_t)( const Tuple &args );
00081 typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
00082
00083 MethodDefExt
00084 (
00085 const char *_name,
00086 method_varargs_function_t _function,
00087 method_varargs_call_handler_t _handler,
00088 const char *_doc
00089 )
00090 {
00091 ext_meth_def.ml_name = const_cast<char *>(_name);
00092 ext_meth_def.ml_meth = _handler;
00093 ext_meth_def.ml_flags = METH_VARARGS;
00094 ext_meth_def.ml_doc = const_cast<char *>(_doc);
00095
00096 ext_varargs_function = _function;
00097 ext_keyword_function = NULL;
00098 }
00099
00100 MethodDefExt
00101 (
00102 const char *_name,
00103 method_keyword_function_t _function,
00104 method_keyword_call_handler_t _handler,
00105 const char *_doc
00106 )
00107 {
00108 ext_meth_def.ml_name = const_cast<char *>(_name);
00109 ext_meth_def.ml_meth = method_varargs_call_handler_t( _handler );
00110 ext_meth_def.ml_flags = METH_VARARGS|METH_KEYWORDS;
00111 ext_meth_def.ml_doc = const_cast<char *>(_doc);
00112
00113 ext_varargs_function = NULL;
00114 ext_keyword_function = _function;
00115 }
00116
00117 ~MethodDefExt()
00118 {}
00119
00120 PyMethodDef ext_meth_def;
00121 method_varargs_function_t ext_varargs_function;
00122 method_keyword_function_t ext_keyword_function;
00123 };
00124
00125 class ExtensionModuleBase
00126 {
00127 public:
00128 ExtensionModuleBase( const char *name );
00129 virtual ~ExtensionModuleBase();
00130
00131 Module module(void) const;
00132 Dict moduleDictionary(void) const;
00133
00134 virtual Object invoke_method_keyword( const std::string &_name, const Tuple &_args, const Dict &_keywords ) = 0;
00135 virtual Object invoke_method_varargs( const std::string &_name, const Tuple &_args ) = 0;
00136
00137 const std::string &name() const;
00138 const std::string &fullName() const;
00139
00140 protected:
00141
00142 void initialize( const char *module_doc );
00143
00144 const std::string module_name;
00145 const std::string full_module_name;
00146 MethodTable method_table;
00147
00148 private:
00149
00150
00151
00152
00153 ExtensionModuleBase( const ExtensionModuleBase & );
00154 void operator=( const ExtensionModuleBase & );
00155
00156 };
00157
00158 extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords );
00159 extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args );
00160 extern "C" void do_not_dealloc( void * );
00161
00162
00163 template<TEMPLATE_TYPENAME T>
00164 class ExtensionModule : public ExtensionModuleBase
00165 {
00166 public:
00167 ExtensionModule( const char *name )
00168 : ExtensionModuleBase( name )
00169 {}
00170 virtual ~ExtensionModule()
00171 {}
00172
00173 protected:
00174 typedef Object (T::*method_varargs_function_t)( const Tuple &args );
00175 typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
00176 typedef std::map<std::string,MethodDefExt<T> *> method_map_t;
00177
00178 static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
00179 {
00180 method_map_t &mm = methods();
00181
00182 MethodDefExt<T> *method_definition = new MethodDefExt<T>
00183 (
00184 name,
00185 function,
00186 method_varargs_call_handler,
00187 doc
00188 );
00189
00190 mm[std::string( name )] = method_definition;
00191 }
00192
00193 static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
00194 {
00195 method_map_t &mm = methods();
00196
00197 MethodDefExt<T> *method_definition = new MethodDefExt<T>
00198 (
00199 name,
00200 function,
00201 method_keyword_call_handler,
00202 doc
00203 );
00204
00205 mm[std::string( name )] = method_definition;
00206 }
00207
00208 void initialize( const char *module_doc="" )
00209 {
00210 ExtensionModuleBase::initialize( module_doc );
00211 Dict dict( moduleDictionary() );
00212
00213
00214
00215
00216
00217 method_map_t &mm = methods();
00218 EXPLICIT_TYPENAME method_map_t::iterator i;
00219
00220 for( i=mm.begin(); i != mm.end(); ++i )
00221 {
00222 MethodDefExt<T> *method_definition = (*i).second;
00223
00224 static PyObject *self = PyCObject_FromVoidPtr( this, do_not_dealloc );
00225
00226 Tuple args( 2 );
00227 args[0] = Object( self );
00228 args[1] = String( (*i).first );
00229
00230 PyObject *func = PyCFunction_New
00231 (
00232 &method_definition->ext_meth_def,
00233 new_reference_to( args )
00234 );
00235
00236 dict[ (*i).first ] = Object( func );
00237 }
00238 }
00239
00240 protected:
00241
00242 static method_map_t &methods(void)
00243 {
00244 static method_map_t *map_of_methods = NULL;
00245 if( map_of_methods == NULL )
00246 map_of_methods = new method_map_t;
00247
00248 return *map_of_methods;
00249 }
00250
00251
00252
00253 virtual Object invoke_method_keyword( const std::string &name, const Tuple &args, const Dict &keywords )
00254 {
00255 method_map_t &mm = methods();
00256 MethodDefExt<T> *meth_def = mm[ name ];
00257 if( meth_def == NULL )
00258 {
00259 std::string error_msg( "CXX - cannot invoke keyword method named " );
00260 error_msg += name;
00261 throw RuntimeError( error_msg );
00262 }
00263
00264
00265 T *self = static_cast<T *>(this);
00266
00267 return (self->*meth_def->ext_keyword_function)( args, keywords );
00268 }
00269
00270
00271 virtual Object invoke_method_varargs( const std::string &name, const Tuple &args )
00272 {
00273 method_map_t &mm = methods();
00274 MethodDefExt<T> *meth_def = mm[ name ];
00275 if( meth_def == NULL )
00276 {
00277 std::string error_msg( "CXX - cannot invoke varargs method named " );
00278 error_msg += name;
00279 throw RuntimeError( error_msg );
00280 }
00281
00282
00283 T *self = static_cast<T *>(this);
00284
00285 return (self->*meth_def->ext_varargs_function)( args );
00286 }
00287
00288 private:
00289
00290
00291
00292 ExtensionModule( const ExtensionModule<T> & );
00293 void operator=( const ExtensionModule<T> & );
00294 };
00295
00296
00297 class PythonType
00298 {
00299 public:
00300
00301
00302
00303 PythonType (size_t base_size, int itemsize, const char *default_name );
00304 virtual ~PythonType ();
00305
00306 const char *getName () const;
00307 const char *getDoc () const;
00308
00309 PyTypeObject* type_object () const;
00310 void name (const char* nam);
00311 void doc (const char* d);
00312 void dealloc(void (*f)(PyObject*));
00313
00314 void supportPrint(void);
00315 void supportGetattr(void);
00316 void supportSetattr(void);
00317 void supportGetattro(void);
00318 void supportSetattro(void);
00319 void supportCompare(void);
00320 void supportRepr(void);
00321 void supportStr(void);
00322 void supportHash(void);
00323 void supportCall(void);
00324 void supportIter(void);
00325
00326 void supportSequenceType(void);
00327 void supportMappingType(void);
00328 void supportNumberType(void);
00329 void supportBufferType(void);
00330
00331 protected:
00332 PyTypeObject *table;
00333 PySequenceMethods *sequence_table;
00334 PyMappingMethods *mapping_table;
00335 PyNumberMethods *number_table;
00336 PyBufferProcs *buffer_table;
00337
00338 void init_sequence();
00339 void init_mapping();
00340 void init_number();
00341 void init_buffer();
00342
00343 private:
00344
00345
00346
00347 PythonType (const PythonType& tb);
00348 void operator=(const PythonType& t);
00349
00350 };
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 class PythonExtensionBase : public PyObject
00375 {
00376 public:
00377 PythonExtensionBase();
00378 virtual ~PythonExtensionBase();
00379
00380 public:
00381 virtual int print( FILE *, int );
00382 virtual Object getattr( const char * ) = 0;
00383 virtual int setattr( const char *, const Object & );
00384 virtual Object getattro( const Object & );
00385 virtual int setattro( const Object &, const Object & );
00386 virtual int compare( const Object & );
00387 virtual Object repr();
00388 virtual Object str();
00389 virtual long hash();
00390 virtual Object call( const Object &, const Object & );
00391 virtual Object iter();
00392 virtual PyObject* iternext();
00393
00394
00395 virtual int sequence_length();
00396 virtual Object sequence_concat( const Object & );
00397 virtual Object sequence_repeat( int );
00398 virtual Object sequence_item( int );
00399 virtual Object sequence_slice( int, int );
00400 virtual int sequence_ass_item( int, const Object & );
00401 virtual int sequence_ass_slice( int, int, const Object & );
00402
00403
00404 virtual int mapping_length();
00405 virtual Object mapping_subscript( const Object & );
00406 virtual int mapping_ass_subscript( const Object &, const Object & );
00407
00408
00409 virtual int number_nonzero();
00410 virtual Object number_negative();
00411 virtual Object number_positive();
00412 virtual Object number_absolute();
00413 virtual Object number_invert();
00414 virtual Object number_int();
00415 virtual Object number_float();
00416 virtual Object number_long();
00417 virtual Object number_oct();
00418 virtual Object number_hex();
00419 virtual Object number_add( const Object & );
00420 virtual Object number_subtract( const Object & );
00421 virtual Object number_multiply( const Object & );
00422 virtual Object number_divide( const Object & );
00423 virtual Object number_remainder( const Object & );
00424 virtual Object number_divmod( const Object & );
00425 virtual Object number_lshift( const Object & );
00426 virtual Object number_rshift( const Object & );
00427 virtual Object number_and( const Object & );
00428 virtual Object number_xor( const Object & );
00429 virtual Object number_or( const Object & );
00430 virtual Object number_power( const Object &, const Object & );
00431
00432
00433 virtual int buffer_getreadbuffer( int, void** );
00434 virtual int buffer_getwritebuffer( int, void** );
00435 virtual int buffer_getsegcount( int* );
00436
00437 private:
00438 void missing_method( void );
00439 static PyObject *method_call_handler( PyObject *self, PyObject *args );
00440 };
00441
00442 template<TEMPLATE_TYPENAME T>
00443 class PythonExtension: public PythonExtensionBase
00444 {
00445 public:
00446 static PyTypeObject* type_object()
00447 {
00448 return behaviors().type_object();
00449 }
00450
00451 static int check( PyObject *p )
00452 {
00453
00454 return p->ob_type == type_object();
00455 }
00456
00457 static int check( const Object& ob )
00458 {
00459 return check( ob.ptr());
00460 }
00461
00462
00463
00464
00465
00466
00467 virtual Object getattr( const char *name )
00468 {
00469 return getattr_methods( name );
00470 }
00471
00472 protected:
00473 explicit PythonExtension()
00474 : PythonExtensionBase()
00475 {
00476 #ifdef PyObject_INIT
00477 (void)PyObject_INIT( this, type_object() );
00478 #else
00479 ob_refcnt = 1;
00480 ob_type = type_object();
00481 #endif
00482
00483
00484 behaviors().supportGetattr();
00485 }
00486
00487 virtual ~PythonExtension()
00488 {}
00489
00490 static PythonType &behaviors()
00491 {
00492 static PythonType* p;
00493 if( p == NULL )
00494 {
00495 #if defined( _CPPRTTI ) || defined(__GNUG__)
00496 const char *default_name = (typeid ( T )).name();
00497 #else
00498 const char *default_name = "unknown";
00499 #endif
00500 p = new PythonType( sizeof( T ), 0, default_name );
00501 p->dealloc( extension_object_deallocator );
00502 }
00503
00504 return *p;
00505 }
00506
00507
00508 typedef Object (T::*method_varargs_function_t)( const Tuple &args );
00509 typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
00510 typedef std::map<std::string,MethodDefExt<T> *> method_map_t;
00511
00512
00513 virtual Object getattr_default( const char *_name )
00514 {
00515 std::string name( _name );
00516
00517 if( name == "__name__" && type_object()->tp_name != NULL )
00518 {
00519 return Py::String( type_object()->tp_name );
00520 }
00521 if( name == "__doc__" && type_object()->tp_doc != NULL )
00522 {
00523 return Py::String( type_object()->tp_doc );
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 return getattr_methods( _name );
00541 }
00542
00543
00544 virtual Object getattr_methods( const char *_name )
00545 {
00546 std::string name( _name );
00547
00548 method_map_t &mm = methods();
00549
00550 if( name == "__methods__" )
00551 {
00552 List methods;
00553
00554 for( EXPLICIT_TYPENAME method_map_t::iterator i = mm.begin(); i != mm.end(); ++i )
00555 methods.append( String( (*i).first ) );
00556
00557 return methods;
00558 }
00559
00560
00561 if( mm.find( name ) == mm.end() )
00562 throw AttributeError( "method '" + name + "' does not exist." );
00563
00564 Tuple self( 2 );
00565
00566 self[0] = Object( this );
00567 self[1] = String( name );
00568
00569 MethodDefExt<T> *method_definition = mm[ name ];
00570
00571 PyObject *func = PyCFunction_New( &method_definition->ext_meth_def, self.ptr() );
00572
00573 return Object(func, true);
00574 }
00575
00576 static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
00577 {
00578 method_map_t &mm = methods();
00579
00580 MethodDefExt<T> *method_definition = new MethodDefExt<T>
00581 (
00582 name,
00583 function,
00584 method_varargs_call_handler,
00585 doc
00586 );
00587
00588 mm[std::string( name )] = method_definition;
00589 }
00590
00591 static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
00592 {
00593 method_map_t &mm = methods();
00594
00595 MethodDefExt<T> *method_definition = new MethodDefExt<T>
00596 (
00597 name,
00598 function,
00599 method_keyword_call_handler,
00600 doc
00601 );
00602
00603 mm[std::string( name )] = method_definition;
00604 }
00605
00606 private:
00607 static method_map_t &methods(void)
00608 {
00609 static method_map_t *map_of_methods = NULL;
00610 if( map_of_methods == NULL )
00611 map_of_methods = new method_map_t;
00612
00613 return *map_of_methods;
00614 }
00615
00616 static PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords )
00617 {
00618 try
00619 {
00620 Tuple self_and_name_tuple( _self_and_name_tuple );
00621
00622 PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
00623 T *self = static_cast<T *>( self_in_cobject );
00624
00625 String name( self_and_name_tuple[1] );
00626
00627 method_map_t &mm = methods();
00628 MethodDefExt<T> *meth_def = mm[ name ];
00629 if( meth_def == NULL )
00630 return 0;
00631
00632 Tuple args( _args );
00633
00634
00635 Dict keywords;
00636 if( _keywords != NULL )
00637 keywords = Dict( _keywords );
00638
00639 Object result( (self->*meth_def->ext_keyword_function)( args, keywords ) );
00640
00641 return new_reference_to( result.ptr() );
00642 }
00643 catch( Exception & )
00644 {
00645 return 0;
00646 }
00647 }
00648
00649 static PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
00650 {
00651 try
00652 {
00653 Tuple self_and_name_tuple( _self_and_name_tuple );
00654
00655 PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
00656 T *self = static_cast<T *>( self_in_cobject );
00657
00658 String name( self_and_name_tuple[1] );
00659
00660 method_map_t &mm = methods();
00661 MethodDefExt<T> *meth_def = mm[ name ];
00662 if( meth_def == NULL )
00663 return 0;
00664
00665 Tuple args( _args );
00666
00667 Object result;
00668
00669
00670 #ifdef _STLP_DEBUG
00671 try
00672 {
00673 result = (self->*meth_def->ext_varargs_function)( args );
00674 }
00675 catch (std::__stl_debug_exception)
00676 {
00677
00678 throw cxx::RuntimeError( "Error message not set yet." );
00679 }
00680 #else
00681 result = (self->*meth_def->ext_varargs_function)( args );
00682 #endif // _STLP_DEBUG
00683
00684 return new_reference_to( result.ptr() );
00685 }
00686 catch( Exception & )
00687 {
00688 return 0;
00689 }
00690 }
00691
00692 static void extension_object_deallocator ( PyObject* t )
00693 {
00694 delete (T *)( t );
00695 }
00696
00697
00698
00699
00700 explicit PythonExtension( const PythonExtension<T>& other );
00701 void operator=( const PythonExtension<T>& rhs );
00702 };
00703
00704
00705
00706
00707 template<TEMPLATE_TYPENAME T>
00708 class ExtensionObject: public Object
00709 {
00710 public:
00711
00712 explicit ExtensionObject ( PyObject *pyob )
00713 : Object( pyob )
00714 {
00715 validate();
00716 }
00717
00718 ExtensionObject( const ExtensionObject<T>& other )
00719 : Object( *other )
00720 {
00721 validate();
00722 }
00723
00724 ExtensionObject( const Object& other )
00725 : Object( *other )
00726 {
00727 validate();
00728 }
00729
00730 ExtensionObject& operator= ( const Object& rhs )
00731 {
00732 return (*this = *rhs );
00733 }
00734
00735 ExtensionObject& operator= ( PyObject* rhsp )
00736 {
00737 if( ptr() == rhsp )
00738 return *this;
00739 set( rhsp );
00740 return *this;
00741 }
00742
00743 virtual bool accepts ( PyObject *pyob ) const
00744 {
00745 return ( pyob && T::check( pyob ));
00746 }
00747
00748
00749
00750
00751 T *extensionObject(void)
00752 {
00753 return static_cast<T *>( ptr() );
00754 }
00755 };
00756
00757 }
00758
00759 #endif