windows-nt/Source/XPSP1/NT/printscan/wia/test/wiastress/testiwiaenumxxx.cpp
2020-09-26 16:20:57 +08:00

442 lines
9.6 KiB
C++

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
TestIWiaEnumXXX.cpp
Abstract:
Author:
Hakki T. Bostanci (hakkib) 06-Apr-2000
Revision History:
--*/
#include "stdafx.h"
//
// This is not a real .cpp module, it is meant to be included in .h
//
#ifdef DEFINE_TEMPLATES
//////////////////////////////////////////////////////////////////////////
//
//
//
template <class> struct storage_traits { };
template <> struct storage_traits<CComPtr<IEnumWIA_DEV_INFO> > { typedef CIWiaPropertyStoragePtr storage_type; };
template <> struct storage_traits<CComPtr<IEnumWIA_DEV_CAPS> > { typedef CWiaDevCap storage_type; };
template <> struct storage_traits<CComPtr<IEnumWIA_FORMAT_INFO> > { typedef CWiaFormatInfo storage_type; };
template <> struct storage_traits<CComPtr<IEnumWiaItem> > { typedef CIWiaItemPtr storage_type; };
template <> struct storage_traits<CComPtr<CMyEnumSTATPROPSTG> > { typedef CStatPropStg storage_type; };
//////////////////////////////////////////////////////////////////////////
//
//
//
template <class interface_type>
void TestEnum(interface_type &pEnum, PCTSTR pInterfaceName)
{
m_pszContext = pInterfaceName;
TestGetCount(pEnum);
TestReset(pEnum);
TestNext(pEnum);
TestSkip(pEnum);
TestClone(pEnum);
m_pszContext = 0;
}
//////////////////////////////////////////////////////////////////////////
//
//
//
template <class interface_type>
void TestNext(interface_type &pEnum)
{
typedef storage_traits<interface_type>::storage_type storage_type;
ULONG nItems = -1;
CHECK_HR(pEnum->GetCount(&nItems));
if (nItems == 0)
{
return;
}
// try to get items; first, last, all, one more than all, past the last
SubTestNext(pEnum, 0, 1, 1, S_OK);
SubTestNext(pEnum, nItems-1, 1, 1, S_OK);
SubTestNext(pEnum, 0, nItems, nItems, S_OK);
SubTestNext(pEnum, 0, nItems+1, nItems, S_FALSE);
SubTestNext(pEnum, nItems-1, 2, 1, S_FALSE);
//SubTestNext(pEnum, nItems, 1, 0, S_FALSE);
//SubTestNext(pEnum, 0, nItems, UINT_MAX, nItems);
// try to pass 0 for celtFetched,
// this should be allowed when fetching one item
CHECK_HR(pEnum->Reset());
CCppMem<storage_type> pOneItem(1);
LOG_HR(pEnum->Next(1, &pOneItem[0], 0), == S_OK);
if (m_bRunBadParamTests)
{
// try to pass 0 for celtFetched,
// this should not be allowed when fetching more than one item
CHECK_HR(pEnum->Reset());
CCppMem<storage_type> pTwoItems(2);
LOG_HR(pEnum->Next(2, &pTwoItems[0], 0), != S_OK);
// try to pass 0 for the element array
// this should not be allowed
CHECK_HR(pEnum->Reset());
ULONG nFetched = -1;
LOG_HR(pEnum->Next(0, 0, &nFetched), != S_OK);
}
}
//////////////////////////////////////////////////////////////////////////
//
//
//
template <class interface_type>
void
SubTestNext(
interface_type &pEnum,
ULONG nToBeSkipped,
ULONG nAskedToBeFetched,
ULONG nExpectedToBeFetched,
HRESULT hrExpected
)
{
typedef storage_traits<interface_type>::storage_type storage_type;
CHECK_HR(pEnum->Reset());
if (nToBeSkipped)
{
CHECK_HR(pEnum->Skip(nToBeSkipped));
}
CCppMem<storage_type> pItems(nAskedToBeFetched);
ULONG nFetched = -1;
HRESULT hrAPI = pEnum->Next(nAskedToBeFetched, &pItems[0], &nFetched);
if (hrAPI != hrExpected)
{
LOG_ERROR(
_T("pEnum->Next(%d, &pItems[0], &nFetched) == %s, expected %s"),
nAskedToBeFetched,
(PCTSTR) HResultToStr(hrAPI),
(PCTSTR) HResultToStr(hrExpected)
);
}
LOG_CMP(nFetched, ==, nExpectedToBeFetched);
}
//////////////////////////////////////////////////////////////////////////
//
//
//
template <class interface_type>
void TestReset(interface_type &pEnum)
{
typedef storage_traits<interface_type>::storage_type storage_type;
ULONG nItems = -1;
CHECK_HR(pEnum->GetCount(&nItems));
if (nItems == 0)
{
return;
}
// reset and read the first element
CHECK_HR(pEnum->Reset());
if (!m_bBVTMode)
{
storage_type FirstItemBeforeQueryingAll;
CHECK_HR(pEnum->Next(1, &FirstItemBeforeQueryingAll, 0));
// go to the last item
HRESULT hr;
do
{
storage_type Item;
hr = pEnum->Next(1, &Item, 0);
}
while (hr == S_OK);
// reset the enumerator and read the first element again
CHECK_HR(pEnum->Reset());
storage_type FirstItemAfterQueryingAll;
CHECK_HR(pEnum->Next(1, &FirstItemAfterQueryingAll, 0));
if (FirstItemBeforeQueryingAll != FirstItemAfterQueryingAll)
{
LOG_ERROR(_T("FirstItemBeforeQueryingAll != FirstItemAfterQueryingAll"));
}
}
}
//////////////////////////////////////////////////////////////////////////
//
//
//
template <class interface_type>
void TestSkip(interface_type &pEnum)
{
typedef storage_traits<interface_type>::storage_type storage_type;
// get the item count
ULONG nItems = -1;
CHECK_HR(pEnum->GetCount(&nItems));
if (nItems == 0)
{
return;
}
// read and store each item
CHECK_HR(pEnum->Reset());
CCppMem<storage_type> pItems(nItems);
for (int i = 0; i < nItems; ++i)
{
CHECK_HR(pEnum->Next(1, &pItems[i], 0));
}
// test valid cases
for (int nToBeSkipped = 0; nToBeSkipped < nItems; ++nToBeSkipped)
{
CHECK_HR(pEnum->Reset());
for (int nItem = nToBeSkipped; nItem < nItems; nItem += nToBeSkipped + 1)
{
CHECK_HR(pEnum->Skip(nToBeSkipped));
storage_type Item;
CHECK_HR(pEnum->Next(1, &Item, 0));
if (Item != pItems[nItem])
{
LOG_ERROR(_T("Item != pItems[nItem] after skipping %d"), nToBeSkipped);
}
}
}
// test invalid cases
if (m_bRunBadParamTests)
{
CHECK_HR(pEnum->Reset());
LOG_HR(pEnum->Skip(nItems+1), == S_FALSE);
CHECK_HR(pEnum->Reset());
LOG_HR(pEnum->Skip(-1), == S_FALSE);
}
}
//////////////////////////////////////////////////////////////////////////
//
//
//
template <class interface_type>
void TestClone(interface_type &pEnum, bool bRecurse = true)
{
typedef storage_traits<interface_type>::storage_type storage_type;
// make the clone
interface_type pClone;
if (LOG_HR(pEnum->Clone(&pClone), == S_OK) && !m_bBVTMode)
{
// reset both the original and the clone enumerators, then iterate
// through each element one by one and compare them
CHECK_HR(pEnum->Reset());
CHECK_HR(pClone->Reset());
HRESULT hr, hr1, hr2;
while (1)
{
// also, make a clone of the current state and check that
// the state is captured in the clone
interface_type pClone2;
CHECK_HR(pEnum->Clone(&pClone2));
// get the next item from the original interface
storage_type Item;
hr = pEnum->Next(1, &Item, 0);
// get the next item from the first clone
storage_type Item1;
hr1 = pClone->Next(1, &Item1, 0);
// get the next item from the second clone
storage_type Item2;
hr2 = pClone2->Next(1, &Item2, 0);
if (hr != S_OK || hr1 != S_OK || hr2 != S_OK)
{
break;
}
if (Item != Item1 || Item1 != Item2)
{
LOG_ERROR(_T("Clone states are not equal"));
}
}
if (hr != S_FALSE || hr1 != S_FALSE || hr2 != S_FALSE)
{
LOG_ERROR(_T("After enumeration, clone states are not equal"));
}
// test the clone
TestNext(pClone);
TestReset(pClone);
TestSkip(pClone);
if (bRecurse)
{
TestClone(pClone, false);
}
TestGetCount(pClone);
}
// test bad param
if (m_bRunBadParamTests)
{
LOG_HR(pEnum->Clone(0), != S_OK);
}
}
//////////////////////////////////////////////////////////////////////////
//
//
//
template <class interface_type>
void TestGetCount(interface_type &pEnum)
{
typedef storage_traits<interface_type>::storage_type storage_type;
// First, get the item count using GetCount()
ULONG cItemsFromGetCount = 0;
if (LOG_HR(pEnum->GetCount(&cItemsFromGetCount), == S_OK) && !m_bBVTMode)
{
// Now, find the item count by first resetting the enumerator
// and then querying for each item one by one using Next()
ULONG cItemsFromNext = 0;
CHECK_HR(pEnum->Reset());
HRESULT hr;
do
{
// verify that GetCount returns the same result after a Next or Reset
ULONG cItemsFromGetCountNow = 0;
LOG_HR(pEnum->GetCount(&cItemsFromGetCountNow), == S_OK);
LOG_CMP(cItemsFromGetCountNow, ==, cItemsFromGetCount);
// get the next item
storage_type Item;
ULONG cFetched = 0;
hr = pEnum->Next(1, &Item, &cFetched);
cItemsFromNext += cFetched;
}
while (hr == S_OK);
LOG_HR(hr, == S_FALSE);
// verify that the two counts are equal
LOG_CMP(cItemsFromNext, ==, cItemsFromGetCount);
}
// test bad param
if (m_bRunBadParamTests)
{
LOG_HR(pEnum->GetCount(0), != S_OK);
}
}
#endif //DEFINE_TEMPLATES