qingdoa daoo : oleaut32: safearray: Convert dimension index at the API boundary.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Jun 6 05:15:57 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: 06fcfda9fff76f7f3d92352c2050181d63613645
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=06fcfda9fff76f7f3d92352c2050181d63613645

Author: qingdoa daoo <qingdao33122 at yahoo.com>
Date:   Sun Jun  4 19:43:13 2006 +0800

oleaut32: safearray: Convert dimension index at the API boundary.

---

 dlls/oleaut32/safearray.c       |   42 +++++++++++----------------------------
 dlls/oleaut32/tests/safearray.c |   16 +++++++++++++++
 2 files changed, 28 insertions(+), 30 deletions(-)

diff --git a/dlls/oleaut32/safearray.c b/dlls/oleaut32/safearray.c
index ad4ce19..cfebfbb 100644
--- a/dlls/oleaut32/safearray.c
+++ b/dlls/oleaut32/safearray.c
@@ -169,25 +169,6 @@ static ULONG SAFEARRAY_GetCellCount(cons
   return ulNumCells;
 }
 
-/* Get the 0 based index of an index into a dimension */
-static inline ULONG SAFEARRAY_GetDimensionIndex(SAFEARRAYBOUND *psab, ULONG ulIndex)
-{
-  return ulIndex - psab->lLbound;
-}
-
-/* Get the size of a dimension in cells */
-static inline ULONG SAFEARRAY_GetDimensionCells(SAFEARRAY *psa, ULONG ulDim)
-{
-  ULONG size = psa->rgsabound[0].cElements;
-
-  while (ulDim)
-  {
-    size *= psa->rgsabound[ulDim].cElements;
-    ulDim--;
-  }
-  return size;
-}
-
 /* Allocate a descriptor for an array */
 static HRESULT SAFEARRAY_AllocDescriptor(ULONG ulSize, SAFEARRAY **ppsaOut)
 {
@@ -226,6 +207,7 @@ static void SAFEARRAY_SetFeatures(VARTYP
 static SAFEARRAY* SAFEARRAY_Create(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound, ULONG ulSize)
 {
   SAFEARRAY *psa = NULL;
+  int i;
 
   if (!rgsabound)
     return NULL;
@@ -240,7 +222,8 @@ static SAFEARRAY* SAFEARRAY_Create(VARTY
       case VT_VARIANT:  psa->fFeatures |= FADF_VARIANT; break;
     }
 
-    memcpy(psa->rgsabound, rgsabound, cDims * sizeof(SAFEARRAYBOUND));
+    for (i = 0; i < cDims; i++)
+      memcpy(psa->rgsabound + i, rgsabound + cDims - 1 - i, sizeof(SAFEARRAYBOUND));
 
     if (ulSize)
       psa->cbElements = ulSize;
@@ -1027,8 +1010,8 @@ HRESULT WINAPI SafeArrayGetUBound(SAFEAR
   if(!nDim || nDim > psa->cDims)
     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;
 }
@@ -1060,7 +1043,7 @@ HRESULT WINAPI SafeArrayGetLBound(SAFEAR
   if(!nDim || nDim > psa->cDims)
     return DISP_E_BADINDEX;
 
-  *plLbound = psa->rgsabound[nDim - 1].lLbound;
+  *plLbound = psa->rgsabound[psa->cDims - nDim].lLbound;
   return S_OK;
 }
 
@@ -1199,7 +1182,7 @@ HRESULT WINAPI SafeArrayPtrOfIndex(SAFEA
   if (!psa || !rgIndices || !ppvData)
     return E_INVALIDARG;
 
-  psab = psa->rgsabound;
+  psab = psa->rgsabound + psa->cDims - 1;
   c1 = *rgIndices++;
 
   if (c1 < psab->lLbound || c1 >= psab->lLbound + (LONG)psab->cElements)
@@ -1209,7 +1192,7 @@ HRESULT WINAPI SafeArrayPtrOfIndex(SAFEA
   {
     dimensionSize *= psab->cElements;
 
-    psab++;
+    psab--;
 
     if (!psab->cElements ||
         *rgIndices < psab->lLbound ||
@@ -1220,7 +1203,7 @@ HRESULT WINAPI SafeArrayPtrOfIndex(SAFEA
     rgIndices++;
   }
 
-  cell += (c1 - psa->rgsabound[0].lLbound);
+  cell += (c1 - psa->rgsabound[psa->cDims - 1].lLbound);
 
   *ppvData = (char*)psa->pvData + cell * psa->cbElements;
   return S_OK;
@@ -1452,7 +1435,7 @@ HRESULT WINAPI SafeArrayRedim(SAFEARRAY 
   if (FAILED(SafeArrayLock(psa)))
     return E_UNEXPECTED;
 
-  oldBounds = &psa->rgsabound[psa->cDims - 1];
+  oldBounds = psa->rgsabound;
   oldBounds->lLbound = psabound->lLbound;
 
   if (psabound->cElements != oldBounds->cElements)
@@ -1460,9 +1443,8 @@ HRESULT WINAPI SafeArrayRedim(SAFEARRAY 
     if (psabound->cElements < oldBounds->cElements)
     {
       /* Shorten the final dimension. */
-      ULONG ulStartCell = psa->cDims == 1 ? 0 : SAFEARRAY_GetDimensionCells(psa, psa->cDims - 1);
-
-      ulStartCell += psabound->cElements;
+      ULONG ulStartCell = psabound->cElements *
+                          (SAFEARRAY_GetCellCount(psa) / oldBounds->cElements);
       SAFEARRAY_DestroyData(psa, ulStartCell);
     }
     else
diff --git a/dlls/oleaut32/tests/safearray.c b/dlls/oleaut32/tests/safearray.c
index e1f761c..c719c69 100644
--- a/dlls/oleaut32/tests/safearray.c
+++ b/dlls/oleaut32/tests/safearray.c
@@ -321,6 +321,22 @@ static void test_safearray(void)
 	hres = SafeArrayDestroy(a);
 	ok(hres == S_OK,"SAD of 0 dim array faild with hres %lx\n", hres);
 
+        SafeArrayAllocDescriptor(2, &a);
+        a->rgsabound[0].cElements = 2;
+        a->rgsabound[0].lLbound = 1;
+        a->rgsabound[1].cElements = 4;
+        a->rgsabound[1].lLbound = 1;
+        a->cbElements = 2;
+        SafeArrayAllocData(a);
+
+        indices[0] = 4;
+        indices[1] = 2;
+        hres = SafeArrayPtrOfIndex(a, indices, (void **)&ptr1);
+        ok(hres == S_OK, "SAPOI failed with hres %lx\n", hres);
+        SafeArrayAccessData(a, (void **)&ptr2);
+        ok(ptr1 - ptr2 == 14, "SAPOI got wrong ptr\n");
+        SafeArrayUnaccessData(a);
+
 	bounds[0].cElements = 0;	bounds[0].lLbound =  1;
 	bounds[1].cElements =  2;	bounds[1].lLbound = 23;
     	a = SafeArrayCreate(VT_I4,2,bounds);




More information about the wine-cvs mailing list