723 lines
15 KiB
C++
723 lines
15 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1993.
|
|
//
|
|
// File: genenum.cpp
|
|
//
|
|
// Contents: implementation of CEnumeratorTest object
|
|
// This is the object that does all of the testing.
|
|
//
|
|
// Classes:
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: dd-mmm-yy Author Comment
|
|
// 24-May-94 kennethm author
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "headers.hxx"
|
|
#pragma hdrstop
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CEnumeratorTest::CEnumeratorTest
|
|
//
|
|
// Synopsis: constructor
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: dd-mmm-yy Author Comment
|
|
// 24-May-94 kennethm author
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
CEnumeratorTest::CEnumeratorTest()
|
|
{
|
|
m_pEnumTest = NULL;
|
|
m_ElementSize = 0;
|
|
m_ElementCount = -1;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CEnumeratorTest::CEnumeratorTest
|
|
//
|
|
// Synopsis: constructor
|
|
//
|
|
// Arguments: [enumtest] -- The enumerator object to be tested
|
|
// [elementsize] -- The size of one element from next
|
|
// [elementcount] -- The number of elements expected to in
|
|
// the enumerator. 0 if unknown.
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: dd-mmm-yy Author Comment
|
|
// 24-May-94 kennethm author
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
CEnumeratorTest::CEnumeratorTest(IGenEnum * enumtest, size_t elementsize, LONG elementcount)
|
|
{
|
|
m_pEnumTest = enumtest;
|
|
m_ElementSize = elementsize;
|
|
m_ElementCount = elementcount;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: CEnumeratorTest::GetNext
|
|
//
|
|
// Synopsis: Internal Next Implementation. Does some basic checks on the
|
|
// return values.
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: [celt] -- the number of items to fetch
|
|
// [pceltFetched] -- the number of items fetched
|
|
// [phresult] -- the return from next
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns: True if the basic tests passed, false if they didn't
|
|
// The result of the next call itself is passed in param 3.
|
|
//
|
|
// Signals:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// Algorithm: Checks:
|
|
// That if s_ok is returned celt and pceltFetched are ==
|
|
// If a verify is provided it is called
|
|
//
|
|
// History: dd-mmm-yy Author Comment
|
|
// 24-May-94 kennethm author
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BOOL CEnumeratorTest::GetNext( ULONG celt,
|
|
ULONG* pceltFetched,
|
|
HRESULT* phresult
|
|
)
|
|
{
|
|
void* prgelt;
|
|
ULONG ul;
|
|
BOOL fRet = TRUE;
|
|
|
|
//
|
|
// Allocate memory for the return elements
|
|
//
|
|
|
|
prgelt = new char[m_ElementSize * celt];
|
|
|
|
if (prgelt == NULL)
|
|
{
|
|
printf("IEnumX::GetNext out of memory.\r\n");
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Call next
|
|
//
|
|
|
|
*phresult = m_pEnumTest->Next(celt, prgelt, pceltFetched);
|
|
|
|
//
|
|
// If the return result is S_OK make sure the numbers match
|
|
//
|
|
|
|
if (*phresult == S_OK)
|
|
{
|
|
if ((pceltFetched) && (celt != *pceltFetched))
|
|
{
|
|
printf("IEnumX::Next returned S_OK but celt"
|
|
" and pceltFetch mismatch.\r\n");
|
|
|
|
fRet = FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// If false is returned then make sure celt is less than
|
|
// the number actually fetched
|
|
//
|
|
|
|
if (*phresult == S_FALSE)
|
|
{
|
|
if ((pceltFetched) && (celt < *pceltFetched))
|
|
{
|
|
printf("IEnumX::Next return S_FALSE but celt is"
|
|
" less than pceltFetch.\r\n");
|
|
|
|
fRet = FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Call verify to make sure the elements are ok.
|
|
//
|
|
|
|
if ((*phresult == S_OK) || (*phresult == S_FALSE))
|
|
{
|
|
//
|
|
// If we got S_FALSE back set celt to the number of elements
|
|
// returned in pceltFetched. If the user gave NULL for
|
|
// pceltFetched and we got S_FALSE back then celt can only be
|
|
// zero.
|
|
//
|
|
|
|
if (*phresult == S_FALSE)
|
|
{
|
|
if (pceltFetched)
|
|
{
|
|
celt = *pceltFetched;
|
|
}
|
|
else
|
|
{
|
|
celt = 0;
|
|
}
|
|
}
|
|
|
|
//
|
|
// loop through every returned element
|
|
//
|
|
|
|
for (ul=0; ul <= celt ; ul++)
|
|
{
|
|
if ((fRet == TRUE) &&
|
|
(Verify(((char *)prgelt) + (ul * m_ElementSize)) == FALSE))
|
|
{
|
|
printf("Data element %d returned by IEnumX::Next is bad.\r\n", ul);
|
|
|
|
fRet = FALSE;
|
|
|
|
//
|
|
// we keep looping anyway just to
|
|
// free up resources.
|
|
//
|
|
}
|
|
|
|
//
|
|
// If the user supplied a cleanup function there is additional
|
|
// memory that needs to be freed
|
|
//
|
|
// Math: cast prgelt to char* to it a one byte size and then scale
|
|
// it by the index * the element size
|
|
//
|
|
|
|
Cleanup(((char *)prgelt) + (ul * m_ElementSize));
|
|
|
|
}
|
|
}
|
|
|
|
delete prgelt;
|
|
|
|
return fRet;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CEnumeratorTest::TestNext
|
|
//
|
|
// Synopsis: Test the next enumerator methods
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: None.
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Signals:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// Algorithm:
|
|
//
|
|
// History: dd-mmm-yy Author Comment
|
|
// 24-May-94 kennethm author
|
|
//
|
|
// Notes: BUGBUG: This function should really be broken down into
|
|
// smaller function.
|
|
// Also, the return mechanism is unwieldy.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
HRESULT CEnumeratorTest::TestNext(void)
|
|
{
|
|
ULONG celtFetched;
|
|
LONG lInternalCount = 0;
|
|
HRESULT hresult;
|
|
ULONG i;
|
|
void* prgelt;
|
|
|
|
//
|
|
// First we want to count the element by doing a next on each one.
|
|
//
|
|
|
|
do {
|
|
if (!GetNext(1, &celtFetched, &hresult))
|
|
{
|
|
return(E_FAIL);
|
|
}
|
|
if (hresult == S_OK)
|
|
{
|
|
lInternalCount++;
|
|
}
|
|
|
|
} while ( hresult == S_OK );
|
|
|
|
//
|
|
// If the user passed in an amount make sure it matches what we got
|
|
//
|
|
|
|
if ((m_ElementCount != -1) && (lInternalCount != m_ElementCount))
|
|
{
|
|
printf("IEnumX: enumerated count and passed count do not match!\r\n");
|
|
|
|
return(E_FAIL);
|
|
}
|
|
else if (m_ElementCount == -1)
|
|
{
|
|
//
|
|
// If the user didn't pass in the element count let's set it here.
|
|
//
|
|
|
|
m_ElementCount = lInternalCount;
|
|
}
|
|
|
|
hresult = m_pEnumTest->Reset();
|
|
|
|
if (hresult != S_OK)
|
|
{
|
|
printf("IEnumnX: Reset failed (%lx)\r\n", hresult );
|
|
|
|
return(E_FAIL);
|
|
}
|
|
|
|
|
|
//
|
|
// Make sure we fail on ...Next(celt>1, ...,NULL)
|
|
//
|
|
|
|
if (GetNext(2, NULL, &hresult))
|
|
{
|
|
if (SUCCEEDED(hresult))
|
|
{
|
|
printf("IEnumX: celt>1 pceltFetched==NULL returned success\r\n");
|
|
|
|
return(E_FAIL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return(E_FAIL);
|
|
}
|
|
|
|
|
|
//
|
|
// This next test will call next getting more each time
|
|
//
|
|
|
|
for (i = 1; i < (ULONG)m_ElementCount; i++)
|
|
{
|
|
hresult = m_pEnumTest->Reset();
|
|
|
|
if (hresult != S_OK)
|
|
{
|
|
printf("IEnumnX: Reset failed (%lx)\r\n", hresult );
|
|
|
|
return(E_FAIL);
|
|
}
|
|
|
|
if (!GetNext(i, &celtFetched, &hresult))
|
|
{
|
|
return(E_FAIL);
|
|
}
|
|
|
|
if ((hresult != S_OK) || (celtFetched != i))
|
|
{
|
|
printf("IEnumX: next/reset test failed!\r\n");
|
|
|
|
return(E_FAIL);
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Now get more elements than we were supposed to
|
|
// This should return S_FALSE with the max number in the number fetched
|
|
//
|
|
|
|
hresult = m_pEnumTest->Reset();
|
|
|
|
if (hresult != S_OK)
|
|
{
|
|
printf("IEnumX: Reset failed (%lx)\r\n", hresult );
|
|
|
|
return(E_FAIL);
|
|
}
|
|
|
|
if (!GetNext(m_ElementCount + 1, &celtFetched, &hresult))
|
|
{
|
|
return(E_FAIL);
|
|
}
|
|
|
|
if ((hresult != S_FALSE) || (lInternalCount != m_ElementCount))
|
|
{
|
|
printf("IEnumX: next/reset test failed!\r\n");
|
|
|
|
return(E_FAIL);
|
|
}
|
|
|
|
//
|
|
// Now verifyall. We do it here after the object has been worked on a bit
|
|
// since it is more likely to fail at this point
|
|
//
|
|
|
|
hresult = m_pEnumTest->Reset();
|
|
|
|
if (hresult != S_OK)
|
|
{
|
|
printf("IEnumX: Reset failed (%lx)\r\n", hresult );
|
|
|
|
return(E_FAIL);
|
|
}
|
|
|
|
//
|
|
// Allocate memory for the return elements
|
|
//
|
|
|
|
prgelt = new char[m_ElementSize * m_ElementCount];
|
|
|
|
if (prgelt == NULL)
|
|
{
|
|
printf("IEnumX: verifyall new failed\r\n");
|
|
|
|
return(E_OUTOFMEMORY);
|
|
}
|
|
|
|
hresult = m_pEnumTest->Next(m_ElementCount, prgelt, &celtFetched);
|
|
|
|
if ((hresult != S_OK) || (celtFetched != (ULONG)m_ElementCount))
|
|
{
|
|
printf("IEnumX: verifyall test: next failed (%lx)\r\n", hresult );
|
|
delete prgelt;
|
|
|
|
return(E_FAIL);
|
|
}
|
|
|
|
if (VerifyAll(prgelt, m_ElementCount) == FALSE)
|
|
{
|
|
printf("IEnumX: verifyall failed (%lx)\r\n", hresult );
|
|
|
|
delete prgelt;
|
|
|
|
return(E_FAIL);
|
|
}
|
|
|
|
delete prgelt;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CEnumeratorTest::TestSkip
|
|
//
|
|
// Synopsis: This function calls all the tests
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Signals:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// Algorithm:
|
|
//
|
|
// History: dd-mmm-yy Author Comment
|
|
// 24-May-94 kennethm author
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
HRESULT CEnumeratorTest::TestSkip(void)
|
|
{
|
|
LONG i;
|
|
HRESULT hresult;
|
|
ULONG celtFetched;
|
|
|
|
//
|
|
// Make sure we call TestNext to set the element count
|
|
//
|
|
|
|
if (m_ElementCount == -1)
|
|
{
|
|
TestNext();
|
|
}
|
|
|
|
//
|
|
// Call Skip, reset and try to get one element
|
|
//
|
|
|
|
for (i = 0; i < (LONG)m_ElementCount; i++)
|
|
{
|
|
hresult = m_pEnumTest->Reset();
|
|
|
|
if (hresult != S_OK)
|
|
{
|
|
printf("IEnumnX: Reset failed (%lx)\r\n", hresult );
|
|
|
|
return(E_FAIL);
|
|
}
|
|
|
|
hresult = m_pEnumTest->Skip(i);
|
|
|
|
if (hresult != S_OK)
|
|
{
|
|
printf("IEnumnX: Skip failed (%lx)\r\n", hresult );
|
|
|
|
return(E_FAIL);
|
|
}
|
|
|
|
//
|
|
// Now one element to provide some check that the skip worked
|
|
//
|
|
|
|
if (!GetNext(1, &celtFetched, &hresult))
|
|
{
|
|
return(E_FAIL);
|
|
}
|
|
|
|
if (hresult != S_OK)
|
|
{
|
|
return(E_FAIL);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Reset the enumerator before we leave
|
|
//
|
|
|
|
hresult = m_pEnumTest->Reset();
|
|
|
|
if (hresult != S_OK)
|
|
{
|
|
printf("IEnumnX: Reset failed (%lx)\r\n", hresult );
|
|
return(E_FAIL);
|
|
}
|
|
|
|
return(S_OK);
|
|
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CEnumeratorTest::TestRelease
|
|
//
|
|
// Synopsis: This function calls all the tests
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Signals:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// Algorithm:
|
|
//
|
|
// History: dd-mmm-yy Author Comment
|
|
// 24-May-94 kennethm author
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
HRESULT CEnumeratorTest::TestRelease(void)
|
|
{
|
|
return(S_OK);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CEnumeratorTest::TestClone
|
|
//
|
|
// Synopsis: This function calls all the tests
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Signals:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// Algorithm:
|
|
//
|
|
// History: dd-mmm-yy Author Comment
|
|
// 24-May-94 kennethm author
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
HRESULT CEnumeratorTest::TestClone(void)
|
|
{
|
|
return(S_OK);
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CEnumeratorTest::TestAll
|
|
//
|
|
// Synopsis: This function calls all the tests
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// Signals:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// Algorithm:
|
|
//
|
|
// History: dd-mmm-yy Author Comment
|
|
// 24-May-94 kennethm author
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
HRESULT CEnumeratorTest::TestAll(void)
|
|
{
|
|
HRESULT hresult;
|
|
|
|
hresult = TestNext();
|
|
|
|
if (hresult == S_OK)
|
|
{
|
|
hresult = TestSkip();
|
|
}
|
|
|
|
if (hresult == S_OK)
|
|
{
|
|
hresult = TestClone();
|
|
}
|
|
|
|
if (hresult == S_OK)
|
|
{
|
|
hresult = TestRelease();
|
|
}
|
|
|
|
return(hresult);
|
|
}
|
|
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CEnumeratorTest::VerifyAll
|
|
//
|
|
// Synopsis: Verify entire array of returned results.
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: BOOL
|
|
//
|
|
// Algorithm: Just default to saying everything is ok
|
|
//
|
|
// History: dd-mmm-yy Author Comment
|
|
// 24-May-94 kennethm author
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BOOL CEnumeratorTest::VerifyAll(void *pv, LONG cl)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CEnumeratorTest::Verify
|
|
//
|
|
// Synopsis: Verify one element
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: BOOL
|
|
//
|
|
// Algorithm: Just default to saying everything is ok
|
|
//
|
|
// History: dd-mmm-yy Author Comment
|
|
// 24-May-94 kennethm author
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BOOL CEnumeratorTest::Verify(void *pv)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Method: CEnumeratorTest::Cleanup
|
|
//
|
|
// Synopsis: Default implementation of cleanup
|
|
//
|
|
// Arguments: [pv] - pointer to entry enumerated
|
|
//
|
|
// Algorithm: If there is nothing special to free this implementation
|
|
// can be used.
|
|
//
|
|
// History: dd-mmm-yy Author Comment
|
|
// 24-May-94 kennethm author
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
void CEnumeratorTest::Cleanup(void *pv)
|
|
{
|
|
return;
|
|
}
|
|
|