Esempio n. 1
0
        def create(cls, value, extra=None):
            """Create a POINTER(SAFEARRAY_...) instance of the correct
            type; value is an object containing the items to store.

            Python lists, tuples, and array.array instances containing
            compatible item types can be passed to create
            one-dimensional arrays.  To create multidimensional arrys,
            numpy arrays must be passed.
            """
            if npsupport.isndarray(value):
                return cls.create_from_ndarray(value, extra)

            # For VT_UNKNOWN or VT_DISPATCH, extra must be a pointer to
            # the GUID of the interface.
            #
            # For VT_RECORD, extra must be a pointer to an IRecordInfo
            # describing the record.

            # XXX How to specify the lbound (3. parameter to CreateVectorEx)?
            # XXX How to write tests for lbound != 0?
            pa = _safearray.SafeArrayCreateVectorEx(cls._vartype_, 0,
                                                    len(value), extra)
            if not pa:
                if cls._vartype_ == VT_RECORD and extra is None:
                    raise TypeError(
                        "Cannot create SAFEARRAY type VT_RECORD without IRecordInfo."
                    )
                # Hm, there may be other reasons why the creation fails...
                raise MemoryError()
            # We now have a POINTER(tagSAFEARRAY) instance which we must cast
            # to the correct type:
            pa = cast(pa, cls)
            # Now, fill the data in:
            ptr = POINTER(cls._itemtype_)()  # container for the values
            _safearray.SafeArrayAccessData(pa, byref(ptr))
            try:
                if isinstance(value, array.array):
                    addr, n = value.buffer_info()
                    nbytes = len(value) * sizeof(cls._itemtype_)
                    memmove(ptr, addr, nbytes)
                else:
                    for index, item in enumerate(value):
                        ptr[index] = item
            finally:
                _safearray.SafeArrayUnaccessData(pa)
            return pa
Esempio n. 2
0
        def create(cls, value, extra=None):
            """Create a POINTER(SAFEARRAY_...) instance of the correct
            type; value is an object containing the items to store.

            Python lists, tuples, and array.array instances containing
            compatible item types can be passed to create
            one-dimensional arrays.  To create multidimensional arrys,
            numpy arrays must be passed.
            """
            if npsupport.isndarray(value):
                return cls.create_from_ndarray(value, extra)

            # For VT_UNKNOWN or VT_DISPATCH, extra must be a pointer to
            # the GUID of the interface.
            #
            # For VT_RECORD, extra must be a pointer to an IRecordInfo
            # describing the record.

            # XXX How to specify the lbound (3. parameter to CreateVectorEx)?
            # XXX How to write tests for lbound != 0?
            pa = _safearray.SafeArrayCreateVectorEx(cls._vartype_,
                                                    0,
                                                    len(value),
                                                    extra)
            if not pa:
                if cls._vartype_ == VT_RECORD and extra is None:
                    raise TypeError("Cannot create SAFEARRAY type VT_RECORD without IRecordInfo.")
                # Hm, there may be other reasons why the creation fails...
                raise MemoryError()
            # We now have a POINTER(tagSAFEARRAY) instance which we must cast
            # to the correct type:
            pa = cast(pa, cls)
            # Now, fill the data in:
            ptr = POINTER(cls._itemtype_)()  # container for the values
            _safearray.SafeArrayAccessData(pa, byref(ptr))
            try:
                if isinstance(value, array.array):
                    addr, n = value.buffer_info()
                    nbytes = len(value) * sizeof(cls._itemtype_)
                    memmove(ptr, addr, nbytes)
                else:
                    for index, item in enumerate(value):
                        ptr[index] = item
            finally:
                _safearray.SafeArrayUnaccessData(pa)
            return pa
