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.

485 lines
12 KiB

  1. /*++
  2. Copyright (c) 1991-1999, Microsoft Corporation All rights reserved.
  3. Module Name:
  4. c_iscii.c
  5. Abstract:
  6. This file contains the main functions for this module.
  7. External Routines in this file:
  8. DllEntry
  9. NlsDllCodePageTranslation
  10. Revision History:
  11. 2-28-98 KChang Created.
  12. --*/
  13. ////////////////////////////////////////////////////////////////////////////
  14. //
  15. // Conversions for Ten ISCII codepages
  16. //
  17. // 57002 : Devanagari
  18. // 57003 : Bengali
  19. // 57004 : Tamil
  20. // 57005 : Telugu
  21. // 57006 : Assamese (same as Bengali)
  22. // 57007 : Oriya
  23. // 57008 : Kannada
  24. // 57009 : Malayalam
  25. // 57010 : Gujarati
  26. // 57011 : Punjabi (Gurmukhi)
  27. //
  28. ////////////////////////////////////////////////////////////////////////////
  29. //
  30. // Include Files.
  31. //
  32. #include <share.h>
  33. #include "c_iscii.h"
  34. //
  35. // Forward Declarations.
  36. //
  37. DWORD MBToWC(
  38. BYTE CP,
  39. LPSTR lpMultiByteStr,
  40. int cchMultiByte,
  41. LPWSTR lpWideCharStr,
  42. int cchWideChar);
  43. DWORD WCToMB(
  44. BYTE CP,
  45. LPWSTR lpWideCharStr,
  46. int cchWideChar,
  47. LPSTR lpMBStr,
  48. int cchMultiByte);
  49. //-------------------------------------------------------------------------//
  50. // DLL ENTRY POINT //
  51. //-------------------------------------------------------------------------//
  52. ////////////////////////////////////////////////////////////////////////////
  53. //
  54. // DllEntry
  55. //
  56. // DLL Entry initialization procedure.
  57. //
  58. // 10-30-96 JulieB Created.
  59. ////////////////////////////////////////////////////////////////////////////
  60. BOOL DllEntry(
  61. HANDLE hModule,
  62. DWORD dwReason,
  63. LPVOID lpRes)
  64. {
  65. switch (dwReason)
  66. {
  67. case ( DLL_THREAD_ATTACH ) :
  68. {
  69. return (TRUE);
  70. }
  71. case ( DLL_THREAD_DETACH ) :
  72. {
  73. return (TRUE);
  74. }
  75. case ( DLL_PROCESS_ATTACH ) :
  76. {
  77. return (TRUE);
  78. }
  79. case ( DLL_PROCESS_DETACH ) :
  80. {
  81. return (TRUE);
  82. }
  83. }
  84. return (FALSE);
  85. hModule;
  86. lpRes;
  87. }
  88. //-------------------------------------------------------------------------//
  89. // EXTERNAL ROUTINES //
  90. //-------------------------------------------------------------------------//
  91. ////////////////////////////////////////////////////////////////////////////
  92. //
  93. // NlsDllCodePageTranslation
  94. //
  95. // This routine is the main exported procedure for the functionality in
  96. // this DLL. All calls to this DLL must go through this function.
  97. //
  98. ////////////////////////////////////////////////////////////////////////////
  99. DWORD NlsDllCodePageTranslation(
  100. DWORD CodePage,
  101. DWORD dwFlags,
  102. LPSTR lpMultiByteStr,
  103. int cchMultiByte,
  104. LPWSTR lpWideCharStr,
  105. int cchWideChar,
  106. LPCPINFO lpCPInfo)
  107. {
  108. BYTE CP;
  109. if ((CodePage < 57002) || (CodePage > 57011))
  110. {
  111. SetLastError(ERROR_INVALID_PARAMETER);
  112. return (0);
  113. }
  114. CP = (BYTE)(CodePage % 100);
  115. switch (dwFlags)
  116. {
  117. case ( NLS_CP_CPINFO ) :
  118. {
  119. memset(lpCPInfo, 0, sizeof(CPINFO));
  120. lpCPInfo->MaxCharSize = 4;
  121. lpCPInfo->DefaultChar[0] = SUB;
  122. //
  123. // The lead-byte does not apply here, leave them all NULL.
  124. //
  125. return (TRUE);
  126. }
  127. case ( NLS_CP_MBTOWC ) :
  128. {
  129. if (cchMultiByte == -1)
  130. {
  131. cchMultiByte = strlen(lpMultiByteStr) + 1;
  132. }
  133. return (MBToWC( CP,
  134. lpMultiByteStr,
  135. cchMultiByte,
  136. lpWideCharStr,
  137. cchWideChar ));
  138. }
  139. case ( NLS_CP_WCTOMB ) :
  140. {
  141. int cchMBCount;
  142. if (cchWideChar == -1)
  143. {
  144. cchWideChar = wcslen(lpWideCharStr) + 1;
  145. }
  146. cchMBCount = WCToMB( CP,
  147. lpWideCharStr,
  148. cchWideChar,
  149. lpMultiByteStr,
  150. cchMultiByte );
  151. return (cchMBCount);
  152. }
  153. }
  154. //
  155. // This shouldn't happen since this function gets called by
  156. // the NLS API routines.
  157. //
  158. SetLastError(ERROR_INVALID_PARAMETER);
  159. return (0);
  160. }
  161. //-------------------------------------------------------------------------//
  162. // INTERNAL ROUTINES //
  163. //-------------------------------------------------------------------------//
  164. ////////////////////////////////////////////////////////////////////////////
  165. //
  166. // MBToWC
  167. //
  168. // This routine does the translations from ISCII to Unicode.
  169. //
  170. ////////////////////////////////////////////////////////////////////////////
  171. DWORD MBToWC(
  172. BYTE CP,
  173. LPSTR lpMultiByteStr,
  174. int cchMultiByte,
  175. LPWSTR lpWideCharStr,
  176. int cchWideChar)
  177. {
  178. BYTE CurCP = CP;
  179. int ctr;
  180. int cchWCCount = 0;
  181. LPWSTR lpWCTempStr;
  182. //
  183. // Allocate a buffer of the appropriate size.
  184. // Use sizeof(WCHAR) because size could potentially double if
  185. // the buffer contains all halfwidth Katakanas
  186. //
  187. lpWCTempStr = (LPWSTR)NLS_ALLOC_MEM(cchMultiByte * sizeof(WCHAR));
  188. if (lpWCTempStr == NULL)
  189. {
  190. SetLastError(ERROR_OUTOFMEMORY);
  191. return (0);
  192. }
  193. for (ctr = 0; ctr < cchMultiByte; ctr++)
  194. {
  195. BYTE mb = (BYTE)lpMultiByteStr[ctr];
  196. if (mb < MB_Beg)
  197. {
  198. lpWCTempStr[cchWCCount++] = (WCHAR)mb;
  199. }
  200. else if (mb == ATR)
  201. {
  202. if (ctr >= (cchMultiByte - 1))
  203. {
  204. //
  205. // Incomplete ATR.
  206. //
  207. lpWCTempStr[cchWCCount++] = SUB;
  208. }
  209. else
  210. {
  211. BYTE mb1 = (BYTE)lpMultiByteStr[ctr + 1];
  212. if ((mb1 < 0x40) || (mb1 > 0x4B))
  213. {
  214. lpWCTempStr[cchWCCount++] = SUB;
  215. }
  216. else
  217. {
  218. //
  219. // Bug #239926 10/29/00 WEIWU
  220. // We don't support Roman script transliteration yet.
  221. // To avoid invoking NULL table, we treat ATR code 0x41 as 0x40.
  222. //
  223. if (mb1 == 0x40 || mb1 == 0x41)
  224. {
  225. CurCP = CP;
  226. }
  227. else
  228. {
  229. CurCP = mb1 & 0x0F;
  230. }
  231. ctr++;
  232. }
  233. }
  234. }
  235. else
  236. {
  237. WCHAR U1 = UniChar(CurCP, mb);
  238. WCHAR U21 = TwoTo1U(CurCP, mb);
  239. if (U21 == 0)
  240. {
  241. lpWCTempStr[cchWCCount++] = U1;
  242. }
  243. else
  244. {
  245. //
  246. // Possible two MBs to one Unicode.
  247. //
  248. if (ctr >= (cchMultiByte - 1))
  249. {
  250. lpWCTempStr[cchWCCount++] = U1;
  251. }
  252. else
  253. {
  254. BYTE mb1 = (BYTE)lpMultiByteStr[ctr + 1];
  255. if (mb == VIRAMA)
  256. {
  257. lpWCTempStr[cchWCCount++] = U1;
  258. if (mb1 == VIRAMA)
  259. {
  260. lpWCTempStr[cchWCCount++] = ZWNJ; // ZWNJ = U+200C
  261. ctr++;
  262. }
  263. else if (mb1 == NUKTA)
  264. {
  265. lpWCTempStr[cchWCCount++] = ZWJ; // U+200D
  266. ctr++;
  267. }
  268. }
  269. else if ((U21 & 0xf000) == 0)
  270. {
  271. if (mb1 == SecondByte[1])
  272. {
  273. //
  274. // NextByte == 0xe9 ?
  275. //
  276. lpWCTempStr[cchWCCount++] = U21;
  277. ctr++;
  278. }
  279. else
  280. {
  281. lpWCTempStr[cchWCCount++] = U1;
  282. }
  283. }
  284. else
  285. {
  286. //
  287. // Devanagari EXT
  288. //
  289. if (mb1 == ExtMBList[0].mb) // 0xf0_0xb8
  290. {
  291. lpWCTempStr[cchWCCount++] = ExtMBList[0].wc; // U+0952
  292. ctr++;
  293. }
  294. else if (mb1 == ExtMBList[1].mb) // 0xf0_0xbf
  295. {
  296. lpWCTempStr[cchWCCount++] = ExtMBList[1].wc; // U+0970
  297. ctr++;
  298. }
  299. else
  300. {
  301. lpWCTempStr[cchWCCount++] = SUB;
  302. }
  303. }
  304. }
  305. }
  306. }
  307. }
  308. if (cchWideChar)
  309. {
  310. if (cchWCCount > cchWideChar)
  311. {
  312. //
  313. // Output buffer is too small.
  314. //
  315. NLS_FREE_MEM(lpWCTempStr);
  316. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  317. return (0);
  318. }
  319. wcsncpy(lpWideCharStr, lpWCTempStr, cchWCCount);
  320. }
  321. NLS_FREE_MEM(lpWCTempStr);
  322. return (cchWCCount);
  323. }
  324. ////////////////////////////////////////////////////////////////////////////
  325. //
  326. // WCToMB
  327. //
  328. // This routine does the translations from Unicode to ISCII.
  329. //
  330. ////////////////////////////////////////////////////////////////////////////
  331. DWORD WCToMB(
  332. BYTE CP,
  333. LPWSTR lpWideCharStr,
  334. int cchWideChar,
  335. LPSTR lpMBStr,
  336. int cchMultiByte)
  337. {
  338. BYTE CurCP = CP;
  339. int ctr;
  340. int cchMBCount = 0;
  341. LPSTR lpMBTmpStr;
  342. lpMBTmpStr = (LPSTR)NLS_ALLOC_MEM(cchWideChar * 4);
  343. if (lpMBTmpStr == NULL)
  344. {
  345. SetLastError(ERROR_OUTOFMEMORY);
  346. return (0);
  347. }
  348. for (ctr = 0; ctr < cchWideChar; ctr++)
  349. {
  350. WCHAR wc = lpWideCharStr[ctr];
  351. if (wc < (WCHAR)MB_Beg)
  352. {
  353. lpMBTmpStr[cchMBCount++] = (BYTE)wc;
  354. }
  355. else if ((wc < WC_Beg) || (wc > WC_End))
  356. {
  357. lpMBTmpStr[cchMBCount++] = SUB;
  358. }
  359. else
  360. {
  361. BYTE mb = MBChar(wc);
  362. if ((Script(wc) != 0) && (Script(wc) != CurCP))
  363. {
  364. lpMBTmpStr[cchMBCount++] = (BYTE)ATR;
  365. CurCP = Script(wc);
  366. lpMBTmpStr[cchMBCount++] = CurCP | 0x40;
  367. }
  368. lpMBTmpStr[cchMBCount++] = mb;
  369. if (mb == VIRAMA)
  370. {
  371. if (ctr < (cchMultiByte - 1))
  372. {
  373. WCHAR wc1 = lpWideCharStr[ctr + 1];
  374. if (wc1 == ZWNJ)
  375. {
  376. lpMBTmpStr[cchMBCount++] = VIRAMA;
  377. ctr++;
  378. }
  379. else if (wc1 == ZWJ)
  380. {
  381. lpMBTmpStr[cchMBCount++] = NUKTA;
  382. ctr++;
  383. }
  384. }
  385. }
  386. else if (OneU_2M(wc) != 0)
  387. {
  388. lpMBTmpStr[cchMBCount++] = SecondByte[OneU_2M(wc) >> 12];
  389. }
  390. }
  391. }
  392. if (cchMultiByte)
  393. {
  394. if (cchMBCount > cchMultiByte)
  395. {
  396. //
  397. // Output buffer is too small.
  398. //
  399. NLS_FREE_MEM(lpMBTmpStr);
  400. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  401. return (0);
  402. }
  403. strncpy(lpMBStr, lpMBTmpStr, cchMBCount);
  404. }
  405. NLS_FREE_MEM(lpMBTmpStr);
  406. return (cchMBCount);
  407. }