|
|
// MLSBWalk.h : Declaration of the CMLStrBufWalk
#ifndef __MLSBWALK_H_
#define __MLSBWALK_H_
/////////////////////////////////////////////////////////////////////////////
// CMLStrBufWalk
template <class IMLSTRBUF, class CHTYPE> 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 <class IMLSTRBUF, class CHTYPE> CMLStrBufWalk<IMLSTRBUF, CHTYPE>::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 <class IMLSTRBUF, class CHTYPE> BOOL CMLStrBufWalk<IMLSTRBUF, CHTYPE>::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 <class IMLSTRBUF, class CHTYPE> void CMLStrBufWalk<IMLSTRBUF, CHTYPE>::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 <class IMLSTRBUF, class CHTYPE> CHTYPE* CMLStrBufWalk<IMLSTRBUF, CHTYPE>::GetStr(void) { ASSERT(m_pszBuf); // Not locked
return m_pszBuf; }
template <class IMLSTRBUF, class CHTYPE> long CMLStrBufWalk<IMLSTRBUF, CHTYPE>::GetCCh(void) const { ASSERT(m_pszBuf); // Not locked
if (m_pszBuf) return m_cchBuf; else return 0; }
template <class IMLSTRBUF, class CHTYPE> long CMLStrBufWalk<IMLSTRBUF, CHTYPE>::GetDoneCCh(void) const { return m_cchDone; }
template <class IMLSTRBUF, class CHTYPE> long CMLStrBufWalk<IMLSTRBUF, CHTYPE>::GetRestCCh(void) const { return m_cchLen - m_cchDone; }
typedef CMLStrBufWalk<IMLangStringBufW, WCHAR> CMLStrBufWalkW; typedef CMLStrBufWalk<IMLangStringBufA, CHAR> CMLStrBufWalkA;
#endif //__MLSBWALK_H_
|