~valavanisalex/ubuntu/oneiric/inkscape/inkscape_0.48.1-2ubuntu4

« back to all changes in this revision

Viewing changes to src/extension/script/CXX/Extensions.hxx

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook, Ted Gould, Kees Cook
  • Date: 2009-06-24 14:00:43 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20090624140043-07stp20mry48hqup
Tags: 0.47~pre0-0ubuntu1
* New upstream release

[ Ted Gould ]
* debian/control: Adding libgsl0 and removing version specifics on boost

[ Kees Cook ]
* debian/watch: updated to run uupdate and mangle pre-release versions.
* Dropped patches that have been taken upstream:
  - 01_mips
  - 02-poppler-0.8.3
  - 03-chinese-inkscape
  - 05_fix_latex_patch
  - 06_gcc-4.4
  - 07_cdr2svg
  - 08_skip-bad-utf-on-pdf-import
  - 09_gtk-clist
  - 10_belarussian
  - 11_libpng
  - 12_desktop
  - 13_slider
  - 100_svg_import_improvements
  - 102_sp_pattern_painter_free
  - 103_bitmap_type_print

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//-----------------------------------------------------------------------------
2
 
//
3
 
// Copyright (c) 1998 - 2007, The Regents of the University of California
4
 
// Produced at the Lawrence Livermore National Laboratory
5
 
// All rights reserved.
6
 
//
7
 
// This file is part of PyCXX. For details,see http://cxx.sourceforge.net/. The
8
 
// full copyright notice is contained in the file COPYRIGHT located at the root
9
 
// of the PyCXX distribution.
10
 
//
11
 
// Redistribution  and  use  in  source  and  binary  forms,  with  or  without
12
 
// modification, are permitted provided that the following conditions are met:
13
 
//
14
 
//  - Redistributions of  source code must  retain the above  copyright notice,
15
 
//    this list of conditions and the disclaimer below.
16
 
//  - Redistributions in binary form must reproduce the above copyright notice,
17
 
//    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
18
 
//    documentation and/or materials provided with the distribution.
19
 
//  - Neither the name of the UC/LLNL nor  the names of its contributors may be
20
 
//    used to  endorse or  promote products derived from  this software without
21
 
//    specific prior written permission.
22
 
//
23
 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
24
 
// AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
25
 
// IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
26
 
// ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  REGENTS  OF  THE  UNIVERSITY OF
27
 
// CALIFORNIA, THE U.S.  DEPARTMENT  OF  ENERGY OR CONTRIBUTORS BE  LIABLE  FOR
28
 
// ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL
29
 
// DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
30
 
// SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
31
 
// CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
32
 
// LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
33
 
// OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
34
 
// DAMAGE.
35
 
//
36
 
//-----------------------------------------------------------------------------
37
 
 
38
 
#ifndef __CXX_Extensions__h
39
 
#define __CXX_Extensions__h
40
 
 
41
 
 
42
 
#ifdef _MSC_VER
43
 
// disable warning C4786: symbol greater than 255 character,
44
 
// okay to ignore
45
 
#pragma warning(disable: 4786)
46
 
#endif
47
 
 
48
 
#include "CXX/WrapPython.h"
49
 
#include "CXX/Version.hxx"
50
 
#include "CXX/Config.hxx"
51
 
#include "CXX/Objects.hxx"
52
 
 
53
 
extern "C"
54
 
{
55
 
    extern PyObject py_object_initializer;
56
 
}
57
 
 
58
 
#include <vector>
59
 
#include <map>
60
 
 
61
 
namespace Py
62
 
