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.

312 lines
13 KiB

  1. // File Name: unix2pc.c
  2. // Owner: Tetsuhide Akaishi
  3. // Revision: 1.00 02/21/'93 Tetsuhide Akaishi
  4. //
  5. #include "pch_c.h"
  6. #include "fechrcnv.h"
  7. int FE_UNIX_to_PC (CONV_CONTEXT *pcontext, int CodePage, int CodeSet,
  8. UCHAR *pUNIXChar, int UNIXChar_len,
  9. UCHAR *pPCChar, int PCChar_len )
  10. // The FE_UNIX_to_PC function convert a character string as Japanese UNIX code
  11. // set string to a PC code set string.
  12. //
  13. //
  14. // int CodeSet Code Set Type.
  15. // There are three Japanese Code set in UNIX world.
  16. // These code sets are JIS, EUC and Shift JIS.
  17. // When CodePage is Japanese, the following Code set
  18. // constants are defined:
  19. //
  20. // Value Meaning
  21. // CODE_UNKNOWN Unknown. If this value is CODE_UNKNOWN,
  22. // Code Type is checked automatically.
  23. //
  24. // CODE_JPN_JIS JIS Code Set. The function convert
  25. // pUNIXChar string as JIS code set string
  26. // to a PC code set string.
  27. // CODE_JPN_EUC EUC Code Set. The function convert
  28. // pUNIXChar string as EUC code set string
  29. // to a PC code set string.
  30. // CODE_JPN_SJIS Shift JIS Code Set.
  31. //
  32. // UCHAR *pUNIXChar Points to the character string to be converted.
  33. //
  34. // int UNIXChar_len Specifies the size in bytes of the string pointed
  35. // to by the pUNIXChar parameter. If this value is -1,
  36. // the string is assumed to be NULL terminated and the
  37. // length is calculated automatically.
  38. //
  39. // UCHAR *pPCChar Points to a buffer that receives the convert string
  40. // from UNIX Code to PC Code.
  41. //
  42. // int PCChar_len Specifies the size, in PC characters of the buffer
  43. // pointed to by the pPCChar parameter. If the value is zero,
  44. // the function returns the number of PC characters
  45. // required for the buffer, and makes no use of the pPCChar
  46. // buffer.
  47. //
  48. // Return Value
  49. // If the function succeeds, and PCChar_len is nonzero, the return value is the
  50. // number of PC characters written to the buffer pointed to by pPCChar.
  51. //
  52. // If the function succeeds, and PCChar_len is zero, the return value is the
  53. // required size, in PC characters, for a buffer that can receive the
  54. // converted string.
  55. //
  56. // If the function fails, the return value is -1. The error mean pPCChar buffer
  57. // is small for setting converted strings.
  58. //
  59. {
  60. int re;
  61. #ifdef DBCS_DIVIDE
  62. int i = 0, nDelta = 0;
  63. if ( PCChar_len == 0 && pcontext->dStatus0.nCodeSet != CODE_UNKNOWN)
  64. CodeSet = pcontext->dStatus0.nCodeSet;
  65. else if ( PCChar_len != 0 && pcontext->dStatus.nCodeSet != CODE_UNKNOWN )
  66. CodeSet = pcontext->dStatus.nCodeSet;
  67. else
  68. #endif
  69. if ( pcontext->nCurrentCodeSet == CODE_UNKNOWN ) {
  70. if ( CodeSet == CODE_UNKNOWN ) {
  71. if ( ( CodeSet = DetectJPNCode ( pUNIXChar, UNIXChar_len ) )
  72. == CODE_ONLY_SBCS ) {
  73. CodeSet = CODE_JPN_JIS;
  74. }
  75. }
  76. pcontext->nCurrentCodeSet = CodeSet;
  77. }
  78. else
  79. CodeSet = pcontext->nCurrentCodeSet;
  80. switch ( CodeSet ) {
  81. case CODE_JPN_JIS: // Japanese JIS Code
  82. // Convert from JIS to Shift JIS
  83. re = JIS_to_ShiftJIS (pcontext, pUNIXChar, UNIXChar_len,
  84. pPCChar, PCChar_len );
  85. break;
  86. case CODE_JPN_EUC: // Japanese EUC Code
  87. // Convert from EUC to Shift JIS
  88. re = EUC_to_ShiftJIS (pcontext, pUNIXChar, UNIXChar_len,
  89. pPCChar, PCChar_len );
  90. break;
  91. case CODE_KRN_KSC: // Korean KSC
  92. // Convert from KSC to Hangeul
  93. re = KSC_to_Hangeul (pcontext, pUNIXChar, UNIXChar_len,
  94. pPCChar, PCChar_len );
  95. break;
  96. case CODE_PRC_HZGB: // PRC HZ-GB
  97. // Convert from HZ-GB to GB2312
  98. re = HZGB_to_GB2312 (pcontext, pUNIXChar, UNIXChar_len,
  99. pPCChar, PCChar_len );
  100. break;
  101. default:
  102. case CODE_ONLY_SBCS:
  103. // Start Only Copy Process
  104. if ( UNIXChar_len == -1 ) {
  105. UNIXChar_len = strlen ( pUNIXChar ) + 1;
  106. }
  107. if ( PCChar_len != 0 ) {
  108. if ( UNIXChar_len > PCChar_len ) { // Is the buffer small?
  109. return ( -1 );
  110. }
  111. memmove ( pPCChar, pUNIXChar, UNIXChar_len );
  112. }
  113. re = UNIXChar_len;
  114. break;
  115. case CODE_JPN_SJIS: // Japanese Shift JIS Code
  116. case CODE_KRN_UHC: // Korean UHC
  117. case CODE_PRC_CNGB: // PRC CN-GB
  118. case CODE_TWN_BIG5: // Taiwanese BIG5
  119. // Start Only Copy Process
  120. if ( UNIXChar_len == -1 ) {
  121. UNIXChar_len = strlen ( pUNIXChar ) + 1;
  122. }
  123. if ( PCChar_len != 0 ) {
  124. #ifdef DBCS_DIVIDE
  125. UCHAR *pPCCharEnd = pPCChar + PCChar_len - 1;
  126. if ( pcontext->dStatus.nCodeSet == CODE_JPN_SJIS && pcontext->dStatus.cSavedByte){
  127. *pPCChar++ = pcontext->dStatus.cSavedByte;
  128. *pPCChar = *pUNIXChar;
  129. ++UNIXChar_len;
  130. ++nDelta;
  131. ++i;
  132. pcontext->dStatus.nCodeSet = CODE_UNKNOWN;
  133. pcontext->dStatus.cSavedByte = '\0';
  134. }
  135. while(i < UNIXChar_len - nDelta){
  136. if(IsDBCSLeadByteEx(CodePage, *(pUNIXChar + i))){
  137. if(i == UNIXChar_len - nDelta - 1){
  138. pcontext->dStatus.nCodeSet = CODE_JPN_SJIS;
  139. pcontext->dStatus.cSavedByte = *(pUNIXChar + i);
  140. --UNIXChar_len;
  141. break;
  142. } else if((i == UNIXChar_len - nDelta - 2) &&
  143. (*(pUNIXChar + i + 1) == '\0')){
  144. pcontext->dStatus.nCodeSet = CODE_JPN_SJIS;
  145. pcontext->dStatus.cSavedByte = *(pUNIXChar + i);
  146. *(pPCChar + i) = '\0';
  147. --UNIXChar_len;
  148. break;
  149. }
  150. if(pPCChar + i > pPCCharEnd) // check destination buf
  151. break;
  152. *(pPCChar + i++) = *(pUNIXChar + i);
  153. *(pPCChar + i++) = *(pUNIXChar + i);
  154. } else
  155. *(pPCChar + i++) = *(pUNIXChar + i);
  156. }
  157. #else
  158. if ( UNIXChar_len > PCChar_len ) { // Is the buffer small?
  159. return ( -1 );
  160. }
  161. memmove ( pPCChar, pUNIXChar, UNIXChar_len );
  162. #endif
  163. }
  164. #ifdef DBCS_DIVIDE
  165. else { // Only retrun the required size
  166. if ( pcontext->dStatus0.nCodeSet == CODE_JPN_SJIS ){ // 1st byte was saved
  167. ++UNIXChar_len;
  168. ++nDelta;
  169. ++i;
  170. pcontext->dStatus0.nCodeSet = CODE_UNKNOWN;
  171. pcontext->dStatus0.cSavedByte = '\0';
  172. }
  173. while(i < UNIXChar_len - nDelta){
  174. if(IsDBCSLeadByteEx(CodePage, *(pUNIXChar + i))){
  175. if(i == UNIXChar_len - nDelta - 1){
  176. pcontext->dStatus0.nCodeSet = CODE_JPN_SJIS;
  177. pcontext->dStatus0.cSavedByte = *(pUNIXChar + i);
  178. --UNIXChar_len;
  179. break;
  180. } else if((i == UNIXChar_len - nDelta - 2) &&
  181. (*(pUNIXChar + i + 1) == '\0')){
  182. pcontext->dStatus0.nCodeSet = CODE_JPN_SJIS;
  183. pcontext->dStatus0.cSavedByte = *(pUNIXChar + i);
  184. --UNIXChar_len;
  185. break;
  186. }
  187. i+=2;
  188. } else
  189. i++;
  190. }
  191. }
  192. #endif
  193. re = UNIXChar_len;
  194. break;
  195. }
  196. return ( re );
  197. }
  198. int WINAPI UNIX_to_PC (CONV_CONTEXT *pcontext, int CodePage, int CodeSet,
  199. UCHAR *pUNIXChar, int UNIXChar_len,
  200. UCHAR *pPCChar, int PCChar_len )
  201. // The UNIX_to_PC function convert a character string as UNIX code
  202. // set string to a PC code set string.
  203. //
  204. // int CodePage Country Code Page.
  205. // If this value is -1, the function use OS CodePage from
  206. // Operating System automatically.
  207. //
  208. // Value Meaning
  209. // -1 Auto Detect Mode.
  210. // 932 Japan.
  211. // ??? Taiwan.
  212. // ??? Korea.
  213. // ??? PRC(Chaina)?
  214. //
  215. // int CodeSet Code Set Type.
  216. // There are three Japanese Code set in UNIX world.
  217. // These code sets are JIS, EUC and Shift JIS.
  218. // When CodePage is Japanese, the following Code set
  219. // constants are defined:
  220. //
  221. // Value Meaning
  222. // CODE_UNKNOWN Unknown. If this value is CODE_UNKNOWN,
  223. // Code Type is checked automatically.
  224. //
  225. // CODE_JPN_JIS JIS Code Set. The function convert
  226. // pUNIXChar string as JIS code set string
  227. // to a PC code set string.
  228. // CODE_JPN_EUC EUC Code Set. The function convert
  229. // pUNIXChar string as EUC code set string
  230. // to a PC code set string.
  231. // CODE_JPN_SJIS Shift JIS Code Set.
  232. //
  233. // UCHAR *pUNIXChar Points to the character string to be converted.
  234. //
  235. // int UNIXChar_len Specifies the size in bytes of the string pointed
  236. // to by the pUNIXChar parameter. If this value is -1,
  237. // the string is assumed to be NULL terminated and the
  238. // length is calculated automatically.
  239. //
  240. // UCHAR *pPCChar Points to a buffer that receives the convert string
  241. // from UNIX Code to PC Code.
  242. //
  243. // int PCChar_len Specifies the size, in PC characters of the buffer
  244. // pointed to by the pPCChar parameter. If the value is zero,
  245. // the function returns the number of PC characters
  246. // required for the buffer, and makes no use of the pPCChar
  247. // buffer.
  248. //
  249. // Return Value
  250. // If the function succeeds, and PCChar_len is nonzero, the return value is the
  251. // number of PC characters written to the buffer pointed to by pPCChar.
  252. //
  253. // If the function succeeds, and PCChar_len is zero, the return value is the
  254. // required size, in PC characters, for a buffer that can receive the
  255. // converted string.
  256. //
  257. // If the function fails, the return value is -1. The error mean pPCChar buffer
  258. // is small for setting converted strings.
  259. //
  260. //@
  261. {
  262. int re;
  263. // we have to run on the given context to be multi-thread safe.
  264. if(!pcontext) return 0;
  265. if ( CodePage == -1 ) {
  266. CodePage = (int)GetOEMCP();
  267. }
  268. switch ( CodePage ) {
  269. case 932: // Japanese Code Page
  270. case 950: // Taiwan Code Page
  271. case 949: // Korea Code Page
  272. case 936: // PRC Code Page
  273. re = FE_UNIX_to_PC (pcontext, CodePage, CodeSet, pUNIXChar, UNIXChar_len,
  274. pPCChar, PCChar_len );
  275. break;
  276. default:
  277. // Start Only Copy Process
  278. if ( UNIXChar_len == -1 ) {
  279. UNIXChar_len = strlen ( pUNIXChar ) + 1;
  280. }
  281. if ( PCChar_len != 0 ) {
  282. if ( UNIXChar_len > PCChar_len ) { // Is the buffer small?
  283. return ( -1 );
  284. }
  285. memmove ( pPCChar, pUNIXChar, UNIXChar_len );
  286. }
  287. re = UNIXChar_len;
  288. break;
  289. }
  290. return ( re );
  291. }