You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
4.1 KiB
169 lines
4.1 KiB
//
|
|
// erfa.cpp
|
|
//
|
|
// CEnumRangesFromAnchorsBase
|
|
//
|
|
// Base class for range enumerators.
|
|
//
|
|
|
|
#include "private.h"
|
|
#include "erfa.h"
|
|
#include "saa.h"
|
|
#include "ic.h"
|
|
#include "range.h"
|
|
#include "immxutil.h"
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// dtor
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CEnumRangesFromAnchorsBase::~CEnumRangesFromAnchorsBase()
|
|
{
|
|
SafeRelease(_pic);
|
|
|
|
if (_prgAnchors != NULL)
|
|
{
|
|
_prgAnchors->_Release();
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Clone
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CEnumRangesFromAnchorsBase::Clone(IEnumTfRanges **ppEnum)
|
|
{
|
|
CEnumRangesFromAnchorsBase *pClone;
|
|
|
|
if (ppEnum == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
*ppEnum = NULL;
|
|
|
|
if ((pClone = new CEnumRangesFromAnchorsBase) == NULL)
|
|
return E_OUTOFMEMORY;
|
|
|
|
pClone->_iCur = _iCur;
|
|
|
|
pClone->_prgAnchors = _prgAnchors;
|
|
pClone->_prgAnchors->_AddRef();
|
|
|
|
pClone->_pic = _pic;
|
|
pClone->_pic->AddRef();
|
|
|
|
*ppEnum = pClone;
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Next
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CEnumRangesFromAnchorsBase::Next(ULONG ulCount, ITfRange **ppRange, ULONG *pcFetched)
|
|
{
|
|
ULONG cFetched;
|
|
CRange *range;
|
|
IAnchor *paPrev;
|
|
IAnchor *pa;
|
|
int iCurOld;
|
|
|
|
if (pcFetched == NULL)
|
|
{
|
|
pcFetched = &cFetched;
|
|
}
|
|
*pcFetched = 0;
|
|
iCurOld = _iCur;
|
|
|
|
if (ulCount > 0 && ppRange == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
// special case empty enum, or 1 anchor enum
|
|
if (_prgAnchors->Count() < 2)
|
|
{
|
|
if (_prgAnchors->Count() == 0 || _iCur > 0)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
// when we have a single anchor in the enum, need to handle it carefully
|
|
if ((range = new CRange) == NULL)
|
|
return E_OUTOFMEMORY;
|
|
if (!range->_InitWithDefaultGravity(_pic, COPY_ANCHORS, _prgAnchors->Get(0), _prgAnchors->Get(0)))
|
|
{
|
|
range->Release();
|
|
return E_FAIL;
|
|
}
|
|
|
|
*ppRange = (ITfRangeAnchor *)range;
|
|
*pcFetched = 1;
|
|
_iCur = 1;
|
|
goto Exit;
|
|
}
|
|
|
|
paPrev = _prgAnchors->Get(_iCur);
|
|
|
|
while (_iCur < _prgAnchors->Count()-1 && *pcFetched < ulCount)
|
|
{
|
|
pa = _prgAnchors->Get(_iCur+1);
|
|
|
|
if ((range = new CRange) == NULL)
|
|
goto ErrorExit;
|
|
if (!range->_InitWithDefaultGravity(_pic, COPY_ANCHORS, paPrev, pa))
|
|
{
|
|
range->Release();
|
|
goto ErrorExit;
|
|
}
|
|
|
|
// we should never be returning empty ranges, since currently this base
|
|
// class is only used for property enums and property spans are never
|
|
// empty.
|
|
// Similarly, paPrev should always precede pa.
|
|
Assert(CompareAnchors(paPrev, pa) < 0);
|
|
|
|
*ppRange++ = (ITfRangeAnchor *)range;
|
|
*pcFetched = *pcFetched + 1;
|
|
_iCur++;
|
|
paPrev = pa;
|
|
}
|
|
|
|
Exit:
|
|
return *pcFetched == ulCount ? S_OK : S_FALSE;
|
|
|
|
ErrorExit:
|
|
while (--_iCur > iCurOld) // Issue: just return what we have, rather than freeing everything
|
|
{
|
|
(*--ppRange)->Release();
|
|
}
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Reset
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CEnumRangesFromAnchorsBase::Reset()
|
|
{
|
|
_iCur = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Skip
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CEnumRangesFromAnchorsBase::Skip(ULONG ulCount)
|
|
{
|
|
_iCur += ulCount;
|
|
|
|
return (_iCur > _prgAnchors->Count()-1) ? S_FALSE : S_OK;
|
|
}
|
|
|