{
63
 
    class ExtensionModuleBase;
64
 
    
65
 
    // Make an Exception Type for use in raising custom exceptions
66
 
    class ExtensionExceptionType : public Object
67
 
    {
68
 
    public:
69
 
        ExtensionExceptionType();
70
 
        virtual ~ExtensionExceptionType();
71
 
 
72
 
        // call init to create the type
73
 
        void init(  ExtensionModuleBase &module, const std::string& name, ExtensionExceptionType &parent );
74
 
        void init(  ExtensionModuleBase &module, const std::string& name );
75
 
    };
76
 
 
77
 
    
78
 
    class MethodTable 
79
 
    {
80
 
    public:
81
 
        MethodTable();
82
 
        virtual ~MethodTable();
83
 
        
84
 
        void add(const char* method_name, PyCFunction f, const char* doc="", int flag=1);
85
 
        PyMethodDef* table();
86
 
        
87
 
    protected:
88
 
        std::vector<PyMethodDef> t;    // accumulator of PyMethodDef's
89
 
        PyMethodDef *mt;        // Actual method table produced when full
90
 
        
91
 
        static PyMethodDef method (const char* method_name, PyCFunction f, int flags = 1, const char* doc="");
92
 
        
93
 
    private:
94
 
        //
95
 
        // prevent the compiler generating these unwanted functions
96
 
        //
97
 
        MethodTable(const MethodTable& m);    //unimplemented
98
 
        void operator=(const MethodTable& m);    //unimplemented
99
 
        
100
 
    }; // end class MethodTable
101
 
    
102
 
    extern "C"
103
 
    {
104
 
        typedef PyObject *(*method_varargs_call_handler_t)( PyObject *_self, PyObject *_args );
105
 
        typedef PyObject *(*method_keyword_call_handler_t)( PyObject *_self, PyObject *_args, PyObject *_dict );
106
 
    };
107
 
    
108
 
    template<class T>
109
 
    class MethodDefExt : public PyMethodDef
110
 
    {
111
 
    public:
112
 
        typedef Object (T::*method_varargs_function_t)( const Tuple &args );
113
 
        typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
114
 
        
115
 
        MethodDefExt
116
 
        (
117
 
        const char *_name,
118
 
        method_varargs_function_t _function,
119
 
        method_varargs_call_handler_t _handler,
120
 
        const char *_doc
121
 
        )
122
 
        {
123
 
            ext_meth_def.ml_name = const_cast<char *>(_name);
124
 
            ext_meth_def.ml_meth = _handler;
125
 
            ext_meth_def.ml_flags = METH_VARARGS;
126
 
            ext_meth_def.ml_doc = const_cast<char *>(_doc);
127
 
            
128
 
            ext_varargs_function = _function;
129
 
            ext_keyword_function = NULL;
130
 
        }
131
 
        
132
 
        MethodDefExt
133
 
        (
134
 
        const char *_name,
135
 
        method_keyword_function_t _function,
136
 
        method_keyword_call_handler_t _handler,
137
 
        const char *_doc
138
 
        )
139
 
        {
140
 
            ext_meth_def.ml_name = const_cast<char *>(_name);
141
 
            ext_meth_def.ml_meth = method_varargs_call_handler_t( _handler );
142
 
            ext_meth_def.ml_flags = METH_VARARGS|METH_KEYWORDS;
143
 
            ext_meth_def.ml_doc = const_cast<char *>(_doc);
144
 
            
145
 
            ext_varargs_function = NULL;
146
 
            ext_keyword_function = _function;
147
 
        }
148
 
        
149
 
        ~MethodDefExt()
150
 
        {}
151
 
        
152
 
        PyMethodDef ext_meth_def;
153
 
        method_varargs_function_t ext_varargs_function;    
154
 
        method_keyword_function_t ext_keyword_function;    
155
 
    };
156
 
    
157
 
    class ExtensionModuleBase
158
 
    {
159
 
    public:
160
 
        ExtensionModuleBase( const char *name );
161
 
        virtual ~ExtensionModuleBase();
162
 
        
163
 
        Module module(void) const;        // only valid after initialize() has been called
164
 
        Dict moduleDictionary(void) const;    // only valid after initialize() has been called
165
 
        
166
 
        virtual Object invoke_method_keyword( const std::string &_name, const Tuple &_args, const Dict &_keywords ) = 0;
167
 
        virtual Object invoke_method_varargs( const std::string &_name, const Tuple &_args ) = 0;
168
 
        
169
 
        const std::string &name() const;
170
 
        const std::string &fullName() const;
171
 
    
172
 
    protected:
173
 
        // Initialize the module
174
 
        void initialize( const char *module_doc );
175
 
        
176
 
        const std::string module_name;
177
 
        const std::string full_module_name;
178
 
        MethodTable method_table;
179
 
        
180
 
    private:
181
 
        
182
 
        //
183
 
        // prevent the compiler generating these unwanted functions
184
 
        //
185
 
        ExtensionModuleBase( const ExtensionModuleBase & );    //unimplemented
186
 
        void operator=( const ExtensionModuleBase & );        //unimplemented
187
 
        
188
 
    };
189
 
    
190
 
    extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords );
