597 lines
17 KiB
C++
597 lines
17 KiB
C++
|
// AttrStrA.cpp : Implementation of CMLStrAttrAStr
|
||
|
#include "private.h"
|
||
|
|
||
|
#ifdef NEWMLSTR
|
||
|
|
||
|
#include "attrstra.h"
|
||
|
#include "mlswalk.h"
|
||
|
#include "mlsbwalk.h"
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CMLStrAttrAStr
|
||
|
|
||
|
CMLStrAttrAStr::CMLStrAttrAStr(void) :
|
||
|
m_pMLCPs(NULL),
|
||
|
m_pMLStr(NULL)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
CMLStrAttrAStr::~CMLStrAttrAStr(void)
|
||
|
{
|
||
|
VERIFY(SetClient(NULL)); // Clean m_pMLStr
|
||
|
if (m_pMLCPs)
|
||
|
m_pMLCPs->Release();
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::SetClient(IUnknown* pUnk)
|
||
|
{
|
||
|
ASSERT_THIS;
|
||
|
ASSERT_READ_PTR_OR_NULL(pUnk);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
// Release old client
|
||
|
IMLangString* const pMLStr = m_pMLStr;
|
||
|
if (pMLStr && SUCCEEDED(hr = StartEndConnectionMLStr(pMLStr, FALSE))) // End connection to MLStr
|
||
|
{
|
||
|
pMLStr->Release();
|
||
|
m_pMLStr = NULL;
|
||
|
}
|
||
|
|
||
|
// Set new client
|
||
|
if (SUCCEEDED(hr) && pUnk) // pUnk is given
|
||
|
{
|
||
|
ASSERT(!m_pMLStr);
|
||
|
if (SUCCEEDED(hr = pUnk->QueryInterface(IID_IMLangString, (void**)&m_pMLStr)))
|
||
|
{
|
||
|
ASSERT_READ_PTR(m_pMLStr);
|
||
|
if (FAILED(hr = StartEndConnectionMLStr(pUnk, TRUE))) // Start connection to MLStr
|
||
|
{
|
||
|
m_pMLStr->Release();
|
||
|
m_pMLStr = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CMLStrAttrAStr::StartEndConnectionMLStr(IUnknown* const pUnk, BOOL fStart)
|
||
|
{
|
||
|
ASSERT_THIS;
|
||
|
ASSERT_READ_PTR(pUnk);
|
||
|
|
||
|
HRESULT hr;
|
||
|
IConnectionPointContainer* pCPC;
|
||
|
|
||
|
if (SUCCEEDED(hr = pUnk->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC)))
|
||
|
{
|
||
|
ASSERT_READ_PTR(pCPC);
|
||
|
|
||
|
IConnectionPoint* pCP;
|
||
|
|
||
|
if (SUCCEEDED(hr = pCPC->FindConnectionPoint(IID_IMLangStringNotifySink, &pCP)))
|
||
|
{
|
||
|
ASSERT_READ_PTR(pCP);
|
||
|
|
||
|
if (fStart)
|
||
|
hr = pCP->Advise((IMLStrAttr*)this, &m_dwMLStrCookie);
|
||
|
else
|
||
|
hr = pCP->Unadvise(m_dwMLStrCookie);
|
||
|
|
||
|
pCP->Release();
|
||
|
}
|
||
|
|
||
|
pCPC->Release();
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::GetClient(IUnknown** ppUnk)
|
||
|
{
|
||
|
ASSERT_THIS;
|
||
|
ASSERT_WRITE_PTR_OR_NULL(ppUnk);
|
||
|
|
||
|
if (ppUnk)
|
||
|
{
|
||
|
IUnknown* const pUnk = m_pMLStr;
|
||
|
*ppUnk = pUnk;
|
||
|
if (pUnk)
|
||
|
pUnk->AddRef();
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::QueryAttr(REFIID riid, LPARAM lParam, IUnknown** ppUnk, long* lConf)
|
||
|
{
|
||
|
return E_NOTIMPL; // CMLStrAttrAStr::QueryAttr()
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::GetAttrInterface(IID* pIID, LPARAM* plParam)
|
||
|
{
|
||
|
return E_NOTIMPL; // CMLStrAttrAStr::GetAttrInterface()
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::SetMLStr(long lDestPos, long lDestLen, IUnknown* pSrcMLStr, long lSrcPos, long lSrcLen)
|
||
|
{
|
||
|
return E_NOTIMPL; // CMLStrAttrAStr::SetMLStr()
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::SetAStr(long lDestPos, long lDestLen, UINT uCodePage, const CHAR* pszSrc, long cchSrc, long* pcchActual, long* plActualLen)
|
||
|
{
|
||
|
ASSERT_THIS;
|
||
|
ASSERT_READ_BLOCK(pszSrc, cchSrc);
|
||
|
ASSERT_WRITE_PTR_OR_NULL(pcchActual);
|
||
|
ASSERT_WRITE_PTR_OR_NULL(plActualLen);
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
// Fire OnRequestEdit
|
||
|
IEnumConnections* pEnumConn;
|
||
|
|
||
|
if (SUCCEEDED(hr = EnumConnections(&pEnumConn)))
|
||
|
{
|
||
|
ASSERT_READ_PTR(pEnumConn);
|
||
|
|
||
|
CONNECTDATA cd;
|
||
|
|
||
|
while ((hr = pEnumConn->Next(1, &cd, NULL)) == S_OK)
|
||
|
{
|
||
|
IMLStrAttrNotifySink* pSink;
|
||
|
|
||
|
if (SUCCEEDED(hr = cd.pUnk->QueryInterface(IID_IMLStrAttrNotifySink, (void**)&pSink)))
|
||
|
{
|
||
|
// TODO: Regularize before fire OnRequestEdit
|
||
|
// TODO: And, calculate lNewLen,
|
||
|
hr = pSink->OnRequestEdit(lDestPos, lDestLen, /*lNewLen*/0, IID_IMLStrAttrAStr, 0, (IMLStrAttr*)this);
|
||
|
pSink->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pEnumConn->Release();
|
||
|
}
|
||
|
|
||
|
hr = CheckThread();
|
||
|
CLock Lock(TRUE, this, hr);
|
||
|
long cchDestPos;
|
||
|
long cchDestLen;
|
||
|
long cchActual;
|
||
|
long lActualLen;
|
||
|
|
||
|
if (SUCCEEDED(hr) && (GetBufFlags() & MLSTR_WRITE))
|
||
|
hr = E_INVALIDARG; // Not writable StrBuf; TODO: Replace StrBuf in this case if allowed
|
||
|
|
||
|
if (SUCCEEDED(hr) &&
|
||
|
SUCCEEDED(hr = PrepareMLStrBuf()) &&
|
||
|
SUCCEEDED(hr = RegularizePosLen(&lDestPos, &lDestLen)) &&
|
||
|
SUCCEEDED(hr = GetCCh(0, lDestPos, &cchDestPos)) &&
|
||
|
SUCCEEDED(hr = GetCCh(cchDestPos, lDestLen, &cchDestLen)))
|
||
|
{
|
||
|
IMLangStringBufA* const pMLStrBufA = GetMLStrBufA();
|
||
|
|
||
|
if (uCodePage == CP_ACP)
|
||
|
uCodePage = g_uACP;
|
||
|
|
||
|
if (pMLStrBufA && uCodePage == GetCodePage())
|
||
|
{
|
||
|
if (cchSrc > cchDestLen)
|
||
|
{
|
||
|
hr = pMLStrBufA->Insert(cchDestPos, cchSrc - cchDestLen, (pcchActual || plActualLen) ? &cchSrc : NULL);
|
||
|
cchSrc += cchDestLen;
|
||
|
}
|
||
|
else if (cchSrc < cchDestLen)
|
||
|
{
|
||
|
hr = pMLStrBufA->Delete(cchDestPos, cchDestLen - cchSrc);
|
||
|
}
|
||
|
|
||
|
CMLStrBufWalkA BufWalk(pMLStrBufA, cchDestPos, cchSrc, (pcchActual || plActualLen));
|
||
|
|
||
|
lActualLen = 0;
|
||
|
while (BufWalk.Lock(hr))
|
||
|
{
|
||
|
long lLen;
|
||
|
|
||
|
if (plActualLen)
|
||
|
hr = CalcLenA(uCodePage, pszSrc, BufWalk.GetCCh(), &lLen);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
lActualLen += lLen;
|
||
|
::memcpy(BufWalk.GetStr(), pszSrc, sizeof(CHAR) * BufWalk.GetCCh());
|
||
|
pszSrc += BufWalk.GetCCh();
|
||
|
}
|
||
|
|
||
|
BufWalk.Unlock(hr);
|
||
|
}
|
||
|
|
||
|
cchActual = BufWalk.GetDoneCCh();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
IMLangStringWStr* pMLStrW;
|
||
|
|
||
|
if (SUCCEEDED(hr = ((IMLStrAttr*)this)->QueryInterface(IID_IMLangStringWStr, (void**)&pMLStrW)))
|
||
|
{
|
||
|
CMLStrWalkW StrWalk(pMLStrW, lDestPos, lDestLen, MLSTR_WRITE, (pcchActual || plActualLen));
|
||
|
|
||
|
cchActual = 0;
|
||
|
lActualLen = 0;
|
||
|
while (StrWalk.Lock(hr))
|
||
|
{
|
||
|
long cchWrittenA;
|
||
|
long lWrittenLen;
|
||
|
|
||
|
if (SUCCEEDED(hr = ConvAStrToWStr(uCodePage, pszSrc, cchSrc, StrWalk.GetStr(), StrWalk.GetCCh(), &cchWrittenA, NULL, &lWrittenLen)))
|
||
|
{
|
||
|
pszSrc += cchWrittenA;
|
||
|
cchSrc -= cchWrittenA;
|
||
|
cchActual += cchWrittenA;
|
||
|
lActualLen += lWrittenLen;
|
||
|
}
|
||
|
|
||
|
StrWalk.Unlock(hr, lWrittenLen);
|
||
|
}
|
||
|
|
||
|
pMLStrW->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (pcchActual)
|
||
|
*pcchActual = cchActual;
|
||
|
if (plActualLen)
|
||
|
*plActualLen = lActualLen;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (pcchActual)
|
||
|
*pcchActual = 0;
|
||
|
if (plActualLen)
|
||
|
*plActualLen = 0;
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::SetStrBufA(long lDestPos, long lDestLen, UINT uCodePage, IMLangStringBufA* pSrcBuf, long* pcchActual, long* plActualLen)
|
||
|
{
|
||
|
ASSERT_THIS;
|
||
|
return SetStrBufCommon(this, lDestPos, lDestLen, uCodePage, NULL, pSrcBuf, pcchActual, plActualLen);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::GetAStr(long lSrcPos, long lSrcLen, UINT uCodePageIn, UINT* puCodePageOut, CHAR* pszDest, long cchDest, long* pcchActual, long* plActualLen)
|
||
|
{
|
||
|
ASSERT_THIS;
|
||
|
ASSERT_WRITE_PTR_OR_NULL(puCodePageOut);
|
||
|
ASSERT_WRITE_BLOCK_OR_NULL(pszDest, cchDest);
|
||
|
ASSERT_WRITE_PTR_OR_NULL(pcchActual);
|
||
|
ASSERT_WRITE_PTR_OR_NULL(plActualLen);
|
||
|
|
||
|
HRESULT hr = CheckThread();
|
||
|
CLock Lock(FALSE, this, hr);
|
||
|
long cchSrcPos;
|
||
|
long cchSrcLen;
|
||
|
long cchActual;
|
||
|
long lActualLen;
|
||
|
|
||
|
if (SUCCEEDED(hr) &&
|
||
|
SUCCEEDED(hr = RegularizePosLen(&lSrcPos, &lSrcLen)) &&
|
||
|
SUCCEEDED(hr = GetCCh(0, lSrcPos, &cchSrcPos)) &&
|
||
|
SUCCEEDED(hr = GetCCh(cchSrcPos, lSrcLen, &cchSrcLen)))
|
||
|
{
|
||
|
IMLangStringBufA* const pMLStrBufA = GetMLStrBufA();
|
||
|
|
||
|
if (pszDest)
|
||
|
cchActual = min(cchSrcLen, cchDest);
|
||
|
else
|
||
|
cchActual = cchSrcLen;
|
||
|
|
||
|
if (uCodePageIn == CP_ACP)
|
||
|
uCodePageIn = g_uACP;
|
||
|
|
||
|
if (pMLStrBufA && (puCodePageOut || uCodePageIn == GetCodePage()))
|
||
|
{
|
||
|
uCodePageIn = GetCodePage();
|
||
|
|
||
|
CMLStrBufWalkA BufWalk(pMLStrBufA, cchSrcPos, cchActual, (pcchActual || plActualLen));
|
||
|
|
||
|
lActualLen = 0;
|
||
|
while (BufWalk.Lock(hr))
|
||
|
{
|
||
|
long lLen;
|
||
|
|
||
|
if (plActualLen)
|
||
|
hr = CalcLenA(uCodePageIn, BufWalk.GetStr(), BufWalk.GetCCh(), &lLen);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
lActualLen += lLen;
|
||
|
|
||
|
if (pszDest)
|
||
|
{
|
||
|
::memcpy(pszDest, BufWalk.GetStr(), sizeof(CHAR) * BufWalk.GetCCh());
|
||
|
pszDest += BufWalk.GetCCh();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BufWalk.Unlock(hr);
|
||
|
}
|
||
|
|
||
|
cchActual = BufWalk.GetDoneCCh();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
IMLangStringWStr* pMLStrW;
|
||
|
|
||
|
if (SUCCEEDED(hr = m_pMLStr->QueryInterface(IID_IMLangStringWStr, (void**)&pMLStrW)))
|
||
|
{
|
||
|
BOOL fDontHaveCodePageIn = (puCodePageOut != 0);
|
||
|
CMLStrWalkW StrWalk(pMLStrW, lSrcPos, lSrcLen, (pcchActual || plActualLen));
|
||
|
|
||
|
cchActual = 0;
|
||
|
while (StrWalk.Lock(hr))
|
||
|
{
|
||
|
LCID locale;
|
||
|
UINT uLocaleCodePage;
|
||
|
DWORD dwLocaleCodePages;
|
||
|
DWORD dwStrCodePages;
|
||
|
long cchWritten;
|
||
|
long lWrittenLen;
|
||
|
|
||
|
if (fDontHaveCodePageIn &&
|
||
|
SUCCEEDED(hr = pMLStrW->GetLocale(lSrcPos, lSrcLen, &locale, NULL, NULL)) &&
|
||
|
SUCCEEDED(hr = ::LocaleToCodePage(locale, &uLocaleCodePage)) &&
|
||
|
SUCCEEDED(hr = PrepareMLangCodePages()) &&
|
||
|
SUCCEEDED(hr = GetMLangCodePages()->CodePageToCodePages(uLocaleCodePage, &dwLocaleCodePages)) &&
|
||
|
SUCCEEDED(hr = GetMLangCodePages()->GetStrCodePages(StrWalk.GetStr(), StrWalk.GetCCh(), dwLocaleCodePages, &dwStrCodePages, NULL)))
|
||
|
{
|
||
|
fDontHaveCodePageIn = FALSE;
|
||
|
hr = GetMLangCodePages()->CodePagesToCodePage(dwStrCodePages, uLocaleCodePage, &uCodePageIn);
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr) &&
|
||
|
SUCCEEDED(hr = ConvWStrToAStr(pcchActual || plActualLen, uCodePageIn, StrWalk.GetStr(), StrWalk.GetCCh(), pszDest, cchDest, &cchWritten, NULL, &lWrittenLen)))
|
||
|
{
|
||
|
pszDest += cchWritten;
|
||
|
cchDest -= cchWritten;
|
||
|
cchActual += cchWritten;
|
||
|
}
|
||
|
|
||
|
StrWalk.Unlock(hr, lWrittenLen);
|
||
|
}
|
||
|
|
||
|
lActualLen = StrWalk.GetDoneLen();
|
||
|
|
||
|
pMLStrW->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (puCodePageOut)
|
||
|
*puCodePageOut = uCodePageIn;
|
||
|
if (pcchActual)
|
||
|
*pcchActual = cchActual;
|
||
|
if (plActualLen)
|
||
|
*plActualLen = lActualLen;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (puCodePageOut)
|
||
|
*puCodePageOut = 0;
|
||
|
if (pcchActual)
|
||
|
*pcchActual = 0;
|
||
|
if (plActualLen)
|
||
|
*plActualLen = 0;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::GetStrBufA(long lSrcPos, long lSrcMaxLen, UINT* puDestCodePage, IMLangStringBufA** ppDestBuf, long* plDestLen)
|
||
|
{
|
||
|
ASSERT_THIS;
|
||
|
ASSERT_WRITE_PTR_OR_NULL(puDestCodePage);
|
||
|
ASSERT_WRITE_PTR_OR_NULL(ppDestBuf);
|
||
|
ASSERT_WRITE_PTR_OR_NULL(plDestLen);
|
||
|
|
||
|
HRESULT hr = CheckThread();
|
||
|
CLock Lock(FALSE, this, hr);
|
||
|
IMLangStringBufA* pMLStrBufA;
|
||
|
|
||
|
if (SUCCEEDED(hr) &&
|
||
|
SUCCEEDED(hr = RegularizePosLen(&lSrcPos, &lSrcMaxLen)) &&
|
||
|
lSrcMaxLen <= 0)
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
pMLStrBufA = GetMLStrBufA();
|
||
|
if (!pMLStrBufA)
|
||
|
hr = MLSTR_E_STRBUFNOTAVAILABLE;
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (puDestCodePage)
|
||
|
*puDestCodePage = GetCodePage();
|
||
|
if (ppDestBuf)
|
||
|
{
|
||
|
pMLStrBufA->AddRef();
|
||
|
*ppDestBuf = pMLStrBufA;
|
||
|
}
|
||
|
if (plDestLen)
|
||
|
*plDestLen = lSrcMaxLen;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (puDestCodePage)
|
||
|
*puDestCodePage = 0;
|
||
|
if (ppDestBuf)
|
||
|
*ppDestBuf = NULL;
|
||
|
if (plDestLen)
|
||
|
*plDestLen = 0;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::LockAStr(long lSrcPos, long lSrcLen, long lFlags, UINT uCodePageIn, long cchRequest, UINT* puCodePageOut, CHAR** ppszDest, long* pcchDest, long* plDestLen)
|
||
|
{
|
||
|
ASSERT_THIS;
|
||
|
ASSERT_WRITE_PTR_OR_NULL(puCodePageOut);
|
||
|
ASSERT_WRITE_PTR_OR_NULL(ppszDest);
|
||
|
ASSERT_WRITE_PTR_OR_NULL(pcchDest);
|
||
|
ASSERT_WRITE_PTR_OR_NULL(plDestLen);
|
||
|
|
||
|
HRESULT hr = CheckThread();
|
||
|
CLock Lock(lFlags & MLSTR_WRITE, this, hr);
|
||
|
long cchSrcPos;
|
||
|
long cchSrcLen;
|
||
|
CHAR* pszBuf = NULL;
|
||
|
long cchBuf;
|
||
|
long lLockLen;
|
||
|
BOOL fDirectLock;
|
||
|
|
||
|
if (SUCCEEDED(hr) && (!lFlags || (lFlags & ~GetBufFlags() & MLSTR_WRITE)))
|
||
|
hr = E_INVALIDARG; // No flags specified, or not writable StrBuf; TODO: Replace StrBuf in this case if allowed
|
||
|
|
||
|
if (!(lFlags & MLSTR_WRITE))
|
||
|
cchRequest = 0;
|
||
|
|
||
|
if (SUCCEEDED(hr) &&
|
||
|
SUCCEEDED(hr = PrepareMLStrBuf()) &&
|
||
|
SUCCEEDED(hr = RegularizePosLen(&lSrcPos, &lSrcLen)) &&
|
||
|
SUCCEEDED(hr = GetCCh(0, lSrcPos, &cchSrcPos)) &&
|
||
|
SUCCEEDED(hr = GetCCh(cchSrcPos, lSrcLen, &cchSrcLen)))
|
||
|
{
|
||
|
IMLangStringBufA* const pMLStrBufA = GetMLStrBufA();
|
||
|
fDirectLock = (pMLStrBufA && (puCodePageOut || uCodePageIn == GetCodePage()));
|
||
|
|
||
|
if (fDirectLock)
|
||
|
{
|
||
|
long cchInserted;
|
||
|
long cchLockLen = cchSrcLen;
|
||
|
|
||
|
if (puCodePageOut)
|
||
|
hr = GetAStr(lSrcPos, lSrcLen, 0, &uCodePageIn, NULL, 0, NULL, NULL);
|
||
|
|
||
|
if (SUCCEEDED(hr) &&
|
||
|
cchRequest > cchSrcLen &&
|
||
|
SUCCEEDED(hr = pMLStrBufA->Insert(cchSrcPos + cchSrcLen, cchRequest - cchSrcLen, &cchInserted)))
|
||
|
{
|
||
|
SetBufCCh(GetBufCCh() + cchInserted);
|
||
|
cchLockLen += cchInserted;
|
||
|
|
||
|
if (!pcchDest && cchLockLen < cchRequest)
|
||
|
hr = E_OUTOFMEMORY; // Can't insert in StrBuf
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr) &&
|
||
|
SUCCEEDED(hr = pMLStrBufA->LockBuf(cchSrcPos, cchLockLen, &pszBuf, &cchBuf)) &&
|
||
|
!pcchDest && cchBuf < max(cchSrcLen, cchRequest))
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY; // Can't lock StrBuf
|
||
|
}
|
||
|
|
||
|
if (plDestLen && SUCCEEDED(hr))
|
||
|
hr = CalcLenA(uCodePageIn, pszBuf, cchBuf, &lLockLen);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
long cchSize;
|
||
|
|
||
|
if (SUCCEEDED(hr = CalcBufSizeA(lSrcLen, &cchSize)))
|
||
|
{
|
||
|
cchBuf = max(cchSize, cchRequest);
|
||
|
hr = MemAlloc(sizeof(*pszBuf) * cchBuf, (void**)&pszBuf);
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr) && ((lFlags & MLSTR_READ) || puCodePageOut))
|
||
|
hr = GetAStr(lSrcPos, lSrcLen, uCodePageIn, (puCodePageOut) ? &uCodePageIn : NULL, (lFlags & MLSTR_READ) ? pszBuf : NULL, cchBuf, (pcchDest) ? &cchBuf : NULL, (plDestLen) ? &lLockLen : NULL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr) &&
|
||
|
SUCCEEDED(hr = Lock.FallThrough()))
|
||
|
{
|
||
|
hr = GetLockInfo()->Lock((fDirectLock) ? UnlockAStrDirect : UnlockAStrIndirect, lFlags, uCodePageIn, pszBuf, lSrcPos, lSrcLen, cchSrcPos, cchBuf);
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (puCodePageOut)
|
||
|
*puCodePageOut = uCodePageIn;
|
||
|
if (ppszDest)
|
||
|
*ppszDest = pszBuf;
|
||
|
if (pcchDest)
|
||
|
*pcchDest = cchBuf;
|
||
|
if (plDestLen)
|
||
|
*plDestLen = lLockLen;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (pszBuf)
|
||
|
{
|
||
|
if (fDirectLock)
|
||
|
GetMLStrBufA()->UnlockBuf(pszBuf, 0, 0);
|
||
|
else
|
||
|
MemFree(pszBuf);
|
||
|
}
|
||
|
|
||
|
if (puCodePageOut)
|
||
|
*puCodePageOut = 0;
|
||
|
if (ppszDest)
|
||
|
*ppszDest = NULL;
|
||
|
if (pcchDest)
|
||
|
*pcchDest = 0;
|
||
|
if (plDestLen)
|
||
|
*plDestLen = 0;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::UnlockAStr(const CHAR* pszSrc, long cchSrc, long* pcchActual, long* plActualLen)
|
||
|
{
|
||
|
ASSERT_THIS;
|
||
|
ASSERT_READ_BLOCK(pszSrc, cchSrc);
|
||
|
ASSERT_WRITE_PTR_OR_NULL(pcchActual);
|
||
|
ASSERT_WRITE_PTR_OR_NULL(plActualLen);
|
||
|
|
||
|
return UnlockStrCommon(pszSrc, cchSrc, pcchActual, plActualLen);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::OnRegisterAttr(IUnknown* pUnk)
|
||
|
{
|
||
|
return E_NOTIMPL; // CMLStrAttrAStr::OnRegisterAttr()
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::OnUnregisterAttr(IUnknown* pUnk)
|
||
|
{
|
||
|
return E_NOTIMPL; // CMLStrAttrAStr::OnUnregisterAttr()
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::OnRequestEdit(long lDestPos, long lDestLen, long lNewLen, REFIID riid, LPARAM lParam, IUnknown* pUnk)
|
||
|
{
|
||
|
return E_NOTIMPL; // CMLStrAttrAStr::OnRequestEdit()
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::OnCanceledEdit(long lDestPos, long lDestLen, long lNewLen, REFIID riid, LPARAM lParam, IUnknown* pUnk)
|
||
|
{
|
||
|
return E_NOTIMPL; // CMLStrAttrAStr::OnCanceledEdit()
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CMLStrAttrAStr::OnChanged(long lDestPos, long lDestLen, long lNewLen, REFIID riid, LPARAM lParam, IUnknown* pUnk)
|
||
|
{
|
||
|
return E_NOTIMPL; // CMLStrAttrAStr::OnChanged()
|
||
|
}
|
||
|
|
||
|
#endif // NEWMLSTR
|