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.

1365 lines
38 KiB

  1. /*++
  2. Copyright (c) 1985 - 1999, Microsoft Corporation
  3. Module Name:
  4. imccomp.h
  5. Abstract:
  6. This file defines the Context of Composition Class.
  7. Author:
  8. Revision History:
  9. Notes:
  10. This implementation is almost identical to ..\inc\ctxtcmp.h.
  11. --*/
  12. #ifndef IMCCOMP_H
  13. #define IMCCOMP_H
  14. #include "template.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. DIMM_IMCLock lpIMC(hIMC);
  37. if (lpIMC.Invalid())
  38. return;
  39. if (lpsz)
  40. WriteCompData(lpsz, dwLen);
  41. }
  42. CompData(DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr)
  43. {
  44. }
  45. CompData(DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr, DWORD dwIndex);
  46. DWORD WriteCompData(IN const ARG_TYPE& data, IN DWORD dwLen)
  47. {
  48. m_array.SetSize(dwLen);
  49. ARG_TYPE* psz = m_array.GetData();
  50. if (!psz)
  51. return 0;
  52. DWORD index = dwLen;
  53. while (index--) {
  54. *psz++ = data;
  55. }
  56. return dwLen;
  57. }
  58. DWORD WriteCompData(IN ARG_TYPE* lpSrc, IN DWORD dwLen)
  59. {
  60. m_array.SetSize(dwLen);
  61. ARG_TYPE* psz = m_array.GetData();
  62. if (!psz)
  63. return 0;
  64. memcpy(psz, lpSrc, dwLen * sizeof(TYPE));
  65. return dwLen;
  66. }
  67. DWORD AddCompData(IN ARG_TYPE* lpSrc, IN DWORD dwLen)
  68. {
  69. DWORD dwl = (DWORD)m_array.GetSize();
  70. ARG_TYPE *psTemp;
  71. m_array.SetSize(dwLen+dwl);
  72. psTemp = m_array.GetData();
  73. if (!psTemp)
  74. return 0;
  75. memcpy(psTemp+dwl, lpSrc, dwLen*sizeof(TYPE));
  76. return dwLen;
  77. }
  78. DWORD AddCompData(IN const ARG_TYPE& data, IN DWORD dwLen)
  79. {
  80. DWORD dwl = (DWORD)m_array.GetSize();
  81. ARG_TYPE *psTemp;
  82. m_array.SetSize(dwLen+dwl);
  83. psTemp = m_array.GetData();
  84. if (!psTemp)
  85. return 0;
  86. psTemp += dwl;
  87. DWORD index = dwLen;
  88. while (index--) {
  89. *psTemp++ = data;
  90. }
  91. return dwLen;
  92. }
  93. const INT_PTR ReadCompData(IN ARG_TYPE* lpDest = NULL, DWORD dwLen = 0) {
  94. INT_PTR dwBufLen;
  95. if (! dwLen) {
  96. // query required buffer size. not inculde \0.
  97. dwBufLen = m_array.GetSize();
  98. }
  99. else {
  100. ARG_TYPE* psz = m_array.GetData();
  101. if ((INT_PTR)dwLen > m_array.GetSize()) {
  102. dwBufLen = m_array.GetSize();
  103. }
  104. else {
  105. dwBufLen = (INT_PTR)dwLen;
  106. }
  107. memcpy(lpDest, psz, dwBufLen * sizeof(TYPE));
  108. }
  109. return dwBufLen;
  110. }
  111. DWORD GetCompStrIndex(IN DWORD dwIndex) {
  112. switch(dwIndex) {
  113. case GCS_COMPATTR: return GCS_COMPSTR;
  114. case GCS_COMPREADATTR: return GCS_COMPREADSTR;
  115. case GCS_COMPCLAUSE: return GCS_COMPSTR;
  116. case GCS_COMPREADCLAUSE: return GCS_COMPREADSTR;
  117. case GCS_RESULTCLAUSE: return GCS_RESULTSTR;
  118. case GCS_RESULTREADCLAUSE: return GCS_RESULTREADSTR;
  119. case GCS_CURSORPOS: return GCS_COMPSTR;
  120. case GCS_DELTASTART: return GCS_COMPSTR;
  121. default: break;
  122. }
  123. ASSERT(FALSE);
  124. return 0;
  125. }
  126. TYPE GetAt(INT_PTR nIndex) const
  127. {
  128. return m_array.GetAt(nIndex);
  129. }
  130. void SetAtGrow(INT_PTR nIndex, ARG_TYPE newElement)
  131. {
  132. m_array.SetAtGrow(nIndex, newElement);
  133. }
  134. INT_PTR Add(ARG_TYPE newElement)
  135. {
  136. return m_array.Add(newElement);
  137. }
  138. INT_PTR GetSize() const
  139. {
  140. return m_array.GetSize();
  141. }
  142. void RemoveAll()
  143. {
  144. m_array.RemoveAll();
  145. }
  146. operator void* ()
  147. {
  148. return m_array.GetData();
  149. }
  150. TYPE operator[](INT_PTR nIndex)
  151. {
  152. return m_array.GetAt(nIndex);
  153. }
  154. protected:
  155. CArray<TYPE, ARG_TYPE> m_array;
  156. };
  157. template<class TYPE, class ARG_TYPE>
  158. CompData<TYPE, ARG_TYPE>::CompData(
  159. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  160. DWORD dwIndex
  161. )
  162. {
  163. switch (dwIndex) {
  164. case GCS_COMPSTR:
  165. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwCompStrOffset),
  166. lpCompStr->CompStr.dwCompStrLen); // # of chars
  167. break;
  168. case GCS_COMPREADSTR:
  169. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwCompReadStrOffset),
  170. lpCompStr->CompStr.dwCompReadStrLen); // # of chars
  171. break;
  172. case GCS_RESULTSTR:
  173. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwResultStrOffset),
  174. lpCompStr->CompStr.dwResultStrLen); // # of chars
  175. break;
  176. case GCS_RESULTREADSTR:
  177. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwResultReadStrOffset),
  178. lpCompStr->CompStr.dwResultReadStrLen); // # of chars
  179. break;
  180. case GCS_COMPATTR: // ANSI-only
  181. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwCompAttrOffset),
  182. lpCompStr->CompStr.dwCompAttrLen);
  183. break;
  184. case GCS_COMPREADATTR: // ANSI-only
  185. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwCompReadAttrOffset),
  186. lpCompStr->CompStr.dwCompReadAttrLen);
  187. break;
  188. case GCS_COMPREADCLAUSE:
  189. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwCompReadClauseOffset),
  190. lpCompStr->CompStr.dwCompReadClauseLen / sizeof(TYPE)); // # of bytes
  191. break;
  192. case GCS_RESULTCLAUSE:
  193. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwResultClauseOffset),
  194. lpCompStr->CompStr.dwResultClauseLen / sizeof(TYPE)); // # of bytes
  195. break;
  196. case GCS_RESULTREADCLAUSE:
  197. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwResultReadClauseOffset),
  198. lpCompStr->CompStr.dwResultReadClauseLen / sizeof(TYPE)); // # of bytes
  199. break;
  200. case GCS_COMPCLAUSE:
  201. WriteCompData((TYPE*)lpCompStr.GetOffsetPointer(lpCompStr->CompStr.dwCompClauseOffset),
  202. lpCompStr->CompStr.dwCompClauseLen / sizeof(TYPE)); // # of bytes
  203. break;
  204. case GCS_CURSORPOS:
  205. SetAtGrow(0, (TYPE)lpCompStr->CompStr.dwCursorPos);
  206. break;
  207. case GCS_DELTASTART:
  208. SetAtGrow(0, (TYPE)lpCompStr->CompStr.dwDeltaStart);
  209. break;
  210. default:
  211. break;
  212. }
  213. }
  214. class CWCompString;
  215. /////////////////////////////////////////////////////////////////////////////
  216. // CBCompString
  217. class CBCompString : public CompData<CHAR, CHAR>
  218. {
  219. public:
  220. CBCompString(
  221. UINT cp=CP_ACP,
  222. HIMC hIMC=NULL,
  223. LPSTR lpsz=NULL,
  224. DWORD dwLen=0) : CompData<CHAR, CHAR>(hIMC, lpsz, dwLen),
  225. m_cp(cp)
  226. {
  227. };
  228. CBCompString(
  229. UINT cp,
  230. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<CHAR, CHAR>(lpCompStr),
  231. m_cp(cp)
  232. {
  233. };
  234. CBCompString(
  235. UINT cp,
  236. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  237. DWORD dwIndex) : CompData<CHAR, CHAR>(lpCompStr, dwIndex),
  238. m_cp(cp)
  239. {
  240. };
  241. const CBCompString& operator=(CWCompString& wcompstr);
  242. const DWORD ConvertUnicodeString(IN OUT LPWSTR lpsz = NULL, DWORD cch = 0)
  243. {
  244. return _mbstowcs(lpsz, cch);
  245. }
  246. CHAR GetAt(IN DWORD dwIndex)
  247. {
  248. return CompData<CHAR, CHAR>::GetAt(dwIndex);
  249. }
  250. BOOL IsDBCSLeadByteEx(IN DWORD dwIndex)
  251. {
  252. CHAR c = GetAt(dwIndex);
  253. return ::IsDBCSLeadByteEx(m_cp, c);
  254. }
  255. private:
  256. UINT m_cp; // code page value.
  257. int _mbstowcs(wchar_t* wcstr, size_t cch);
  258. };
  259. inline
  260. int
  261. CBCompString::_mbstowcs(
  262. wchar_t* wcstr,
  263. size_t cch
  264. )
  265. {
  266. if (cch == 0 && wcstr != NULL)
  267. return 0;
  268. const char* mbstr = m_array.GetData();
  269. if (!mbstr)
  270. return 0;
  271. INT_PTR nSize = m_array.GetSize();
  272. int result = ::MultiByteToWideChar(m_cp, // code page
  273. 0, // character-type option
  274. mbstr, // address of string to map
  275. (int)nSize, // number of bytes in string
  276. wcstr, // address of wide-char buffer
  277. (int)cch); // size of buffer, in wide character
  278. return result;
  279. }
  280. /////////////////////////////////////////////////////////////////////////////
  281. // CWCompString
  282. class CWCompString : public CompData<WCHAR, WCHAR>
  283. {
  284. public:
  285. CWCompString(
  286. UINT cp=CP_ACP,
  287. HIMC hIMC=NULL,
  288. LPWSTR lpsz=NULL,
  289. DWORD dwLen=0) : CompData<WCHAR, WCHAR>(hIMC, lpsz, dwLen),
  290. m_cp(cp)
  291. {
  292. };
  293. CWCompString(
  294. UINT cp,
  295. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<WCHAR, WCHAR>(lpCompStr),
  296. m_cp(cp)
  297. {
  298. };
  299. CWCompString(
  300. UINT cp,
  301. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  302. DWORD dwIndex) : CompData<WCHAR, WCHAR>(lpCompStr, dwIndex),
  303. m_cp(cp)
  304. {
  305. };
  306. const CWCompString& operator=(CBCompString& bcompstr);
  307. const DWORD ConvertANSIString(IN OUT LPSTR lpsz = NULL, DWORD dwLen = 0)
  308. {
  309. return _wcstombs(lpsz, dwLen);
  310. }
  311. WCHAR GetAt(IN DWORD dwIndex)
  312. {
  313. return (WCHAR)CompData<WCHAR, WCHAR>::GetAt(dwIndex);
  314. }
  315. int UnicodeToMultiByteSize(IN DWORD dwIndex)
  316. {
  317. WCHAR wc = GetAt(dwIndex);
  318. return ::WideCharToMultiByte(m_cp, // code page
  319. 0, // performance and mapping flags
  320. (const wchar_t*)&wc, // address of wide-char string
  321. 1, // number of char string
  322. NULL, // address of buffer for new string
  323. 0, // size of buffer
  324. NULL, // default for unmappable char
  325. NULL); // flag set when default char
  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. m_array.SetSize(len);
  370. LPSTR psz = m_array.GetData();
  371. if (psz)
  372. len = wcompstr.ConvertANSIString(psz, len * sizeof(CHAR));
  373. return *this;
  374. }
  375. inline
  376. const CWCompString&
  377. CWCompString::operator=(
  378. CBCompString& bcompstr
  379. )
  380. /*+++
  381. *
  382. * Get Unicode string from ANSI composition string.
  383. *
  384. ---*/
  385. {
  386. m_array.RemoveAll();
  387. DWORD len = bcompstr.ConvertUnicodeString();
  388. m_array.SetSize(len);
  389. LPWSTR psz = m_array.GetData();
  390. if (psz)
  391. len = bcompstr.ConvertUnicodeString(psz, len);
  392. return *this;
  393. }
  394. /////////////////////////////////////////////////////////////////////////////
  395. // CheckAttribute template
  396. template<class APPS_ATTR, class HIMC_ATTR, class HIMC_CLAUSE>
  397. HRESULT
  398. CheckAttribute(
  399. APPS_ATTR& apps_attr, // the attr from apps
  400. HIMC_ATTR& himc_attr, // the attr from IMC
  401. HIMC_CLAUSE& himc_clause // the clause from IMC
  402. )
  403. {
  404. if (himc_clause.ReadCompData() == 0) {
  405. TraceMsg(TF_WARNING, "CheckAttribute: no Clause. Pass it to IME.");
  406. }
  407. else {
  408. if (himc_attr.ReadCompData() != 0) {
  409. if (apps_attr.GetSize() != himc_attr.GetSize()) {
  410. TraceMsg(TF_ERROR, "CheckAttribute: wrong length.");
  411. return E_FAIL;
  412. }
  413. /*
  414. * The attr. of chars of one clause have to be same.
  415. */
  416. DWORD dwAttrIndex = 0;
  417. DWORD dwClauseIndex;
  418. for (dwClauseIndex = 0;
  419. (INT_PTR)himc_clause.GetAt(dwClauseIndex) < apps_attr.ReadCompData();
  420. dwClauseIndex++
  421. ) {
  422. DWORD dwBound = himc_clause.GetAt(dwClauseIndex+1) - himc_clause.GetAt(dwClauseIndex);
  423. DWORD battr = apps_attr.GetAt(dwAttrIndex++);
  424. DWORD dwCnt;
  425. for (dwCnt = 1; dwCnt < dwBound; dwCnt++) {
  426. if (battr != apps_attr.GetAt(dwAttrIndex++)) {
  427. TraceMsg(TF_ERROR, "CheckAttribute: mismatch clause attribute.");
  428. return E_FAIL;
  429. }
  430. }
  431. }
  432. }
  433. }
  434. return S_OK;
  435. }
  436. class CWCompAttribute;
  437. /////////////////////////////////////////////////////////////////////////////
  438. // CBCompAttribute
  439. class CBCompAttribute : public CompData<BYTE, BYTE>
  440. {
  441. public:
  442. CBCompAttribute(
  443. UINT cp=CP_ACP,
  444. HIMC hIMC=NULL,
  445. BYTE* lpsz=NULL,
  446. DWORD dwLen=0) : CompData<BYTE, BYTE>(hIMC, lpsz, dwLen),
  447. m_bcompstr(cp, hIMC)
  448. {
  449. };
  450. CBCompAttribute(
  451. UINT cp,
  452. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<BYTE, BYTE>(lpCompStr),
  453. m_bcompstr(cp, lpCompStr)
  454. {
  455. };
  456. CBCompAttribute(
  457. UINT cp,
  458. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  459. DWORD dwIndex) : CompData<BYTE, BYTE>(lpCompStr, dwIndex),
  460. m_bcompstr(cp, lpCompStr, GetCompStrIndex(dwIndex))
  461. {
  462. };
  463. const CBCompAttribute& operator=(CWCompAttribute& wcompattr);
  464. INT_PTR Add(IN BYTE newElement)
  465. {
  466. return CompData<BYTE, BYTE>::Add(newElement);
  467. }
  468. CBCompString m_bcompstr;
  469. };
  470. /////////////////////////////////////////////////////////////////////////////
  471. // CWCompAttribute
  472. class CWCompAttribute : public CompData<BYTE, BYTE>
  473. {
  474. public:
  475. CWCompAttribute(
  476. UINT cp=CP_ACP,
  477. HIMC hIMC=NULL,
  478. BYTE* lpsz=NULL,
  479. DWORD dwLen=0) : CompData<BYTE, BYTE>(hIMC, lpsz, dwLen),
  480. m_wcompstr(cp, hIMC)
  481. {
  482. };
  483. CWCompAttribute(
  484. UINT cp,
  485. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<BYTE, BYTE>(lpCompStr),
  486. m_wcompstr(cp, lpCompStr)
  487. {
  488. };
  489. CWCompAttribute(
  490. UINT cp,
  491. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  492. DWORD dwIndex) : CompData<BYTE, BYTE>(lpCompStr, dwIndex),
  493. m_wcompstr(cp, lpCompStr, GetCompStrIndex(dwIndex))
  494. {
  495. };
  496. const CWCompAttribute& operator=(CBCompAttribute& bcompattr);
  497. INT_PTR Add(IN BYTE newElement)
  498. {
  499. return CompData<BYTE, BYTE>::Add(newElement);
  500. }
  501. CWCompString m_wcompstr;
  502. };
  503. /////////////////////////////////////////////////////////////////////////////
  504. // CBCompAttribute/CWCompAttribute::operator=
  505. inline
  506. const CBCompAttribute&
  507. CBCompAttribute::operator=(
  508. CWCompAttribute& wcompattr
  509. )
  510. /*+++
  511. *
  512. * Get ANSI attribute from Unicode composition attribute.
  513. *
  514. ---*/
  515. {
  516. m_bcompstr = wcompattr.m_wcompstr;
  517. INT_PTR dwAttrIndexW = 0;
  518. INT_PTR dwStrIndex = 0;
  519. while ( dwStrIndex < m_bcompstr.ReadCompData() &&
  520. dwAttrIndexW < wcompattr.ReadCompData() &&
  521. m_bcompstr.GetAt((DWORD)dwStrIndex) != '\0'
  522. ) {
  523. if (m_bcompstr.IsDBCSLeadByteEx((DWORD)dwStrIndex)) {
  524. Add( wcompattr.GetAt(dwAttrIndexW) );
  525. Add( wcompattr.GetAt(dwAttrIndexW) );
  526. dwStrIndex += 2;
  527. }
  528. else {
  529. Add( wcompattr.GetAt(dwAttrIndexW) );
  530. dwStrIndex++;
  531. }
  532. dwAttrIndexW++;
  533. }
  534. return *this;
  535. }
  536. inline
  537. const CWCompAttribute&
  538. CWCompAttribute::operator=(
  539. CBCompAttribute& bcompattr
  540. )
  541. /*+++
  542. *
  543. * Get Unicode attribute from ANSI composition attribute.
  544. *
  545. ---*/
  546. {
  547. m_wcompstr = bcompattr.m_bcompstr;
  548. INT_PTR dwAttrIndexA = 0;
  549. INT_PTR dwStrIndex = 0;
  550. while ( dwStrIndex < m_wcompstr.ReadCompData() &&
  551. dwAttrIndexA < bcompattr.ReadCompData() &&
  552. m_wcompstr.GetAt((DWORD)dwStrIndex) != '\0'
  553. ) {
  554. if (m_wcompstr.UnicodeToMultiByteSize((DWORD)dwStrIndex) == 2) {
  555. Add( bcompattr.GetAt(dwAttrIndexA) );
  556. dwAttrIndexA += 2;
  557. }
  558. else {
  559. Add( bcompattr.GetAt(dwAttrIndexA) );
  560. dwAttrIndexA++;
  561. }
  562. dwStrIndex++;
  563. }
  564. return *this;
  565. }
  566. /////////////////////////////////////////////////////////////////////////////
  567. // CheckClause template
  568. template<class APPS_CLAUSE, class HIMC_CLAUSE>
  569. HRESULT
  570. CheckClause(
  571. APPS_CLAUSE& apps_clause, // the clause from apps
  572. HIMC_CLAUSE& himc_clause // the clause from IMC
  573. )
  574. {
  575. if (apps_clause.ReadCompData() == 0 ||
  576. himc_clause.ReadCompData() == 0 ) {
  577. TraceMsg(TF_ERROR, "CheckClause: no Clause.");
  578. return E_FAIL;
  579. }
  580. if (apps_clause.GetAt(0) ||
  581. himc_clause.GetAt(0) ) {
  582. TraceMsg(TF_ERROR, "CheckClause: clause[0] have to be ZERO.");
  583. return E_FAIL;
  584. }
  585. INT_PTR dwClauseIndex;
  586. for (dwClauseIndex = 0;
  587. dwClauseIndex < himc_clause.ReadCompData();
  588. dwClauseIndex++
  589. ) {
  590. if (apps_clause.GetAt((DWORD)dwClauseIndex) != himc_clause.GetAt((DWORD)dwClauseIndex)) {
  591. return E_FAIL;
  592. }
  593. }
  594. return S_OK;
  595. }
  596. class CWCompClause;
  597. /////////////////////////////////////////////////////////////////////////////
  598. // CBCompClause
  599. class CBCompClause : public CompData<DWORD, DWORD>
  600. {
  601. public:
  602. CBCompClause(
  603. UINT cp=CP_ACP,
  604. HIMC hIMC=NULL,
  605. DWORD* lpsz=NULL,
  606. DWORD dwLen=0) : CompData<DWORD, DWORD>(hIMC,lpsz,dwLen),
  607. m_bcompstr(cp, hIMC)
  608. {
  609. };
  610. CBCompClause(
  611. UINT cp,
  612. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<DWORD, DWORD>(lpCompStr),
  613. m_bcompstr(cp, lpCompStr)
  614. {
  615. };
  616. CBCompClause(
  617. UINT cp,
  618. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  619. DWORD dwIndex) : CompData<DWORD, DWORD>(lpCompStr, dwIndex),
  620. m_bcompstr(cp, lpCompStr, GetCompStrIndex(dwIndex))
  621. {
  622. };
  623. DWORD GetAt(IN DWORD dwIndex)
  624. {
  625. return (DWORD)CompData<DWORD, DWORD>::GetAt(dwIndex);
  626. }
  627. const CBCompClause& operator=(CWCompClause& wcompclause);
  628. INT_PTR Add(IN DWORD newElement)
  629. {
  630. return CompData<DWORD, DWORD>::Add(newElement);
  631. }
  632. friend DWORD CalcCharacterPositionAtoW(DWORD dwCharPosA, CBCompString* bcompstr);
  633. CBCompString m_bcompstr;
  634. };
  635. /////////////////////////////////////////////////////////////////////////////
  636. // CWCompClause
  637. class CWCompClause : public CompData<DWORD, DWORD>
  638. {
  639. public:
  640. CWCompClause(
  641. UINT cp=CP_ACP,
  642. HIMC hIMC=NULL,
  643. DWORD* lpsz=NULL,
  644. DWORD dwLen=0) : CompData<DWORD, DWORD>(hIMC,lpsz,dwLen),
  645. m_wcompstr(cp, hIMC)
  646. {
  647. };
  648. CWCompClause(
  649. UINT cp,
  650. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<DWORD, DWORD>(lpCompStr),
  651. m_wcompstr(cp, lpCompStr)
  652. {
  653. };
  654. CWCompClause(
  655. UINT cp,
  656. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  657. DWORD dwIndex) : CompData<DWORD, DWORD>(lpCompStr, dwIndex),
  658. m_wcompstr(cp, lpCompStr, GetCompStrIndex(dwIndex))
  659. {
  660. };
  661. DWORD GetAt(IN DWORD dwIndex)
  662. {
  663. return (DWORD)CompData<DWORD, DWORD>::GetAt(dwIndex);
  664. }
  665. const CWCompClause& operator=(CBCompClause& bcompclause);
  666. INT_PTR Add(IN DWORD newElement)
  667. {
  668. return CompData<DWORD, DWORD>::Add(newElement);
  669. }
  670. friend DWORD CalcCharacterPositionWtoA(DWORD dwCharPosW, CWCompString* wcompstr);
  671. CWCompString m_wcompstr;
  672. };
  673. /////////////////////////////////////////////////////////////////////////////
  674. // CBCompClause/CWCompClause::operator=
  675. inline
  676. const CBCompClause&
  677. CBCompClause::operator=(
  678. CWCompClause& wcompclause
  679. )
  680. /*+++
  681. *
  682. * Get ANSI clause from Unicode composition clause.
  683. *
  684. ---*/
  685. {
  686. m_bcompstr = wcompclause.m_wcompstr;
  687. INT_PTR dwClauseIndex;
  688. for (dwClauseIndex = 0;
  689. dwClauseIndex < wcompclause.ReadCompData();
  690. dwClauseIndex++
  691. ) {
  692. Add( CalcCharacterPositionWtoA( wcompclause.GetAt((DWORD)dwClauseIndex), &wcompclause.m_wcompstr ) );
  693. }
  694. return *this;
  695. }
  696. inline
  697. const CWCompClause&
  698. CWCompClause::operator=(
  699. CBCompClause& bcompclause
  700. )
  701. /*+++
  702. *
  703. * Get Unicode clause from ANSI composition clause.
  704. *
  705. ---*/
  706. {
  707. m_wcompstr = bcompclause.m_bcompstr;
  708. INT_PTR dwClauseIndex;
  709. for (dwClauseIndex = 0;
  710. dwClauseIndex < bcompclause.ReadCompData();
  711. dwClauseIndex++
  712. ) {
  713. Add( CalcCharacterPositionAtoW( bcompclause.GetAt((DWORD)dwClauseIndex), &bcompclause.m_bcompstr ) );
  714. }
  715. return *this;
  716. }
  717. class CWCompCursorPos;
  718. /////////////////////////////////////////////////////////////////////////////
  719. // CBCompCursorPos
  720. class CBCompCursorPos : public CompData<DWORD, DWORD>
  721. {
  722. public:
  723. CBCompCursorPos(
  724. UINT cp=CP_ACP,
  725. HIMC hIMC=NULL) : CompData<DWORD, DWORD>(hIMC),
  726. m_bcompstr(cp, hIMC)
  727. {
  728. };
  729. CBCompCursorPos(
  730. UINT cp,
  731. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<DWORD, DWORD>(lpCompStr),
  732. m_bcompstr(cp, lpCompStr)
  733. {
  734. };
  735. CBCompCursorPos(
  736. UINT cp,
  737. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  738. DWORD dwIndex) : CompData<DWORD, DWORD>(lpCompStr, dwIndex),
  739. m_bcompstr(cp, lpCompStr, GetCompStrIndex(dwIndex))
  740. {
  741. };
  742. void Set(IN DWORD newElement)
  743. {
  744. CompData<DWORD, DWORD>::SetAtGrow(0, newElement);
  745. }
  746. const CBCompCursorPos& operator=(CWCompCursorPos& wcompcursor);
  747. friend DWORD CalcCharacterPositionAtoW(DWORD dwCharPosA, CBCompString* bcompstr);
  748. CBCompString m_bcompstr;
  749. };
  750. /////////////////////////////////////////////////////////////////////////////
  751. // CWCompCursorPos
  752. class CWCompCursorPos : public CompData<DWORD, DWORD>
  753. {
  754. public:
  755. CWCompCursorPos(
  756. UINT cp=CP_ACP,
  757. HIMC hIMC=NULL) : CompData<DWORD, DWORD>(hIMC),
  758. m_wcompstr(cp, hIMC)
  759. {
  760. };
  761. CWCompCursorPos(
  762. UINT cp,
  763. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr) : CompData<DWORD, DWORD>(lpCompStr),
  764. m_wcompstr(cp, lpCompStr)
  765. {
  766. };
  767. CWCompCursorPos(
  768. UINT cp,
  769. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  770. DWORD dwIndex) : CompData<DWORD, DWORD>(lpCompStr, dwIndex),
  771. m_wcompstr(cp, lpCompStr, GetCompStrIndex(dwIndex))
  772. {
  773. };
  774. void Set(IN DWORD newElement)
  775. {
  776. CompData<DWORD, DWORD>::SetAtGrow(0, newElement);
  777. }
  778. const CWCompCursorPos& operator=(CBCompCursorPos& bcompcursorpos);
  779. friend DWORD CalcCharacterPositionWtoA(DWORD dwCharPosW, CWCompString* wcompstr);
  780. CWCompString m_wcompstr;
  781. };
  782. /////////////////////////////////////////////////////////////////////////////
  783. // CBCompCursorPos/CWCompCursorPos::operator=
  784. inline
  785. const CBCompCursorPos&
  786. CBCompCursorPos::operator=(
  787. CWCompCursorPos& wcompcursor
  788. )
  789. /*+++
  790. *
  791. * Get ANSI cursor/delta start position from Unicode composition string.
  792. *
  793. ---*/
  794. {
  795. if (wcompcursor.m_wcompstr.GetSize() > 0)
  796. {
  797. m_bcompstr = wcompcursor.m_wcompstr;
  798. m_array.SetAtGrow( 0, CalcCharacterPositionWtoA(wcompcursor.GetAt(0), &wcompcursor.m_wcompstr) );
  799. }
  800. return *this;
  801. }
  802. inline
  803. const CWCompCursorPos&
  804. CWCompCursorPos::operator=(
  805. CBCompCursorPos& bcompcursor
  806. )
  807. /*+++
  808. *
  809. * Get Unicode cursor/delta start position from ANSI composition string.
  810. *
  811. ---*/
  812. {
  813. if (bcompcursor.m_bcompstr.GetSize() > 0)
  814. {
  815. m_wcompstr = bcompcursor.m_bcompstr;
  816. m_array.SetAtGrow( 0, CalcCharacterPositionAtoW(bcompcursor.GetAt(0), &bcompcursor.m_bcompstr) );
  817. }
  818. return *this;
  819. }
  820. class CWReconvertString;
  821. /////////////////////////////////////////////////////////////////////////////
  822. // CBReconvetString
  823. class CBReconvertString
  824. {
  825. public:
  826. CBReconvertString(
  827. UINT cp,
  828. HIMC hIMC,
  829. LPRECONVERTSTRING lpReconv=NULL,
  830. DWORD dwLen=0) : m_bcompstr(cp, hIMC)
  831. {
  832. m_dwVersion = 0;
  833. m_CompStrIndex = 0;
  834. m_CompStrLen = 0;
  835. m_TargetStrIndex = 0;
  836. m_TargetStrLen = 0;
  837. if (lpReconv) {
  838. m_dwVersion = lpReconv->dwVersion;
  839. if (dwLen && lpReconv->dwStrOffset) {
  840. m_bcompstr.WriteCompData((CHAR*)((LPBYTE)lpReconv + lpReconv->dwStrOffset),
  841. lpReconv->dwStrLen); // # of chars
  842. m_CompStrIndex = lpReconv->dwCompStrOffset;
  843. m_CompStrLen = lpReconv->dwCompStrLen;
  844. m_TargetStrIndex = lpReconv->dwTargetStrOffset;
  845. m_TargetStrLen = lpReconv->dwTargetStrLen;
  846. }
  847. }
  848. }
  849. DWORD WriteCompData(IN LPSTR lpSrc, IN DWORD dwLen)
  850. {
  851. m_CompStrLen = dwLen;
  852. m_TargetStrLen = dwLen;
  853. return m_bcompstr.WriteCompData(lpSrc, dwLen);
  854. }
  855. const DWORD ReadCompData(IN LPRECONVERTSTRING lpReconv = NULL, DWORD dwLen = 0) {
  856. INT_PTR dwBufLen;
  857. if (! dwLen) {
  858. // query required buffer size. not inculde \0.
  859. dwBufLen = m_bcompstr.ReadCompData() * sizeof(CHAR) + sizeof(RECONVERTSTRING);
  860. }
  861. else {
  862. lpReconv->dwSize = dwLen;
  863. lpReconv->dwVersion = m_dwVersion;
  864. lpReconv->dwStrLen = (DWORD)(m_bcompstr.ReadCompData() * sizeof(CHAR));
  865. lpReconv->dwStrOffset = (DWORD)sizeof(RECONVERTSTRING);
  866. lpReconv->dwCompStrLen = (DWORD)m_CompStrLen;
  867. lpReconv->dwCompStrOffset = (DWORD)(m_CompStrIndex * sizeof(CHAR));
  868. lpReconv->dwTargetStrLen = (DWORD)m_TargetStrLen;
  869. lpReconv->dwTargetStrOffset = (DWORD)(m_TargetStrIndex * sizeof(CHAR));
  870. dwBufLen = m_bcompstr.ReadCompData((CHAR*)((LPBYTE)lpReconv + lpReconv->dwStrOffset),
  871. lpReconv->dwStrLen); // # of chars
  872. }
  873. return (DWORD)dwBufLen;
  874. }
  875. const CBReconvertString& operator=(CWReconvertString& wReconvStr);
  876. void SetData(CWReconvertString& wReconvStr);
  877. friend DWORD CalcCharacterPositionAtoW(DWORD dwCharPosA, CBCompString* bcompstr);
  878. public:
  879. CBCompString m_bcompstr;
  880. DWORD m_dwVersion; // Version number. Must be zero.
  881. INT_PTR m_CompStrIndex; // Index in the CBCompString::<string array> that will be the composition string.
  882. INT_PTR m_CompStrLen; // Character count length of the string that will be the composition string.
  883. INT_PTR m_TargetStrIndex; // Index in the CBCompString::<string array> that is related to the target clause in the composition string.
  884. INT_PTR m_TargetStrLen; // Character count length of the string that is related to the target clause.
  885. };
  886. /////////////////////////////////////////////////////////////////////////////
  887. // CWReconvertString
  888. class CWReconvertString
  889. {
  890. public:
  891. CWReconvertString(
  892. UINT cp,
  893. HIMC hIMC,
  894. LPRECONVERTSTRING lpReconv=NULL,
  895. DWORD dwLen=0) : m_wcompstr(cp, hIMC)
  896. {
  897. m_dwVersion = 0;
  898. m_CompStrIndex = 0;
  899. m_CompStrLen = 0;
  900. m_TargetStrIndex = 0;
  901. m_TargetStrLen = 0;
  902. if (lpReconv) {
  903. m_dwVersion = lpReconv->dwVersion;
  904. if (dwLen && lpReconv->dwStrOffset) {
  905. m_wcompstr.WriteCompData((WCHAR*)((LPBYTE)lpReconv + lpReconv->dwStrOffset),
  906. lpReconv->dwStrLen); // # of chars
  907. m_CompStrIndex = lpReconv->dwCompStrOffset / sizeof(WCHAR); // char count
  908. m_CompStrLen = lpReconv->dwCompStrLen;
  909. m_TargetStrIndex = lpReconv->dwTargetStrOffset / sizeof(WCHAR); // char count
  910. m_TargetStrLen = lpReconv->dwTargetStrLen;
  911. }
  912. }
  913. }
  914. DWORD WriteCompData(IN LPWSTR lpSrc, IN DWORD dwLen)
  915. {
  916. m_CompStrLen = dwLen;
  917. m_TargetStrLen = dwLen;
  918. return m_wcompstr.WriteCompData(lpSrc, dwLen);
  919. }
  920. const DWORD ReadCompData(IN LPRECONVERTSTRING lpReconv = NULL, DWORD dwLen = 0) {
  921. INT_PTR dwBufLen;
  922. if (! dwLen) {
  923. // query required buffer size. not inculde \0.
  924. dwBufLen = m_wcompstr.ReadCompData() * sizeof(WCHAR) + sizeof(RECONVERTSTRING);
  925. }
  926. else {
  927. lpReconv->dwSize = dwLen;
  928. lpReconv->dwVersion = m_dwVersion;
  929. lpReconv->dwStrLen = (DWORD)m_wcompstr.ReadCompData();
  930. lpReconv->dwStrOffset = (DWORD)sizeof(RECONVERTSTRING);
  931. lpReconv->dwCompStrLen = (DWORD)m_CompStrLen;
  932. lpReconv->dwCompStrOffset = (DWORD)(m_CompStrIndex * sizeof(WCHAR)); // byte count
  933. lpReconv->dwTargetStrLen = (DWORD)m_TargetStrLen;
  934. lpReconv->dwTargetStrOffset = (DWORD)(m_TargetStrIndex * sizeof(WCHAR)); // byte count
  935. dwBufLen = m_wcompstr.ReadCompData((WCHAR*)((LPBYTE)lpReconv + lpReconv->dwStrOffset),
  936. lpReconv->dwStrLen); // # of chars
  937. }
  938. return (DWORD)dwBufLen;
  939. }
  940. const CWReconvertString& operator=(CBReconvertString& bReconvStr);
  941. void SetData(CBReconvertString& bReconvStr);
  942. friend DWORD CalcCharacterPositionWtoA(DWORD dwCharPosW, CWCompString* wcompstr);
  943. public:
  944. CWCompString m_wcompstr;
  945. DWORD m_dwVersion; // Version number. Must be zero.
  946. INT_PTR m_CompStrIndex; // Index in the CWCompString::<string array> that will be the composition string.
  947. INT_PTR m_CompStrLen; // Character count length of the string that will be the composition string.
  948. INT_PTR m_TargetStrIndex; // Index in the CWCompString::<string array> that is related to the target clause in the composition string.
  949. INT_PTR m_TargetStrLen; // Character count length of the string that is related to the target clause.
  950. };
  951. /////////////////////////////////////////////////////////////////////////////
  952. // CBCompReconvertString/CWCompReconvertString::operator=
  953. inline
  954. const CBReconvertString&
  955. CBReconvertString::operator=(
  956. CWReconvertString& wReconvStr
  957. )
  958. {
  959. m_bcompstr = wReconvStr.m_wcompstr;
  960. SetData(wReconvStr);
  961. return *this;
  962. }
  963. inline
  964. const CWReconvertString&
  965. CWReconvertString::operator=(
  966. CBReconvertString& bReconvStr
  967. )
  968. {
  969. m_wcompstr = bReconvStr.m_bcompstr;
  970. SetData(bReconvStr);
  971. return *this;
  972. }
  973. /////////////////////////////////////////////////////////////////////////////
  974. // CBReconvertString/CWReconvertString::SetData
  975. inline
  976. void
  977. CBReconvertString::SetData(
  978. CWReconvertString& wReconvStr
  979. )
  980. {
  981. m_dwVersion = wReconvStr.m_dwVersion;
  982. m_CompStrIndex = CalcCharacterPositionWtoA((DWORD)(wReconvStr.m_CompStrIndex), &wReconvStr.m_wcompstr);
  983. m_CompStrLen = CalcCharacterPositionWtoA((DWORD)(wReconvStr.m_CompStrIndex + wReconvStr.m_CompStrLen), &wReconvStr.m_wcompstr) - m_CompStrIndex;
  984. m_TargetStrIndex = CalcCharacterPositionWtoA((DWORD)(wReconvStr.m_TargetStrIndex), &wReconvStr.m_wcompstr);
  985. m_TargetStrLen = CalcCharacterPositionWtoA((DWORD)(wReconvStr.m_TargetStrIndex + wReconvStr.m_TargetStrLen), &wReconvStr.m_wcompstr) - m_TargetStrIndex;
  986. }
  987. inline
  988. void
  989. CWReconvertString::SetData(
  990. CBReconvertString& bReconvStr
  991. )
  992. {
  993. m_dwVersion = bReconvStr.m_dwVersion;
  994. m_CompStrIndex = CalcCharacterPositionAtoW((DWORD)(bReconvStr.m_CompStrIndex), &bReconvStr.m_bcompstr);
  995. m_CompStrLen = (CalcCharacterPositionAtoW((DWORD)(bReconvStr.m_CompStrIndex + bReconvStr.m_CompStrLen), &bReconvStr.m_bcompstr) - m_CompStrIndex);
  996. m_TargetStrIndex = CalcCharacterPositionAtoW((DWORD)(bReconvStr.m_TargetStrIndex), &bReconvStr.m_bcompstr);
  997. m_TargetStrLen = (CalcCharacterPositionAtoW((DWORD)(bReconvStr.m_TargetStrIndex + bReconvStr.m_TargetStrLen), &bReconvStr.m_bcompstr) - m_TargetStrIndex);
  998. }
  999. /////////////////////////////////////////////////////////////////////////////
  1000. // CWInterimString
  1001. class CWInterimString
  1002. {
  1003. public:
  1004. CWInterimString(
  1005. UINT cp,
  1006. HIMC hIMC
  1007. ) : m_wresultstr(cp, hIMC)
  1008. {
  1009. m_InterimChar = L'\0';
  1010. m_InterimAttr = 0;
  1011. }
  1012. DWORD WriteResultStr(IN LPWSTR lpSrc, IN DWORD dwLen)
  1013. {
  1014. return m_wresultstr.WriteCompData(lpSrc, dwLen);
  1015. }
  1016. const DWORD ReadResultStr(IN LPWSTR lpSrc = NULL, DWORD dwLen = 0)
  1017. {
  1018. return (DWORD)m_wresultstr.ReadCompData(lpSrc, dwLen);
  1019. }
  1020. VOID WriteInterimChar(WCHAR ch, BYTE attr)
  1021. {
  1022. m_InterimChar = ch;
  1023. m_InterimAttr = attr;
  1024. }
  1025. void ReadInterimChar(WCHAR* ch, BYTE* attr)
  1026. {
  1027. *ch = m_InterimChar;
  1028. *attr = m_InterimAttr;
  1029. }
  1030. public:
  1031. CWCompString m_wresultstr;
  1032. WCHAR m_InterimChar;
  1033. BYTE m_InterimAttr;
  1034. };
  1035. /////////////////////////////////////////////////////////////////////////////
  1036. // CWCompTfGuidAtom
  1037. class CWCompTfGuidAtom : public CompData<TfGuidAtom, TfGuidAtom>
  1038. {
  1039. public:
  1040. };
  1041. /////////////////////////////////////////////////////////////////////////////
  1042. // friend
  1043. inline
  1044. DWORD
  1045. CalcCharacterPositionAtoW(
  1046. DWORD dwCharPosA,
  1047. CBCompString* bcompstr
  1048. )
  1049. /*+++
  1050. Calculation Unicode character position to ANSI character position
  1051. ---*/
  1052. {
  1053. DWORD dwCharPosW = 0;
  1054. DWORD dwStrIndex = 0;
  1055. while (dwCharPosA != 0) {
  1056. if (bcompstr->IsDBCSLeadByteEx(dwStrIndex)) {
  1057. if (dwCharPosA >= 2) {
  1058. dwCharPosA -= 2;
  1059. }
  1060. else {
  1061. dwCharPosA--;
  1062. }
  1063. dwStrIndex += 2;
  1064. }
  1065. else {
  1066. dwCharPosA--;
  1067. dwStrIndex++;
  1068. }
  1069. dwCharPosW++;
  1070. }
  1071. return dwCharPosW;
  1072. }
  1073. inline
  1074. DWORD
  1075. CalcCharacterPositionWtoA(
  1076. DWORD dwCharPosW,
  1077. CWCompString* wcompstr
  1078. )
  1079. /*+++
  1080. Calculate ANSI character position to Unicode character position.
  1081. ---*/
  1082. {
  1083. DWORD dwCharPosA = 0;
  1084. DWORD dwStrIndex = 0;
  1085. while (dwCharPosW != 0) {
  1086. if (wcompstr->UnicodeToMultiByteSize(dwStrIndex) == 2) {
  1087. dwCharPosA += 2;
  1088. }
  1089. else {
  1090. dwCharPosA++;
  1091. }
  1092. dwStrIndex++;
  1093. dwCharPosW--;
  1094. }
  1095. return dwCharPosA;
  1096. }
  1097. #endif // IMCCOMP_H