191
 
    extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args );
192
 
    extern "C" void do_not_dealloc( void * );
193
 
    
194
 
    
195
 
    template<TEMPLATE_TYPENAME T>
196
 
    class ExtensionModule : public ExtensionModuleBase
197
 
    {
198
 
    public:
199
 
        ExtensionModule( const char *name )
200
 
            : ExtensionModuleBase( name )
201
 
        {}
202
 
        virtual ~ExtensionModule()
203
 
        {}
204
 
        
205
 
    protected:
206
 
        typedef Object (T::*method_varargs_function_t)( const Tuple &args );
207
 
        typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
208
 
        typedef std::map<std::string,MethodDefExt<T> *> method_map_t;
209
 
        
210
 
        static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
211
 
        {
212
 
            method_map_t &mm = methods();
213
 
            
214
 
            MethodDefExt<T> *method_definition = new MethodDefExt<T>
215
 
            (
216
 
            name,
217
 
            function,
218
 
            method_varargs_call_handler,
219
 
            doc
220
 
            );
221
 
            
222
 
            mm[std::string( name )] = method_definition;
223
 
        }
224
 
        
225
 
        static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
226
 
        {
227
 
            method_map_t &mm = methods();
228
 
            
229
 
            MethodDefExt<T> *method_definition = new MethodDefExt<T>
230
 
            (
231
 
            name,
232
 
            function,
233
 
            method_keyword_call_handler,
234
 
            doc
235
 
            );
236
 
            
237
 
            mm[std::string( name )] = method_definition;
238
 
        }
239
 
 
240
 
        void initialize( const char *module_doc="" )
241
 
        {
242
 
            ExtensionModuleBase::initialize( module_doc );
243
 
            Dict dict( moduleDictionary() );
244
 
            
245
 
            //
246
 
            // put each of the methods into the modules dictionary
247
 
            // so that we get called back at the function in T.
248
 
            //
249
 
            method_map_t &mm = methods();
250
 
            EXPLICIT_TYPENAME method_map_t::iterator i;
251
 
            
252
 
            for( i=mm.begin(); i != mm.end(); ++i )
253
 
            {
254
 
                MethodDefExt<T> *method_definition = (*i).second;
255
 
                
256
 
                static PyObject *self = PyCObject_FromVoidPtr( this, do_not_dealloc );
257
 
                
258
 
                Tuple args( 2 );
259
 
                args[0] = Object( self );
260
 
                args[1] = String( (*i).first );
261
 
                
262
 
                PyObject *func = PyCFunction_New
263
 
                (
264
 
                &method_definition->ext_meth_def,
265
 
                new_reference_to( args )
266
 
                );
267
 
                
268
 
                dict[ (*i).first ] = Object( func );
269
 
            }
270
 
        }
271
 
        
272
 
    protected:    // Tom Malcolmson reports that derived classes need access to these
273
 
        
274
 
        static method_map_t &methods(void)
275
 
        {
276
 
            static method_map_t *map_of_methods = NULL;
277
 
            if( map_of_methods == NULL )
278
 
            map_of_methods = new method_map_t;
279
 
            
280
 
            return *map_of_methods;
281
 
        }
282
 
        
283
 
        
284
 
        // this invoke function must be called from within a try catch block
285
 
        virtual Object invoke_method_keyword( const std::string &name, const Tuple &args, const Dict &keywords )
286
 
        {
287
 
            method_map_t &mm = methods();
288
 
            MethodDefExt<T> *meth_def = mm[ name ];
289
 
            if( meth_def == NULL )
290
 
            {
291
 
                std::string error_msg( "CXX - cannot invoke keyword method named " );
292
 
                error_msg += name;
293
 
                throw RuntimeError( error_msg );
294
 
            }
295
 
            
296
 
            // cast up to the derived class
297
 
            T *self = static_cast<T *>(this);
298
 
            
299
 
            return (self->*meth_def->ext_keyword_function)( args, keywords );
300
 
        }
301
 
        
302
 
        // this invoke function must be called from within a try catch block
303
 
        virtual Object invoke_method_varargs( const std::string &name, const Tuple &args )
304
 
        {
305
 
            method_map_t &mm = methods();
306
 
            MethodDefExt<T> *meth_def = mm[ name ];
307
 
            if( meth_def == NULL )
308
 
            {
309
 
                std::string error_msg( "CXX - cannot invoke varargs method named " );
310
 
                error_msg += name;
311
 
                throw RuntimeError( error_msg );
312
 
            }
313
 
            
314
 
            // cast up to the derived class
315
 
            T *self = static_cast<T *>(this);
316
 
            
317
 
            return (self->*meth_def->ext_varargs_function)( args );
318
 
        }
319
 
        
320
 
    private:
321
 
        //
322
 
        // prevent the compiler generating these unwanted functions
323
 
        //
324
 
        ExtensionModule( const ExtensionModule<T> & );    //unimplemented
325
 
        void operator=( const ExtensionModule<T> & );    //unimplemented
326
 
    };
