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

  1. //
  2. // enumss.cpp
  3. //
  4. // CEnumSpanSetRanges
  5. //
  6. #include "private.h"
  7. #include "enumss.h"
  8. #include "range.h"
  9. DBG_ID_INSTANCE(CEnumSpanSetRanges);
  10. //+---------------------------------------------------------------------------
  11. //
  12. // ctor
  13. //
  14. //----------------------------------------------------------------------------
  15. CEnumSpanSetRanges::CEnumSpanSetRanges(CInputContext *pic)
  16. {
  17. Dbg_MemSetThisNameID(TEXT("CEnumSpanSetRanges"));
  18. _pic = pic;
  19. _pic->AddRef();
  20. }
  21. //+---------------------------------------------------------------------------
  22. //
  23. // dtor
  24. //
  25. //----------------------------------------------------------------------------
  26. CEnumSpanSetRanges::~CEnumSpanSetRanges()
  27. {
  28. _pic->Release();
  29. }
  30. //+---------------------------------------------------------------------------
  31. //
  32. // Clone
  33. //
  34. //----------------------------------------------------------------------------
  35. STDAPI CEnumSpanSetRanges::Clone(IEnumTfRanges **ppEnum)
  36. {
  37. CEnumSpanSetRanges *pClone;
  38. SPAN *pSpanSrc;
  39. SPAN *pSpanDst;
  40. int i;
  41. if (ppEnum == NULL)
  42. return E_INVALIDARG;
  43. *ppEnum = NULL;
  44. if ((pClone = new CEnumSpanSetRanges(_pic)) == NULL)
  45. return E_OUTOFMEMORY;
  46. pClone->_iCur = _iCur;
  47. i = 0;
  48. if (!pClone->_rgSpans.Insert(0, _rgSpans.Count()))
  49. goto ErrorExit;
  50. for (; i<_rgSpans.Count(); i++)
  51. {
  52. pSpanDst = pClone->_rgSpans.GetPtr(i);
  53. pSpanSrc = _rgSpans.GetPtr(i);
  54. pSpanDst->paStart = pSpanDst->paEnd = NULL;
  55. if (pSpanSrc->paStart->Clone(&pSpanDst->paStart)!= S_OK)
  56. goto ErrorExit;
  57. if (pSpanSrc->paEnd->Clone(&pSpanDst->paEnd) != S_OK)
  58. goto ErrorExit;
  59. pSpanDst->dwFlags = pSpanSrc->dwFlags;
  60. }
  61. *ppEnum = pClone;
  62. return S_OK;
  63. ErrorExit:
  64. for (; i>=0; i--)
  65. {
  66. pSpanDst = pClone->_rgSpans.GetPtr(i);
  67. if (pSpanDst != NULL)
  68. {
  69. SafeRelease(pSpanDst->paStart);
  70. SafeRelease(pSpanDst->paEnd);
  71. }
  72. }
  73. pClone->Release();
  74. return E_OUTOFMEMORY;
  75. }
  76. //+---------------------------------------------------------------------------
  77. //
  78. // Next
  79. //
  80. //----------------------------------------------------------------------------
  81. STDAPI CEnumSpanSetRanges::Next(ULONG ulCount, ITfRange **ppRange, ULONG *pcFetched)
  82. {
  83. ULONG cFetched;
  84. CRange *range;
  85. SPAN *pSpan;
  86. int iCurOld;
  87. if (pcFetched == NULL)
  88. {
  89. pcFetched = &cFetched;
  90. }
  91. *pcFetched = 0;
  92. iCurOld = _iCur;
  93. if (ulCount > 0 && ppRange == NULL)
  94. return E_INVALIDARG;
  95. while (_iCur < _rgSpans.Count() && *pcFetched < ulCount)
  96. {
  97. pSpan = _rgSpans.GetPtr(_iCur);
  98. if ((range = new CRange) == NULL)
  99. goto ErrorExit;
  100. if (!range->_InitWithDefaultGravity(_pic, COPY_ANCHORS, pSpan->paStart, pSpan->paEnd))
  101. {
  102. range->Release();
  103. goto ErrorExit;
  104. }
  105. *ppRange++ = (ITfRangeAnchor *)range;
  106. *pcFetched = *pcFetched + 1;
  107. _iCur++;
  108. }
  109. return *pcFetched == ulCount ? S_OK : S_FALSE;
  110. ErrorExit:
  111. while (--_iCur > iCurOld)
  112. {
  113. (*--ppRange)->Release();
  114. }
  115. return E_OUTOFMEMORY;
  116. }
  117. //+---------------------------------------------------------------------------
  118. //
  119. // Reset
  120. //
  121. //----------------------------------------------------------------------------
  122. STDAPI CEnumSpanSetRanges::Reset()
  123. {
  124. _iCur = 0;
  125. return S_OK;
  126. }
  127. //+---------------------------------------------------------------------------
  128. //
  129. // Skip
  130. //
  131. //----------------------------------------------------------------------------
  132. STDAPI CEnumSpanSetRanges::Skip(ULONG ulCount)
  133. {
  134. _iCur += ulCount;
  135. return (_iCur > _rgSpans.Count()) ? S_FALSE : S_OK;
  136. }
  137. //+---------------------------------------------------------------------------
  138. //
  139. // _Merge
  140. //
  141. //----------------------------------------------------------------------------
  142. void CEnumSpanSetRanges::_Merge(CSpanSet *pss)
  143. {
  144. int i;
  145. SPAN *rgSpans;
  146. //
  147. // perf: this method could be much more efficient -> O(n log n) -> O(n)
  148. // we could take advantage of the fact that we are always
  149. // adding new spans _that are already ordered_.
  150. //
  151. // get rid of any NULL/NULL spans -> covers entire doc
  152. //
  153. // perf: wait to normalize until all _Merge calls are done!
  154. //
  155. if (!pss->Normalize(_pic->_GetTSI()))
  156. {
  157. Assert(0); // doh!
  158. return;
  159. }
  160. rgSpans = pss->GetSpans();
  161. for (i=0; i<pss->GetCount();i++)
  162. {
  163. Add(0, rgSpans[i].paStart, rgSpans[i].paEnd, COPY_ANCHORS);
  164. }
  165. }