PATCH: safearray indices
Marcus Meissner
marcus at jet.franken.de
Mon Jun 9 13:54:00 CDT 2003
Hi,
This comes from debugging Past.exe, a statistical analysis program.
I added testcases for all fixes and checked them with native oleaut32.
Ciao, Marcus
Changelog:
fixed index handling for multi dimensional arrays.
Index: dlls/oleaut32/safearray.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/safearray.c,v
retrieving revision 1.24
diff -u -r1.24 safearray.c
--- dlls/oleaut32/safearray.c 19 May 2003 21:43:20 -0000 1.24
+++ dlls/oleaut32/safearray.c 9 Jun 2003 18:49:13 -0000
@@ -43,9 +43,6 @@
#define SYSDUPSTRING(str) SysAllocStringLen((str), SysStringLen(str))
/* Locally used methods */
-static INT
-endOfDim(LONG *coor, SAFEARRAYBOUND *mat, LONG dim, LONG realDim);
-
static ULONG
calcDisplacement(LONG *coor, SAFEARRAYBOUND *mat, LONG dim);
@@ -303,6 +316,18 @@
}
/*************************************************************************
+ * SafeArrayCreate (OLEAUT32.15)
+ * Create a SafeArray object by encapsulating AllocDescriptor and AllocData
+ */
+SAFEARRAY* WINAPI SafeArrayCreate(
+ VARTYPE vt,
+ UINT cDims,
+ SAFEARRAYBOUND *rgsabound
+) {
+ return SafeArrayCreateEx(vt, cDims, rgsabound, NULL);
+}
+
+/*************************************************************************
* SafeArrayDestroyDescriptor (OLEAUT32.38)
* Frees the memory associated with the descriptor.
*/
@@ -485,6 +510,7 @@
/*************************************************************************
* SafeArrayGetUBound (OLEAUT32.19)
* return the UP bound for a given array dimension
+ * Note: [0] is the right most (least significant) array index!
*/
HRESULT WINAPI SafeArrayGetUBound(
SAFEARRAY *psa,
@@ -500,8 +526,8 @@
if(0 == nDim)
return DISP_E_BADINDEX;
- *plUbound = psa->rgsabound[nDim-1].lLbound +
- psa->rgsabound[nDim-1].cElements - 1;
+ *plUbound = psa->rgsabound[psa->cDims - nDim].lLbound +
+ psa->rgsabound[psa->cDims - nDim].cElements - 1;
return S_OK;
}
@@ -509,6 +535,7 @@
/*************************************************************************
* SafeArrayGetLBound (OLEAUT32.20)
* Return the LO bound for a given array dimension
+ * Note: [0] is the right most (least significant) array index!
*/
HRESULT WINAPI SafeArrayGetLBound(
SAFEARRAY *psa,
@@ -524,7 +551,7 @@
if(0 == nDim)
return DISP_E_BADINDEX;
- *plLbound = psa->rgsabound[nDim-1].lLbound;
+ *plLbound = psa->rgsabound[psa->cDims - nDim].lLbound;
return S_OK;
}
@@ -1088,31 +1115,19 @@
ULONG res = 0;
LONG iterDim;
- for(iterDim=0; iterDim<dim; iterDim++)
- /* the -mat[dim] bring coor[dim] relative to 0 for calculation */
- res += ((coor[iterDim]-mat[iterDim].lLbound) *
- endOfDim(coor, mat, iterDim+1, dim));
+ TRACE("dims is %ld\n", dim);
+
+ for (iterDim = dim-1; iterDim >= 0; iterDim--) {
+ TRACE("%ld: lbound is %ld, adding %ld\n", iterDim, mat[dim-iterDim-1].lLbound,(coor[iterDim] - mat[dim-iterDim-1].lLbound));
+ res += (coor[iterDim] - mat[dim-iterDim-1].lLbound);
+
+ if (iterDim > 0)
+ res *= mat[dim-iterDim].cElements;
+ }
TRACE("SafeArray: calculated displacement is %lu.\n", res);
return(res);
}
-
-/************************************************************************
- * Recursivity agent for calcDisplacement method. Used within Put and
- * Get methods.
- */
-static INT endOfDim(
- LONG *coor,
- SAFEARRAYBOUND *mat,
- LONG dim,
- LONG realDim)
-{
- if(dim==realDim)
- return 1;
- else
- return (endOfDim(coor, mat, dim+1, realDim) * mat[dim].cElements);
-}
-
/************************************************************************
* Method used to validate the coordinate received in Put and Get
Index: tests/safearray.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/tests/safearray.c,v
retrieving revision 1.6
diff -u -r1.6 dlls/oleaut32/test/safearray.c
--- dlls/oleaut32/tests/safearray.c 13 May 2003 23:36:33 -0000 1.6
+++ dlls/oleaut32/tests/safearray.c 9 Jun 2003 18:49:14 -0000
@@ -100,12 +100,15 @@
HMODULE hdll;
SAFEARRAY *a, b, *c;
unsigned int i;
+ long indices[2];
HRESULT hres;
- SAFEARRAYBOUND bound;
+ SAFEARRAYBOUND bound, bounds[2];
VARIANT v;
LPVOID data;
IID iid;
VARTYPE vt;
+ LONG l;
+ unsigned char *ptr1, *ptr2;
hdll=LoadLibraryA("oleaut32.dll");
pSafeArrayAllocDescriptorEx=(void*)GetProcAddress(hdll,"SafeArrayAllocDescriptorEx");
@@ -145,7 +148,87 @@
bound.lLbound = 0;
a = SafeArrayCreate(-1, 1, &bound);
ok(NULL == a,"SAC(-1,1,[1,0]) not failed?");
-
+
+
+ bounds[0].cElements = 42; bounds[0].lLbound = 1;
+ bounds[1].cElements = 2; bounds[1].lLbound = 23;
+ a = SafeArrayCreate(VT_I4,2,bounds);
+ ok(a != NULL,"SAC(VT_INT32,2,...) failed.");
+
+ hres = SafeArrayGetLBound (a, 0, &l);
+ ok (hres == DISP_E_BADINDEX, "SAGLB 0 failed with %lx", hres);
+ hres = SafeArrayGetLBound (a, 1, &l);
+ ok (hres == S_OK, "SAGLB 1 failed with %lx", hres);
+ ok (l == 1, "SAGLB 1 returned %ld instead of 1", l);
+ hres = SafeArrayGetLBound (a, 2, &l);
+ ok (hres == S_OK, "SAGLB 2 failed with %lx", hres);
+ ok (l == 23, "SAGLB 2 returned %ld instead of 1", l);
+ hres = SafeArrayGetLBound (a, 3, &l);
+ ok (hres == DISP_E_BADINDEX, "SAGLB 3 failed with %lx", hres);
+
+ hres = SafeArrayGetUBound (a, 0, &l);
+ ok (hres == DISP_E_BADINDEX, "SAGUB 0 failed with %lx", hres);
+ hres = SafeArrayGetUBound (a, 1, &l);
+ ok (hres == S_OK, "SAGUB 1 failed with %lx", hres);
+ ok (l == 42, "SAGUB 1 returned %ld instead of 1", l);
+ hres = SafeArrayGetUBound (a, 2, &l);
+ ok (hres == S_OK, "SAGUB 2 failed with %lx", hres);
+ ok (l == 24, "SAGUB 2 returned %ld instead of 24", l);
+ hres = SafeArrayGetUBound (a, 3, &l);
+ ok (hres == DISP_E_BADINDEX, "SAGUB 3 failed with %lx", hres);
+
+ i = SafeArrayGetDim(a);
+ ok(i == 2, "getdims of 2 din array returned %d",i);
+
+ indices[0] = 0;
+ indices[1] = 23;
+ hres = SafeArrayGetElement(a, indices, &i);
+ ok(DISP_E_BADINDEX == hres,"SAGE failed [0,23], hres 0x%lx",hres);
+
+ indices[0] = 1;
+ indices[1] = 22;
+ hres = SafeArrayGetElement(a, indices, &i);
+ ok(DISP_E_BADINDEX == hres,"SAGE failed [1,22], hres 0x%lx",hres);
+
+ indices[0] = 1;
+ indices[1] = 23;
+ hres = SafeArrayGetElement(a, indices, &i);
+ ok(S_OK == hres,"SAGE failed [1,23], hres 0x%lx",hres);
+
+ indices[0] = 1;
+ indices[1] = 25;
+ hres = SafeArrayGetElement(a, indices, &i);
+ ok(DISP_E_BADINDEX == hres,"SAGE failed [1,24], hres 0x%lx",hres);
+
+ indices[0] = 3;
+ indices[1] = 23;
+ hres = SafeArrayGetElement(a, indices, &i);
+ ok(S_OK == hres,"SAGE failed [42,23], hres 0x%lx",hres);
+
+ hres = SafeArrayAccessData(a, (void**)&ptr1);
+ ok(S_OK == hres, "SAAD failed with 0x%lx", hres);
+
+ indices[0] = 3;
+ indices[1] = 23;
+ hres = SafeArrayPtrOfIndex(a, indices, (void**)&ptr2);
+ ok(S_OK == hres,"SAPOI failed [1,23], hres 0x%lx",hres);
+ ok(ptr2 - ptr1 == 8,"ptr difference is not 8, but %d (%p vs %p)", ptr2-ptr1, ptr2, ptr1);
+
+ indices[0] = 3;
+ indices[1] = 24;
+ hres = SafeArrayPtrOfIndex(a, indices, (void**)&ptr2);
+ ok(S_OK == hres,"SAPOI failed [5,24], hres 0x%lx",hres);
+ ok(ptr2 - ptr1 == 176,"ptr difference is not 176, but %d (%p vs %p)", ptr2-ptr1, ptr2, ptr1);
+
+ indices[0] = 20;
+ indices[1] = 23;
+ hres = SafeArrayPtrOfIndex(a, indices, (void**)&ptr2);
+ ok(S_OK == hres,"SAPOI failed [20,23], hres 0x%lx",hres);
+ ok(ptr2 - ptr1 == 76,"ptr difference is not 176, but %d (%p vs %p)", ptr2-ptr1, ptr2, ptr1);
+
+ hres = SafeArrayUnaccessData(a);
+ ok(S_OK == hres, "SAUAD failed with 0x%lx", hres);
+
for (i=0;i<sizeof(vttypes)/sizeof(vttypes[0]);i++) {
a = SafeArrayCreate(vttypes[i].vt, 1, &bound);
ok( ((a == NULL) && (vttypes[i].elemsize == 0)) ||
More information about the wine-patches
mailing list