327
 
    
328
 
    
329
 
    class PythonType
330
 
    {
331
 
    public:
332
 
        // if you define one sequence method you must define 
333
 
        // all of them except the assigns
334
 
        
335
 
        PythonType (size_t base_size, int itemsize, const char *default_name );
336
 
        virtual ~PythonType ();
337
 
        
338
 
        const char *getName () const;
339
 
        const char *getDoc () const;
340
 
 
341
 
        PyTypeObject* type_object () const;
342
 
        PythonType & name (const char* nam);
343
 
        PythonType & doc (const char* d);
344
 
        PythonType & dealloc(void (*f)(PyObject*));
345
 
        
346
 
        PythonType & supportPrint(void);
347
 
        PythonType & supportGetattr(void);
348
 
        PythonType & supportSetattr(void);
349
 
        PythonType & supportGetattro(void);
350
 
        PythonType & supportSetattro(void);
351
 
        PythonType & supportCompare(void);
352
 
        PythonType & supportRepr(void);
353
 
        PythonType & supportStr(void);
354
 
        PythonType & supportHash(void);
355
 
        PythonType & supportCall(void);
356
 
        PythonType & supportIter(void);
357
 
        
358
 
        PythonType & supportSequenceType(void);
359
 
        PythonType & supportMappingType(void);
360
 
        PythonType & supportNumberType(void);
361
 
        PythonType & supportBufferType(void);
362
 
        
363
 
    protected:
364
 
        PyTypeObject        *table;
365
 
        PySequenceMethods    *sequence_table;
366
 
        PyMappingMethods    *mapping_table;
367
 
        PyNumberMethods        *number_table;
368
 
        PyBufferProcs        *buffer_table;
369
 
        
370
 
        void init_sequence();
371
 
        void init_mapping();
372
 
        void init_number();
373
 
        void init_buffer();
374
 
        
375
 
    private:
376
 
        //
377
 
        // prevent the compiler generating these unwanted functions
378
 
        //
379
 
        PythonType (const PythonType& tb);    // unimplemented
380
 
        void operator=(const PythonType& t);    // unimplemented
381
 
        
382
 
    }; // end of PythonType
383
 
    
384
 
    
385
 
    
386
 
    // Class PythonExtension is what you inherit from to create
387
 
    // a new Python extension type. You give your class itself
388
 
    // as the template paramter.
389
 
    
390
 
    // There are two ways that extension objects can get destroyed.
391
 
    // 1. Their reference count goes to zero
392
 
    // 2. Someone does an explicit delete on a pointer.
393
 
    // In (1) the problem is to get the destructor called 
394
 
    //        We register a special deallocator in the Python type object
395
 
    //        (see behaviors()) to do this.
396
 
    // In (2) there is no problem, the dtor gets called.
397
 
    
398
 
    // PythonExtension does not use the usual Python heap allocator, 
399
 
    // instead using new/delete. We do the setting of the type object
400
 
    // and reference count, usually done by PyObject_New, in the 
401
 
    // base class ctor.
402
 
    
403
 
    // This special deallocator does a delete on the pointer.
404
 
    
405
 
    
406
 
    class PythonExtensionBase : public PyObject
