windows-nt/Source/XPSP1/NT/base/fs/hsm/wsb/wsbenum.cpp
2020-09-26 16:20:57 +08:00

1154 lines
25 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
© 1998 Seagate Software, Inc. All rights reserved
Module Name:
wsbenum.cpp
Abstract:
These classes provides enumerators (iterators) for the collection classes.
Author:
Chuck Bardeen [cbardeen] 29-Oct-1996
Revision History:
--*/
#include "stdafx.h"
#include "wsbenum.h"
HRESULT
CWsbIndexedEnum::Clone(
OUT IWsbEnum** ppEnum
)
/*++
Implements:
IWsbEnum::Clone
--*/
{
HRESULT hr = S_OK;
CComPtr<IWsbEnum> pWsbEnum;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Clone(IWsbEnum)"), OLESTR(""));
try {
// Create a new enumeration instance.
WsbAffirmHr(CoCreateInstance(CLSID_CWsbIndexedEnum, NULL, CLSCTX_ALL, IID_IWsbEnum, (void**) &pWsbEnum));
// It should reference the same collection.
WsbAffirmHr(pWsbEnum->Init((IWsbCollection*) m_pCollection));
// It should reference the same item in the collection.
WsbAffirmHr(pWsbEnum->SkipTo(m_currentIndex));
*ppEnum = pWsbEnum;
pWsbEnum->AddRef();
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::Clone(IWbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::Clone(
OUT IWsbEnumEx** ppEnum
)
/*++
Implements:
IWsbEnumEx::Clone
--*/
{
HRESULT hr = S_OK;
CComPtr<IWsbEnumEx> pWsbEnum;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Clone(IWsbEnumEx)"), OLESTR(""));
try {
// Create a new enumeration instance.
WsbAffirmHr(CoCreateInstance(CLSID_CWsbIndexedEnum, NULL, CLSCTX_ALL, IID_IWsbEnumEx, (void**) &pWsbEnum));
// It should reference the same collection.
WsbAffirmHr(pWsbEnum->Init((IWsbCollection*) m_pCollection));
// It should reference the same item in the collection.
WsbAffirmHr(pWsbEnum->SkipTo(m_currentIndex));
*ppEnum = pWsbEnum;
pWsbEnum->AddRef();
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::Clone(IWbEnumEx)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::Clone(
OUT IEnumUnknown** ppEnum
)
/*++
Implements:
IEnumUknown::Clone
--*/
{
HRESULT hr = S_OK;
CComPtr<IWsbEnum> pWsbEnum;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Clone(IEnumUnknown)"), OLESTR(""));
try {
// This does the major part of the work.
WsbAffirmHr(Clone(&pWsbEnum));
// Now get them the interace that they wanted.
WsbAffirmHr(pWsbEnum->QueryInterface(IID_IEnumUnknown, (void**) ppEnum));
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::Clone(IEnumUnknown)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
#pragma optimize("g", off)
HRESULT
CWsbIndexedEnum::FinalConstruct(
void
)
/*++
Implements:
CComObjectRoot::FinalConstruct
--*/
{
HRESULT hr = S_OK;
try {
WsbAffirmHr(CComObjectRoot::FinalConstruct());
m_currentIndex = 0;
} WsbCatch(hr);
return(hr);
}
#pragma optimize("", on)
HRESULT
CWsbIndexedEnum::Find(
IN IUnknown* pCollectable,
IN REFIID riid,
OUT void** ppElement
)
/*++
Implements:
IWsbEnum::Find
--*/
{
HRESULT hr = S_OK;
ULONG elementsFetched;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Find(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
try {
hr = m_pCollection->CopyIfMatches(WSB_COLLECTION_MIN_INDEX, WSB_COLLECTION_MAX_INDEX, pCollectable, 1, riid, ppElement, &elementsFetched, &m_currentIndex);
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::Find(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::Find(
IN IUnknown* pCollectable,
IN ULONG element,
IN REFIID riid,
OUT void** elements,
OUT ULONG* pElementsFetched
)
/*++
Implements:
IWsbEnumEx::Find
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Find(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
try {
hr = m_pCollection->CopyIfMatches(WSB_COLLECTION_MIN_INDEX, WSB_COLLECTION_MAX_INDEX, pCollectable, element, riid, elements, pElementsFetched, &m_currentIndex);
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::Find(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%ls>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
return(hr);
}
HRESULT
CWsbIndexedEnum::FindNext(
IN IUnknown* pCollectable,
IN REFIID riid,
OUT void** ppElement
)
/*++
Implements:
IWsbEnum::FindNext
--*/
{
HRESULT hr = S_OK;
ULONG elementsFetched;
WsbTraceIn(OLESTR("CWsbIndexedEnum::FindNext(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
try {
// If we are already at the end of the list, then you can't go any
// further.
WsbAffirm(WSB_COLLECTION_MAX_INDEX != m_currentIndex, WSB_E_NOTFOUND);
hr = m_pCollection->CopyIfMatches(m_currentIndex + 1, WSB_COLLECTION_MAX_INDEX, pCollectable, 1, riid, ppElement, &elementsFetched, &m_currentIndex);
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::FindNext(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::FindNext(
IN IUnknown* pCollectable,
IN ULONG element,
IN REFIID riid,
OUT void** elements,
OUT ULONG* pElementsFetched
)
/*++
Implements:
IWsbEnumEx::FindNext
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CWsbIndexedEnum::FindNext(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
try {
// If we are already at the end of the list, then you can't go any
// further.
WsbAffirm(WSB_COLLECTION_MAX_INDEX != m_currentIndex, WSB_E_NOTFOUND);
hr = m_pCollection->CopyIfMatches(m_currentIndex + 1, WSB_COLLECTION_MAX_INDEX, pCollectable, element, riid, elements, pElementsFetched, &m_currentIndex);
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::FindNext(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%ls>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
return(hr);
}
HRESULT
CWsbIndexedEnum::FindPrevious(
IN IUnknown* pCollectable,
IN REFIID riid,
OUT void** ppElement
)
/*++
Implements:
IWsbEnum::FindPrevious
--*/
{
HRESULT hr = S_OK;
ULONG elementsFetched;
WsbTraceIn(OLESTR("CWsbIndexedEnum::FindPrevious(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
try {
// If we are already at the beginning of the list, then you can't go any
// further.
WsbAffirm(WSB_COLLECTION_MIN_INDEX != m_currentIndex, WSB_E_NOTFOUND);
hr = m_pCollection->CopyIfMatches(m_currentIndex - 1, WSB_COLLECTION_MIN_INDEX, pCollectable, 1, riid, ppElement, &elementsFetched, &m_currentIndex);
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::FindPrevious(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::FindPrevious(
IN IUnknown* pCollectable,
IN ULONG element,
IN REFIID riid,
OUT void** elements,
OUT ULONG* pElementsFetched
)
/*++
Implements:
IWsbEnumEx::FindPrevious
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CWsbIndexedEnum::FindPrevious(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
try {
// If we are already at the beginning of the list, then you can't go any
// further.
WsbAffirm(WSB_COLLECTION_MIN_INDEX != m_currentIndex, WSB_E_NOTFOUND);
hr = m_pCollection->CopyIfMatches(m_currentIndex - 1, WSB_COLLECTION_MIN_INDEX, pCollectable, element, riid, elements, pElementsFetched, &m_currentIndex);
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::FindPrevious(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%ls>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
return(hr);
}
HRESULT
CWsbIndexedEnum::First(
IN REFIID riid,
OUT void** ppElement
)
/*++
Implements:
IWsbEnum::First
--*/
{
HRESULT hr = S_OK;
ULONG fetched = 0;
WsbTraceIn(OLESTR("CWsbIndexedEnum::First(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
try {
// Since we aren't doing any addition to the number of elements, the
// Copy command does all the range checking that we need.
WsbAffirmHr(m_pCollection->Copy(WSB_COLLECTION_MIN_INDEX, 0, riid, ppElement, &fetched));
// If items were read, then update the current index, and return to
// them the number of elements fetched if they wanted to know.
m_currentIndex = 0;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::First(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::First(
IN ULONG element,
IN REFIID riid,
OUT void** elements,
OUT ULONG* pElementsFetched
)
/*++
Implements:
IWsbEnumEx::First
--*/
{
HRESULT hr = S_OK;
ULONG fetched = 0;
WsbTraceIn(OLESTR("CWsbIndexedEnum::First(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
try {
WsbAssert((0 != pElementsFetched), E_POINTER);
// Since we aren't doing any addition to the number of elements, the
// Copy command does all the range checking that we need.
WsbAffirmHr(m_pCollection->Copy(WSB_COLLECTION_MIN_INDEX, element - 1, riid, elements, &fetched));
// If items were read, then update the current index, and return to
// them the number of elements fetched if they wanted to know.
m_currentIndex = fetched - 1;
*pElementsFetched = fetched;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::First(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%lu>"), WsbHrAsString(hr), fetched);
return(hr);
}
HRESULT
CWsbIndexedEnum::Init(
IN IWsbCollection* pCollection
)
/*++
Implements:
IWsbEnum::Init
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Init"), OLESTR(""));
try {
WsbAssert(0 != pCollection, E_POINTER);
// Only let them initialize the enumeration once.
WsbAssert(m_pCollection == 0, S_FALSE);
// Since this enum is for indexed collections, get an indexed
// interface to it.
WsbAffirmHr(pCollection->QueryInterface(IID_IWsbIndexedCollection, (void**) &m_pCollection));
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::Init"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
};
HRESULT
CWsbIndexedEnum::Last(
IN REFIID riid,
OUT void** ppElement
)
/*++
Implements:
IWsbEnum::Last
--*/
{
HRESULT hr = S_OK;
ULONG entries;
ULONG fetched;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Last(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
try {
// Find out where the end is located.
WsbAffirmHr(m_pCollection->GetEntries(&entries));
// We must have some entries.
WsbAffirm(entries != 0, WSB_E_NOTFOUND);
WsbAffirmHr(m_pCollection->Copy(entries - 1, entries - 1, riid, ppElement, &fetched));
// If items were read, then update the current index, and return to
// them the number of elements fetched if they wanted to know.
m_currentIndex = entries - fetched;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::Last(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::Last(
IN ULONG element,
IN REFIID riid,
OUT void** elements,
OUT ULONG* pElementsFetched
)
/*++
Implements:
IWsbEnumEx::Last
--*/
{
HRESULT hr = S_OK;
ULONG entries;
ULONG fetched;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Last(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
try {
WsbAssertPointer(pElementsFetched);
// Find out where the end is located.
WsbAffirmHr(m_pCollection->GetEntries(&entries));
// We must have some entries.
WsbAffirm(entries != 0, WSB_E_NOTFOUND);
// If they have asked for more elements than could be represented by
// then index, then don't let the index wrap around.
if (element > entries) {
WsbAffirmHr(m_pCollection->Copy(entries - 1, WSB_COLLECTION_MIN_INDEX, riid, elements, &fetched));
// Let them know that they didn't get all the items they requested.
hr = S_FALSE;
} else {
WsbAffirmHr(m_pCollection->Copy(entries - 1, entries - element, riid, elements, &fetched));
}
// If items were read, then update the current index, and return to
// them the number of elements fetched if they wanted to know.
m_currentIndex = entries - fetched;
*pElementsFetched = fetched;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::Last(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%lu>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
return(hr);
}
HRESULT
CWsbIndexedEnum::Next(
IN ULONG element,
OUT IUnknown** elements,
OUT ULONG* pElementsFetched
)
/*++
Implements:
IEnumUknown::Next
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Next(IEnumUnknown)"), OLESTR("element = <%lu>"), element);
hr = Next(element, IID_IUnknown, (void**) elements, pElementsFetched);
WsbTraceOut(OLESTR("CWsbIndexedEnum::Next(IEnumUnknown)"), OLESTR("hr = <%ls>, fetched = <%lu>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
return(hr);
}
HRESULT
CWsbIndexedEnum::Next(
IN REFIID riid,
OUT void** ppElement
)
/*++
Implements:
IWsbEnum::Next
--*/
{
HRESULT hr = S_OK;
ULONG fetched;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Next(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
try {
// If we are already at the end of the list, then you can't go any
// further.
WsbAffirm(WSB_COLLECTION_MAX_INDEX != m_currentIndex, WSB_E_NOTFOUND);
WsbAffirmHr(m_pCollection->Copy(m_currentIndex + 1, m_currentIndex + 1, riid, ppElement, &fetched));
m_currentIndex += fetched;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::Next(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::Next(
IN ULONG element,
IN REFIID riid,
OUT void** elements,
OUT ULONG* pElementsFetched
)
/*++
Implements:
IWsbEnumEx::Next
--*/
{
HRESULT hr = S_OK;
ULONG fetched;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Next(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
try {
WsbAssert(0 != element, E_INVALIDARG);
WsbAssertPointer(pElementsFetched);
// If we are already at the end of the list, then you can't go any
// further.
WsbAffirm(WSB_COLLECTION_MAX_INDEX != m_currentIndex, WSB_E_NOTFOUND);
// If they have asked for more elements than could be represented by
// then index, then don't let the index wrap around.
if ((WSB_COLLECTION_MAX_INDEX - m_currentIndex) < element) {
WsbAffirmHr(m_pCollection->Copy(m_currentIndex + 1, WSB_COLLECTION_MAX_INDEX, riid, elements, &fetched));
// Let them know that they didn't get all the items they requested.
hr = S_FALSE;
} else {
WsbAffirmHr(m_pCollection->Copy(m_currentIndex + 1, m_currentIndex + element, riid, elements, &fetched));
}
m_currentIndex += fetched;
*pElementsFetched = fetched;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::Next(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%lu>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
return(hr);
}
HRESULT
CWsbIndexedEnum::Previous(
IN REFIID riid,
OUT void** ppElement
)
/*++
Implements:
IWsbEnum::Previous
--*/
{
HRESULT hr = S_OK;
ULONG fetched;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Previous(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
try {
// If we are already at the beginning of the list, then you can't go any
// further.
WsbAffirm(m_currentIndex != WSB_COLLECTION_MIN_INDEX, WSB_E_NOTFOUND);
WsbAffirmHr(m_pCollection->Copy(m_currentIndex - 1, m_currentIndex - 1, riid, ppElement, &fetched));
m_currentIndex -= fetched;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::Previous(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::Previous(
IN ULONG element,
IN REFIID riid,
OUT void** elements,
IN ULONG* pElementsFetched
)
/*++
Implements:
IWsbEnum::Previous
--*/
{
HRESULT hr = S_OK;
ULONG fetched;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Previous(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
try {
WsbAssertPointer(pElementsFetched);
// If we are already at the beginning of the list, then you can't go any
// further.
WsbAffirm(m_currentIndex != WSB_COLLECTION_MIN_INDEX, WSB_E_NOTFOUND);
// If they have asked for more elements than are before us in the
// collection, then don't let the index wrap around.
if (m_currentIndex < element) {
WsbAffirmHr(m_pCollection->Copy(m_currentIndex - 1, WSB_COLLECTION_MIN_INDEX, riid, elements, &fetched));
// Let them know that they didn't get all the items they requested.
hr = S_FALSE;
} else {
WsbAffirmHr(m_pCollection->Copy(m_currentIndex - 1, m_currentIndex - element, riid, elements, &fetched));
}
m_currentIndex -= fetched;
*pElementsFetched = fetched;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::Previous(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%lu>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
return(hr);
}
HRESULT
CWsbIndexedEnum::Reset(
void
)
/*++
Implements:
IEnumUnknown::Reset
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Reset"), OLESTR(""));
hr = SkipToFirst();
WsbTraceOut(OLESTR("CWsbIndexedEnum::Reset"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(S_OK);
}
HRESULT
CWsbIndexedEnum::Skip(
IN ULONG element
)
/*++
Implements:
IEnumUnknown::Skip
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CWsbIndexedEnum::Skip"), OLESTR("element = <%lu>"), element);
hr = SkipNext(element);
WsbTraceOut(OLESTR("CWsbIndexedEnum::Skip"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::SkipNext(
IN ULONG element
)
/*++
Implements:
IWsbEnum::SkipNext
--*/
{
HRESULT hr = S_OK;
ULONG entries;
WsbTraceIn(OLESTR("CWsbIndexedEnum::SkipNext"), OLESTR("element = <%lu>"), element);
try {
// Find out where the end is located.
WsbAffirmHr(m_pCollection->GetEntries(&entries));
// If there aren't any entries, then put it at the beginning
// and let them no it was empty.
if (0 == entries) {
hr = S_FALSE;
m_currentIndex = WSB_COLLECTION_MIN_INDEX;
}
// Are we already at the end of the list, or have they requested
// to go beyond the end of the list?
else if ((m_currentIndex >= (entries - 1)) ||
((entries - m_currentIndex) < element)) {
hr = S_FALSE;
m_currentIndex = entries - 1;
}
// They asked for something legal.
else {
m_currentIndex += element;
}
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::SkipNext"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::SkipPrevious(
IN ULONG element
)
/*++
Implements:
IWsbEnum::SkipPrevious
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CWsbIndexedEnum::SkipPrevious"), OLESTR("element = <%lu>"), element);
// If we are already at the beginning of the list, then you can't go any
// further.
if (m_currentIndex == WSB_COLLECTION_MIN_INDEX) {
hr = S_FALSE;
}
// If they have asked for more elements than could be represented by
// then index, then don't let the index wrap around.
else if (m_currentIndex < element) {
m_currentIndex = WSB_COLLECTION_MIN_INDEX;
// Let them know that they didn't get all the items they requested.
hr = S_FALSE;
}
// They asked for something legal.
else {
m_currentIndex -= element;
}
WsbTraceOut(OLESTR("CWsbIndexedEnum::SkipPrevious"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::SkipTo(
IN ULONG index
)
/*++
Implements:
IWsbEnum::SkipTo
--*/
{
HRESULT hr = S_OK;
ULONG entries;
WsbTraceIn(OLESTR("CWsbIndexedEnum::SkipToIndex"), OLESTR("index = <%lu>"), index);
try {
// Find out where the end is located.
WsbAffirmHr(m_pCollection->GetEntries(&entries));
// If there aren't any entries, then put it at the beginning
// and let them no it was empty.
if (0 == entries) {
hr = S_FALSE;
m_currentIndex = WSB_COLLECTION_MIN_INDEX;
}
// They asked for something beyond the end of the collection, so
// put them at the end of the collection and let them now there
// was a problem.
else if (index > (entries - 1)) {
hr = S_FALSE;
m_currentIndex = entries - 1;
}
// They asked for something legal.
else {
m_currentIndex = index;
}
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::SkipToIndex"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::SkipToFirst(
void
)
/*++
Implements:
IWsbEnum::SkipToFirst
--*/
{
HRESULT hr = S_OK;
ULONG entries;
WsbTraceIn(OLESTR("CWsbIndexedEnum::SkipToFirst"), OLESTR(""));
try {
// Find out where the end is located.
WsbAffirmHr(m_pCollection->GetEntries(&entries));
// If there aren't any entries, then put it at the beginning
// and let them no it was empty.
if (0 == entries) {
hr = S_FALSE;
}
m_currentIndex = WSB_COLLECTION_MIN_INDEX;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::SkipToFirst"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::SkipToLast(
void
)
/*++
Implements:
IWsbEnum::SkipToLast
--*/
{
HRESULT hr = S_OK;
ULONG entries;
WsbTraceIn(OLESTR("CWsbIndexedEnum::SkipToLast"), OLESTR(""));
try {
// Find out where the end is located.
WsbAffirmHr(m_pCollection->GetEntries(&entries));
// If there aren't any entries, then put it at the beginning
// and let them no it was empty.
if (0 == entries) {
hr = S_FALSE;
m_currentIndex = WSB_COLLECTION_MIN_INDEX;
}
// They asked for something legal.
else {
m_currentIndex = entries - 1;
}
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::SkipToLast"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::This(
IN REFIID riid,
OUT void** ppElement
)
/*++
Implements:
IWsbEnum::This
--*/
{
HRESULT hr = S_OK;
ULONG fetched;
WsbTraceIn(OLESTR("CWsbIndexedEnum::This(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
try {
WsbAssert(0 != ppElement, E_POINTER);
WsbAffirmHr(m_pCollection->Copy(m_currentIndex, m_currentIndex, riid, ppElement, &fetched));
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::This(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CWsbIndexedEnum::This(
IN ULONG element,
IN REFIID riid,
OUT void** elements,
OUT ULONG* pElementsFetched
)
/*++
Implements:
IWsbEnum::This
--*/
{
HRESULT hr = S_OK;
ULONG fetched;
WsbTraceIn(OLESTR("CWsbIndexedEnum::This(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
try {
WsbAssert(0 != element, E_INVALIDARG);
WsbAssertPointer(elements);
WsbAssertPointer(pElementsFetched);
// If they have asked for more elements than could be represented by
// then index, then don't let the index wrap around.
if ((WSB_COLLECTION_MAX_INDEX - m_currentIndex) <= element) {
WsbAffirmHr(m_pCollection->Copy(m_currentIndex, WSB_COLLECTION_MAX_INDEX, riid, elements, &fetched));
// Let them know that they didn't get all the items they requested.
hr = S_FALSE;
} else {
WsbAffirmHr(m_pCollection->Copy(m_currentIndex, m_currentIndex + element - 1, riid, elements, &fetched));
}
*pElementsFetched = fetched - 1;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CWsbIndexedEnum::This(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%lu>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
return(hr);
}