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