407
 
    {
408
 
    public:
409
 
        PythonExtensionBase();
410
 
        virtual ~PythonExtensionBase();
411
 
        
412
 
    public:
413
 
        virtual int print( FILE *, int );
414
 
        virtual Object getattr( const char * ) = 0;
415
 
        virtual int setattr( const char *, const Object & );
416
 
        virtual Object getattro( const Object & );
417
 
        virtual int setattro( const Object &, const Object & );
418
 
        virtual int compare( const Object & );
419
 
        virtual Object repr();
420
 
        virtual Object str();
421
 
        virtual long hash();
422
 
        virtual Object call( const Object &, const Object & );
423
 
                virtual Object iter();
424
 
                virtual PyObject* iternext();
425
 
        
426
 
        // Sequence methods
427
 
        virtual int sequence_length();
428
 
        virtual Object sequence_concat( const Object & );
429
 
        virtual Object sequence_repeat( Py_ssize_t );
430
 
        virtual Object sequence_item( Py_ssize_t );
431
 
        virtual Object sequence_slice( Py_ssize_t, Py_ssize_t );
432
 
        virtual int sequence_ass_item( Py_ssize_t, const Object & );
433
 
        virtual int sequence_ass_slice( Py_ssize_t, Py_ssize_t, const Object & );
434
 
        
435
 
        // Mapping
436
 
        virtual int mapping_length();
437
 
        virtual Object mapping_subscript( const Object & );
438
 
        virtual int mapping_ass_subscript( const Object &, const Object & );
439
 
        
440
 
        // Number
441
 
        virtual int number_nonzero();
442
 
        virtual Object number_negative();
443
 
        virtual Object number_positive();
444
 
        virtual Object number_absolute();
445
 
        virtual Object number_invert();
446
 
        virtual Object number_int();
447
 
        virtual Object number_float();
448
 
        virtual Object number_long();
449
 
        virtual Object number_oct();
450
 
        virtual Object number_hex();
451
 
        virtual Object number_add( const Object & );
452
 
        virtual Object number_subtract( const Object & );
453
 
        virtual Object number_multiply( const Object & );
454
 
        virtual Object number_divide( const Object & );
455
 
        virtual Object number_remainder( const Object & );
456
 
        virtual Object number_divmod( const Object & );
457
 
        virtual Object number_lshift( const Object & );
458
 
        virtual Object number_rshift( const Object & );
459
 
        virtual Object number_and( const Object & );
460
 
        virtual Object number_xor( const Object & );
461
 
        virtual Object number_or( const Object & );
462
 
        virtual Object number_power( const Object &, const Object & );
463
 
        
464
 
        // Buffer
465
 
        virtual Py_ssize_t buffer_getreadbuffer( Py_ssize_t, void** );
466
 
        virtual Py_ssize_t buffer_getwritebuffer( Py_ssize_t, void** );
467
 
        virtual Py_ssize_t buffer_getsegcount( Py_ssize_t* );
468
 
        
469
 
    private:
470
 
        void missing_method( void );
471
 
        static PyObject *method_call_handler( PyObject *self, PyObject *args );
472
 
    };
473
 
    
474
 
    template<TEMPLATE_TYPENAME T>
475
 
    class PythonExtension: public PythonExtensionBase 
