Source code of Windows XP (NT5)
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.

125 lines
3.1 KiB

  1. // MLSBWalk.h : Declaration of the CMLStrBufWalk
  2. #ifndef __MLSBWALK_H_
  3. #define __MLSBWALK_H_
  4. /////////////////////////////////////////////////////////////////////////////
  5. // CMLStrBufWalk
  6. template <class IMLSTRBUF, class CHTYPE>
  7. class CMLStrBufWalk
  8. {
  9. public:
  10. inline CMLStrBufWalk(IMLSTRBUF* pMLStrBuf, long cchOffset, long cchLen, BOOL fCanStopAtMiddle = FALSE);
  11. BOOL Lock(HRESULT& rhr);
  12. void Unlock(HRESULT& rhr, long cchActual = 0);
  13. inline CHTYPE* GetStr(void);
  14. inline long GetCCh(void) const;
  15. inline long GetDoneCCh(void) const;
  16. inline long GetRestCCh(void) const;
  17. protected:
  18. IMLSTRBUF* m_pMLStrBuf;
  19. BOOL m_fCanStopAtMiddle;
  20. long m_cchOffset;
  21. long m_cchLen;
  22. long m_cchDone;
  23. CHTYPE* m_pszBuf;
  24. long m_cchBuf;
  25. };
  26. template <class IMLSTRBUF, class CHTYPE>
  27. CMLStrBufWalk<IMLSTRBUF, CHTYPE>::CMLStrBufWalk(IMLSTRBUF* pMLStrBuf, long cchOffset, long cchLen, BOOL fCanStopAtMiddle) :
  28. m_pMLStrBuf(pMLStrBuf),
  29. m_fCanStopAtMiddle(fCanStopAtMiddle)
  30. {
  31. m_cchOffset = cchOffset;
  32. m_cchLen = cchLen;
  33. m_cchDone = 0;
  34. m_pszBuf = NULL; // Mark as it's not locked
  35. }
  36. template <class IMLSTRBUF, class CHTYPE>
  37. BOOL CMLStrBufWalk<IMLSTRBUF, CHTYPE>::Lock(HRESULT& rhr)
  38. {
  39. if (m_pszBuf)
  40. rhr = E_FAIL; // Already locked
  41. if (SUCCEEDED(rhr) &&
  42. m_cchLen > 0 &&
  43. FAILED(rhr = m_pMLStrBuf->LockBuf(m_cchOffset, m_cchLen, &m_pszBuf, &m_cchBuf)))
  44. {
  45. m_pszBuf = NULL; // Mark as it's not locked
  46. }
  47. if (m_fCanStopAtMiddle && FAILED(rhr) && m_cchDone > 0)
  48. {
  49. rhr = S_OK;
  50. return FALSE; // Stop it, but not fail
  51. }
  52. else
  53. {
  54. return (SUCCEEDED(rhr) && m_cchLen > 0);
  55. }
  56. }
  57. template <class IMLSTRBUF, class CHTYPE>
  58. void CMLStrBufWalk<IMLSTRBUF, CHTYPE>::Unlock(HRESULT& rhr, long cchActual)
  59. {
  60. HRESULT hr = S_OK;
  61. if (!m_pszBuf)
  62. hr = E_FAIL; // Not locked yet
  63. if (SUCCEEDED(hr) &&
  64. SUCCEEDED(hr = m_pMLStrBuf->UnlockBuf(m_pszBuf, 0, 0))) // Unlock even if rhr is already failed
  65. {
  66. if (!cchActual)
  67. cchActual = m_cchBuf;
  68. else
  69. ASSERT(cchActual > 0 && cchActual <= m_cchBuf);
  70. m_cchOffset += cchActual;
  71. m_cchLen -= cchActual;
  72. m_cchDone += cchActual;
  73. }
  74. m_pszBuf = NULL; // Unlock anyway
  75. if (SUCCEEDED(rhr))
  76. rhr = hr; // if rhr is failed before UnlockBuf, use it
  77. }
  78. template <class IMLSTRBUF, class CHTYPE>
  79. CHTYPE* CMLStrBufWalk<IMLSTRBUF, CHTYPE>::GetStr(void)
  80. {
  81. ASSERT(m_pszBuf); // Not locked
  82. return m_pszBuf;
  83. }
  84. template <class IMLSTRBUF, class CHTYPE>
  85. long CMLStrBufWalk<IMLSTRBUF, CHTYPE>::GetCCh(void) const
  86. {
  87. ASSERT(m_pszBuf); // Not locked
  88. if (m_pszBuf)
  89. return m_cchBuf;
  90. else
  91. return 0;
  92. }
  93. template <class IMLSTRBUF, class CHTYPE>
  94. long CMLStrBufWalk<IMLSTRBUF, CHTYPE>::GetDoneCCh(void) const
  95. {
  96. return m_cchDone;
  97. }
  98. template <class IMLSTRBUF, class CHTYPE>
  99. long CMLStrBufWalk<IMLSTRBUF, CHTYPE>::GetRestCCh(void) const
  100. {
  101. return m_cchLen - m_cchDone;
  102. }
  103. typedef CMLStrBufWalk<IMLangStringBufW, WCHAR> CMLStrBufWalkW;
  104. typedef CMLStrBufWalk<IMLangStringBufA, CHAR> CMLStrBufWalkA;
  105. #endif //__MLSBWALK_H_