PyXR

c:\python24\lib\site-packages\win32 \ com \ makegw \ makegwenum.py



0001 """Utility file for generating PyIEnum support.
0002 
0003 This is almost a 'template' file.  It simplay contains almost full
0004 C++ source code for PyIEnum* support, and the Python code simply
0005 substitutes the appropriate interface name.
0006 
0007 This module is notmally not used directly - the @makegw@ module
0008 automatically calls this.
0009 """
0010 #
0011 # INTERNAL FUNCTIONS
0012 #
0013 #
0014 import string
0015 
0016 def is_interface_enum(enumtype):
0017   return not (enumtype[0] in string.uppercase and enumtype[2] in string.uppercase)
0018 
0019 
0020 def _write_enumifc_cpp(f, interface):
0021   enumtype = interface.name[5:]
0022   if is_interface_enum(enumtype):
0023     # Assume an interface.
0024     enum_interface = "I" + enumtype[:-1]
0025     converter = "PyObject *ob = PyCom_PyObjectFromIUnknown(rgVar[i], IID_%(enum_interface)s, FALSE);" % locals()
0026     arraydeclare = "%(enum_interface)s **rgVar = new %(enum_interface)s *[celt];" % locals()
0027   else:
0028     # Enum of a simple structure
0029     converter = "PyObject *ob = PyCom_PyObjectFrom%(enumtype)s(&rgVar[i]);" % locals()
0030     arraydeclare = "%(enumtype)s *rgVar = new %(enumtype)s[celt];" % locals()
0031 
0032   f.write(\
0033 '''
0034 // ---------------------------------------------------
0035 //
0036 // Interface Implementation
0037 
0038 PyIEnum%(enumtype)s::PyIEnum%(enumtype)s(IUnknown *pdisp):
0039         PyIUnknown(pdisp)
0040 {
0041         ob_type = &type;
0042 }
0043 
0044 PyIEnum%(enumtype)s::~PyIEnum%(enumtype)s()
0045 {
0046 }
0047 
0048 /* static */ IEnum%(enumtype)s *PyIEnum%(enumtype)s::GetI(PyObject *self)
0049 {
0050         return (IEnum%(enumtype)s *)PyIUnknown::GetI(self);
0051 }
0052 
0053 // @pymethod object|PyIEnum%(enumtype)s|Next|Retrieves a specified number of items in the enumeration sequence.
0054 PyObject *PyIEnum%(enumtype)s::Next(PyObject *self, PyObject *args)
0055 {
0056         long celt = 1;
0057         // @pyparm int|num|1|Number of items to retrieve.
0058         if ( !PyArg_ParseTuple(args, "|l:Next", &celt) )
0059                 return NULL;
0060 
0061         IEnum%(enumtype)s *pIE%(enumtype)s = GetI(self);
0062         if ( pIE%(enumtype)s == NULL )
0063                 return NULL;
0064 
0065         %(arraydeclare)s
0066         if ( rgVar == NULL ) {
0067                 PyErr_SetString(PyExc_MemoryError, "allocating result %(enumtype)ss");
0068                 return NULL;
0069         }
0070 
0071         int i;
0072 /*      for ( i = celt; i--; )
0073                 // *** possibly init each structure element???
0074 */
0075 
0076         ULONG celtFetched = 0;
0077         PY_INTERFACE_PRECALL;
0078         HRESULT hr = pIE%(enumtype)s->Next(celt, rgVar, &celtFetched);
0079         PY_INTERFACE_POSTCALL;
0080         if (  HRESULT_CODE(hr) != ERROR_NO_MORE_ITEMS && FAILED(hr) )
0081         {
0082                 delete [] rgVar;
0083                 return PyCom_BuildPyException(hr,pIE%(enumtype)s, IID_IE%(enumtype)s);
0084         }
0085 
0086         PyObject *result = PyTuple_New(celtFetched);
0087         if ( result != NULL )
0088         {
0089                 for ( i = celtFetched; i--; )
0090                 {
0091                         %(converter)s
0092                         if ( ob == NULL )
0093                         {
0094                                 Py_DECREF(result);
0095                                 result = NULL;
0096                                 break;
0097                         }
0098                         PyTuple_SET_ITEM(result, i, ob);
0099                 }
0100         }
0101 
0102 /*      for ( i = celtFetched; i--; )
0103                 // *** possibly cleanup each structure element???
0104 */
0105         delete [] rgVar;
0106         return result;
0107 }
0108 
0109 // @pymethod |PyIEnum%(enumtype)s|Skip|Skips over the next specified elementes.
0110 PyObject *PyIEnum%(enumtype)s::Skip(PyObject *self, PyObject *args)
0111 {
0112         long celt;
0113         if ( !PyArg_ParseTuple(args, "l:Skip", &celt) )
0114                 return NULL;
0115 
0116         IEnum%(enumtype)s *pIE%(enumtype)s = GetI(self);
0117         if ( pIE%(enumtype)s == NULL )
0118                 return NULL;
0119 
0120         PY_INTERFACE_PRECALL;
0121         HRESULT hr = pIE%(enumtype)s->Skip(celt);
0122         PY_INTERFACE_POSTCALL;
0123         if ( FAILED(hr) )
0124                 return PyCom_BuildPyException(hr, pIE%(enumtype)s, IID_IE%(enumtype)s);
0125 
0126         Py_INCREF(Py_None);
0127         return Py_None;
0128 }
0129 
0130 // @pymethod |PyIEnum%(enumtype)s|Reset|Resets the enumeration sequence to the beginning.
0131 PyObject *PyIEnum%(enumtype)s::Reset(PyObject *self, PyObject *args)
0132 {
0133         if ( !PyArg_ParseTuple(args, ":Reset") )
0134                 return NULL;
0135 
0136         IEnum%(enumtype)s *pIE%(enumtype)s = GetI(self);
0137         if ( pIE%(enumtype)s == NULL )
0138                 return NULL;
0139 
0140         PY_INTERFACE_PRECALL;
0141         HRESULT hr = pIE%(enumtype)s->Reset();
0142         PY_INTERFACE_POSTCALL;
0143         if ( FAILED(hr) )
0144                 return PyCom_BuildPyException(hr, pIE%(enumtype)s, IID_IE%(enumtype)s);
0145 
0146         Py_INCREF(Py_None);
0147         return Py_None;
0148 }
0149 
0150 // @pymethod <o PyIEnum%(enumtype)s>|PyIEnum%(enumtype)s|Clone|Creates another enumerator that contains the same enumeration state as the current one
0151 PyObject *PyIEnum%(enumtype)s::Clone(PyObject *self, PyObject *args)
0152 {
0153         if ( !PyArg_ParseTuple(args, ":Clone") )
0154                 return NULL;
0155 
0156         IEnum%(enumtype)s *pIE%(enumtype)s = GetI(self);
0157         if ( pIE%(enumtype)s == NULL )
0158                 return NULL;
0159 
0160         IEnum%(enumtype)s *pClone;
0161         PY_INTERFACE_PRECALL;
0162         HRESULT hr = pIE%(enumtype)s->Clone(&pClone);
0163         PY_INTERFACE_POSTCALL;
0164         if ( FAILED(hr) )
0165                 return PyCom_BuildPyException(hr, pIE%(enumtype)s, IID_IE%(enumtype)s);
0166 
0167         return PyCom_PyObjectFromIUnknown(pClone, IID_IEnum%(enumtype)s, FALSE);
0168 }
0169 
0170 // @object PyIEnum%(enumtype)s|A Python interface to IEnum%(enumtype)s
0171 static struct PyMethodDef PyIEnum%(enumtype)s_methods[] =
0172 {
0173         { "Next", PyIEnum%(enumtype)s::Next, 1 },    // @pymeth Next|Retrieves a specified number of items in the enumeration sequence.
0174         { "Skip", PyIEnum%(enumtype)s::Skip, 1 },       // @pymeth Skip|Skips over the next specified elementes.
0175         { "Reset", PyIEnum%(enumtype)s::Reset, 1 },     // @pymeth Reset|Resets the enumeration sequence to the beginning.
0176         { "Clone", PyIEnum%(enumtype)s::Clone, 1 },     // @pymeth Clone|Creates another enumerator that contains the same enumeration state as the current one.
0177         { NULL }
0178 };
0179 
0180 PyComTypeObject PyIEnum%(enumtype)s::type("PyIEnum%(enumtype)s",
0181                 &PyIUnknown::type,
0182                 sizeof(PyIEnum%(enumtype)s),
0183                 PyIEnum%(enumtype)s_methods,
0184                 GET_PYCOM_CTOR(PyIEnum%(enumtype)s));
0185 ''' % locals() )
0186 
0187 
0188 
0189 def _write_enumgw_cpp(f, interface):
0190   enumtype = interface.name[5:]
0191   if is_interface_enum(enumtype):
0192     # Assume an interface.
0193     enum_interface = "I" + enumtype[:-1]
0194     converter = "if ( !PyCom_InterfaceFromPyObject(ob, IID_%(enum_interface)s, (void **)&rgVar[i], FALSE) )" % locals()
0195     argdeclare="%(enum_interface)s __RPC_FAR * __RPC_FAR *rgVar" % locals()
0196   else:
0197     argdeclare="%(enumtype)s __RPC_FAR *rgVar" % locals()
0198     converter="if ( !PyCom_PyObjectAs%(enumtype)s(ob, &rgVar[i]) )" % locals()
0199   f.write(
0200 '''
0201 // ---------------------------------------------------
0202 //
0203 // Gateway Implementation
0204 
0205 // Std delegation
0206 STDMETHODIMP_(ULONG) PyGEnum%(enumtype)s::AddRef(void) {return PyGatewayBase::AddRef();}
0207 STDMETHODIMP_(ULONG) PyGEnum%(enumtype)s::Release(void) {return PyGatewayBase::Release();}
0208 STDMETHODIMP PyGEnum%(enumtype)s::QueryInterface(REFIID iid, void ** obj) {return PyGatewayBase::QueryInterface(iid, obj);}
0209 STDMETHODIMP PyGEnum%(enumtype)s::GetTypeInfoCount(UINT FAR* pctInfo) {return PyGatewayBase::GetTypeInfoCount(pctInfo);}
0210 STDMETHODIMP PyGEnum%(enumtype)s::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo FAR* FAR* pptInfo) {return PyGatewayBase::GetTypeInfo(itinfo, lcid, pptInfo);}
0211 STDMETHODIMP PyGEnum%(enumtype)s::GetIDsOfNames(REFIID refiid, OLECHAR FAR* FAR* rgszNames, UINT cNames, LCID lcid, DISPID FAR* rgdispid) {return PyGatewayBase::GetIDsOfNames( refiid, rgszNames, cNames, lcid, rgdispid);}
0212 STDMETHODIMP PyGEnum%(enumtype)s::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR* params, VARIANT FAR* pVarResult, EXCEPINFO FAR* pexcepinfo, UINT FAR* puArgErr) {return PyGatewayBase::Invoke( dispid, riid, lcid, wFlags, params, pVarResult, pexcepinfo, puArgErr);}
0213 
0214 STDMETHODIMP PyGEnum%(enumtype)s::Next( 
0215             /* [in] */ ULONG celt,
0216             /* [length_is][size_is][out] */ %(argdeclare)s,
0217             /* [out] */ ULONG __RPC_FAR *pCeltFetched)
0218 {
0219         PY_GATEWAY_METHOD;
0220         PyObject *result;
0221         HRESULT hr = InvokeViaPolicy("Next", &result, "i", celt);
0222         if ( FAILED(hr) )
0223                 return hr;
0224 
0225         if ( !PySequence_Check(result) )
0226                 goto error;
0227         int len;
0228         len = PyObject_Length(result);
0229         if ( len == -1 )
0230                 goto error;
0231         if ( len > (int)celt)
0232                 len = celt;
0233 
0234         if ( pCeltFetched )
0235                 *pCeltFetched = len;
0236 
0237         int i;
0238         for ( i = 0; i < len; ++i )
0239         {
0240                 PyObject *ob = PySequence_GetItem(result, i);
0241                 if ( ob == NULL )
0242                         goto error;
0243 
0244                 %(converter)s
0245                 {
0246                         Py_DECREF(result);
0247                         return PyCom_SetCOMErrorFromPyException(IID_IEnum%(enumtype)s);
0248                 }
0249         }
0250 
0251         Py_DECREF(result);
0252 
0253         return len < (int)celt ? S_FALSE : S_OK;
0254 
0255   error:
0256         PyErr_Clear();  // just in case
0257         Py_DECREF(result);
0258         return PyCom_SetCOMErrorFromSimple(E_FAIL, IID_IEnum%(enumtype)s, "Next() did not return a sequence of objects");
0259 }
0260 
0261 STDMETHODIMP PyGEnum%(enumtype)s::Skip( 
0262             /* [in] */ ULONG celt)
0263 {
0264         PY_GATEWAY_METHOD;
0265         return InvokeViaPolicy("Skip", NULL, "i", celt);
0266 }
0267 
0268 STDMETHODIMP PyGEnum%(enumtype)s::Reset(void)
0269 {
0270         PY_GATEWAY_METHOD;
0271         return InvokeViaPolicy("Reset");
0272 }
0273 
0274 STDMETHODIMP PyGEnum%(enumtype)s::Clone( 
0275             /* [out] */ IEnum%(enumtype)s __RPC_FAR *__RPC_FAR *ppEnum)
0276 {
0277         PY_GATEWAY_METHOD;
0278         PyObject * result;
0279         HRESULT hr = InvokeViaPolicy("Clone", &result);
0280         if ( FAILED(hr) )
0281                 return hr;
0282 
0283         /*
0284         ** Make sure we have the right kind of object: we should have some kind
0285         ** of IUnknown subclass wrapped into a PyIUnknown instance.
0286         */
0287         if ( !PyIBase::is_object(result, &PyIUnknown::type) )
0288         {
0289                 /* the wrong kind of object was returned to us */
0290                 Py_DECREF(result);
0291                 return PyCom_SetCOMErrorFromSimple(E_FAIL, IID_IEnum%(enumtype)s);
0292         }
0293 
0294         /*
0295         ** Get the IUnknown out of the thing. note that the Python ob maintains
0296         ** a reference, so we don't have to explicitly AddRef() here.
0297         */
0298         IUnknown *punk = ((PyIUnknown *)result)->m_obj;
0299         if ( !punk )
0300         {
0301                 /* damn. the object was released. */
0302                 Py_DECREF(result);
0303                 return PyCom_SetCOMErrorFromSimple(E_FAIL, IID_IEnum%(enumtype)s);
0304         }
0305 
0306         /*
0307         ** Get the interface we want. note it is returned with a refcount.
0308         ** This QI is actually going to instantiate a PyGEnum%(enumtype)s.
0309         */
0310         hr = punk->QueryInterface(IID_IEnum%(enumtype)s, (LPVOID *)ppEnum);
0311 
0312         /* done with the result; this DECREF is also for <punk> */
0313         Py_DECREF(result);
0314 
0315         return PyCom_SetCOMErrorFromSimple(hr, IID_IEnum%(enumtype)s, "Python could not convert the result from Next() into the required COM interface");
0316 }
0317 ''' % locals())
0318 

Generated by PyXR 0.9.4
SourceForge.net Logo