476
 
    {
477
 
    public:
478
 
        static PyTypeObject* type_object() 
479
 
        {
480
 
            return behaviors().type_object();
481
 
        }
482
 
        
483
 
        static int check( PyObject *p )
484
 
        {
485
 
            // is p like me?
486
 
            return p->ob_type == type_object();
487
 
        }
488
 
        
489
 
        static int check( const Object& ob )
490
 
        {
491
 
            return check( ob.ptr());
492
 
        }
493
 
        
494
 
        
495
 
        //
496
 
        // every object needs getattr implemented
497
 
        // to support methods
498
 
        //
499
 
        virtual Object getattr( const char *name )
500
 
        {
501
 
            return getattr_methods( name );
502
 
        }
503
 
        
504
 
    protected:
505
 
        explicit PythonExtension()
506
 
            : PythonExtensionBase()
507
 
        {
508
 
            #ifdef PyObject_INIT
509
 
            (void)PyObject_INIT( this, type_object() );
510
 
            #else
511
 
            ob_refcnt = 1;
512
 
            ob_type = type_object();
513
 
            #endif
514
 
            
515
 
            // every object must support getattr
516
 
            behaviors().supportGetattr();
517
 
        }
518
 
        
519
 
        virtual ~PythonExtension()
520
 
        {} 
521
 
        
522
 
        static PythonType &behaviors()
523
 
        {
524
 
            static PythonType* p;
525
 
            if( p == NULL ) 
526
 
            {
527
 
#if defined( _CPPRTTI ) || defined(__GNUG__)
528
 
                const char *default_name = (typeid ( T )).name();
529
 
#else
530
 
                const char *default_name = "unknown";
531
 
#endif
532
 
                p = new PythonType( sizeof( T ), 0, default_name );
533
 
                p->dealloc( extension_object_deallocator );
534
 
            }
535
 
            
536
 
            return *p;
537
 
        }
538
 
        
539
 
        
540
 
        typedef Object (T::*method_varargs_function_t)( const Tuple &args );
541
 
        typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
542
 
        typedef std::map<std::string,MethodDefExt<T> *> method_map_t;
543
 
        
544
 
        // support the default attributes, __name__, __doc__ and methods
545
 
        virtual Object getattr_default( const char *_name )
546
 
        {
547
 
            std::string name( _name );
548
 
 
549
 
            if( name == "__name__" && type_object()->tp_name != NULL )
550
 
            {
551
 
                return Py::String( type_object()->tp_name );
552
 
            }
553
 
            if( name == "__doc__" && type_object()->tp_doc != NULL )
554
 
            {
555
 
                return Py::String( type_object()->tp_doc );
556
 
            }
557
 
 
558
 
// trying to fake out being a class for help()
559
 
//            else if( name == "__bases__"  )
560
 
//            {
561
 
//                return Py::Tuple(0);
562
 
//            }
563
 
//            else if( name == "__module__"  )
564
 
//            {
565
 
//                return Py::Nothing();
566
 
//            }
567
 
//            else if( name == "__dict__"  )
568
 
//            {
569
 
//                return Py::Dict();
570
 
//            }
571
 
 
572
 
            return getattr_methods( _name );
573
 
        }
574
 
 
575
 
        // turn a name into function object
576
 
        virtual Object getattr_methods( const char *_name )
577
 
        {
578
 
            std::string name( _name );
579
 
            
580
 
            method_map_t &mm = methods();
581
 
            
582
 
            if( name == "__methods__" )
583
 
            {
584
 
                List methods;
585
 
                
586
 
                for( EXPLICIT_TYPENAME method_map_t::iterator i = mm.begin(); i != mm.end(); ++i )
587
 
                    methods.append( String( (*i).first ) );
588
 
                
589
 
                return methods;
590
 
            }
591
 
            
592
 
            // see if name exists
593
 
            if( mm.find( name ) == mm.end() )
594
 
                throw AttributeError( name );
595
 
            
596
 
            Tuple self( 2 );
597
 
            
598
 
            self[0] = Object( this );
599
 
            self[1] = String( name );
600
 
            
601
 
            MethodDefExt<T> *method_definition = mm[ name ];
602
 
            
603
 
            PyObject *func = PyCFunction_New( &method_definition->ext_meth_def, self.ptr() );
604
 
            
605
 
            return Object(func, true);
606
 
        }
607
 
        
608
 
        static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
609
 
        {
610
 
            method_map_t &mm = methods();
611
 
            
612
 
            MethodDefExt<T> *method_definition = new MethodDefExt<T>
613
 
            (
614
 
            name,
615
 
            function,
616
 
            method_varargs_call_handler,
617
 
            doc
618
 
            );
619
 
            
620
 
            mm[std::string( name )] = method_definition;
621
 
        }
622
 
        
623
 
        static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
624
 
        {
625
 
            method_map_t &mm = methods();
626
 
            
627
 
            MethodDefExt<T> *method_definition = new MethodDefExt<T>
628
 
            (
629
 
            name,
630
 
            function,
631
 
            method_keyword_call_handler,
632
 
            doc
633
 
            );
634
 
            
635
 
            mm[std::string( name )] = method_definition;
636
 
        }
637
 
        
638
 
    private:
639
 
        static method_map_t &methods(void)
640
 
        {
641
 
            static method_map_t *map_of_methods = NULL;
642
 
            if( map_of_methods == NULL )
643
 
            map_of_methods = new method_map_t;
644
 
            
645
 
            return *map_of_methods;
646
 
        }
647
 
        
648
 
        static PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords )
