home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 May / PCWorld_2002-05_cd.bin / Software / TemaCD / activepython / ActivePython-2.1.1.msi / Python21_win32com_server_util.py < prev    next >
Encoding:
Python Source  |  2001-07-26  |  5.3 KB  |  181 lines

  1. """ General Server side utilities 
  2. """
  3. import pythoncom
  4. import policy
  5. import winerror
  6. from exception import COMException
  7.  
  8. def wrap(ob, iid=None, usePolicy=None, useDispatcher=None):
  9.   """Wraps an object in a PyGDispatch gateway.
  10.  
  11.      Returns a client side PyI{iid} interface.
  12.  
  13.      Interface and gateway support must exist for the specified IID, as
  14.      the QueryInterface() method is used.
  15.  
  16.   """
  17.   if usePolicy is None: 
  18.     usePolicy = policy.DefaultPolicy
  19.   if useDispatcher is None:
  20.     ob = usePolicy(ob)
  21.   else:
  22.     ob = useDispatcher(usePolicy, ob)
  23.  
  24.   # get a PyIDispatch, which interfaces to PyGDispatch
  25.   ob = pythoncom.WrapObject(ob)
  26.   if iid is not None:
  27.     ob = ob.QueryInterface(iid)       # Ask the PyIDispatch if it supports it?
  28.   return ob
  29.  
  30. def unwrap(ob):
  31.   """Unwraps an interface.
  32.  
  33.   Given an interface which wraps up a Gateway, return the object behind
  34.   the gateway.
  35.   """
  36.   ob = pythoncom.UnwrapObject(ob)
  37.   # see if the object is a dispatcher
  38.   if hasattr(ob, 'policy'):
  39.     ob = ob.policy
  40.   return ob._obj_
  41.  
  42.  
  43. class ListEnumerator:
  44.   """A class to expose a Python sequence as an EnumVARIANT.
  45.  
  46.      Create an instance of this class passing a sequence (list, tuple, or
  47.      any sequence protocol supporting object) and it will automatically
  48.      support the EnumVARIANT interface for the object.
  49.  
  50.      See also the @NewEnum@ function, which can be used to turn the
  51.      instance into an actual COM server.
  52.   """
  53.   _public_methods_ = [ 'Next', 'Skip', 'Reset', 'Clone' ]
  54.   _com_interfaces_ = [ pythoncom.IID_IEnumVARIANT ]
  55.  
  56.   def __init__(self, data, index=0):
  57.     self._list_ = data
  58.     self.index = index
  59.  
  60.   def Next(self, count):
  61.     result = self._list_[self.index:self.index+count]
  62.     self.Skip(count)
  63.     return result
  64.  
  65.   def Skip(self, count):
  66.     end = self.index + count
  67.     if end > len(self._list_):
  68.       end = len(self._list_)
  69.     self.index = end
  70.  
  71.   def Reset(self):
  72.     self.index = 0
  73.  
  74.   def Clone(self):
  75.     return self._wrap(self.__class__(self._list_, self.index))
  76.  
  77.   def _wrap(self, ob):
  78.     return wrap(ob)
  79.  
  80.  
  81. class ListEnumeratorGateway(ListEnumerator):
  82.   """A List Enumerator which wraps a sequence's items in gateways.
  83.  
  84.   If a sequence contains items (objects) that have not been wrapped for
  85.   return through the COM layers, then a ListEnumeratorGateway can be
  86.   used to wrap those items before returning them (from the Next() method).
  87.  
  88.   See also the @ListEnumerator@ class and the @NewEnum@ function.
  89.   """
  90.  
  91.   def Next(self, count):
  92.     result = self._list_[self.index:self.index+count]
  93.     self.Skip(count)
  94.     return map(self._wrap, result) 
  95.  
  96.  
  97. def NewEnum(seq, cls=ListEnumerator):
  98.   """Creates a new enumerator COM server.
  99.  
  100.   This function creates a new COM Server that implements the 
  101.   IID_IEnumVARIANT interface.
  102.  
  103.   A COM server that can enumerate the passed in sequence will be
  104.   created, then wrapped up for return through the COM framework.
  105.   Optionally, a custom COM server for enumeration can be passed
  106.   (the default is @ListEnumerator@).
  107.   """
  108.   return pythoncom.WrapObject(policy.DefaultPolicy(cls(seq)),
  109.                               pythoncom.IID_IEnumVARIANT,
  110.                               pythoncom.IID_IEnumVARIANT)
  111.  
  112.  
  113. class Collection:
  114.   "A collection of VARIANT values."
  115.  
  116.   _public_methods_ = [ 'Item', 'Count', 'Add', 'Remove', 'Insert' ]
  117.  
  118.   def __init__(self, data=None, readOnly=0):
  119.     if data is None:
  120.       data = [ ]
  121.     self.data = data
  122.  
  123.     # disable Add/Remove if read-only. note that we adjust _public_methods_
  124.     # on this instance only.
  125.     if readOnly:
  126.       self._public_methods_ = [ 'Item', 'Count' ]
  127.  
  128.   # This method is also used as the "default" method.
  129.   # Thus "print ob" will cause this to be called with zero
  130.   # params.  Handle this slightly more elegantly here.
  131.   # Ideally the  policy should handle this.
  132.   def Item(self, *args):
  133.     if len(args) != 1:
  134.       raise COMException(scode=winerror.DISP_E_BADPARAMCOUNT)
  135.  
  136.     try:
  137.       return self.data[args[0]]
  138.     except IndexError, desc:
  139.       raise COMException(scode=winerror.DISP_E_BADINDEX, desc=str(desc))
  140.  
  141.     
  142.   _value_ = Item
  143.   
  144.   def Count(self):
  145.     return len(self.data)
  146.  
  147.   def Add(self, value):
  148.     self.data.append(value)
  149.  
  150.   def Remove(self, index):
  151.     try:
  152.       del self.data[index]
  153.     except IndexError, desc:
  154.       raise COMException(scode=winerror.DISP_E_BADINDEX, desc=str(desc))
  155.  
  156.   def Insert(self, index, value):
  157.     try:
  158.       index = int(index)
  159.     except (ValueError, TypeError):
  160.       raise COMException(scode=winerror.DISP_E_TYPEMISMATCH)
  161.     self.data.insert(index, value)
  162.  
  163.   def _NewEnum(self):
  164.     return NewEnum(self.data)
  165.  
  166. def NewCollection(seq, cls=Collection):
  167.   """Creates a new COM collection object
  168.  
  169.   This function creates a new COM Server that implements the 
  170.   common collection protocols, including enumeration. (_NewEnum)
  171.  
  172.   A COM server that can enumerate the passed in sequence will be
  173.   created, then wrapped up for return through the COM framework.
  174.   Optionally, a custom COM server for enumeration can be passed
  175.   (the default is @Collection@).
  176.   """
  177.   return pythoncom.WrapObject(policy.DefaultPolicy(cls(seq)),
  178.                               pythoncom.IID_IDispatch,
  179.                               pythoncom.IID_IDispatch)
  180.  
  181.