Esempio n. 3
0
 def _set_value(self, value):
     _VariantClear(self)
     if value is None:
         self.vt = VT_NULL
     elif hasattr(value, '__len__') and len(value) == 0:
         self.vt = VT_NULL
     # since bool is a subclass of int, this check must come before
     # the check for int
     elif isinstance(value, bool):
         self.vt = VT_BOOL
         self._.VT_BOOL = value
     elif isinstance(value, (int, c_int)):
         self.vt = VT_I4
         self._.VT_I4 = value
     elif isinstance(value, long):
         u = self._
         # try VT_I4 first.
         u.VT_I4 = value
         if u.VT_I4 == value:
             # it did work.
             self.vt = VT_I4
             return
         # try VT_UI4 next.
         if value >= 0:
             u.VT_UI4 = value
             if u.VT_UI4 == value:
                 # did work.
                 self.vt = VT_UI4
                 return
         # try VT_I8 next.
         if value >= 0:
             u.VT_I8 = value
             if u.VT_I8 == value:
                 # did work.
                 self.vt = VT_I8
                 return
         # try VT_UI8 next.
         if value >= 0:
             u.VT_UI8 = value
             if u.VT_UI8 == value:
                 # did work.
                 self.vt = VT_UI8
                 return
         # VT_R8 is last resort.
         self.vt = VT_R8
         u.VT_R8 = float(value)
     elif isinstance(value, (float, c_double)):
         self.vt = VT_R8
         self._.VT_R8 = value
     elif isinstance(value, (str, unicode)):
         self.vt = VT_BSTR
         # do the c_wchar_p auto unicode conversion
         self._.c_void_p = _SysAllocStringLen(value, len(value))
     elif isinstance(value, datetime.datetime):
         delta = value - _com_null_date
         # a day has 24 * 60 * 60 = 86400 seconds
         com_days = delta.days + (delta.seconds + delta.microseconds * 1e-6) / 86400.
         self.vt = VT_DATE
         self._.VT_R8 = com_days
     elif npsupport.isdatetime64(value):
         com_days = value - npsupport.com_null_date64
         com_days /= npsupport.numpy.timedelta64(1, 'D')
         self.vt = VT_DATE
         self._.VT_R8 = com_days
     elif decimal is not None and isinstance(value, decimal.Decimal):
         self._.VT_CY = int(round(value * 10000))
         self.vt = VT_CY
     elif isinstance(value, POINTER(IDispatch)):
         CopyComPointer(value, byref(self._))
         self.vt = VT_DISPATCH
     elif isinstance(value, POINTER(IUnknown)):
         CopyComPointer(value, byref(self._))
         self.vt = VT_UNKNOWN
     elif isinstance(value, (list, tuple)):
         obj = _midlSAFEARRAY(VARIANT).create(value)
         memmove(byref(self._), byref(obj), sizeof(obj))
         self.vt = VT_ARRAY | obj._vartype_
     elif isinstance(value, array.array):
         vartype = _arraycode_to_vartype[value.typecode]
         typ = _vartype_to_ctype[vartype]
         obj = _midlSAFEARRAY(typ).create(value)
         memmove(byref(self._), byref(obj), sizeof(obj))
         self.vt = VT_ARRAY | obj._vartype_
     elif npsupport.isndarray(value):
         # Try to convert a simple array of basic types.
         descr = value.dtype.descr[0][1]
         typ = npsupport.numpy.ctypeslib._typecodes.get(descr)
         if typ is None:
             # Try for variant
             obj = _midlSAFEARRAY(VARIANT).create(value)
         else:
             obj = _midlSAFEARRAY(typ).create(value)
         memmove(byref(self._), byref(obj), sizeof(obj))
         self.vt = VT_ARRAY | obj._vartype_
     elif isinstance(value, Structure) and hasattr(value, "_recordinfo_"):
         guids = value._recordinfo_
         from comtypes.typeinfo import GetRecordInfoFromGuids
         ri = GetRecordInfoFromGuids(*guids)
         self.vt = VT_RECORD
         # Assigning a COM pointer to a structure field does NOT
         # call AddRef(), have to call it manually:
         ri.AddRef()
         self._.pRecInfo = ri
         self._.pvRecord = ri.RecordCreateCopy(byref(value))
     elif isinstance(getattr(value, "_comobj", None), POINTER(IDispatch)):
         CopyComPointer(value._comobj, byref(self._))
         self.vt = VT_DISPATCH
     elif isinstance(value, VARIANT):
         _VariantCopy(self, value)
     elif isinstance(value, c_ubyte):
         self._.VT_UI1 = value
         self.vt = VT_UI1
     elif isinstance(value, c_char):
         self._.VT_UI1 = ord(value.value)
         self.vt = VT_UI1
     elif isinstance(value, c_byte):
         self._.VT_I1 = value
         self.vt = VT_I1
     elif isinstance(value, c_ushort):
         self._.VT_UI2 = value
         self.vt = VT_UI2
     elif isinstance(value, c_short):
         self._.VT_I2 = value
         self.vt = VT_I2
     elif isinstance(value, c_uint):
         self.vt = VT_UI4
         self._.VT_UI4 = value
     elif isinstance(value, c_float):
         self.vt = VT_R4
         self._.VT_R4 = value
     elif isinstance(value, c_int64):
         self.vt = VT_I8
         self._.VT_I8 = value
     elif isinstance(value, c_uint64):
         self.vt = VT_UI8
         self._.VT_UI8 = value
     elif isinstance(value, _byref_type):
         ref = value._obj
         self._.c_void_p = addressof(ref)
         self.__keepref = value
         self.vt = _ctype_to_vartype[type(ref)] | VT_BYREF
     elif isinstance(value, _Pointer):
         ref = value.contents
         self._.c_void_p = addressof(ref)
         self.__keepref = value
         self.vt = _ctype_to_vartype[type(ref)] | VT_BYREF
     else:
         raise TypeError("Cannot put %r in VARIANT" % value)
