0001 """ General Server side utilities 0002 """ 0003 import pythoncom 0004 import policy 0005 import winerror 0006 from exception import COMException 0007 0008 def wrap(ob, iid=None, usePolicy=None, useDispatcher=None): 0009 """Wraps an object in a PyGDispatch gateway. 0010 0011 Returns a client side PyI{iid} interface. 0012 0013 Interface and gateway support must exist for the specified IID, as 0014 the QueryInterface() method is used. 0015 0016 """ 0017 if usePolicy is None: 0018 usePolicy = policy.DefaultPolicy 0019 if useDispatcher == 1: # True will also work here. 0020 import win32com.server.dispatcher 0021 useDispatcher = win32com.server.dispatcher.DefaultDebugDispatcher 0022 if useDispatcher is None or useDispatcher==0: 0023 ob = usePolicy(ob) 0024 else: 0025 ob = useDispatcher(usePolicy, ob) 0026 0027 # get a PyIDispatch, which interfaces to PyGDispatch 0028 ob = pythoncom.WrapObject(ob) 0029 if iid is not None: 0030 ob = ob.QueryInterface(iid) # Ask the PyIDispatch if it supports it? 0031 return ob 0032 0033 def unwrap(ob): 0034 """Unwraps an interface. 0035 0036 Given an interface which wraps up a Gateway, return the object behind 0037 the gateway. 0038 """ 0039 ob = pythoncom.UnwrapObject(ob) 0040 # see if the object is a dispatcher 0041 if hasattr(ob, 'policy'): 0042 ob = ob.policy 0043 return ob._obj_ 0044 0045 0046 class ListEnumerator: 0047 """A class to expose a Python sequence as an EnumVARIANT. 0048 0049 Create an instance of this class passing a sequence (list, tuple, or 0050 any sequence protocol supporting object) and it will automatically 0051 support the EnumVARIANT interface for the object. 0052 0053 See also the @NewEnum@ function, which can be used to turn the 0054 instance into an actual COM server. 0055 """ 0056 _public_methods_ = [ 'Next', 'Skip', 'Reset', 'Clone' ] 0057 0058 def __init__(self, data, index=0, iid = pythoncom.IID_IEnumVARIANT): 0059 self._list_ = data 0060 self.index = index 0061 self._iid_ = iid 0062 0063 def _query_interface_(self, iid): 0064 if iid == self._iid_: 0065 return 1 0066 def Next(self, count): 0067 result = self._list_[self.index:self.index+count] 0068 self.Skip(count) 0069 return result 0070 0071 def Skip(self, count): 0072 end = self.index + count 0073 if end > len(self._list_): 0074 end = len(self._list_) 0075 self.index = end 0076 0077 def Reset(self): 0078 self.index = 0 0079 0080 def Clone(self): 0081 return self._wrap(self.__class__(self._list_, self.index)) 0082 0083 def _wrap(self, ob): 0084 return wrap(ob) 0085 0086 0087 class ListEnumeratorGateway(ListEnumerator): 0088 """A List Enumerator which wraps a sequence's items in gateways. 0089 0090 If a sequence contains items (objects) that have not been wrapped for 0091 return through the COM layers, then a ListEnumeratorGateway can be 0092 used to wrap those items before returning them (from the Next() method). 0093 0094 See also the @ListEnumerator@ class and the @NewEnum@ function. 0095 """ 0096 0097 def Next(self, count): 0098 result = self._list_[self.index:self.index+count] 0099 self.Skip(count) 0100 return map(self._wrap, result) 0101 0102 0103 def NewEnum(seq, 0104 cls=ListEnumerator, 0105 iid=pythoncom.IID_IEnumVARIANT, 0106 usePolicy=None, 0107 useDispatcher=None): 0108 """Creates a new enumerator COM server. 0109 0110 This function creates a new COM Server that implements the 0111 IID_IEnumVARIANT interface. 0112 0113 A COM server that can enumerate the passed in sequence will be 0114 created, then wrapped up for return through the COM framework. 0115 Optionally, a custom COM server for enumeration can be passed 0116 (the default is @ListEnumerator@), and the specific IEnum 0117 interface can be specified. 0118 """ 0119 ob = cls(seq, iid=iid) 0120 return wrap(ob, iid, usePolicy=usePolicy, useDispatcher=useDispatcher) 0121 0122 0123 class Collection: 0124 "A collection of VARIANT values." 0125 0126 _public_methods_ = [ 'Item', 'Count', 'Add', 'Remove', 'Insert' ] 0127 0128 def __init__(self, data=None, readOnly=0): 0129 if data is None: 0130 data = [ ] 0131 self.data = data 0132 0133 # disable Add/Remove if read-only. note that we adjust _public_methods_ 0134 # on this instance only. 0135 if readOnly: 0136 self._public_methods_ = [ 'Item', 'Count' ] 0137 0138 # This method is also used as the "default" method. 0139 # Thus "print ob" will cause this to be called with zero 0140 # params. Handle this slightly more elegantly here. 0141 # Ideally the policy should handle this. 0142 def Item(self, *args): 0143 if len(args) != 1: 0144 raise COMException(scode=winerror.DISP_E_BADPARAMCOUNT) 0145 0146 try: 0147 return self.data[args[0]] 0148 except IndexError, desc: 0149 raise COMException(scode=winerror.DISP_E_BADINDEX, desc=str(desc)) 0150 0151 0152 _value_ = Item 0153 0154 def Count(self): 0155 return len(self.data) 0156 0157 def Add(self, value): 0158 self.data.append(value) 0159 0160 def Remove(self, index): 0161 try: 0162 del self.data[index] 0163 except IndexError, desc: 0164 raise COMException(scode=winerror.DISP_E_BADINDEX, desc=str(desc)) 0165 0166 def Insert(self, index, value): 0167 try: 0168 index = int(index) 0169 except (ValueError, TypeError): 0170 raise COMException(scode=winerror.DISP_E_TYPEMISMATCH) 0171 self.data.insert(index, value) 0172 0173 def _NewEnum(self): 0174 return NewEnum(self.data) 0175 0176 def NewCollection(seq, cls=Collection): 0177 """Creates a new COM collection object 0178 0179 This function creates a new COM Server that implements the 0180 common collection protocols, including enumeration. (_NewEnum) 0181 0182 A COM server that can enumerate the passed in sequence will be 0183 created, then wrapped up for return through the COM framework. 0184 Optionally, a custom COM server for enumeration can be passed 0185 (the default is @Collection@). 0186 """ 0187 return pythoncom.WrapObject(policy.DefaultPolicy(cls(seq)), 0188 pythoncom.IID_IDispatch, 0189 pythoncom.IID_IDispatch) 0190 0191 class FileStream: 0192 _public_methods_ = [ 'Read', 'Write', 'Clone', 'CopyTo', 'Seek' ] 0193 _com_interfaces_ = [ pythoncom.IID_IStream ] 0194 0195 def __init__(self, file): 0196 self.file = file 0197 0198 def Read(self, amount): 0199 return self.file.read(amount) 0200 0201 def Write(self, data): 0202 self.file.write(data) 0203 0204 def Clone(self): 0205 return self._wrap(self.__class__(self.file)) 0206 0207 def CopyTo(self, dest, cb): 0208 dest.Write(file.read(cb)) 0209 0210 def Seek(self, offset, origin): 0211 # how convient that the 'origin' values are the same as the CRT :) 0212 self.file.seek(offset, origin) 0213 0214 def _wrap(self, ob): 0215 return wrap(ob) 0216
Generated by PyXR 0.9.4