// MLSBWalk.h : Declaration of the CMLStrBufWalk #ifndef __MLSBWALK_H_ #define __MLSBWALK_H_ ///////////////////////////////////////////////////////////////////////////// // CMLStrBufWalk template class CMLStrBufWalk { public: inline CMLStrBufWalk(IMLSTRBUF* pMLStrBuf, long cchOffset, long cchLen, BOOL fCanStopAtMiddle = FALSE); BOOL Lock(HRESULT& rhr); void Unlock(HRESULT& rhr, long cchActual = 0); inline CHTYPE* GetStr(void); inline long GetCCh(void) const; inline long GetDoneCCh(void) const; inline long GetRestCCh(void) const; protected: IMLSTRBUF* m_pMLStrBuf; BOOL m_fCanStopAtMiddle; long m_cchOffset; long m_cchLen; long m_cchDone; CHTYPE* m_pszBuf; long m_cchBuf; }; template CMLStrBufWalk::CMLStrBufWalk(IMLSTRBUF* pMLStrBuf, long cchOffset, long cchLen, BOOL fCanStopAtMiddle) : m_pMLStrBuf(pMLStrBuf), m_fCanStopAtMiddle(fCanStopAtMiddle) { m_cchOffset = cchOffset; m_cchLen = cchLen; m_cchDone = 0; m_pszBuf = NULL; // Mark as it's not locked } template BOOL CMLStrBufWalk::Lock(HRESULT& rhr) { if (m_pszBuf) rhr = E_FAIL; // Already locked if (SUCCEEDED(rhr) && m_cchLen > 0 && FAILED(rhr = m_pMLStrBuf->LockBuf(m_cchOffset, m_cchLen, &m_pszBuf, &m_cchBuf))) { m_pszBuf = NULL; // Mark as it's not locked } if (m_fCanStopAtMiddle && FAILED(rhr) && m_cchDone > 0) { rhr = S_OK; return FALSE; // Stop it, but not fail } else { return (SUCCEEDED(rhr) && m_cchLen > 0); } } template void CMLStrBufWalk::Unlock(HRESULT& rhr, long cchActual) { HRESULT hr = S_OK; if (!m_pszBuf) hr = E_FAIL; // Not locked yet if (SUCCEEDED(hr) && SUCCEEDED(hr = m_pMLStrBuf->UnlockBuf(m_pszBuf, 0, 0))) // Unlock even if rhr is already failed { if (!cchActual) cchActual = m_cchBuf; else ASSERT(cchActual > 0 && cchActual <= m_cchBuf); m_cchOffset += cchActual; m_cchLen -= cchActual; m_cchDone += cchActual; } m_pszBuf = NULL; // Unlock anyway if (SUCCEEDED(rhr)) rhr = hr; // if rhr is failed before UnlockBuf, use it } template CHTYPE* CMLStrBufWalk::GetStr(void) { ASSERT(m_pszBuf); // Not locked return m_pszBuf; } template long CMLStrBufWalk::GetCCh(void) const { ASSERT(m_pszBuf); // Not locked if (m_pszBuf) return m_cchBuf; else return 0; } template long CMLStrBufWalk::GetDoneCCh(void) const { return m_cchDone; } template long CMLStrBufWalk::GetRestCCh(void) const { return m_cchLen - m_cchDone; } typedef CMLStrBufWalk CMLStrBufWalkW; typedef CMLStrBufWalk CMLStrBufWalkA; #endif //__MLSBWALK_H_