649
 
        {
650
 
            try
651
 
            {
652
 
                Tuple self_and_name_tuple( _self_and_name_tuple );
653
 
                
654
 
                PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
655
 
                T *self = static_cast<T *>( self_in_cobject );
656
 
                
657
 
                String name( self_and_name_tuple[1] );
658
 
                
659
 
                method_map_t &mm = methods();
660
 
                MethodDefExt<T> *meth_def = mm[ name ];
661
 
                if( meth_def == NULL )
662
 
                    return 0;
663
 
                
664
 
                Tuple args( _args );
665
 
 
666
 
                // _keywords may be NULL so be careful about the way the dict is created
667
 
                Dict keywords;
668
 
                if( _keywords != NULL )
669
 
                    keywords = Dict( _keywords );
670
 
                
671
 
                Object result( (self->*meth_def->ext_keyword_function)( args, keywords ) );
672
 
                
673
 
                return new_reference_to( result.ptr() );
674
 
            }
675
 
            catch( Exception & )
676
 
            {
677
 
                return 0;
678
 
            }
679
 
        }
680
 
        
681
 
        static PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
682
 
        {
683
 
            try
684
 
            {
685
 
                Tuple self_and_name_tuple( _self_and_name_tuple );
686
 
                
687
 
                PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
688
 
                T *self = static_cast<T *>( self_in_cobject );
689
 
                
690
 
                String name( self_and_name_tuple[1] );
691
 
                
692
 
                method_map_t &mm = methods();
693
 
                MethodDefExt<T> *meth_def = mm[ name ];
694
 
                if( meth_def == NULL )
695
 
                    return 0;
696
 
                
697
 
                Tuple args( _args );
698
 
                
699
 
                Object result;
700
 
                
701
 
                // TMM: 7Jun'01 - Adding try & catch in case of STL debug-mode exceptions.
702
 
                #ifdef _STLP_DEBUG
703
 
                try
704
 
                {
705
 
                    result = (self->*meth_def->ext_varargs_function)( args );
706
 
                }
707
 
                catch (std::__stl_debug_exception)
708
 
                {
709
 
                    // throw cxx::RuntimeError( sErrMsg );
710
 
                    throw cxx::RuntimeError( "Error message not set yet." );
711
 
                }
712
 
                #else
713
 
                result = (self->*meth_def->ext_varargs_function)( args );
714
 
                #endif // _STLP_DEBUG
715
 
                
716
 
                return new_reference_to( result.ptr() );
717
 
            }
718
 
            catch( Exception & )
719
 
            {
720
 
                return 0;
721
 
            }
722
 
        }
723
 
        
724
 
        static void extension_object_deallocator ( PyObject* t )
725
 
        {
726
 
            delete (T *)( t );
727
 
        }
728
 
        
729
 
        //
730
 
        // prevent the compiler generating these unwanted functions
731
 
        //
732
 
        explicit PythonExtension( const PythonExtension<T>& other );
733
 
        void operator=( const PythonExtension<T>& rhs );
734
 
    };
735
 
    
736
 
    //
737
 
    // ExtensionObject<T> is an Object that will accept only T's.
738
 
    //
739
 
    template<TEMPLATE_TYPENAME T>
740
 
    class ExtensionObject: public Object
741
 
    {
742
 
    public:
743
 
        
744
 
        explicit ExtensionObject ( PyObject *pyob )
745
 
            : Object( pyob )
746
 
        {
747
 
            validate();
748
 
        }
749
 
        
750
 
        ExtensionObject( const ExtensionObject<T>& other )
751
 
            : Object( *other )
752
 
        {
753
 
            validate();
754
 
        }
755
 
        
756
 
        ExtensionObject( const Object& other )
757
 
            : Object( *other )
758
 
        {
759
 
            validate();
760
 
        }
761
 
        
762
 
        ExtensionObject& operator= ( const Object& rhs )
763
 
        {
764
 
            return (*this = *rhs );
765
 
        }
766
 
        
767
 
        ExtensionObject& operator= ( PyObject* rhsp )
768
 
        {
769
 
            if( ptr() == rhsp )
770
 
            return *this;
771
 
            set( rhsp );
772
 
            return *this;
773
 
        }
774
 
        
775
 
        virtual bool accepts ( PyObject *pyob ) const
776
 
        {
777
 
            return ( pyob && T::check( pyob ));
778
 
        }       
779
 
        
780
 
        //
781
 
        //    Obtain a pointer to the PythonExtension object
782
 
        //
783
 
        T *extensionObject(void)
784
 
        {
785
 
            return static_cast<T *>( ptr() );
786
 
        }
787
 
    };
788
 
    
789
 
} // Namespace Py
790
 
// End of CXX_Extensions.h
791
 
#endif