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.

269 lines
6.7 KiB

  1. // MLLBCons.h : Declaration of the CMLLBCons
  2. #ifndef __MLLBCONS_H_
  3. #define __MLLBCONS_H_
  4. #include "mlatl.h"
  5. class CMultiLanguage;
  6. /////////////////////////////////////////////////////////////////////////////
  7. // CMLLBCons
  8. class ATL_NO_VTABLE CMLLBCons :
  9. public CComTearOffObjectBase<CMultiLanguage>,
  10. public IMLangLineBreakConsole
  11. {
  12. public:
  13. CMLLBCons(void)
  14. {
  15. DllAddRef();
  16. m_pMLStrClass = NULL;
  17. }
  18. ~CMLLBCons(void)
  19. {
  20. if (m_pMLStrClass)
  21. m_pMLStrClass->Release();
  22. DllRelease();
  23. }
  24. DECLARE_NO_REGISTRY()
  25. BEGIN_COM_MAP(CMLLBCons)
  26. COM_INTERFACE_ENTRY(IMLangLineBreakConsole)
  27. END_COM_MAP()
  28. public:
  29. // IMLangLineBreakConsole
  30. STDMETHOD(BreakLineML)(/*[in]*/ IMLangString* pSrcMLStr, /*[in]*/ long lSrcPos, /*[in]*/ long lSrcLen, /*[in]*/ long cMinColumns, /*[in]*/ long cMaxColumns, /*[out]*/ long* plLineLen, /*[out]*/ long* plSkipLen);
  31. STDMETHOD(BreakLineW)(/*[in]*/ LCID locale, /*[in, size_is(cchSrc)]*/ const WCHAR* pszSrc, /*[in]*/ long cchSrc, /*[in]*/ long cMaxColumns, /*[out]*/ long* pcchLine, /*[out]*/ long* pcchSkip);
  32. STDMETHOD(BreakLineA)(/*[in]*/ LCID locale, /*[in]*/ UINT uCodePage, /*[in, size_is(cchSrc)]*/ const CHAR* pszSrc, /*[in]*/ long cchSrc, /*[in]*/ long cMaxColumns, /*[out]*/ long* pcchLine, /*[out]*/ long* pcchSkip);
  33. protected:
  34. template <DWORD INFOTYPE, int CACHESIZE>
  35. class CCharType
  36. {
  37. public:
  38. #ifdef ASTRIMPL
  39. inline CCharType(void);
  40. #else
  41. inline CCharType(LCID locale);
  42. #endif
  43. inline ~CCharType(void);
  44. inline void Flush(void);
  45. #ifdef ASTRIMPL
  46. WORD GetCharType(IMLangString* pMLStr, long lPos, long lLen, HRESULT* phr = NULL);
  47. #else
  48. WORD GetCharType(LPCWSTR psz, int cch);
  49. #endif
  50. protected:
  51. LPWORD m_pwBuf;
  52. #ifdef ASTRIMPL
  53. IMLangStringAStr* m_pMLStrAStr;
  54. long m_lPos;
  55. long m_lLen;
  56. #else
  57. LPSTR m_pszConv;
  58. LPCWSTR m_psz;
  59. int m_cch;
  60. LCID m_locale;
  61. UINT m_uCodePage;
  62. #endif
  63. WORD m_wHalfWidth;
  64. };
  65. HRESULT PrepareMLStrClass(void)
  66. {
  67. if (m_pMLStrClass)
  68. return S_OK;
  69. else
  70. return ::_Module.GetClassObject(CLSID_CMLangString, IID_IClassFactory, (void**)&m_pMLStrClass);
  71. }
  72. IClassFactory* m_pMLStrClass;
  73. };
  74. template <DWORD INFOTYPE, int CACHESIZE>
  75. #ifdef ASTRIMPL
  76. CMLLBCons::CCharType<INFOTYPE, CACHESIZE>::CCharType(void)
  77. #else
  78. CMLLBCons::CCharType<INFOTYPE, CACHESIZE>::CCharType(LCID locale)
  79. #endif
  80. {
  81. #ifndef ASTRIMPL
  82. TCHAR szCodePage[8];
  83. #endif
  84. m_pwBuf = NULL;
  85. #ifdef ASTRIMPL
  86. m_pMLStrAStr = NULL;
  87. // TODO: Set m_wHaldWidth here.
  88. m_wHalfWidth = 0;
  89. #else
  90. m_pszConv = NULL;
  91. m_locale = locale;
  92. ::GetLocaleInfo(m_locale, LOCALE_IDEFAULTANSICODEPAGE, szCodePage, ARRAYSIZE(szCodePage));
  93. m_uCodePage = _ttoi(szCodePage);
  94. CPINFO cpi;
  95. ::GetCPInfo(m_uCodePage, &cpi);
  96. m_wHalfWidth = (cpi.LeadByte[0]) ? 0 : C3_HALFWIDTH;
  97. #endif
  98. }
  99. template <DWORD INFOTYPE, int CACHESIZE>
  100. CMLLBCons::CCharType<INFOTYPE, CACHESIZE>::~CCharType(void)
  101. {
  102. if (m_pwBuf)
  103. delete[] m_pwBuf;
  104. #ifdef ASTRIMPL
  105. if (m_pMLStrAStr)
  106. m_pMLStrAStr->Release();
  107. #else
  108. if (m_pszConv)
  109. delete[] m_pszConv;
  110. #endif
  111. }
  112. template <DWORD INFOTYPE, int CACHESIZE>
  113. void CMLLBCons::CCharType<INFOTYPE, CACHESIZE>::Flush(void)
  114. {
  115. #ifdef ASTRIMPL
  116. m_lPos = 0;
  117. m_lLen = 0;
  118. #else
  119. m_psz = NULL;
  120. m_cch = 0;
  121. #endif
  122. }
  123. template <DWORD INFOTYPE, int CACHESIZE>
  124. #ifdef ASTRIMPL
  125. WORD CMLLBCons::CCharType<INFOTYPE, CACHESIZE>::GetCharType(IMLangString* pMLStr, long lPos, long lLen, HRESULT* phr)
  126. #else
  127. WORD CMLLBCons::CCharType<INFOTYPE, CACHESIZE>::GetCharType(LPCWSTR psz, int cch)
  128. #endif
  129. {
  130. #ifdef ASTRIMPL
  131. if (lPos >= m_lPos + m_lLen || lPos + lLen <= m_lPos)
  132. #else
  133. if (psz < m_psz || psz >= m_psz + m_cch)
  134. #endif
  135. {
  136. #ifdef ASTRIMPL
  137. HRESULT hr;
  138. #endif
  139. LPWORD pwCharType;
  140. #ifdef ASTRIMPL
  141. WORD wCharType;
  142. CHAR* psz;
  143. long cch;
  144. LCID locale;
  145. UINT uCodePage;
  146. if (m_pMLStrAStr)
  147. {
  148. m_pMLStrAStr->Release();
  149. m_pMLStrAStr = NULL;
  150. }
  151. if (SUCCEEDED(hr = pMLStr->QueryInterface(IID_IMLangStringAStr, (void**)&m_pMLStrAStr)))
  152. {
  153. if (!m_pwBuf)
  154. m_pwBuf = new WORD[CACHESIZE];
  155. if (m_pwBuf)
  156. {
  157. pwCharType = m_pwBuf;
  158. cch = CACHESIZE;
  159. }
  160. else
  161. {
  162. pwCharType = &wCharType;
  163. cch = 1;
  164. }
  165. lLen = min(lLen, cch);
  166. if (SUCCEEDED(hr = m_pMLStrAStr->GetLocale(lPos, lLen, &locale, NULL, &lLen)) &&
  167. SUCCEEDED(hr = ::LocaleToCodePage(locale, &uCodePage)) &&
  168. SUCCEEDED(hr = m_pMLStrAStr->LockAStr(lPos, lLen, MLSTR_READ, uCodePage, 0, NULL, &psz, &cch, NULL)))
  169. {
  170. if (!::GetStringTypeExA(locale, INFOTYPE, psz, cch, pwCharType))
  171. hr = E_FAIL; // NLS failed
  172. ASSIGN_IF_FAILED(hr, m_pMLStrAStr->UnlockAStr(psz, 0, NULL, NULL));
  173. }
  174. }
  175. if (phr)
  176. *phr = hr;
  177. if (SUCCEEDED(hr))
  178. {
  179. m_lPos = lPos;
  180. m_lLen = lLen;
  181. return pwCharType[0] | m_wHalfWidth;
  182. }
  183. else
  184. {
  185. m_lPos = 0;
  186. m_lLen = 0;
  187. return 0 | m_wHalfWidth;
  188. }
  189. #else
  190. LPSTR pszConv;
  191. WORD wCharType = 0;
  192. CHAR szTemp[2];
  193. if (!m_pwBuf)
  194. m_pwBuf = new WORD[CACHESIZE];
  195. if (m_pwBuf)
  196. {
  197. pwCharType = m_pwBuf;
  198. cch = min(cch, CACHESIZE);
  199. }
  200. else
  201. {
  202. pwCharType = &wCharType;
  203. cch = 1;
  204. }
  205. if (!m_pszConv)
  206. m_pszConv = new CHAR[CACHESIZE * 2];
  207. if (m_pszConv)
  208. {
  209. pszConv = m_pszConv;
  210. }
  211. else
  212. {
  213. pszConv = szTemp;
  214. cch = 1;
  215. }
  216. if (m_pwBuf && m_pszConv)
  217. {
  218. m_psz = psz;
  219. m_cch = cch;
  220. }
  221. int cchTemp = ::WideCharToMultiByte(m_uCodePage, 0, psz, cch, pszConv, CACHESIZE * 2, NULL, NULL);
  222. ::GetStringTypeExA(m_locale, INFOTYPE, pszConv, cchTemp, pwCharType);
  223. return pwCharType[0] | m_wHalfWidth;
  224. #endif
  225. }
  226. else
  227. {
  228. #ifdef ASTRIMPL
  229. return m_pwBuf[lPos - m_lPos] | m_wHalfWidth;
  230. #else
  231. return m_pwBuf[psz - m_psz] | m_wHalfWidth;
  232. #endif
  233. }
  234. }
  235. #endif //__MLLBCONS_H_