attrstrw.cpp
上传用户:xhy777
上传日期:2007-02-14
资源大小:24088k
文件大小:16k
源码类别:

系统编程

开发平台:

Visual C++

  1. // AttrStrW.cpp : Implementation of CMLStrAttrWStr
  2. #include "private.h"
  3. #ifdef NEWMLSTR
  4. #include "attrstrw.h"
  5. #include "mlsbwalk.h"
  6. /////////////////////////////////////////////////////////////////////////////
  7. // CMLStrAttrWStr
  8. CMLStrAttrWStr::CMLStrAttrWStr(void) :
  9.     m_pMLStr(NULL)
  10. {
  11. }
  12. CMLStrAttrWStr::~CMLStrAttrWStr(void)
  13. {
  14.     VERIFY(SetClient(NULL)); // Clean m_pMLStr
  15. }
  16. STDMETHODIMP CMLStrAttrWStr::SetClient(IUnknown* pUnk)
  17. {
  18.     ASSERT_THIS;
  19.     ASSERT_READ_PTR_OR_NULL(pUnk);
  20.     HRESULT hr = S_OK;
  21.     // Release old client
  22.     IMLangString* const pMLStr = m_pMLStr;
  23.     if (pMLStr && SUCCEEDED(hr = StartEndConnectionMLStr(pMLStr, FALSE))) // End connection to MLStr
  24.     {
  25.         pMLStr->Release();
  26.         m_pMLStr = NULL;
  27.     }
  28.     // Set new client
  29.     if (SUCCEEDED(hr) && pUnk) // pUnk is given
  30.     {
  31.         ASSERT(!m_pMLStr);
  32.         if (SUCCEEDED(hr = pUnk->QueryInterface(IID_IMLangString, (void**)&m_pMLStr)))
  33.         {
  34.             ASSERT_READ_PTR(m_pMLStr);
  35.             if (FAILED(hr = StartEndConnectionMLStr(pUnk, TRUE))) // Start connection to MLStr
  36.             {
  37.                 m_pMLStr->Release();
  38.                 m_pMLStr = NULL;
  39.             }
  40.         }
  41.     }
  42.     return hr;
  43. }
  44. HRESULT CMLStrAttrWStr::StartEndConnectionMLStr(IUnknown* const pUnk, BOOL fStart)
  45. {
  46.     ASSERT_THIS;
  47.     ASSERT_READ_PTR(pUnk);
  48.     HRESULT hr;
  49.     IConnectionPointContainer* pCPC;
  50.     if (SUCCEEDED(hr = pUnk->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC)))
  51.     {
  52.         ASSERT_READ_PTR(pCPC);
  53.         IConnectionPoint* pCP;
  54.         if (SUCCEEDED(hr = pCPC->FindConnectionPoint(IID_IMLangStringNotifySink, &pCP)))
  55.         {
  56.             ASSERT_READ_PTR(pCP);
  57.             if (fStart)
  58.                 hr = pCP->Advise((IMLStrAttr*)this, &m_dwMLStrCookie);
  59.             else
  60.                 hr = pCP->Unadvise(m_dwMLStrCookie);
  61.             pCP->Release();
  62.         }
  63.         pCPC->Release();
  64.     }
  65.     return hr;
  66. }
  67. STDMETHODIMP CMLStrAttrWStr::GetClient(IUnknown** ppUnk)
  68. {
  69.     ASSERT_THIS;
  70.     ASSERT_WRITE_PTR_OR_NULL(ppUnk);
  71.     if (ppUnk)
  72.     {
  73.         IUnknown* const pUnk = m_pMLStr;
  74.         *ppUnk = pUnk;
  75.         if (pUnk)
  76.             pUnk->AddRef();
  77.     }
  78.     return S_OK;
  79. }
  80. STDMETHODIMP CMLStrAttrWStr::QueryAttr(REFIID riid, LPARAM lParam, IUnknown** ppUnk, long* lConf)
  81. {
  82.     return E_NOTIMPL; // CMLStrAttrWStr::QueryAttr()
  83. }
  84. STDMETHODIMP CMLStrAttrWStr::GetAttrInterface(IID* pIID, LPARAM* plParam)
  85. {
  86.     return E_NOTIMPL; // CMLStrAttrWStr::GetAttrInterface()
  87. }
  88. STDMETHODIMP CMLStrAttrWStr::SetMLStr(long lDestPos, long lDestLen, IUnknown* pSrcMLStr, long lSrcPos, long lSrcLen)
  89. {
  90.     return E_NOTIMPL; // CMLStrAttrWStr::SetMLStr()
  91. }
  92. STDMETHODIMP CMLStrAttrWStr::SetWStr(long lDestPos, long lDestLen, const WCHAR* pszSrc, long cchSrc, long* pcchActual, long* plActualLen)
  93. {
  94.     ASSERT_THIS;
  95.     ASSERT_READ_BLOCK(pszSrc, cchSrc);
  96.     ASSERT_WRITE_PTR_OR_NULL(pcchActual);
  97.     ASSERT_WRITE_PTR_OR_NULL(plActualLen);
  98.     HRESULT hr = CheckThread();
  99.     CLock Lock(TRUE, this, hr);
  100.     long cchDestPos;
  101.     long cchDestLen;
  102.     long cchActual;
  103.     long lActualLen;
  104.     if (SUCCEEDED(hr) && (GetBufFlags() & MLSTR_WRITE))
  105.         hr = E_INVALIDARG; // Not writable StrBuf; TODO: Replace StrBuf in this case if allowed
  106.     if (SUCCEEDED(hr) &&
  107.         SUCCEEDED(hr = PrepareMLStrBuf()) &&
  108.         SUCCEEDED(hr = RegularizePosLen(&lDestPos, &lDestLen)) &&
  109.         SUCCEEDED(hr = GetCCh(0, lDestPos, &cchDestPos)) &&
  110.         SUCCEEDED(hr = GetCCh(cchDestPos, lDestLen, &cchDestLen)))
  111.     {
  112.         IMLangStringBufW* const pMLStrBufW = GetMLStrBufW();
  113.         if (pMLStrBufW)
  114.         {
  115.             if (cchSrc > cchDestLen)
  116.             {
  117.                 hr = pMLStrBufW->Insert(cchDestPos, cchSrc - cchDestLen, (pcchActual || plActualLen) ? &cchSrc : NULL);
  118.                 cchSrc += cchDestLen;
  119.             }
  120.             else if  (cchSrc < cchDestLen)
  121.             {
  122.                 hr = pMLStrBufW->Delete(cchDestPos, cchDestLen - cchSrc);
  123.             }
  124.             CMLStrBufWalkW BufWalk(pMLStrBufW, cchDestPos, cchSrc, (pcchActual || plActualLen));
  125.             lActualLen = 0;
  126.             while (BufWalk.Lock(hr))
  127.             {
  128.                 long lLen;
  129.                 if (plActualLen)
  130.                     hr = CalcLenW(pszSrc, BufWalk.GetCCh(), &lLen);
  131.                 if (SUCCEEDED(hr))
  132.                 {
  133.                     lActualLen += lLen;
  134.                     ::memcpy(BufWalk.GetStr(), pszSrc, sizeof(WCHAR) * BufWalk.GetCCh());
  135.                     pszSrc += BufWalk.GetCCh();
  136.                 }
  137.                 BufWalk.Unlock(hr);
  138.             }
  139.             cchActual = BufWalk.GetDoneCCh();
  140.         }
  141.         else
  142.         {
  143.             IMLangStringBufA* const pMLStrBufA = GetMLStrBufA(); // Should succeed because PrepareMLStrBuf() above was succeeded
  144.             const UINT uCodePage = GetCodePage();
  145.             long cchSrcA;
  146.             if (SUCCEEDED(hr = ConvWStrToAStr(pcchActual || plActualLen, uCodePage, pszSrc, cchSrc, NULL, 0, &cchSrcA, NULL, NULL)))
  147.             {
  148.                 if (cchSrcA > cchDestLen)
  149.                 {
  150.                     hr = pMLStrBufA->Insert(cchDestPos, cchSrcA - cchDestLen, (pcchActual || plActualLen) ? &cchSrcA : NULL);
  151.                     cchSrcA += cchDestLen;
  152.                 }
  153.                 else if  (cchSrcA < cchDestLen)
  154.                 {
  155.                     hr = pMLStrBufA->Delete(cchDestPos, cchDestLen - cchSrcA);
  156.                 }
  157.             }
  158.             CMLStrBufWalkA BufWalk(pMLStrBufA, cchDestPos, cchSrcA, (pcchActual || plActualLen));
  159.             cchActual = 0;
  160.             lActualLen = 0;
  161.             while (BufWalk.Lock(hr))
  162.             {
  163.                 long cchWrittenA;
  164.                 long cchWrittenW;
  165.                 long lWrittenLen;
  166.                 if (SUCCEEDED(hr = ConvWStrToAStr(pcchActual || plActualLen, uCodePage, pszSrc, cchSrc, BufWalk.GetStr(), BufWalk.GetCCh(), &cchWrittenA, &cchWrittenW, &lWrittenLen)))
  167.                 {
  168.                     pszSrc += cchWrittenW;
  169.                     cchSrc -= cchWrittenW;
  170.                     cchActual += cchWrittenW;
  171.                     lActualLen += lWrittenLen;
  172.                 }
  173.                 BufWalk.Unlock(hr, cchWrittenA);
  174.             }
  175.         }
  176.     }
  177.     if (SUCCEEDED(hr))
  178.     {
  179.         if (pcchActual)
  180.             *pcchActual = cchActual;
  181.         if (plActualLen)
  182.             *plActualLen = lActualLen;
  183.     }
  184.     else
  185.     {
  186.         if (pcchActual)
  187.             *pcchActual = 0;
  188.         if (plActualLen)
  189.             *plActualLen = 0;
  190.     }
  191.     return hr;
  192. }
  193. STDMETHODIMP CMLStrAttrWStr::SetStrBufW(long lDestPos, long lDestLen, IMLangStringBufW* pSrcBuf, long* pcchActual, long* plActualLen)
  194. {
  195.     ASSERT_THIS;
  196.     return SetStrBufCommon(this, lDestPos, lDestLen, 0, pSrcBuf, NULL, pcchActual, plActualLen);
  197. }
  198. STDMETHODIMP CMLStrAttrWStr::GetWStr(long lSrcPos, long lSrcLen, WCHAR* pszDest, long cchDest, long* pcchActual, long* plActualLen)
  199. {
  200.     ASSERT_THIS;
  201.     ASSERT_WRITE_BLOCK_OR_NULL(pszDest, cchDest);
  202.     ASSERT_WRITE_PTR_OR_NULL(pcchActual);
  203.     ASSERT_WRITE_PTR_OR_NULL(plActualLen);
  204.     HRESULT hr = CheckThread();
  205.     CLock Lock(FALSE, this, hr);
  206.     long cchSrcPos;
  207.     long cchSrcLen;
  208.     long cchActual;
  209.     long lActualLen;
  210.     if (SUCCEEDED(hr) &&
  211.         SUCCEEDED(hr = RegularizePosLen(&lSrcPos, &lSrcLen)) &&
  212.         SUCCEEDED(hr = GetCCh(0, lSrcPos, &cchSrcPos)) &&
  213.         SUCCEEDED(hr = GetCCh(cchSrcPos, lSrcLen, &cchSrcLen)))
  214.     {
  215.         IMLangStringBufW* const pMLStrBufW = GetMLStrBufW();
  216.         IMLangStringBufA* const pMLStrBufA = GetMLStrBufA();
  217.         if (pszDest)
  218.             cchActual = min(cchSrcLen, cchDest);
  219.         else
  220.             cchActual = cchSrcLen;
  221.         if (pMLStrBufW)
  222.         {
  223.             CMLStrBufWalkW BufWalk(pMLStrBufW, cchSrcPos, cchActual, (pcchActual || plActualLen));
  224.             lActualLen = 0;
  225.             while (BufWalk.Lock(hr))
  226.             {
  227.                 long lLen;
  228.                 if (plActualLen)
  229.                     hr = CalcLenW(BufWalk.GetStr(), BufWalk.GetCCh(), &lLen);
  230.                 if (SUCCEEDED(hr))
  231.                 {
  232.                     lActualLen += lLen;
  233.                     if (pszDest)
  234.                     {
  235.                         ::memcpy(pszDest, BufWalk.GetStr(), sizeof(WCHAR) * BufWalk.GetCCh());
  236.                         pszDest += BufWalk.GetCCh();
  237.                     }
  238.                 }
  239.                 BufWalk.Unlock(hr);
  240.             }
  241.             cchActual = BufWalk.GetDoneCCh();
  242.         }
  243.         else if (pMLStrBufA)
  244.         {
  245.             CMLStrBufWalkA BufWalk(pMLStrBufA, cchSrcPos, cchActual, (pcchActual || plActualLen));
  246.             cchActual = 0;
  247.             lActualLen = 0;
  248.             while ((!pszDest || cchDest > 0) && BufWalk.Lock(hr))
  249.             {
  250.                 CHAR* const pszBuf = BufWalk.GetStr();
  251.                 long cchWrittenA;
  252.                 long cchWrittenW;
  253.                 long lWrittenLen;
  254.                 if (SUCCEEDED(hr = ConvAStrToWStr(GetCodePage(), pszBuf, BufWalk.GetCCh(), pszDest, cchDest, &cchWrittenA, &cchWrittenW, &lWrittenLen)))
  255.                 {
  256.                     lActualLen += lWrittenLen;
  257.                     cchActual += cchWrittenW;
  258.                     if (pszDest)
  259.                     {
  260.                         pszDest += cchWrittenW;
  261.                         cchDest -= cchWrittenW;
  262.                     }
  263.                 }
  264.                 BufWalk.Unlock(hr, cchWrittenA);
  265.             }
  266.         }
  267.         else
  268.         {
  269.             ASSERT(cchActual == 0); // MLStrBuf is not available
  270.             lActualLen = 0;
  271.         }
  272.     }
  273.     if (SUCCEEDED(hr))
  274.     {
  275.         if (pcchActual)
  276.             *pcchActual = cchActual;
  277.         if (plActualLen)
  278.             *plActualLen = lActualLen;
  279.     }
  280.     else
  281.     {
  282.         if (pcchActual)
  283.             *pcchActual = 0;
  284.         if (plActualLen)
  285.             *plActualLen = 0;
  286.     }
  287.     return hr;
  288. }
  289. STDMETHODIMP CMLStrAttrWStr::GetStrBufW(long lSrcPos, long lSrcMaxLen, IMLangStringBufW** ppDestBuf, long* plDestLen)
  290. {
  291.     ASSERT_THIS;
  292.     ASSERT_WRITE_PTR_OR_NULL(ppDestBuf);
  293.     ASSERT_WRITE_PTR_OR_NULL(plDestLen);
  294.     HRESULT hr = CheckThread();
  295.     CLock Lock(FALSE, this, hr);
  296.     IMLangStringBufW* pMLStrBufW;
  297.     if (SUCCEEDED(hr) &&
  298.         SUCCEEDED(hr = RegularizePosLen(&lSrcPos, &lSrcMaxLen)) &&
  299.         lSrcMaxLen <= 0)
  300.     {
  301.         hr = E_INVALIDARG;
  302.     }
  303.     if (SUCCEEDED(hr))
  304.     {
  305.         pMLStrBufW = GetMLStrBufW();
  306.         if (!pMLStrBufW)
  307.             hr = MLSTR_E_STRBUFNOTAVAILABLE;
  308.     }
  309.     if (SUCCEEDED(hr))
  310.     {
  311.         if (ppDestBuf)
  312.         {
  313.             pMLStrBufW->AddRef();
  314.             *ppDestBuf = pMLStrBufW;
  315.         }
  316.         if (plDestLen)
  317.             *plDestLen = lSrcMaxLen;
  318.     }
  319.     else
  320.     {
  321.         if (ppDestBuf)
  322.             *ppDestBuf = NULL;
  323.         if (plDestLen)
  324.             *plDestLen = 0;
  325.     }
  326.     return hr;
  327. }
  328. STDMETHODIMP CMLStrAttrWStr::LockWStr(long lSrcPos, long lSrcLen, long lFlags, long cchRequest, WCHAR** ppszDest, long* pcchDest, long* plDestLen)
  329. {
  330.     ASSERT_THIS;
  331.     ASSERT_WRITE_PTR_OR_NULL(ppszDest);
  332.     ASSERT_WRITE_PTR_OR_NULL(pcchDest);
  333.     ASSERT_WRITE_PTR_OR_NULL(plDestLen);
  334.     HRESULT hr = CheckThread();
  335.     CLock Lock(lFlags & MLSTR_WRITE, this, hr);
  336.     long cchSrcPos;
  337.     long cchSrcLen;
  338.     WCHAR* pszBuf = NULL;
  339.     long cchBuf;
  340.     long lLockLen;
  341.     BOOL fDirectLock;
  342.     if (SUCCEEDED(hr) && (!lFlags || (lFlags & ~GetBufFlags() & MLSTR_WRITE)))
  343.         hr = E_INVALIDARG; // No flags specified, or not writable StrBuf; TODO: Replace StrBuf in this case if allowed
  344.     if (!(lFlags & MLSTR_WRITE))
  345.         cchRequest = 0;
  346.     if (SUCCEEDED(hr) &&
  347.         SUCCEEDED(hr = PrepareMLStrBuf()) &&
  348.         SUCCEEDED(hr = RegularizePosLen(&lSrcPos, &lSrcLen)) &&
  349.         SUCCEEDED(hr = GetCCh(0, lSrcPos, &cchSrcPos)) &&
  350.         SUCCEEDED(hr = GetCCh(cchSrcPos, lSrcLen, &cchSrcLen)))
  351.     {
  352.         IMLangStringBufW* const pMLStrBufW = GetMLStrBufW();
  353.         fDirectLock = (pMLStrBufW != 0);
  354.         if (fDirectLock)
  355.         {
  356.             long cchInserted;
  357.             long cchLockLen = cchSrcLen;
  358.             if (cchRequest > cchSrcLen &&
  359.                 SUCCEEDED(hr = pMLStrBufW->Insert(cchSrcPos + cchSrcLen, cchRequest - cchSrcLen, &cchInserted)))
  360.             {
  361.                 SetBufCCh(GetBufCCh() + cchInserted);
  362.                 cchLockLen += cchInserted;
  363.                 if (!pcchDest && cchLockLen < cchRequest)
  364.                     hr = E_OUTOFMEMORY; // Can't insert in StrBuf
  365.             }
  366.             if (SUCCEEDED(hr) &&
  367.                 SUCCEEDED(hr = pMLStrBufW->LockBuf(cchSrcPos, cchLockLen, &pszBuf, &cchBuf)) &&
  368.                 !pcchDest && cchBuf < max(cchSrcLen, cchRequest))
  369.             {
  370.                 hr = E_OUTOFMEMORY; // Can't lock StrBuf
  371.             }
  372.             if (plDestLen && SUCCEEDED(hr))
  373.                 hr = CalcLenW(pszBuf, cchBuf, &lLockLen);
  374.         }
  375.         else
  376.         {
  377.             long cchSize;
  378.             if (SUCCEEDED(hr = CalcBufSizeW(lSrcLen, &cchSize)))
  379.             {
  380.                 cchBuf = max(cchSize, cchRequest);
  381.                 hr = MemAlloc(sizeof(*pszBuf) * cchBuf, (void**)&pszBuf);
  382.             }
  383.             if (SUCCEEDED(hr) && (lFlags & MLSTR_READ))
  384.                 hr = GetWStr(lSrcPos, lSrcLen,  pszBuf, cchBuf, (pcchDest) ? &cchBuf : NULL, (plDestLen) ? &lLockLen : NULL);
  385.         }
  386.     }
  387.     if (SUCCEEDED(hr) &&
  388.         SUCCEEDED(hr = Lock.FallThrough()))
  389.     {
  390.         hr = GetLockInfo()->Lock((fDirectLock) ? UnlockWStrDirect : UnlockWStrIndirect, lFlags, 0, pszBuf, lSrcPos, lSrcLen, cchSrcPos, cchBuf);
  391.     }
  392.     if (SUCCEEDED(hr))
  393.     {
  394.         if (ppszDest)
  395.             *ppszDest = pszBuf;
  396.         if (pcchDest)
  397.             *pcchDest = cchBuf;
  398.         if (plDestLen)
  399.             *plDestLen = lLockLen;
  400.     }
  401.     else
  402.     {
  403.         if (pszBuf)
  404.         {
  405.             if (fDirectLock)
  406.                 GetMLStrBufW()->UnlockBuf(pszBuf, 0, 0);
  407.             else
  408.                 MemFree(pszBuf);
  409.         }
  410.         if (ppszDest)
  411.             *ppszDest = NULL;
  412.         if (pcchDest)
  413.             *pcchDest = 0;
  414.         if (plDestLen)
  415.             *plDestLen = 0;
  416.     }
  417.     return hr;
  418. }
  419. STDMETHODIMP CMLStrAttrWStr::UnlockWStr(const WCHAR* pszSrc, long cchSrc, long* pcchActual, long* plActualLen)
  420. {
  421.     ASSERT_THIS;
  422.     ASSERT_READ_BLOCK(pszSrc, cchSrc);
  423.     ASSERT_WRITE_PTR_OR_NULL(pcchActual);
  424.     ASSERT_WRITE_PTR_OR_NULL(plActualLen);
  425.     return UnlockStrCommon(pszSrc, cchSrc, pcchActual, plActualLen);
  426. }
  427. STDMETHODIMP CMLStrAttrWStr::OnRegisterAttr(IUnknown* pUnk)
  428. {
  429.     return E_NOTIMPL; // CMLStrAttrWStr::OnRegisterAttr()
  430. }
  431. STDMETHODIMP CMLStrAttrWStr::OnUnregisterAttr(IUnknown* pUnk)
  432. {
  433.     return E_NOTIMPL; // CMLStrAttrWStr::OnUnregisterAttr()
  434. }
  435. STDMETHODIMP CMLStrAttrWStr::OnRequestEdit(long lDestPos, long lDestLen, long lNewLen, REFIID riid, LPARAM lParam, IUnknown* pUnk)
  436. {
  437.     return E_NOTIMPL; // CMLStrAttrWStr::OnRequestEdit()
  438. }
  439. STDMETHODIMP CMLStrAttrWStr::OnCanceledEdit(long lDestPos, long lDestLen, long lNewLen, REFIID riid, LPARAM lParam, IUnknown* pUnk)
  440. {
  441.     return E_NOTIMPL; // CMLStrAttrWStr::OnCanceledEdit()
  442. }
  443. STDMETHODIMP CMLStrAttrWStr::OnChanged(long lDestPos, long lDestLen, long lNewLen, REFIID riid, LPARAM lParam, IUnknown* pUnk)
  444. {
  445.     return E_NOTIMPL; // CMLStrAttrWStr::OnChanged()
  446. }
  447. #endif // NEWMLSTR