PyXR

c:\python24\lib\site-packages\win32 \ com \ server \ util.py



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
SourceForge.net Logo