Leaked source code of windows server 2003
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.

1123 lines
31 KiB

  1. /*++
  2. Copyright (c) 2001, Microsoft Corporation
  3. Module Name:
  4. ctxtcomp.h
  5. Abstract:
  6. This file defines the Context of Composition Class.
  7. Author:
  8. Revision History:
  9. Notes:
  10. --*/
  11. #ifndef _CTXTCOMP_H_
  12. #define _CTXTCOMP_H_
  13. #include "template.h"
  14. #include "imc.h"
  15. /////////////////////////////////////////////////////////////////////////////
  16. // GetCompInfo
  17. template<class T>
  18. HRESULT
  19. GetCompInfo(
  20. IN T size,
  21. IN DWORD len,
  22. IN LONG*& lpCopied
  23. )
  24. {
  25. *lpCopied = (LONG)(len * size);
  26. return S_OK;
  27. }
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CompData
  30. template<class TYPE, class ARG_TYPE>
  31. class CompData
  32. {
  33. public:
  34. CompData(HIMC hIMC = NULL, ARG_TYPE* lpsz = NULL, DWORD dwLen = 0)
  35. {
  36. IMCLock lpIMC(hIMC);
  37. if (lpIMC.Invalid())
  38. return;
  39. if (lpsz)
  40. WriteCompData(lpsz, dwLen);
  41. }
  42. CompData(IMCCLock<COMPOSITIONSTRING>& lpCompStr)
  43. {
  44. }
  45. CompData(IMCCLock<COMPOSITIONSTRING>& lpCompStr, DWORD dwIndex);
  46. DWORD WriteCompData(IN const ARG_TYPE& data, IN DWORD dwLen)
  47. {
  48. if (! m_array.SetSize(dwLen))
  49. return 0;
  50. ARG_TYPE* psz = m_array.GetData();
  51. if (!psz)
  52. return 0;
  53. DWORD index = dwLen;
  54. while (index--) {
  55. *psz++ = data;
  56. }
  57. return dwLen;
  58. }
  59. DWORD WriteCompData(IN ARG_TYPE* lpSrc, IN DWORD dwLen)
  60. {
  61. if (! m_array.SetSize(dwLen))
  62. return 0;
  63. ARG_TYPE* psz = m_array.GetData();
  64. if (!psz)
  65. return 0;
  66. memcpy(psz, lpSrc, dwLen * sizeof(TYPE));
  67. return dwLen;
  68. }
  69. DWORD AddCompData(IN ARG_TYPE* lpSrc, IN DWORD dwLen)
  70. {
  71. DWORD dwl = (DWORD)m_array.GetSize();
  72. ARG_TYPE *psTemp;
  73. if (! m_array.SetSize(dwLen+dwl))
  74. return 0;
  75. psTemp = m_array.GetData();
  76. if (!psTemp)
  77. return 0;
  78. memcpy(psTemp+dwl, lpSrc, dwLen*sizeof(TYPE));
  79. return dwLen;
  80. }
  81. DWORD AddCompData(IN const ARG_TYPE& data, IN DWORD dwLen)
  82. {
  83. DWORD dwl = (DWORD)m_array.GetSize();
  84. ARG_TYPE *psTemp;
  85. if (! m_array.SetSize(dwLen+dwl))
  86. return 0;
  87. psTemp = m_array.GetData();
  88. if (!psTemp)
  89. return 0;
  90. psTemp += dwl;
  91. DWORD index = dwLen;
  92. while (index--) {
  93. *psTemp++ = data;
  94. }
  95. return dwLen;
  96. }
  97. const INT_PTR ReadCompData(IN ARG_TYPE* lpDest = NULL, DWORD dwLen = 0) {
  98. INT_PTR dwBufLen;
  99. if (! dwLen) {
  100. // query required buffer size. not inculde \0.
  101. dwBufLen = m_array.GetSize();
  102. }
  103. else {
  104. ARG_TYPE* psz = m_array.GetData();
  105. if ((INT_PTR)dwLen > m_array.GetSize()) {
  106. dwBufLen = m_array.GetSize();
  107. }
  108. else {
  109. dwBufLen = (INT_PTR)dwLen;
  110. }
  111. memcpy(lpDest, psz, dwBufLen * sizeof(TYPE));
  112. }
  113. return dwBufLen;
  114. }
  115. DWORD GetCompStrIndex(IN DWORD dwIndex) {
  116. switch(dwIndex) {
  117. case GCS_COMPATTR: return GCS_COMPSTR;
  118. case GCS_COMPREADATTR: return GCS_COMPREADSTR;
  119. case GCS_COMPCLAUSE: return GCS_COMPSTR;
  120. case GCS_COMPREADCLAUSE: return GCS_COMPREADSTR;
  121. case GCS_RESULTCLAUSE: return GCS_RESULTSTR;
  122. case GCS_RESULTREADCLAUSE: return GCS_RESULTREADSTR;
  123. case GCS_CURSORPOS: return GCS_COMPSTR;
  124. case GCS_DELTASTART: return GCS_COMPSTR;
  125. default: break;
  126. }
  127. ASSERT(FALSE);
  128. return 0;
  129. }
  130. TYPE GetAt(INT_PTR nIndex) const
  131. {
  132. return m_array.GetAt(nIndex);
  133. }
  134. void SetAtGrow(INT_PTR nIndex, ARG_TYPE newElement)
  135. {
  136. m_array.SetAtGrow(nIndex, newElement);
  137. }
  138. INT_PTR Add(ARG_TYPE newElement)
  139. {
  140. return m_array.Add(newElement);
  141. }
  142. INT_PTR GetSize() const
  143. {
  144. return m_array.GetSize();
  145. }
  146. void RemoveAll()
  147. {
  148. m_array.RemoveAll();
  149. }
  150. operator void* ()
  151. {
  152. return m_array.GetData();
  153. }
  154. TYPE operator[](INT_PTR nIndex)
  155. {
  156. return m_array.GetAt(nIndex);
  157. }
  158. protected:
  159. CArray<TYPE, ARG_TYPE> m_array;
  160. };
  161. template<class TYPE, class ARG_TYPE>
  162. CompData<TYPE, ARG_TYPE>::CompData(
  163. IMCCLock<COMPOSITIONSTRING>& lpCompStr,
  164. DWORD dwIndex
  165. )
  166. {
  167. switch (dwIndex) {
  168. case GCS_COMPSTR:
  169. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->dwCompStrOffset),
  170. lpCompStr->dwCompStrLen); // # of chars
  171. break;
  172. case GCS_COMPREADSTR:
  173. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->dwCompReadStrOffset),
  174. lpCompStr->dwCompReadStrLen); // # of chars
  175. break;
  176. case GCS_RESULTSTR:
  177. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->dwResultStrOffset),
  178. lpCompStr->dwResultStrLen); // # of chars
  179. break;
  180. case GCS_RESULTREADSTR:
  181. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->dwResultReadStrOffset),
  182. lpCompStr->dwResultReadStrLen); // # of chars
  183. break;
  184. case GCS_COMPATTR: // ANSI-only
  185. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->dwCompAttrOffset),
  186. lpCompStr->dwCompAttrLen);
  187. break;
  188. case GCS_COMPREADATTR: // ANSI-only
  189. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->dwCompReadAttrOffset),
  190. lpCompStr->dwCompReadAttrLen);
  191. break;
  192. case GCS_COMPREADCLAUSE:
  193. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->dwCompReadClauseOffset),
  194. lpCompStr->dwCompReadClauseLen / sizeof(TYPE)); // # of bytes
  195. break;
  196. case GCS_RESULTCLAUSE:
  197. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->dwResultClauseOffset),
  198. lpCompStr->dwResultClauseLen / sizeof(TYPE)); // # of bytes
  199. break;
  200. case GCS_RESULTREADCLAUSE:
  201. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->dwResultReadClauseOffset),
  202. lpCompStr->dwResultReadClauseLen / sizeof(TYPE)); // # of bytes
  203. break;
  204. case GCS_COMPCLAUSE:
  205. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->dwCompClauseOffset),
  206. lpCompStr->dwCompClauseLen / sizeof(TYPE)); // # of bytes
  207. break;
  208. case GCS_CURSORPOS:
  209. SetAtGrow(0, (TYPE)lpCompStr->dwCursorPos);
  210. break;
  211. case GCS_DELTASTART:
  212. SetAtGrow(0, (TYPE)lpCompStr->dwDeltaStart);
  213. break;
  214. default:
  215. break;
  216. }
  217. }
  218. class CWCompString;
  219. /////////////////////////////////////////////////////////////////////////////
  220. // CBCompString
  221. class CBCompString : public CompData<CHAR, CHAR>
  222. {
  223. public:
  224. CBCompString(
  225. HIMC hIMC=NULL,
  226. LPSTR lpsz=NULL,
  227. DWORD dwLen=0) : CompData<CHAR, CHAR>(hIMC, lpsz, dwLen)
  228. {
  229. };
  230. CBCompString(
  231. IMCCLock<COMPOSITIONSTRING>& lpCompStr) : CompData<CHAR, CHAR>(lpCompStr)
  232. {
  233. };
  234. CBCompString(
  235. IMCCLock<COMPOSITIONSTRING>& lpCompStr,
  236. DWORD dwIndex) : CompData<CHAR, CHAR>(lpCompStr, dwIndex)
  237. {
  238. };
  239. const CBCompString& operator=(CWCompString& wcompstr);
  240. const DWORD ConvertUnicodeString(IN OUT LPWSTR lpsz = NULL, DWORD cch = 0)
  241. {
  242. return _mbstowcs(lpsz, cch);
  243. }
  244. CHAR GetAt(IN DWORD dwIndex)
  245. {
  246. return CompData<CHAR, CHAR>::GetAt(dwIndex);
  247. }
  248. BOOL IsDBCSLeadByteEx(IN DWORD dwIndex)
  249. {
  250. CHAR c = GetAt(dwIndex);
  251. return ::IsDBCSLeadByteEx(m_cp, c);
  252. }
  253. void SetCodePage(UINT cp)
  254. {
  255. m_cp = cp;
  256. }
  257. private:
  258. UINT m_cp; // code page value.
  259. int _mbstowcs(wchar_t* wcstr, size_t cch);
  260. };
  261. inline
  262. int
  263. CBCompString::_mbstowcs(
  264. wchar_t* wcstr,
  265. size_t cch
  266. )
  267. {
  268. if (cch == 0 && wcstr != NULL)
  269. return 0;
  270. const char* mbstr = m_array.GetData();
  271. if (!mbstr)
  272. return 0;
  273. INT_PTR nSize = m_array.GetSize();
  274. int result = ::MultiByteToWideChar(m_cp, // code page
  275. 0, // character-type option
  276. mbstr, // address of string to map
  277. (int)nSize, // number of bytes in string
  278. wcstr, // address of wide-char buffer
  279. (int)cch); // size of buffer, in wide character.
  280. return result;
  281. }
  282. /////////////////////////////////////////////////////////////////////////////
  283. // CWCompString
  284. class CWCompString : public CompData<WCHAR, WCHAR>
  285. {
  286. public:
  287. CWCompString(
  288. HIMC hIMC=NULL,
  289. LPWSTR lpsz=NULL,
  290. DWORD dwLen=0) : CompData<WCHAR, WCHAR>(hIMC, lpsz, dwLen)
  291. {
  292. };
  293. CWCompString(
  294. IMCCLock<COMPOSITIONSTRING>& lpCompStr) : CompData<WCHAR, WCHAR>(lpCompStr)
  295. {
  296. };
  297. CWCompString(
  298. IMCCLock<COMPOSITIONSTRING>& lpCompStr,
  299. DWORD dwIndex) : CompData<WCHAR, WCHAR>(lpCompStr, dwIndex)
  300. {
  301. };
  302. const CWCompString& operator=(CBCompString& bcompstr);
  303. const DWORD ConvertANSIString(IN OUT LPSTR lpsz = NULL, DWORD dwLen = 0)
  304. {
  305. return _wcstombs(lpsz, dwLen);
  306. }
  307. WCHAR GetAt(IN DWORD dwIndex)
  308. {
  309. return (WCHAR)CompData<WCHAR, WCHAR>::GetAt(dwIndex);
  310. }
  311. int UnicodeToMultiByteSize(IN DWORD dwIndex)
  312. {
  313. WCHAR wc = GetAt(dwIndex);
  314. return ::WideCharToMultiByte(m_cp, // code page
  315. 0, // performance and mapping flags
  316. (const wchar_t*)&wc, // address of wide-char string
  317. 1, // number of char string
  318. NULL, // address of buffer for new string
  319. 0, // size of buffer
  320. NULL, // default for unmappable char
  321. NULL); // flag set when default char
  322. }
  323. void SetCodePage(UINT cp)
  324. {
  325. m_cp = cp;
  326. }
  327. private:
  328. UINT m_cp; // code page value.
  329. int _wcstombs(char* mbstr, size_t count);
  330. };
  331. inline
  332. int
  333. CWCompString::_wcstombs(
  334. char* mbstr,
  335. size_t count
  336. )
  337. {
  338. if (count == 0 && mbstr != NULL)
  339. return 0;
  340. const wchar_t* wcstr = m_array.GetData();
  341. if (!wcstr)
  342. return 0;
  343. INT_PTR nSize = m_array.GetSize();
  344. int result = ::WideCharToMultiByte(m_cp, // code page
  345. 0, // performance and mapping flags
  346. wcstr, // address of wide-char string
  347. (int)nSize, // number of char string
  348. mbstr, // address of buffer for new string
  349. (int)count, // size of buffer
  350. NULL, // default for unmappable char
  351. NULL); // flag set when default char
  352. return result;
  353. }
  354. /////////////////////////////////////////////////////////////////////////////
  355. // CBCompStrin/CWCompString::operator=
  356. inline
  357. const CBCompString&
  358. CBCompString::operator=(
  359. CWCompString& wcompstr
  360. )
  361. /*+++
  362. *
  363. * Get ANSI string from Unicode composition string.
  364. *
  365. ---*/
  366. {
  367. m_array.RemoveAll();
  368. DWORD len = wcompstr.ConvertANSIString();
  369. if (! m_array.SetSize(len))
  370. return *this;
  371. LPSTR psz = m_array.GetData();
  372. if (psz)
  373. len = wcompstr.ConvertANSIString(psz, len * sizeof(CHAR));
  374. return *this;
  375. }
  376. inline
  377. const CWCompString&
  378. CWCompString::operator=(
  379. CBCompString& bcompstr
  380. )
  381. /*+++
  382. *
  383. * Get Unicode string from ANSI composition string.
  384. *
  385. ---*/
  386. {
  387. m_array.RemoveAll();
  388. DWORD len = bcompstr.ConvertUnicodeString();
  389. if (! m_array.SetSize(len))
  390. return *this;
  391. LPWSTR psz = m_array.GetData();
  392. if (psz)
  393. len = bcompstr.ConvertUnicodeString(psz, len);
  394. return *this;
  395. }
  396. /////////////////////////////////////////////////////////////////////////////
  397. // CheckAttribute template
  398. template<class APPS_ATTR, class HIMC_ATTR, class HIMC_CLAUSE>
  399. HRESULT
  400. CheckAttribute(
  401. APPS_ATTR& apps_attr, // the attr from apps
  402. HIMC_ATTR& himc_attr, // the attr from IMC
  403. HIMC_CLAUSE& himc_clause // the clause from IMC
  404. )
  405. {
  406. if (himc_clause.ReadCompData() == 0) {
  407. TraceMsg(TF_WARNING, "CheckAttribute: no Clause. Pass it to IME.");
  408. }
  409. else {
  410. if (himc_attr.ReadCompData() != 0) {
  411. if (apps_attr.GetSize() != himc_attr.GetSize()) {
  412. TraceMsg(TF_ERROR, "CheckAttribute: wrong length.");
  413. return E_FAIL;
  414. }
  415. /*
  416. * The attr. of chars of one clause have to be same.
  417. */
  418. DWORD dwAttrIndex = 0;
  419. DWORD dwClauseIndex;
  420. for (dwClauseIndex = 0;
  421. (INT_PTR)himc_clause.GetAt(dwClauseIndex) < apps_attr.ReadCompData();
  422. dwClauseIndex++
  423. ) {
  424. DWORD dwBound = himc_clause.GetAt(dwClauseIndex+1) - himc_clause.GetAt(dwClauseIndex);
  425. DWORD battr = apps_attr.GetAt(dwAttrIndex++);
  426. DWORD dwCnt;
  427. for (dwCnt = 1; dwCnt < dwBound; dwCnt++) {
  428. if (battr != apps_attr.GetAt(dwAttrIndex++)) {
  429. TraceMsg(TF_ERROR, "CheckAttribute: mismatch clause attribute.");
  430. return E_FAIL;
  431. }
  432. }
  433. }
  434. }
  435. }
  436. return S_OK;
  437. }
  438. /////////////////////////////////////////////////////////////////////////////
  439. // CWCompAttribute
  440. class CWCompAttribute : public CompData<BYTE, BYTE>
  441. {
  442. public:
  443. CWCompAttribute(
  444. HIMC hIMC=NULL,
  445. BYTE* lpsz=NULL,
  446. DWORD dwLen=0) : CompData<BYTE, BYTE>(hIMC, lpsz, dwLen),
  447. m_wcompstr(hIMC)
  448. {
  449. };
  450. CWCompAttribute(
  451. IMCCLock<COMPOSITIONSTRING>& lpCompStr) : CompData<BYTE, BYTE>(lpCompStr),
  452. m_wcompstr(lpCompStr)
  453. {
  454. };
  455. CWCompAttribute(
  456. IMCCLock<COMPOSITIONSTRING>& lpCompStr,
  457. DWORD dwIndex) : CompData<BYTE, BYTE>(lpCompStr, dwIndex),
  458. m_wcompstr(lpCompStr, GetCompStrIndex(dwIndex))
  459. {
  460. };
  461. // const CWCompAttribute& operator=(CBCompAttribute& bcompattr);
  462. INT_PTR Add(IN BYTE newElement)
  463. {
  464. return CompData<BYTE, BYTE>::Add(newElement);
  465. }
  466. CWCompString m_wcompstr;
  467. };
  468. /////////////////////////////////////////////////////////////////////////////
  469. // CheckClause template
  470. template<class APPS_CLAUSE, class HIMC_CLAUSE>
  471. HRESULT
  472. CheckClause(
  473. APPS_CLAUSE& apps_clause, // the clause from apps
  474. HIMC_CLAUSE& himc_clause // the clause from IMC
  475. )
  476. {
  477. if (apps_clause.ReadCompData() == 0 ||
  478. himc_clause.ReadCompData() == 0 ) {
  479. TraceMsg(TF_ERROR, "CheckClause: no Clause.");
  480. return E_FAIL;
  481. }
  482. if (apps_clause.GetAt(0) ||
  483. himc_clause.GetAt(0) ) {
  484. TraceMsg(TF_ERROR, "CheckClause: clause[0] have to be ZERO.");
  485. return E_FAIL;
  486. }
  487. INT_PTR dwClauseIndex;
  488. for (dwClauseIndex = 0;
  489. dwClauseIndex < himc_clause.ReadCompData();
  490. dwClauseIndex++
  491. ) {
  492. if (apps_clause.GetAt(dwClauseIndex) != himc_clause.GetAt(dwClauseIndex)) {
  493. return E_FAIL;
  494. }
  495. }
  496. return S_OK;
  497. }
  498. class CWCompClause;
  499. /////////////////////////////////////////////////////////////////////////////
  500. // CWCompClause
  501. class CWCompClause : public CompData<DWORD, DWORD>
  502. {
  503. public:
  504. CWCompClause(
  505. HIMC hIMC=NULL,
  506. DWORD* lpsz=NULL,
  507. DWORD dwLen=0) : CompData<DWORD, DWORD>(hIMC,lpsz,dwLen),
  508. m_wcompstr(hIMC)
  509. {
  510. };
  511. CWCompClause(
  512. IMCCLock<COMPOSITIONSTRING>& lpCompStr) : CompData<DWORD, DWORD>(lpCompStr),
  513. m_wcompstr(lpCompStr)
  514. {
  515. };
  516. CWCompClause(
  517. IMCCLock<COMPOSITIONSTRING>& lpCompStr,
  518. DWORD dwIndex) : CompData<DWORD, DWORD>(lpCompStr, dwIndex),
  519. m_wcompstr(lpCompStr, GetCompStrIndex(dwIndex))
  520. {
  521. };
  522. DWORD GetAt(IN DWORD dwIndex)
  523. {
  524. return (DWORD)CompData<DWORD, DWORD>::GetAt(dwIndex);
  525. }
  526. // const CWCompClause& operator=(CBCompClause& bcompclause);
  527. INT_PTR Add(IN DWORD newElement)
  528. {
  529. return CompData<DWORD, DWORD>::Add(newElement);
  530. }
  531. friend DWORD CalcCharacterPositionWtoA(DWORD dwCharPosW, CWCompString* wcompstr);
  532. CWCompString m_wcompstr;
  533. };
  534. /////////////////////////////////////////////////////////////////////////////
  535. // CWCompCursorPos
  536. class CWCompCursorPos : public CompData<DWORD, DWORD>
  537. {
  538. public:
  539. CWCompCursorPos(
  540. HIMC hIMC=NULL) : CompData<DWORD, DWORD>(hIMC),
  541. m_wcompstr(hIMC)
  542. {
  543. };
  544. CWCompCursorPos(
  545. IMCCLock<COMPOSITIONSTRING>& lpCompStr) : CompData<DWORD, DWORD>(lpCompStr),
  546. m_wcompstr(lpCompStr)
  547. {
  548. };
  549. CWCompCursorPos(
  550. IMCCLock<COMPOSITIONSTRING>& lpCompStr,
  551. DWORD dwIndex) : CompData<DWORD, DWORD>(lpCompStr, dwIndex),
  552. m_wcompstr(lpCompStr, GetCompStrIndex(dwIndex))
  553. {
  554. };
  555. void Set(IN DWORD newElement)
  556. {
  557. CompData<DWORD, DWORD>::SetAtGrow(0, newElement);
  558. }
  559. // const CWCompCursorPos& operator=(CBCompCursorPos& bcompcursorpos);
  560. friend DWORD CalcCharacterPositionWtoA(DWORD dwCharPosW, CWCompString* wcompstr);
  561. CWCompString m_wcompstr;
  562. };
  563. /////////////////////////////////////////////////////////////////////////////
  564. // CWCompDeltaStart
  565. class CWCompDeltaStart : public CompData<DWORD, DWORD>
  566. {
  567. public:
  568. CWCompDeltaStart(
  569. HIMC hIMC=NULL) : CompData<DWORD, DWORD>(hIMC),
  570. m_wcompstr(hIMC)
  571. {
  572. };
  573. CWCompDeltaStart(
  574. IMCCLock<COMPOSITIONSTRING>& lpCompStr) : CompData<DWORD, DWORD>(lpCompStr),
  575. m_wcompstr(lpCompStr)
  576. {
  577. };
  578. CWCompDeltaStart(
  579. IMCCLock<COMPOSITIONSTRING>& lpCompStr,
  580. DWORD dwIndex) : CompData<DWORD, DWORD>(lpCompStr, dwIndex),
  581. m_wcompstr(lpCompStr, GetCompStrIndex(dwIndex))
  582. {
  583. };
  584. void Set(IN DWORD newElement)
  585. {
  586. CompData<DWORD, DWORD>::SetAtGrow(0, newElement);
  587. }
  588. // const CWCompDeltaStart& operator=(CBCompDeltaStart& bcompdeltastart);
  589. friend DWORD CalcCharacterPositionWtoA(DWORD dwCharPosW, CWCompString* wcompstr);
  590. CWCompString m_wcompstr;
  591. };
  592. class CWReconvertString;
  593. /////////////////////////////////////////////////////////////////////////////
  594. // CBReconvetString
  595. class CBReconvertString
  596. {
  597. public:
  598. CBReconvertString(
  599. HIMC hIMC,
  600. LPRECONVERTSTRING lpReconv=NULL,
  601. DWORD dwLen=0) : m_bcompstr(hIMC)
  602. {
  603. m_dwVersion = 0;
  604. m_CompStrIndex = 0;
  605. m_CompStrLen = 0;
  606. m_TargetStrIndex = 0;
  607. m_TargetStrLen = 0;
  608. if (lpReconv) {
  609. m_dwVersion = lpReconv->dwVersion;
  610. if (dwLen && lpReconv->dwStrOffset) {
  611. m_bcompstr.WriteCompData((CHAR*)((LPBYTE)lpReconv + lpReconv->dwStrOffset),
  612. lpReconv->dwStrLen); // # of chars
  613. m_CompStrIndex = lpReconv->dwCompStrOffset;
  614. m_CompStrLen = lpReconv->dwCompStrLen;
  615. m_TargetStrIndex = lpReconv->dwTargetStrOffset;
  616. m_TargetStrLen = lpReconv->dwTargetStrLen;
  617. }
  618. }
  619. }
  620. DWORD WriteCompData(IN LPSTR lpSrc, IN DWORD dwLen)
  621. {
  622. m_CompStrLen = dwLen;
  623. m_TargetStrLen = dwLen;
  624. return m_bcompstr.WriteCompData(lpSrc, dwLen);
  625. }
  626. const DWORD ReadCompData(IN LPRECONVERTSTRING lpReconv = NULL, DWORD dwLen = 0) {
  627. INT_PTR dwBufLen;
  628. if (! dwLen) {
  629. // query required buffer size. not inculde \0.
  630. dwBufLen = m_bcompstr.ReadCompData() * sizeof(CHAR) + sizeof(RECONVERTSTRING);
  631. }
  632. else {
  633. lpReconv->dwSize = dwLen;
  634. lpReconv->dwVersion = m_dwVersion;
  635. lpReconv->dwStrLen = (DWORD)(m_bcompstr.ReadCompData() * sizeof(CHAR));
  636. lpReconv->dwStrOffset = (DWORD)sizeof(RECONVERTSTRING);
  637. lpReconv->dwCompStrLen = (DWORD)m_CompStrLen;
  638. lpReconv->dwCompStrOffset = (DWORD)(m_CompStrIndex * sizeof(CHAR));
  639. lpReconv->dwTargetStrLen = (DWORD)m_TargetStrLen;
  640. lpReconv->dwTargetStrOffset = (DWORD)(m_TargetStrIndex * sizeof(CHAR));
  641. dwBufLen = m_bcompstr.ReadCompData((CHAR*)((LPBYTE)lpReconv + lpReconv->dwStrOffset),
  642. lpReconv->dwStrLen); // # of chars
  643. }
  644. return (DWORD)dwBufLen;
  645. }
  646. const CBReconvertString& operator=(CWReconvertString& wReconvStr);
  647. void SetData(CWReconvertString& wReconvStr);
  648. void SetCodePage(UINT cp)
  649. {
  650. m_bcompstr.SetCodePage(cp);
  651. }
  652. friend DWORD CalcCharacterPositionAtoW(DWORD dwCharPosA, CBCompString* bcompstr);
  653. public:
  654. CBCompString m_bcompstr;
  655. DWORD m_dwVersion; // Version number. Must be zero.
  656. INT_PTR m_CompStrIndex; // Index in the CBCompString::<string array> that will be the composition string.
  657. INT_PTR m_CompStrLen; // Character count length of the string that will be the composition string.
  658. INT_PTR m_TargetStrIndex; // Index in the CBCompString::<string array> that is related to thetarget clause in the composition string.
  659. INT_PTR m_TargetStrLen; // Character count length of the string that is related to the target clause.
  660. };
  661. /////////////////////////////////////////////////////////////////////////////
  662. // CWReconvertString
  663. class CWReconvertString
  664. {
  665. public:
  666. CWReconvertString(
  667. HIMC hIMC,
  668. LPRECONVERTSTRING lpReconv=NULL,
  669. DWORD dwLen=0) : m_wcompstr(hIMC)
  670. {
  671. m_dwVersion = 0;
  672. m_CompStrIndex = 0;
  673. m_CompStrLen = 0;
  674. m_TargetStrIndex = 0;
  675. m_TargetStrLen = 0;
  676. if (lpReconv) {
  677. m_dwVersion = lpReconv->dwVersion;
  678. if (dwLen && lpReconv->dwStrOffset) {
  679. m_wcompstr.WriteCompData((WCHAR*)((LPBYTE)lpReconv + lpReconv->dwStrOffset),
  680. lpReconv->dwStrLen); // # of chars
  681. m_CompStrIndex = lpReconv->dwCompStrOffset / sizeof(WCHAR); // char count
  682. m_CompStrLen = lpReconv->dwCompStrLen;
  683. m_TargetStrIndex = lpReconv->dwTargetStrOffset / sizeof(WCHAR); // char count
  684. m_TargetStrLen = lpReconv->dwTargetStrLen;
  685. }
  686. }
  687. }
  688. DWORD WriteCompData(IN LPWSTR lpSrc, IN DWORD dwLen)
  689. {
  690. m_CompStrLen = dwLen;
  691. m_TargetStrLen = dwLen;
  692. return m_wcompstr.WriteCompData(lpSrc, dwLen);
  693. }
  694. const DWORD ReadCompData(IN LPRECONVERTSTRING lpReconv = NULL, DWORD dwLen = 0) {
  695. INT_PTR dwBufLen;
  696. if (! dwLen) {
  697. // query required buffer size. not inculde \0.
  698. dwBufLen = m_wcompstr.ReadCompData() * sizeof(WCHAR) + sizeof(RECONVERTSTRING);
  699. }
  700. else {
  701. lpReconv->dwSize = dwLen;
  702. lpReconv->dwVersion = m_dwVersion;
  703. lpReconv->dwStrLen = (DWORD)m_wcompstr.ReadCompData();
  704. lpReconv->dwStrOffset = (DWORD)sizeof(RECONVERTSTRING);
  705. lpReconv->dwCompStrLen = (DWORD)m_CompStrLen;
  706. lpReconv->dwCompStrOffset = (DWORD)(m_CompStrIndex * sizeof(WCHAR)); // byte count
  707. lpReconv->dwTargetStrLen = (DWORD)m_TargetStrLen;
  708. lpReconv->dwTargetStrOffset = (DWORD)(m_TargetStrIndex * sizeof(WCHAR)); // byte count
  709. dwBufLen = m_wcompstr.ReadCompData((WCHAR*)((LPBYTE)lpReconv + lpReconv->dwStrOffset),
  710. lpReconv->dwStrLen); // # of chars
  711. }
  712. return (DWORD)dwBufLen;
  713. }
  714. const CWReconvertString& operator=(CBReconvertString& bReconvStr);
  715. void SetData(CBReconvertString& bReconvStr);
  716. void SetCodePage(UINT cp)
  717. {
  718. m_wcompstr.SetCodePage(cp);
  719. }
  720. friend DWORD CalcCharacterPositionWtoA(DWORD dwCharPosW, CWCompString* wcompstr);
  721. public:
  722. CWCompString m_wcompstr;
  723. DWORD m_dwVersion; // Version number. Must be zero.
  724. INT_PTR m_CompStrIndex; // Index in the CWCompString::<string array> that will be the composition string.
  725. INT_PTR m_CompStrLen; // Character count length of the string that will be the composition string.
  726. INT_PTR m_TargetStrIndex; // Index in the CWCompString::<string array> that is related to the target clause in the composition string.
  727. INT_PTR m_TargetStrLen; // Character count length of the string that is related to the target clause.
  728. };
  729. /////////////////////////////////////////////////////////////////////////////
  730. // CBCompReconvertString/CWCompReconvertString::operator=
  731. inline
  732. const CBReconvertString&
  733. CBReconvertString::operator=(
  734. CWReconvertString& wReconvStr
  735. )
  736. {
  737. m_bcompstr = wReconvStr.m_wcompstr;
  738. SetData(wReconvStr);
  739. return *this;
  740. }
  741. inline
  742. const CWReconvertString&
  743. CWReconvertString::operator=(
  744. CBReconvertString& bReconvStr
  745. )
  746. {
  747. m_wcompstr = bReconvStr.m_bcompstr;
  748. SetData(bReconvStr);
  749. return *this;
  750. }
  751. /////////////////////////////////////////////////////////////////////////////
  752. // CBReconvertString/CWReconvertString::SetData
  753. inline
  754. void
  755. CBReconvertString::SetData(
  756. CWReconvertString& wReconvStr
  757. )
  758. {
  759. m_dwVersion = wReconvStr.m_dwVersion;
  760. m_CompStrIndex = CalcCharacterPositionWtoA((DWORD)(wReconvStr.m_CompStrIndex), &wReconvStr.m_wcompstr);
  761. m_CompStrLen = CalcCharacterPositionWtoA((DWORD)(wReconvStr.m_CompStrIndex + wReconvStr.m_CompStrLen), &wReconvStr.m_wcompstr) - m_CompStrIndex;
  762. m_TargetStrIndex = CalcCharacterPositionWtoA((DWORD)(wReconvStr.m_TargetStrIndex), &wReconvStr.m_wcompstr);
  763. m_TargetStrLen = CalcCharacterPositionWtoA((DWORD)(wReconvStr.m_TargetStrIndex + wReconvStr.m_TargetStrLen), &wReconvStr.m_wcompstr) - m_TargetStrIndex;
  764. }
  765. inline
  766. void
  767. CWReconvertString::SetData(
  768. CBReconvertString& bReconvStr
  769. )
  770. {
  771. m_dwVersion = bReconvStr.m_dwVersion;
  772. m_CompStrIndex = CalcCharacterPositionAtoW((DWORD)(bReconvStr.m_CompStrIndex), &bReconvStr.m_bcompstr);
  773. m_CompStrLen = (CalcCharacterPositionAtoW((DWORD)(bReconvStr.m_CompStrIndex + bReconvStr.m_CompStrLen), &bReconvStr.m_bcompstr) - m_CompStrIndex);
  774. m_TargetStrIndex = CalcCharacterPositionAtoW((DWORD)(bReconvStr.m_TargetStrIndex), &bReconvStr.m_bcompstr);
  775. m_TargetStrLen = (CalcCharacterPositionAtoW((DWORD)(bReconvStr.m_TargetStrIndex + bReconvStr.m_TargetStrLen), &bReconvStr.m_bcompstr) - m_TargetStrIndex);
  776. }
  777. /////////////////////////////////////////////////////////////////////////////
  778. // CWInterimString
  779. class CWInterimString : public CWCompString
  780. {
  781. public:
  782. CWInterimString(
  783. HIMC hIMC
  784. ) : CWCompString(hIMC)
  785. {
  786. m_InterimChar = L'\0';
  787. m_InterimAttr = 0;
  788. }
  789. VOID WriteInterimChar(WCHAR ch, BYTE attr)
  790. {
  791. m_InterimChar = ch;
  792. m_InterimAttr = attr;
  793. }
  794. void ReadInterimChar(WCHAR* ch, BYTE* attr)
  795. {
  796. *ch = m_InterimChar;
  797. *attr = m_InterimAttr;
  798. }
  799. void ReadInterimChar(CWCompString* ch, CWCompAttribute* attr)
  800. {
  801. ch->WriteCompData(&m_InterimChar, 1);
  802. attr->WriteCompData(&m_InterimAttr, 1);
  803. }
  804. public:
  805. WCHAR m_InterimChar;
  806. BYTE m_InterimAttr;
  807. };
  808. /////////////////////////////////////////////////////////////////////////////
  809. // CWCompTfGuidAtom
  810. class CWCompTfGuidAtom : public CompData<TfGuidAtom, TfGuidAtom>
  811. {
  812. public:
  813. };
  814. /////////////////////////////////////////////////////////////////////////////
  815. // friend
  816. inline
  817. DWORD
  818. CalcCharacterPositionAtoW(
  819. DWORD dwCharPosA,
  820. CBCompString* bcompstr
  821. )
  822. /*+++
  823. Calculation Unicode character position to ANSI character position
  824. ---*/
  825. {
  826. DWORD dwCharPosW = 0;
  827. DWORD dwStrIndex = 0;
  828. while (dwCharPosA != 0) {
  829. if (bcompstr->IsDBCSLeadByteEx(dwStrIndex)) {
  830. if (dwCharPosA >= 2) {
  831. dwCharPosA -= 2;
  832. }
  833. else {
  834. dwCharPosA--;
  835. }
  836. dwStrIndex += 2;
  837. }
  838. else {
  839. dwCharPosA--;
  840. dwStrIndex++;
  841. }
  842. dwCharPosW++;
  843. }
  844. return dwCharPosW;
  845. }
  846. inline
  847. DWORD
  848. CalcCharacterPositionWtoA(
  849. DWORD dwCharPosW,
  850. CWCompString* wcompstr
  851. )
  852. /*+++
  853. Calculate ANSI character position to Unicode character position.
  854. ---*/
  855. {
  856. DWORD dwCharPosA = 0;
  857. DWORD dwStrIndex = 0;
  858. while (dwCharPosW != 0) {
  859. if (wcompstr->UnicodeToMultiByteSize(dwStrIndex) == 2) {
  860. dwCharPosA += 2;
  861. }
  862. else {
  863. dwCharPosA++;
  864. }
  865. dwStrIndex++;
  866. dwCharPosW--;
  867. }
  868. return dwCharPosA;
  869. }
  870. #endif // _CTXTCOMP_H_