Leaked source code of windows server 2003
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.
 
 
 
 
 
 

206 lines
4.7 KiB

//
// enumss.cpp
//
// CEnumSpanSetRanges
//
#include "private.h"
#include "enumss.h"
#include "range.h"
DBG_ID_INSTANCE(CEnumSpanSetRanges);
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CEnumSpanSetRanges::CEnumSpanSetRanges(CInputContext *pic)
{
Dbg_MemSetThisNameID(TEXT("CEnumSpanSetRanges"));
_pic = pic;
_pic->AddRef();
}
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CEnumSpanSetRanges::~CEnumSpanSetRanges()
{
_pic->Release();
}
//+---------------------------------------------------------------------------
//
// Clone
//
//----------------------------------------------------------------------------
STDAPI CEnumSpanSetRanges::Clone(IEnumTfRanges **ppEnum)
{
CEnumSpanSetRanges *pClone;
SPAN *pSpanSrc;
SPAN *pSpanDst;
int i;
if (ppEnum == NULL)
return E_INVALIDARG;
*ppEnum = NULL;
if ((pClone = new CEnumSpanSetRanges(_pic)) == NULL)
return E_OUTOFMEMORY;
pClone->_iCur = _iCur;
i = 0;
if (!pClone->_rgSpans.Insert(0, _rgSpans.Count()))
goto ErrorExit;
for (; i<_rgSpans.Count(); i++)
{
pSpanDst = pClone->_rgSpans.GetPtr(i);
pSpanSrc = _rgSpans.GetPtr(i);
pSpanDst->paStart = pSpanDst->paEnd = NULL;
if (pSpanSrc->paStart->Clone(&pSpanDst->paStart)!= S_OK)
goto ErrorExit;
if (pSpanSrc->paEnd->Clone(&pSpanDst->paEnd) != S_OK)
goto ErrorExit;
pSpanDst->dwFlags = pSpanSrc->dwFlags;
}
*ppEnum = pClone;
return S_OK;
ErrorExit:
for (; i>=0; i--)
{
pSpanDst = pClone->_rgSpans.GetPtr(i);
if (pSpanDst != NULL)
{
SafeRelease(pSpanDst->paStart);
SafeRelease(pSpanDst->paEnd);
}
}
pClone->Release();
return E_OUTOFMEMORY;
}
//+---------------------------------------------------------------------------
//
// Next
//
//----------------------------------------------------------------------------
STDAPI CEnumSpanSetRanges::Next(ULONG ulCount, ITfRange **ppRange, ULONG *pcFetched)
{
ULONG cFetched;
CRange *range;
SPAN *pSpan;
int iCurOld;
if (pcFetched == NULL)
{
pcFetched = &cFetched;
}
*pcFetched = 0;
iCurOld = _iCur;
if (ulCount > 0 && ppRange == NULL)
return E_INVALIDARG;
while (_iCur < _rgSpans.Count() && *pcFetched < ulCount)
{
pSpan = _rgSpans.GetPtr(_iCur);
if ((range = new CRange) == NULL)
goto ErrorExit;
if (!range->_InitWithDefaultGravity(_pic, COPY_ANCHORS, pSpan->paStart, pSpan->paEnd))
{
range->Release();
goto ErrorExit;
}
*ppRange++ = (ITfRangeAnchor *)range;
*pcFetched = *pcFetched + 1;
_iCur++;
}
return *pcFetched == ulCount ? S_OK : S_FALSE;
ErrorExit:
while (--_iCur > iCurOld)
{
(*--ppRange)->Release();
}
return E_OUTOFMEMORY;
}
//+---------------------------------------------------------------------------
//
// Reset
//
//----------------------------------------------------------------------------
STDAPI CEnumSpanSetRanges::Reset()
{
_iCur = 0;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Skip
//
//----------------------------------------------------------------------------
STDAPI CEnumSpanSetRanges::Skip(ULONG ulCount)
{
_iCur += ulCount;
return (_iCur > _rgSpans.Count()) ? S_FALSE : S_OK;
}
//+---------------------------------------------------------------------------
//
// _Merge
//
//----------------------------------------------------------------------------
void CEnumSpanSetRanges::_Merge(CSpanSet *pss)
{
int i;
SPAN *rgSpans;
//
// perf: this method could be much more efficient -> O(n log n) -> O(n)
// we could take advantage of the fact that we are always
// adding new spans _that are already ordered_.
//
// get rid of any NULL/NULL spans -> covers entire doc
//
// perf: wait to normalize until all _Merge calls are done!
//
if (!pss->Normalize(_pic->_GetTSI()))
{
Assert(0); // doh!
return;
}
rgSpans = pss->GetSpans();
for (i=0; i<pss->GetCount();i++)
{
Add(0, rgSpans[i].paStart, rgSpans[i].paEnd, COPY_ANCHORS);
}
}