[pywin32-checkins] pywin32/com/win32com/src oleargs.cpp,1.43,1.44
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
From: Mark H. <mha...@us...> - 2009-01-12 05:41:46
|
Update of /cvsroot/pywin32/pywin32/com/win32com/src In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv793 Modified Files: oleargs.cpp Log Message: merge py3k support from Roger's py3k branch Index: oleargs.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32com/src/oleargs.cpp,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** oleargs.cpp 8 Jan 2009 02:56:17 -0000 1.43 --- oleargs.cpp 12 Jan 2009 05:41:40 -0000 1.44 *************** *** 6,11 **** #include "PythonCOM.h" - extern void PyCom_LogF(const TCHAR *fmt, ...); - extern PyObject *PyObject_FromRecordInfo(IRecordInfo *, void *, ULONG); extern PyObject *PyObject_FromSAFEARRAYRecordInfo(SAFEARRAY *psa); --- 6,9 ---- *************** *** 18,34 **** #define BYREF_ARRAY_USE_EXISTING_ARRAY ! // A little helper just for this file ! static PyObject* OleSetTypeError(char *msg) ! { ! PyErr_SetString(PyExc_TypeError, msg); ! return NULL; ! } ! #ifdef UNICODE ! // In a Unicode environment, we provide a helper that ! // converts the argument to a string before raising the error. ! static PyObject* OleSetTypeErrorW(TCHAR *msg) { ! PyObject *obMsg = PyString_FromUnicode(msg); if (obMsg) { PyErr_SetObject(PyExc_TypeError, obMsg); --- 16,30 ---- #define BYREF_ARRAY_USE_EXISTING_ARRAY ! // Need to put this in pywintypes.h with rest of compatibility macros ! #if (PY_VERSION_HEX < 0x03000000) ! #define PYWIN_BUFFER_CHECK PyBuffer_Check ! #else ! #define PYWIN_BUFFER_CHECK PyObject_CheckBuffer ! #endif ! // A little helper just for this file ! static PyObject* OleSetTypeError(TCHAR *msg) { ! PyObject *obMsg = PyWinObject_FromTCHAR(msg); if (obMsg) { PyErr_SetObject(PyExc_TypeError, obMsg); *************** *** 37,44 **** return NULL; } - #define OleSetTypeErrorT OleSetTypeErrorW - #else - #define OleSetTypeErrorT OleSetTypeError - #endif /////////////////////////////////////////////////////////// --- 33,36 ---- *************** *** 116,120 **** V_I4(var) = PyInt_AsLong(obj); } ! else if (PyInstance_Check(obj) && PyObject_HasAttrString(obj, "_oleobj_")) { if (PyCom_InterfaceFromPyInstanceOrObject(obj, IID_IDispatch, (void **)&V_DISPATCH(var), FALSE)) --- 108,112 ---- V_I4(var) = PyInt_AsLong(obj); } ! else if (PyObject_HasAttrString(obj, "_oleobj_")) { if (PyCom_InterfaceFromPyInstanceOrObject(obj, IID_IDispatch, (void **)&V_DISPATCH(var), FALSE)) *************** *** 166,170 **** return FALSE; } ! else if (PyBuffer_Check(obj)) { // We have a buffer object - convert to safe array of VT_UI1 if (!PyCom_SAFEARRAYFromPyObject(obj, &V_ARRAY(var), VT_UI1)) --- 158,162 ---- return FALSE; } ! else if (PYWIN_BUFFER_CHECK(obj)) { // We have a buffer object - convert to safe array of VT_UI1 if (!PyCom_SAFEARRAYFromPyObject(obj, &V_ARRAY(var), VT_UI1)) *************** *** 194,207 **** V_VT(var) = VT_CY; } ! /* ! else if (obj->ob_type == &AutomatedType) ! { ! } ! */ if (V_VT(var) == VT_EMPTY && !bGoodEmpty) { // Must ensure we have a Python error set if we fail! if (!PyErr_Occurred()) { char *extraMessage = ""; ! if (obj->ob_type->tp_as_buffer && obj->ob_type->tp_as_buffer->bf_getreadbuffer) extraMessage = " (but obtaining the buffer() of this object could)"; PyErr_Format(PyExc_TypeError, "Objects of type '%s' can not be converted to a COM VARIANT%s", obj->ob_type->tp_name, extraMessage); --- 186,195 ---- V_VT(var) = VT_CY; } ! if (V_VT(var) == VT_EMPTY && !bGoodEmpty) { // Must ensure we have a Python error set if we fail! if (!PyErr_Occurred()) { char *extraMessage = ""; ! if (obj->ob_type->tp_as_buffer) extraMessage = " (but obtaining the buffer() of this object could)"; PyErr_Format(PyExc_TypeError, "Objects of type '%s' can not be converted to a COM VARIANT%s", obj->ob_type->tp_name, extraMessage); *************** *** 232,236 **** /* ### note: we shouldn't see this, it is illegal in a VARIANT */ if (V_ISVECTOR(var)) { ! return OleSetTypeError("Cant convert vectors!"); } --- 220,224 ---- /* ### note: we shouldn't see this, it is illegal in a VARIANT */ if (V_ISVECTOR(var)) { ! return OleSetTypeError(_T("Cant convert vectors!")); } *************** *** 270,279 **** TCHAR buf[200]; wsprintf(buf, _T("Error converting integer variant (%08lx)"), hr); ! OleSetTypeErrorT(buf); break; } // The result may be too large for a simple "long". If so, // we must return a long. ! if (V_UI4(&varValue) <= (unsigned)PyInt_GetMax()) result = PyInt_FromLong(V_UI4(&varValue)); else --- 258,267 ---- TCHAR buf[200]; wsprintf(buf, _T("Error converting integer variant (%08lx)"), hr); ! OleSetTypeError(buf); break; } // The result may be too large for a simple "long". If so, // we must return a long. ! if (V_UI4(&varValue) <= INT_MAX) result = PyInt_FromLong(V_UI4(&varValue)); else *************** *** 290,294 **** TCHAR buf[200]; wsprintf(buf, _T("Error converting integer variant (%08lx)"), hr); ! OleSetTypeErrorT(buf); break; } --- 278,282 ---- TCHAR buf[200]; wsprintf(buf, _T("Error converting integer variant (%08lx)"), hr); ! OleSetTypeError(buf); break; } *************** *** 308,312 **** TCHAR buf[200]; wsprintf(buf, _T("Error converting floating point variant (%08lx)"), hr); ! OleSetTypeErrorT(buf); break; } --- 296,300 ---- TCHAR buf[200]; wsprintf(buf, _T("Error converting floating point variant (%08lx)"), hr); ! OleSetTypeError(buf); break; } *************** *** 371,375 **** TCHAR buf[200]; wsprintf(buf, _T("The Variant type (0x%x) is not supported, and it can not be converted to a string"), V_VT(var)); ! OleSetTypeErrorT(buf); break; } --- 359,363 ---- TCHAR buf[200]; wsprintf(buf, _T("The Variant type (0x%x) is not supported, and it can not be converted to a string"), V_VT(var)); ! OleSetTypeError(buf); break; } *************** *** 392,397 **** { LONG numElements = pBounds[dimNo-1].cElements; ! if ((LONG)PySequence_Length(obj)!=numElements) { ! OleSetTypeError("All dimensions must be a sequence of the same size"); return FALSE; } --- 380,385 ---- { LONG numElements = pBounds[dimNo-1].cElements; ! if ((LONG)PyObject_Length(obj)!=numElements) { ! OleSetTypeError(_T("All dimensions must be a sequence of the same size")); return FALSE; } *************** *** 400,427 **** // (only support single segment buffers for now) if (dimNo==nDims && vt==VT_UI1 && obj->ob_type->tp_as_buffer) { ! PyBufferProcs *pb = obj->ob_type->tp_as_buffer; ! Py_ssize_t bufSize; ! if (pb->bf_getreadbuffer && ! pb->bf_getsegcount && ! (*pb->bf_getsegcount)(obj, &bufSize)==1) ! { ! if (PyWin_SAFE_DOWNCAST(bufSize, Py_ssize_t, LONG) != numElements) { ! OleSetTypeError("Internal error - the buffer length is not the sequence length!"); ! return FALSE; } ! void *ob_buf, *sa_buf; ! HRESULT hr = SafeArrayAccessData(pSA,&sa_buf); ! if (FAILED(hr)) { ! PyCom_BuildPyException(hr); ! return FALSE; } ! pb->bf_getreadbuffer(obj, 0, &ob_buf); ! memcpy(sa_buf, ob_buf, bufSize); ! SafeArrayUnaccessData(pSA); ! // All done without a single loop :-) ! return TRUE; } // Otherwise just fall through into the standard mechanisms ! } BOOL ok = TRUE; for (int index=0;index<(int)numElements && ok;index++) { --- 388,413 ---- // (only support single segment buffers for now) if (dimNo==nDims && vt==VT_UI1 && obj->ob_type->tp_as_buffer) { ! DWORD bufSize; ! void *ob_buf, *sa_buf; ! if (!PyWinObject_AsReadBuffer(obj, &ob_buf, &bufSize)) ! return FALSE; ! ! if (bufSize != numElements) { ! OleSetTypeError(_T("Internal error - the buffer length is not the sequence length!")); ! return FALSE; } ! ! HRESULT hr = SafeArrayAccessData(pSA,&sa_buf); ! if (FAILED(hr)) { ! PyCom_BuildPyException(hr); ! return FALSE; } ! memcpy(sa_buf, ob_buf, bufSize); ! SafeArrayUnaccessData(pSA); ! // All done without a single loop :-) ! return TRUE; } // Otherwise just fall through into the standard mechanisms ! BOOL ok = TRUE; for (int index=0;index<(int)numElements && ok;index++) { *************** *** 439,443 **** // Complex conversion. if (vt & VT_ARRAY || vt & VT_BYREF) { ! OleSetTypeError("Internal error - unexpected argument - only simple VARIANTTYPE expected"); ok = FALSE; } else { --- 425,429 ---- // Complex conversion. if (vt & VT_ARRAY || vt & VT_BYREF) { ! OleSetTypeError(_T("Internal error - unexpected argument - only simple VARIANTTYPE expected")); ok = FALSE; } else { *************** *** 484,575 **** static long PyCom_CalculatePyObjectDimension(PyObject *obItemCheck, long lDimension, PyObject* ppyobDimensionDictionary) { ! long lReturnDimension = lDimension; // Allow arbitrary sequences, but not strings or Unicode objects. ! if(obItemCheck && ! PySequence_Check(obItemCheck) && ! !PyString_Check(obItemCheck) && ! !PyUnicode_Check(obItemCheck)) ! { ! PyObject* ppyobDimension; ! PyObject* ppyobSize; ! PyObject* ppyobDimensionSize; ! PyObject* ppyobItem; ! Py_ssize_t lIndex; ! long lMinimalDimension = -1; ! long lActualDimension = -1; ! Py_ssize_t lObjectSize; ! if (PyBuffer_Check(obItemCheck)) ! // buffers are a special case - they define 1 new dimension. ! return lReturnDimension+1; ! // Retrieve the size of the object ! lObjectSize = PySequence_Length(obItemCheck); ! if (lObjectSize == -1) { ! /* has a __len__, but it failed. Treat as not a sequence */ ! assert(PyErr_Occurred()); // can't *really* have -1 elems! */ PyErr_Clear(); } ! if (lObjectSize != -1) { // A real sequence of size zero should be OK though. ! ppyobSize = PyInt_FromSsize_t(lObjectSize); ! // Retrieve the stored size in this dimension ! ppyobDimension = PyInt_FromLong(lDimension); ! // Note: No ref added by PyDict_GetItem ! ppyobDimensionSize = PyDict_GetItem(ppyobDimensionDictionary, ppyobDimension); ! if (NULL == ppyobDimensionSize) { ! // Not found so first element defines the size in this dimension PyErr_Clear(); ! PyDict_SetItem(ppyobDimensionDictionary, ppyobDimension, ppyobSize); ! } else { ! // Check if stored size in this dimension equals the size of the element to check ! Py_ssize_t lStoredSize = PyInt_AsSsize_t(ppyobDimensionSize); ! if (lStoredSize != lObjectSize) ! { ! // if not the same size => no new dimension ! Py_XDECREF(ppyobSize); ! Py_XDECREF(ppyobDimension); ! return lReturnDimension; ! } } ! Py_XDECREF(ppyobSize); ! Py_XDECREF(ppyobDimension); ! ! // A special case for a zero-length sequence - we accept this as ! // a new dimension, but no children to check. ! // ie an empty list has 1 dimension. ! if (lObjectSize==0) ! return lReturnDimension+1; ! ! // Now check for all elements in this list for their dimensionality ! // Their size is compared to the size stored in the dimension dictionary ! for(lIndex = 0; lIndex < lObjectSize; lIndex++) { ! ppyobItem = PySequence_GetItem(obItemCheck, lIndex); ! if (ppyobItem == NULL) { ! // Says it is a sequence, but getting the item failed. ! // (eg, may be a COM instance that has __getitem__, but fails when attempting) ! // Ignore the error, and pretend it is not a sequence. ! PyErr_Clear(); ! break; ! } ! // Call method recursively ! lActualDimension = PyCom_CalculatePyObjectDimension(ppyobItem, lDimension + 1, ppyobDimensionDictionary); ! if (-1 == lMinimalDimension) { ! // First call so store it lMinimalDimension = lActualDimension; - lReturnDimension = lActualDimension; - } else { - // Get the smallest dimension - if (lActualDimension < lMinimalDimension) { - lMinimalDimension = lActualDimension; - } - // Check if all dimensions of the sublist are equal - if (lReturnDimension != lActualDimension) { - // if not set the minimal dimension - lReturnDimension = lMinimalDimension; - } } ! Py_XDECREF(ppyobItem); } } } --- 470,561 ---- static long PyCom_CalculatePyObjectDimension(PyObject *obItemCheck, long lDimension, PyObject* ppyobDimensionDictionary) { ! // Buffers are a special case - they define 1 new dimension. ! // Buffers supported sequence semantics in 2.x, but for some reason memoryview objects ! // in py3k do not, so check separately ! if (PYWIN_BUFFER_CHECK(obItemCheck)) ! return lDimension+1; ! // Allow arbitrary sequences, but not strings or Unicode objects. ! if (PyString_Check(obItemCheck) || PyUnicode_Check(obItemCheck) ! ||!PySequence_Check(obItemCheck)) ! return lDimension; ! long lReturnDimension = lDimension; ! PyObject* ppyobDimension; ! PyObject* ppyobSize; ! PyObject* ppyobDimensionSize; ! PyObject* ppyobItem; ! Py_ssize_t lIndex; ! long lMinimalDimension = -1; ! long lActualDimension = -1; ! Py_ssize_t lObjectSize; ! // Retrieve the size of the object ! lObjectSize = PySequence_Length(obItemCheck); ! if (lObjectSize == -1) { ! /* has a __len__, but it failed. Treat as not a sequence */ ! assert(PyErr_Occurred()); // can't *really* have -1 elems! */ ! PyErr_Clear(); ! } ! if (lObjectSize != -1) { // A real sequence of size zero should be OK though. ! ppyobSize = PyInt_FromSsize_t(lObjectSize); ! ! // Retrieve the stored size in this dimension ! ppyobDimension = PyInt_FromLong(lDimension); ! // Note: No ref added by PyDict_GetItem ! ppyobDimensionSize = PyDict_GetItem(ppyobDimensionDictionary, ppyobDimension); ! if (NULL == ppyobDimensionSize) { ! // Not found so first element defines the size in this dimension PyErr_Clear(); + PyDict_SetItem(ppyobDimensionDictionary, ppyobDimension, ppyobSize); + } else { + // Check if stored size in this dimension equals the size of the element to check + Py_ssize_t lStoredSize = PyInt_AsSsize_t(ppyobDimensionSize); + if (lStoredSize != lObjectSize) + { + // if not the same size => no new dimension + Py_XDECREF(ppyobSize); + Py_XDECREF(ppyobDimension); + return lReturnDimension; + } } ! Py_XDECREF(ppyobSize); ! Py_XDECREF(ppyobDimension); ! // A special case for a zero-length sequence - we accept this as ! // a new dimension, but no children to check. ! // ie an empty list has 1 dimension. ! if (lObjectSize==0) ! return lReturnDimension+1; ! ! // Now check for all elements in this list for their dimensionality ! // Their size is compared to the size stored in the dimension dictionary ! for(lIndex = 0; lIndex < lObjectSize; lIndex++) { ! ppyobItem = PySequence_GetItem(obItemCheck, lIndex); ! if (ppyobItem == NULL) { ! // Says it is a sequence, but getting the item failed. ! // (eg, may be a COM instance that has __getitem__, but fails when attempting) ! // Ignore the error, and pretend it is not a sequence. PyErr_Clear(); ! break; } ! // Call method recursively ! lActualDimension = PyCom_CalculatePyObjectDimension(ppyobItem, lDimension + 1, ppyobDimensionDictionary); ! if (-1 == lMinimalDimension) { ! // First call so store it ! lMinimalDimension = lActualDimension; ! lReturnDimension = lActualDimension; ! } else { ! // Get the smallest dimension ! if (lActualDimension < lMinimalDimension) { lMinimalDimension = lActualDimension; } ! // Check if all dimensions of the sublist are equal ! if (lReturnDimension != lActualDimension) { ! // if not set the minimal dimension ! lReturnDimension = lMinimalDimension; ! } } + Py_XDECREF(ppyobItem); } } *************** *** 600,604 **** if (cDims==0) { ! OleSetTypeError("Objects for SAFEARRAYS must be sequences (of sequences), or a buffer object."); return FALSE; } --- 586,590 ---- if (cDims==0) { ! OleSetTypeError(_T("Objects for SAFEARRAYS must be sequences (of sequences), or a buffer object.")); return FALSE; } *************** *** 617,621 **** for (LONG dimLook = 1;dimLook <= cDims;dimLook++) { pBounds[dimLook-1].lLbound = 0; // always! ! pBounds[dimLook-1].cElements = PySequence_Length(obItemCheck); if (!bAllocNewArray) { LONG exist_lbound, exist_ubound; --- 603,608 ---- for (LONG dimLook = 1;dimLook <= cDims;dimLook++) { pBounds[dimLook-1].lLbound = 0; // always! ! // Don't use PySequence_Length due to memoryview not supporting sequence protocol ! pBounds[dimLook-1].cElements = PyObject_Length(obItemCheck); if (!bAllocNewArray) { LONG exist_lbound, exist_ubound; *************** *** 629,640 **** } } ! PyObject *obSave = obItemCheck; ! if (pBounds[dimLook-1].cElements) { ! obItemCheck = PySequence_GetItem(obItemCheck,0); ! Py_DECREF(obSave); ! if (obItemCheck==NULL) { ! Py_XDECREF(obItemCheck); ! delete [] pBounds; ! return FALSE; } } --- 616,629 ---- } } ! // Don't need to do this check if buffer is last dim ! if (!PYWIN_BUFFER_CHECK(obItemCheck)){ ! PyObject *obSave = obItemCheck; ! if (pBounds[dimLook-1].cElements) { ! obItemCheck = PySequence_GetItem(obItemCheck,0); ! Py_DECREF(obSave); ! if (obItemCheck==NULL) { ! delete [] pBounds; ! return FALSE; ! } } } *************** *** 807,811 **** TCHAR buf[200]; wsprintf(buf, _T("The VARIANT type 0x%x is not supported for SAFEARRAYS"), vt); ! OleSetTypeErrorT(buf); } } --- 796,800 ---- TCHAR buf[200]; wsprintf(buf, _T("The VARIANT type 0x%x is not supported for SAFEARRAYS"), vt); ! OleSetTypeError(buf); } } *************** *** 842,855 **** if (ret!=NULL) { // Access the buffer object using the buffer interfaces. ! PyBufferProcs *pb = ret->ob_type->tp_as_buffer; ! if (!pb->bf_getwritebuffer || ! !pb->bf_getsegcount || ! (*pb->bf_getsegcount)(ret, NULL)!=1) { ! PyErr_SetString(PyExc_RuntimeError, "New buffer has no buffer interfaces!!"); SafeArrayUnaccessData(psa); Py_DECREF(ret); return NULL; } - long count = pb->bf_getwritebuffer(ret, 0, &ob_buf); if (count != cElems) { PyErr_SetString(PyExc_RuntimeError, "buffer size is not what we created!"); --- 831,840 ---- if (ret!=NULL) { // Access the buffer object using the buffer interfaces. ! DWORD count; ! if (!PyWinObject_AsWriteBuffer(ret, &ob_buf, &count)){ SafeArrayUnaccessData(psa); Py_DECREF(ret); return NULL; } if (count != cElems) { PyErr_SetString(PyExc_RuntimeError, "buffer size is not what we created!"); *************** *** 900,904 **** // Our caller must has resolved all byref and array references. if (vt & VT_ARRAY || vt & VT_BYREF) { ! OleSetTypeError("Internal error - unexpected argument - only simple VARIANTTYPE expected"); return FALSE; } --- 885,889 ---- // Our caller must has resolved all byref and array references. if (vt & VT_ARRAY || vt & VT_BYREF) { ! OleSetTypeError(_T("Internal error - unexpected argument - only simple VARIANTTYPE expected")); return FALSE; } *************** *** 1060,1064 **** } if (m_reqdType & VT_VECTOR) { // we have been asked for an array. ! OleSetTypeError("Sorry - cant support VT_VECTOR arguments"); return FALSE; } --- 1045,1049 ---- } if (m_reqdType & VT_VECTOR) { // we have been asked for an array. ! OleSetTypeError(_T("Sorry - cant support VT_VECTOR arguments")); return FALSE; } *************** *** 1347,1351 **** TCHAR buf[200]; wsprintf(buf, _T("The VARIANT type is unknown (0x%08lx)"), m_reqdType); ! OleSetTypeErrorT(buf); rc = FALSE; break; --- 1332,1336 ---- TCHAR buf[200]; wsprintf(buf, _T("The VARIANT type is unknown (0x%08lx)"), m_reqdType); ! OleSetTypeError(buf); rc = FALSE; break; |