Esempio n. 4
0
 def _set_value(self, value):
     _VariantClear(self)
     if value is None:
         self.vt = VT_NULL
     elif hasattr(value, '__len__') and len(value) == 0:
         self.vt = VT_NULL
     # since bool is a subclass of int, this check must come before
     # the check for int
     elif isinstance(value, bool):
         self.vt = VT_BOOL
         self._.VT_BOOL = value
     elif isinstance(value, (int, c_int)):
         self.vt = VT_I4
         self._.VT_I4 = value
     elif isinstance(value, long):
         u = self._
         # try VT_I4 first.
         u.VT_I4 = value
         if u.VT_I4 == value:
             # it did work.
             self.vt = VT_I4
             return
         # try VT_UI4 next.
         if value >= 0:
             u.VT_UI4 = value
             if u.VT_UI4 == value:
                 # did work.
                 self.vt = VT_UI4
                 return
         # try VT_I8 next.
         if value >= 0:
             u.VT_I8 = value
             if u.VT_I8 == value:
                 # did work.
                 self.vt = VT_I8
                 return
         # try VT_UI8 next.
         if value >= 0:
             u.VT_UI8 = value
             if u.VT_UI8 == value:
                 # did work.
                 self.vt = VT_UI8
                 return
         # VT_R8 is last resort.
         self.vt = VT_R8
         u.VT_R8 = float(value)
     elif isinstance(value, (float, c_double)):
         self.vt = VT_R8
         self._.VT_R8 = value
     elif isinstance(value, (str, unicode)):
         self.vt = VT_BSTR
         # do the c_wchar_p auto unicode conversion
         self._.c_void_p = _SysAllocStringLen(value, len(value))
     elif isinstance(value, datetime.datetime):
         delta = value - _com_null_date
         # a day has 24 * 60 * 60 = 86400 seconds
         com_days = delta.days + (delta.seconds +
                                  delta.microseconds * 1e-6) / 86400.
         self.vt = VT_DATE
         self._.VT_R8 = com_days
     elif npsupport.isdatetime64(value):
         com_days = value - npsupport.com_null_date64
         com_days /= npsupport.numpy.timedelta64(1, 'D')
         self.vt = VT_DATE
         self._.VT_R8 = com_days
     elif decimal is not None and isinstance(value, decimal.Decimal):
         self._.VT_CY = int(round(value * 10000))
         self.vt = VT_CY
     elif isinstance(value, POINTER(IDispatch)):
         CopyComPointer(value, byref(self._))
         self.vt = VT_DISPATCH
     elif isinstance(value, POINTER(IUnknown)):
         CopyComPointer(value, byref(self._))
         self.vt = VT_UNKNOWN
     elif isinstance(value, (list, tuple)):
         obj = _midlSAFEARRAY(VARIANT).create(value)
         memmove(byref(self._), byref(obj), sizeof(obj))
         self.vt = VT_ARRAY | obj._vartype_
     elif isinstance(value, array.array):
         vartype = _arraycode_to_vartype[value.typecode]
         typ = _vartype_to_ctype[vartype]
         obj = _midlSAFEARRAY(typ).create(value)
         memmove(byref(self._), byref(obj), sizeof(obj))
         self.vt = VT_ARRAY | obj._vartype_
     elif npsupport.isndarray(value):
         # Try to convert a simple array of basic types.
         descr = value.dtype.descr[0][1]
         typ = npsupport.numpy.ctypeslib._typecodes.get(descr)
         if typ is None:
             # Try for variant
             obj = _midlSAFEARRAY(VARIANT).create(value)
         else:
             obj = _midlSAFEARRAY(typ).create(value)
         memmove(byref(self._), byref(obj), sizeof(obj))
         self.vt = VT_ARRAY | obj._vartype_
     elif isinstance(value, Structure) and hasattr(value, "_recordinfo_"):
         guids = value._recordinfo_
         from comtypes.typeinfo import GetRecordInfoFromGuids
         ri = GetRecordInfoFromGuids(*guids)
         self.vt = VT_RECORD
         # Assigning a COM pointer to a structure field does NOT
         # call AddRef(), have to call it manually:
         ri.AddRef()
         self._.pRecInfo = ri
         self._.pvRecord = ri.RecordCreateCopy(byref(value))
     elif isinstance(getattr(value, "_comobj", None), POINTER(IDispatch)):
         CopyComPointer(value._comobj, byref(self._))
         self.vt = VT_DISPATCH
     elif isinstance(value, VARIANT):
         _VariantCopy(self, value)
     elif isinstance(value, c_ubyte):
         self._.VT_UI1 = value
         self.vt = VT_UI1
     elif isinstance(value, c_char):
         self._.VT_UI1 = ord(value.value)
         self.vt = VT_UI1
     elif isinstance(value, c_byte):
         self._.VT_I1 = value
         self.vt = VT_I1
     elif isinstance(value, c_ushort):
         self._.VT_UI2 = value
         self.vt = VT_UI2
     elif isinstance(value, c_short):
         self._.VT_I2 = value
         self.vt = VT_I2
     elif isinstance(value, c_uint):
         self.vt = VT_UI4
         self._.VT_UI4 = value
     elif isinstance(value, c_float):
         self.vt = VT_R4
         self._.VT_R4 = value
     elif isinstance(value, c_int64):
         self.vt = VT_I8
         self._.VT_I8 = value
     elif isinstance(value, c_uint64):
         self.vt = VT_UI8
         self._.VT_UI8 = value
     elif isinstance(value, _byref_type):
         ref = value._obj
         self._.c_void_p = addressof(ref)
         self.__keepref = value
         self.vt = _ctype_to_vartype[type(ref)] | VT_BYREF
     elif isinstance(value, _Pointer):
         ref = value.contents
         self._.c_void_p = addressof(ref)
         self.__keepref = value
         self.vt = _ctype_to_vartype[type(ref)] | VT_BYREF
     else:
         raise TypeError("Cannot put %r in VARIANT" % value)