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.

169 lines
4.1 KiB

  1. //
  2. // erfa.cpp
  3. //
  4. // CEnumRangesFromAnchorsBase
  5. //
  6. // Base class for range enumerators.
  7. //
  8. #include "private.h"
  9. #include "erfa.h"
  10. #include "saa.h"
  11. #include "ic.h"
  12. #include "range.h"
  13. #include "immxutil.h"
  14. //+---------------------------------------------------------------------------
  15. //
  16. // dtor
  17. //
  18. //----------------------------------------------------------------------------
  19. CEnumRangesFromAnchorsBase::~CEnumRangesFromAnchorsBase()
  20. {
  21. SafeRelease(_pic);
  22. if (_prgAnchors != NULL)
  23. {
  24. _prgAnchors->_Release();
  25. }
  26. }
  27. //+---------------------------------------------------------------------------
  28. //
  29. // Clone
  30. //
  31. //----------------------------------------------------------------------------
  32. STDAPI CEnumRangesFromAnchorsBase::Clone(IEnumTfRanges **ppEnum)
  33. {
  34. CEnumRangesFromAnchorsBase *pClone;
  35. if (ppEnum == NULL)
  36. return E_INVALIDARG;
  37. *ppEnum = NULL;
  38. if ((pClone = new CEnumRangesFromAnchorsBase) == NULL)
  39. return E_OUTOFMEMORY;
  40. pClone->_iCur = _iCur;
  41. pClone->_prgAnchors = _prgAnchors;
  42. pClone->_prgAnchors->_AddRef();
  43. pClone->_pic = _pic;
  44. pClone->_pic->AddRef();
  45. *ppEnum = pClone;
  46. return S_OK;
  47. }
  48. //+---------------------------------------------------------------------------
  49. //
  50. // Next
  51. //
  52. //----------------------------------------------------------------------------
  53. STDAPI CEnumRangesFromAnchorsBase::Next(ULONG ulCount, ITfRange **ppRange, ULONG *pcFetched)
  54. {
  55. ULONG cFetched;
  56. CRange *range;
  57. IAnchor *paPrev;
  58. IAnchor *pa;
  59. int iCurOld;
  60. if (pcFetched == NULL)
  61. {
  62. pcFetched = &cFetched;
  63. }
  64. *pcFetched = 0;
  65. iCurOld = _iCur;
  66. if (ulCount > 0 && ppRange == NULL)
  67. return E_INVALIDARG;
  68. // special case empty enum, or 1 anchor enum
  69. if (_prgAnchors->Count() < 2)
  70. {
  71. if (_prgAnchors->Count() == 0 || _iCur > 0)
  72. {
  73. return S_FALSE;
  74. }
  75. // when we have a single anchor in the enum, need to handle it carefully
  76. if ((range = new CRange) == NULL)
  77. return E_OUTOFMEMORY;
  78. if (!range->_InitWithDefaultGravity(_pic, COPY_ANCHORS, _prgAnchors->Get(0), _prgAnchors->Get(0)))
  79. {
  80. range->Release();
  81. return E_FAIL;
  82. }
  83. *ppRange = (ITfRangeAnchor *)range;
  84. *pcFetched = 1;
  85. _iCur = 1;
  86. goto Exit;
  87. }
  88. paPrev = _prgAnchors->Get(_iCur);
  89. while (_iCur < _prgAnchors->Count()-1 && *pcFetched < ulCount)
  90. {
  91. pa = _prgAnchors->Get(_iCur+1);
  92. if ((range = new CRange) == NULL)
  93. goto ErrorExit;
  94. if (!range->_InitWithDefaultGravity(_pic, COPY_ANCHORS, paPrev, pa))
  95. {
  96. range->Release();
  97. goto ErrorExit;
  98. }
  99. // we should never be returning empty ranges, since currently this base
  100. // class is only used for property enums and property spans are never
  101. // empty.
  102. // Similarly, paPrev should always precede pa.
  103. Assert(CompareAnchors(paPrev, pa) < 0);
  104. *ppRange++ = (ITfRangeAnchor *)range;
  105. *pcFetched = *pcFetched + 1;
  106. _iCur++;
  107. paPrev = pa;
  108. }
  109. Exit:
  110. return *pcFetched == ulCount ? S_OK : S_FALSE;
  111. ErrorExit:
  112. while (--_iCur > iCurOld) // Issue: just return what we have, rather than freeing everything
  113. {
  114. (*--ppRange)->Release();
  115. }
  116. return E_OUTOFMEMORY;
  117. }
  118. //+---------------------------------------------------------------------------
  119. //
  120. // Reset
  121. //
  122. //----------------------------------------------------------------------------
  123. STDAPI CEnumRangesFromAnchorsBase::Reset()
  124. {
  125. _iCur = 0;
  126. return S_OK;
  127. }
  128. //+---------------------------------------------------------------------------
  129. //
  130. // Skip
  131. //
  132. //----------------------------------------------------------------------------
  133. STDAPI CEnumRangesFromAnchorsBase::Skip(ULONG ulCount)
  134. {
  135. _iCur += ulCount;
  136. return (_iCur > _prgAnchors->Count()-1) ? S_FALSE : S_OK;
  137. }