home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libi18n / fe_ccc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  39.3 KB  |  1,135 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /*    fe_ccc.c    */
  19. /* Test harness code to be replaced by FE specific code    */
  20.  
  21. #ifdef XP_OS2
  22. #define INCL_DOS
  23. #endif
  24. #include "intlpriv.h"
  25.  
  26. #include <stdio.h>
  27. #include "xp.h"
  28. #include "intl_csi.h"
  29.  
  30. #ifdef XP_MAC
  31. #include "resgui.h"
  32. #endif
  33.  
  34. /* for XP_GetString() */
  35. #include "xpgetstr.h"
  36. extern int MK_OUT_OF_MEMORY;
  37.  
  38.  
  39. /*
  40. IMPORTANT NOTE:
  41.  
  42.     mz_euc2euc
  43.     mz_b52b5
  44.     mz_cns2cns
  45.     mz_ksc2ksc
  46.     mz_sjis2sjis
  47.     mz_utf82utf8
  48.     
  49.     is now replaced by mz_mbNullConv 
  50.     we eventually should replacing mz_hz2gb after we extract the hz -> gb conversion
  51. */
  52. PRIVATE unsigned char *
  53. mz_hz2gb(CCCDataObject obj, const unsigned char *kscbuf, int32 kscbufsz);
  54. PRIVATE unsigned char *
  55. mz_gb2gb(CCCDataObject obj, const unsigned char *kscbuf, int32 kscbufsz);
  56.  
  57. PRIVATE unsigned char *
  58. mz_mbNullConv(CCCDataObject obj, const unsigned char *buf, int32 bufsz);
  59.  
  60. PRIVATE unsigned char *
  61. mz_AnyToAnyThroughUCS2(CCCDataObject obj, const unsigned char *buf, int32 bufsz);
  62.  
  63. /*    intl_CharLenFunc is designed to used with mz_mbNullConv */
  64. typedef int16 (*intl_CharLenFunc) (    unsigned char ch);
  65. PRIVATE int16 intl_CharLen_SJIS(        unsigned char ch);
  66. PRIVATE int16 intl_CharLen_EUC_JP(    unsigned char ch);
  67. PRIVATE int16 intl_CharLen_CGK(        unsigned char ch);
  68. PRIVATE int16 intl_CharLen_CNS_8BIT(    unsigned char ch);
  69. PRIVATE int16 intl_CharLen_UTF8(        unsigned char ch);
  70. PRIVATE int16 intl_CharLen_SingleByte(unsigned char ch);
  71.  
  72. #define INTL_CHARLEN_SJIS         0
  73. #define INTL_CHARLEN_EUC_JP     1
  74. #define INTL_CHARLEN_CGK         2
  75. #define INTL_CHARLEN_CNS_8BIT     3
  76. #define INTL_CHARLEN_UTF8         4
  77. #define INTL_CHARLEN_SINGLEBYTE 5
  78.  
  79. PRIVATE intl_CharLenFunc intl_char_len_func[]=
  80. {
  81.     intl_CharLen_SJIS,
  82.     intl_CharLen_EUC_JP,
  83.     intl_CharLen_CGK,
  84.     intl_CharLen_CNS_8BIT,
  85.     intl_CharLen_UTF8,
  86.      intl_CharLen_SingleByte,
  87. };
  88.  
  89. int haveBig5 = 0;
  90. PRIVATE int16 *availableFontCharSets = NULL;
  91.  
  92.  
  93. /* Table that maps the FROM char, codeset to all other relevant info:
  94.  *    - TO character codeset
  95.  *    - Fonts (fixe & proportional) for TO character codeset
  96.  *    - Type of conversion (func for Win/Mac, value for X)
  97.  *    - Argument for conversion routine.  Routine-defined.
  98.  *
  99.  * Not all of these may be available.  Depends upon available fonts,
  100.  * scripts, codepages, etc.  Need to query system to build valid table.
  101.  *
  102.  * What info do I need to make the font change API on the 3 platforms?
  103.  *  Is just a 32bit font ID sufficient?
  104.  *
  105.  * Some X Windows can render Japanese in either EUC or SJIS, how do we
  106.  * choose?
  107.  */
  108. /* The ***first*** match of a "FROM" encoding (1st col.) will be
  109.  * used as the URL->native encoding.  Be careful of the
  110.  * ordering.
  111.  * Additional entries for the same "FROM" encoding, specifies
  112.  * how to convert going out (e.g., sending mail, news or forms).
  113.  */
  114.  
  115. /*
  116.     What is the flag mean ?
  117.  
  118.     For Mac the flag in One2OneCCC is the resouce number of a 256 byte mapping table
  119.     For all platform the flag in  mz_mbNullConv is a pointer to a intl_CharLenFunc routine
  120.  
  121. */
  122. #ifdef XP_MAC
  123. MODULE_PRIVATE cscvt_t        cscvt_tbl[] = {
  124.         /*    SINGLE BYTE */
  125.         /*    LATIN1 */
  126.         {CS_LATIN1,        CS_MAC_ROMAN,    0, (CCCFunc)One2OneCCC,    xlat_LATIN1_TO_MAC_ROMAN},
  127.         {CS_ASCII,        CS_MAC_ROMAN,    0, (CCCFunc)One2OneCCC,    xlat_LATIN1_TO_MAC_ROMAN},
  128.         {CS_MAC_ROMAN,    CS_MAC_ROMAN,    0, (CCCFunc)0,            0},
  129.         {CS_MAC_ROMAN,    CS_LATIN1,        0, (CCCFunc)One2OneCCC,    xlat_MAC_ROMAN_TO_LATIN1},
  130.         {CS_MAC_ROMAN,    CS_ASCII,        0, (CCCFunc)One2OneCCC,    xlat_MAC_ROMAN_TO_LATIN1},
  131.  
  132.         /*    LATIN2 */
  133.         {CS_LATIN2,        CS_MAC_CE,        0, (CCCFunc)One2OneCCC, xlat_LATIN2_TO_MAC_CE},
  134.         {CS_MAC_CE,        CS_MAC_CE,        0, (CCCFunc)0,            0},
  135.         {CS_MAC_CE,        CS_LATIN2,        0, (CCCFunc)One2OneCCC, xlat_MAC_CE_TO_LATIN2},
  136.         {CS_MAC_CE,        CS_ASCII,        0, (CCCFunc)One2OneCCC, xlat_MAC_CE_TO_LATIN2},
  137.  
  138.         {CS_CP_1250,    CS_MAC_CE,        0, (CCCFunc)One2OneCCC, xlat_CP_1250_TO_MAC_CE},
  139.         {CS_MAC_CE,        CS_CP_1250,        0, (CCCFunc)One2OneCCC, xlat_MAC_CE_TO_CP_1250},
  140.  
  141.         /*    CYRILLIC */
  142.         {CS_8859_5,        CS_MAC_CYRILLIC,0, (CCCFunc)One2OneCCC, xlat_8859_5_TO_MAC_CYRILLIC},
  143.         {CS_MAC_CYRILLIC,CS_MAC_CYRILLIC,        0, (CCCFunc)0,            0},
  144.         {CS_MAC_CYRILLIC,CS_8859_5,        0, (CCCFunc)One2OneCCC, xlat_MAC_CYRILLIC_TO_8859_5},
  145.         {CS_MAC_CYRILLIC,CS_ASCII,        0, (CCCFunc)One2OneCCC, xlat_MAC_CYRILLIC_TO_8859_5},
  146.  
  147.         {CS_CP_1251,    CS_MAC_CYRILLIC,0, (CCCFunc)One2OneCCC, xlat_CP_1251_TO_MAC_CYRILLIC},
  148.         {CS_MAC_CYRILLIC,CS_CP_1251,    0, (CCCFunc)One2OneCCC, xlat_MAC_CYRILLIC_TO_CP_1251},
  149.  
  150.         {CS_KOI8_R,        CS_MAC_CYRILLIC,0, (CCCFunc)One2OneCCC, xlat_KOI8_R_TO_MAC_CYRILLIC},
  151.         {CS_MAC_CYRILLIC,CS_KOI8_R,        0, (CCCFunc)One2OneCCC, xlat_MAC_CYRILLIC_TO_KOI8_R},
  152.  
  153.         /*    GREEK */
  154.         {CS_8859_7,        CS_MAC_GREEK,    0, (CCCFunc)One2OneCCC, xlat_8859_7_TO_MAC_GREEK},
  155.         {CS_MAC_GREEK,    CS_MAC_GREEK,    0, (CCCFunc)0,            0},
  156.         {CS_MAC_GREEK,    CS_8859_7,        0, (CCCFunc)One2OneCCC, xlat_MAC_GREEK_TO_8859_7},
  157.         {CS_MAC_GREEK,    CS_ASCII,        0, (CCCFunc)One2OneCCC, xlat_MAC_GREEK_TO_8859_7},
  158.         
  159.         {CS_CP_1253,    CS_MAC_GREEK,    0, (CCCFunc)One2OneCCC, xlat_CP_1253_TO_MAC_GREEK},
  160.         {CS_MAC_GREEK,    CS_CP_1253,        0, (CCCFunc)One2OneCCC, xlat_MAC_GREEK_TO_CP_1253},
  161.  
  162.         /*    TURKISH */
  163.         {CS_8859_9,        CS_MAC_TURKISH,    0, (CCCFunc)One2OneCCC, xlat_8859_9_TO_MAC_TURKISH},
  164.         {CS_MAC_TURKISH,CS_MAC_TURKISH,    0, (CCCFunc)0,            0},
  165.         {CS_MAC_TURKISH,CS_8859_9,        0, (CCCFunc)One2OneCCC, xlat_MAC_TURKISH_TO_8859_9},
  166.         {CS_MAC_TURKISH,CS_ASCII,        0, (CCCFunc)One2OneCCC, xlat_MAC_TURKISH_TO_8859_9},
  167.  
  168.         /*  MULTIBYTE */
  169.         /*    JAPANESE */
  170.         {CS_SJIS,        CS_SJIS,        1, (CCCFunc)mz_mbNullConv,    INTL_CHARLEN_SJIS },
  171.         {CS_SJIS,        CS_JIS,            1, (CCCFunc)mz_sjis2jis,    0},
  172.         {CS_JIS,        CS_SJIS,        1, (CCCFunc)jis2other,        0},
  173.         {CS_EUCJP,        CS_SJIS,        1, (CCCFunc)mz_euc2sjis,    0},
  174.         {CS_JIS,        CS_EUCJP,        1, (CCCFunc)jis2other,        1},
  175.         {CS_EUCJP,        CS_JIS,            1, (CCCFunc)mz_euc2jis,        0},
  176.         {CS_SJIS,        CS_EUCJP,        1, (CCCFunc)mz_sjis2euc,    0},
  177.         /* auto-detect Japanese conversions                        */
  178.         {CS_SJIS_AUTO,    CS_SJIS,        1, (CCCFunc)autoJCCC,        0},
  179.         {CS_JIS_AUTO,    CS_SJIS,        1, (CCCFunc)autoJCCC,        0},
  180.         {CS_EUCJP_AUTO,    CS_SJIS,        1, (CCCFunc)autoJCCC,        0},
  181.  
  182.         /*    KOREAN */
  183.         {CS_KSC_8BIT,    CS_KSC_8BIT,    0, (CCCFunc)mz_mbNullConv,    INTL_CHARLEN_CGK },
  184.         {CS_2022_KR,    CS_KSC_8BIT,    0, (CCCFunc)mz_iso2euckr,    0},
  185.         {CS_KSC_8BIT,    CS_2022_KR,        0, (CCCFunc)mz_euckr2iso,    0},
  186.         /* auto-detect Korean conversions                        */
  187.         {CS_KSC_8BIT_AUTO,  CS_KSC_8BIT,1, (CCCFunc)autoKCCC,        0},
  188.          {(CS_2022_KR|CS_AUTO) ,  CS_KSC_8BIT,1, (CCCFunc)autoKCCC,        0},
  189.  
  190.         /*  SIMPLIFIED CHINESE */
  191.         {CS_GB_8BIT,    CS_GB_8BIT,        0, (CCCFunc)mz_gb2gb,        0},
  192.  
  193.         /*  TRADITIONAL CHINESE */
  194.         {CS_BIG5,        CS_BIG5,        0, (CCCFunc)mz_mbNullConv,    INTL_CHARLEN_CGK },
  195. #ifdef FEATURE_BIG5CNS
  196.         {CS_BIG5,        CS_CNS_8BIT,    0, (CCCFunc)mz_b52cns,        0},
  197.         {CS_CNS_8BIT,    CS_BIG5,        0, (CCCFunc)mz_cns2b5,        0},
  198. #endif
  199.  
  200.         /*  UNICODE */
  201.         {CS_UTF8,        CS_UTF8,        0, (CCCFunc)mz_mbNullConv,    INTL_CHARLEN_UTF8 },
  202.  
  203.         {CS_UTF8,        CS_UCS2,        0, (CCCFunc)mz_utf82ucs,    0},
  204.         {CS_UTF8,        CS_UTF7,        0, (CCCFunc)mz_utf82utf7,    0},
  205.         {CS_UTF8,        CS_UCS2_SWAP,    0, (CCCFunc)mz_utf82ucsswap,    0},
  206.         {CS_UTF8,        CS_IMAP4_UTF7,        0, (CCCFunc)mz_utf82imap4utf7,    0},
  207.         {CS_UCS2,        CS_UTF8,        0, (CCCFunc)mz_ucs2utf8,    0},
  208.         {CS_UCS2,        CS_UTF7,        0, (CCCFunc)mz_ucs2utf7,    0},
  209.         {CS_UCS2_SWAP,    CS_UTF8,        0, (CCCFunc)mz_ucs2utf8,    0},
  210.         {CS_UCS2_SWAP,    CS_UTF7,        0, (CCCFunc)mz_ucs2utf7,    0},
  211.         {CS_UTF7,        CS_UTF8,        0, (CCCFunc)mz_utf72utf8,    0},
  212.         {CS_IMAP4_UTF7,        CS_UTF8,        0, (CCCFunc)mz_imap4utf72utf8,    0},
  213.  
  214.          {CS_MAC_ROMAN,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  215.          {CS_MAC_CE,            CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  216.          {CS_MAC_CYRILLIC,    CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  217.           {CS_KOI8_R,            CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  218.           {CS_MAC_GREEK,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  219.           {CS_MAC_TURKISH,    CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  220.         {CS_SJIS,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SJIS},
  221.          {CS_KSC_8BIT,    CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_CGK},
  222.          {CS_BIG5,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_CGK},
  223.          {CS_GB_8BIT,    CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_CGK},
  224.  
  225.           {CS_UTF8,        CS_MAC_ROMAN,    0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  226.          {CS_UTF8,        CS_MAC_CE,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  227.          {CS_UTF8,        CS_MAC_CYRILLIC,0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  228.           {CS_UTF8,        CS_KOI8_R,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  229.           {CS_UTF8,        CS_MAC_GREEK,    0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  230.           {CS_UTF8,        CS_MAC_TURKISH,    0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  231.         {CS_UTF8,        CS_SJIS,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  232.          {CS_UTF8,        CS_KSC_8BIT,    0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  233.          {CS_UTF8,        CS_BIG5,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  234.          {CS_UTF8,        CS_GB_8BIT,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  235.  
  236.  
  237.         {CS_USER_DEFINED_ENCODING,    CS_USER_DEFINED_ENCODING,    0, (CCCFunc)0,            0},    
  238.         {0,                    0,                1, (CCCFunc)0,            0}
  239. };
  240.  
  241. #endif    /* XP_MAC */
  242.  
  243. #if defined(XP_WIN) || defined(XP_OS2)
  244. MODULE_PRIVATE cscvt_t        cscvt_tbl[] = {
  245.         /*    SINGLE BYTE */
  246.         /*    LATIN1 */
  247.         {CS_LATIN1,        CS_LATIN1,        0,    (CCCFunc)0,                0},
  248.         {CS_LATIN1,        CS_ASCII,        0,     (CCCFunc)0,                0},
  249.         {CS_ASCII,        CS_LATIN1,        0,     (CCCFunc)0,                0},
  250.         {CS_ASCII,        CS_ASCII,        0,     (CCCFunc)0,                0},
  251.     
  252.         /* LATIN2 */
  253.         {CS_CP_1250,    CS_CP_1250,        0,    (CCCFunc)0,                0},
  254.         {CS_CP_1250,    CS_LATIN2,        0,    (CCCFunc)One2OneCCC,    0},
  255.         {CS_LATIN2,        CS_CP_1250,        0,    (CCCFunc)One2OneCCC,    0},
  256.         {CS_LATIN2,        CS_LATIN2,        0,    (CCCFunc)0,                0},
  257.         {CS_LATIN2,        CS_ASCII,        0,    (CCCFunc)0,                0},
  258.  
  259.         /* CYRILLIC */
  260.         {CS_CP_1251,    CS_CP_1251,        0, (CCCFunc)0,                0},
  261.         {CS_8859_5,        CS_CP_1251,        0, (CCCFunc)One2OneCCC,        0},
  262.         {CS_CP_1251,    CS_8859_5,        0, (CCCFunc)One2OneCCC,        0},
  263.         {CS_CP_1251,    CS_CP_1251,        0, (CCCFunc)0,                0},
  264.  
  265.         {CS_KOI8_R,        CS_CP_1251,        0, (CCCFunc)One2OneCCC,        0},
  266.         {CS_CP_1251,    CS_KOI8_R,        0, (CCCFunc)One2OneCCC,        0},
  267.  
  268.         /* GREEK */
  269.         {CS_CP_1253,    CS_CP_1253,        0,    (CCCFunc)0,                0},
  270.         {CS_CP_1253,    CS_8859_7,        0,    (CCCFunc)One2OneCCC,    0},
  271.         {CS_8859_7,        CS_CP_1253,        0,    (CCCFunc)One2OneCCC,    0},
  272.         {CS_8859_7,        CS_8859_7,        0,    (CCCFunc)0,                0},
  273.  
  274.         /* TURKISH */
  275. #ifdef XP_OS2
  276.                 {CS_CP_1254,    CS_CP_1254,             0, (CCCFunc)0,                          0},
  277.                 {CS_CP_1254,    CS_8859_9,              0, (CCCFunc)One2OneCCC,         0},
  278.                 {CS_8859_9,             CS_CP_1254,             0, (CCCFunc)One2OneCCC,         0},
  279. #endif
  280.         {CS_8859_9,        CS_8859_9,        0, (CCCFunc)0,                0},
  281.  
  282.         /*  MULTIBYTE */
  283.         /*    JAPANESE */
  284.         {CS_SJIS,        CS_SJIS,        1, (CCCFunc)mz_mbNullConv,    INTL_CHARLEN_SJIS},
  285.         {CS_SJIS,        CS_JIS,            1, (CCCFunc)mz_sjis2jis,    0},
  286.         {CS_JIS,        CS_SJIS,        1, (CCCFunc)jis2other,        0},
  287.         {CS_EUCJP,        CS_SJIS,        1, (CCCFunc)mz_euc2sjis,    0},
  288.         {CS_JIS,        CS_EUCJP,        1, (CCCFunc)jis2other,        1},
  289.         {CS_EUCJP,        CS_JIS,            1, (CCCFunc)mz_euc2jis,        0},
  290.         {CS_SJIS,        CS_EUCJP,        1, (CCCFunc)mz_sjis2euc,    0},
  291.         /* auto-detect Japanese conversions                        */
  292.         {CS_SJIS_AUTO,    CS_SJIS,        1, (CCCFunc)autoJCCC,        0},
  293.         {CS_JIS_AUTO,    CS_SJIS,        1, (CCCFunc)autoJCCC,        0},
  294.         {CS_EUCJP_AUTO,    CS_SJIS,        1, (CCCFunc)autoJCCC,        0},
  295.  
  296.         /*    KOREAN */
  297.         {CS_KSC_8BIT,    CS_KSC_8BIT,    0, (CCCFunc)mz_mbNullConv,    INTL_CHARLEN_CGK},
  298.         {CS_2022_KR,    CS_KSC_8BIT,    0, (CCCFunc)mz_iso2euckr,    0},
  299.         {CS_KSC_8BIT,    CS_2022_KR,        0, (CCCFunc)mz_euckr2iso,    0},
  300.         /* auto-detect Korean conversions                        */
  301.         {CS_KSC_8BIT_AUTO,  CS_KSC_8BIT,1, (CCCFunc)autoKCCC,        0},
  302.          {(CS_2022_KR|CS_AUTO) ,  CS_KSC_8BIT,1, (CCCFunc)autoKCCC,        0},
  303.  
  304.         /*  SIMPLIFIED CHINESE */
  305.         {CS_GB_8BIT,    CS_GB_8BIT,        0, (CCCFunc)mz_gb2gb,        0},
  306.  
  307.         /*  TRADITIONAL CHINESE */
  308.         {CS_BIG5,        CS_BIG5,        0, (CCCFunc)mz_mbNullConv,    INTL_CHARLEN_CGK},
  309. #ifdef FEATURE_BIG5CNS
  310.         {CS_BIG5,        CS_CNS_8BIT,    0, (CCCFunc)mz_b52cns,        0},
  311.         {CS_CNS_8BIT,    CS_BIG5,        0, (CCCFunc)mz_cns2b5,        0},
  312. #endif
  313.  
  314.         /* UNICODE */
  315.         {CS_UTF8,        CS_UTF8,        0, (CCCFunc)mz_mbNullConv,    INTL_CHARLEN_UTF8},
  316.  
  317.         {CS_UTF8,        CS_UCS2,        0, (CCCFunc)mz_utf82ucs,    0},
  318.         {CS_UTF8,        CS_UTF7,        0, (CCCFunc)mz_utf82utf7,    0},
  319.         {CS_UTF8,        CS_UCS2_SWAP,    0, (CCCFunc)mz_utf82ucsswap,    0},
  320.         {CS_UCS2,        CS_UTF8,        0, (CCCFunc)mz_ucs2utf8,    0},
  321.         {CS_UCS2,        CS_UTF7,        0, (CCCFunc)mz_ucs2utf7,    0},
  322.         {CS_UTF8,        CS_IMAP4_UTF7,        0, (CCCFunc)mz_utf82imap4utf7,    0},
  323.         {CS_UCS2_SWAP,    CS_UTF8,        0, (CCCFunc)mz_ucs2utf8,    0},
  324.         {CS_UCS2_SWAP,    CS_UTF7,        0, (CCCFunc)mz_ucs2utf7,    0},
  325.         {CS_UTF7,        CS_UTF8,        0, (CCCFunc)mz_utf72utf8,    0},
  326.         {CS_IMAP4_UTF7,        CS_UTF8,        0, (CCCFunc)mz_imap4utf72utf8,    0},
  327.  
  328.          {CS_LATIN1,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  329.          {CS_CP_1250,    CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  330.          {CS_CP_1251,    CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  331.           {CS_CP_1253,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  332.           {CS_8859_9,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  333.         {CS_SJIS,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SJIS},
  334.          {CS_KSC_8BIT,    CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_CGK},
  335.          {CS_BIG5,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_CGK},
  336.          {CS_GB_8BIT,    CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_CGK},
  337.  
  338.           {CS_UTF8,        CS_LATIN1,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  339.          {CS_UTF8,        CS_CP_1250,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  340.          {CS_UTF8,        CS_CP_1251,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  341.           {CS_UTF8,        CS_CP_1253,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  342.           {CS_UTF8,        CS_8859_9,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  343.         {CS_UTF8,        CS_SJIS,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  344.          {CS_UTF8,        CS_KSC_8BIT,    0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  345.          {CS_UTF8,        CS_BIG5,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  346.          {CS_UTF8,        CS_GB_8BIT,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  347.  
  348. #ifdef XP_OS2
  349.                 /*
  350.                  * Define additional codepage conversions for OS/2.  All of these use the unicode
  351.                  * based conversion tables.
  352.                     */
  353.          /* Thai */
  354.          {CS_CP_874,             CS_CP_874,              0, (CCCFunc)0,                          0},
  355.          {CS_CP_874,             CS_UTF8,                0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  356.          {CS_UTF8,               CS_CP_874,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_UTF8},
  357.  
  358.          /* Baltic */
  359.          {CS_CP_1257,    CS_CP_1257,             0, (CCCFunc)0,                          0},
  360.          {CS_CP_1257,    CS_UTF8,                0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  361.          {CS_UTF8,               CS_CP_1257,             0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_UTF8},
  362.  
  363.          /* Hebrew */
  364.          {CS_CP_862,             CS_CP_862,              0, (CCCFunc)0,                          0},
  365.          {CS_CP_862,             CS_UTF8,                0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  366.          {CS_UTF8,               CS_CP_862,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_UTF8},
  367.  
  368.          /* Arabic */
  369.          {CS_CP_864,             CS_CP_864,              0, (CCCFunc)0,                          0},
  370.          {CS_CP_864,             CS_UTF8,                0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  371.          {CS_UTF8,               CS_CP_864,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_UTF8},
  372.  
  373.          /* PC codepages - Default convert to windows codepages */
  374.          {CS_CP_850,             CS_LATIN1,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  375.          {CS_CP_852,             CS_LATIN2,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  376.          {CS_CP_855,             CS_CP_1251,     0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  377.          {CS_CP_857,             CS_CP_1254,             0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  378.          {CS_CP_866,             CS_CP_1251,     0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  379.  
  380.          {CS_CP_850,             CS_CP_850,              0, (CCCFunc)0,                          0},
  381.          {CS_CP_852,             CS_CP_852,              0, (CCCFunc)0,                          0},
  382.          {CS_CP_855,             CS_CP_855,              0, (CCCFunc)0,                          0},
  383.          {CS_CP_857,             CS_CP_857,              0, (CCCFunc)0,                          0},
  384.          {CS_CP_866,             CS_CP_866,              0, (CCCFunc)0,                          0},
  385.  
  386.          {CS_LATIN1,             CS_CP_850,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  387.          {CS_LATIN2,             CS_CP_852,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  388.          {CS_CP_1251,    CS_CP_855,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  389.          {CS_CP_1254,    CS_CP_857,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  390.          {CS_CP_1251,    CS_CP_866,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  391.  
  392.          {CS_CP_850,             CS_UTF8,                0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  393.          {CS_CP_852,             CS_UTF8,                0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  394.          {CS_CP_855,             CS_UTF8,                0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  395.          {CS_CP_857,             CS_UTF8,                0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  396.          {CS_CP_866,             CS_UTF8,                0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  397.          {CS_KOI8_R,             CS_UTF8,                0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  398.  
  399.          {CS_UTF8,               CS_CP_850,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_UTF8},
  400.          {CS_UTF8,               CS_CP_852,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_UTF8},
  401.          {CS_UTF8,               CS_CP_855,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_UTF8},
  402.          {CS_UTF8,               CS_CP_857,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_UTF8},
  403.          {CS_UTF8,               CS_CP_866,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_UTF8},
  404.          {CS_UTF8,               CS_KOI8_R,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_UTF8},
  405.  
  406.          {CS_MAC_ROMAN,  CS_LATIN1,              0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  407.          {CS_LATIN1,             CS_MAC_ROMAN,   0, (CCCFunc)mz_AnyToAnyThroughUCS2,     INTL_CHARLEN_SINGLEBYTE},
  408. #endif /* XP_OS2 */
  409.  
  410.  
  411.         {CS_USER_DEFINED_ENCODING,    CS_USER_DEFINED_ENCODING,    0, (CCCFunc)0,            0},    
  412.         {0,                    0,                1, (CCCFunc)0,            0}
  413. };
  414.  
  415. #endif    /* XP_WIN || XP_OS2 */
  416. #ifdef XP_UNIX
  417. MODULE_PRIVATE cscvt_t        cscvt_tbl[] = {
  418.         /*    SINGLE BYTE */
  419.         /*    LATIN1 */
  420.         {CS_LATIN1,        CS_LATIN1,        0, (CCCFunc)One2OneCCC,    0},
  421.         {CS_LATIN1,        CS_ASCII,        0, NULL,            0},
  422.         {CS_ASCII,        CS_LATIN1,        0, NULL,            0},
  423.  
  424.         /* LATIN2 */
  425.         {CS_LATIN2,        CS_LATIN2,        0, NULL,            0},
  426.         {CS_LATIN2,        CS_ASCII,        0, NULL,            0},
  427.  
  428.         /* CYRILLIC */
  429.         {CS_KOI8_R,        CS_KOI8_R,        0, NULL,            0},    
  430.         {CS_8859_5,        CS_8859_5,        0, NULL,            0},    
  431.         {CS_8859_5,        CS_KOI8_R,        0, (CCCFunc)One2OneCCC, 0},    
  432.         {CS_KOI8_R,        CS_8859_5,        0, (CCCFunc)One2OneCCC, 0},    
  433.  
  434.         /* GREEK */
  435.         {CS_8859_7,        CS_8859_7,        0, NULL,            0},    
  436.  
  437.         /* TURKISH */
  438.         {CS_8859_9,        CS_8859_9,        0, NULL,            0},    
  439.  
  440.         /*  MULTIBYTE */
  441.         /*    JAPANESE */
  442.         {CS_EUCJP,        CS_EUCJP,        1, mz_mbNullConv,    INTL_CHARLEN_EUC_JP},
  443.         {CS_JIS,        CS_EUCJP,        1, jis2other,        1},
  444.         {CS_SJIS,        CS_EUCJP,        1, mz_sjis2euc,        0},
  445.         {CS_EUCJP,        CS_SJIS,        1, mz_euc2sjis,        0},
  446.         {CS_JIS,        CS_SJIS,        1, jis2other,        0},
  447.         {CS_SJIS,        CS_SJIS,        1, mz_mbNullConv,   INTL_CHARLEN_SJIS},
  448.         {CS_EUCJP,        CS_JIS,            1, mz_euc2jis,        0},
  449.         {CS_SJIS,        CS_JIS,            1, mz_sjis2jis,        0},
  450.         /* auto-detect Japanese conversions                    */
  451.         {CS_JIS_AUTO,    CS_EUCJP,        1, autoJCCC,        1},
  452.         {CS_SJIS_AUTO,    CS_EUCJP,        1, autoJCCC,        0},
  453.         {CS_EUCJP_AUTO,    CS_EUCJP,        1, autoJCCC,        0},
  454.         {CS_EUCJP_AUTO,    CS_SJIS,        1, autoJCCC,        0},
  455.         {CS_JIS_AUTO,    CS_SJIS,        1, autoJCCC,        0},
  456.         {CS_SJIS_AUTO,    CS_SJIS,        1, autoJCCC,        0},
  457.  
  458.         /*    KOREAN */
  459.         {CS_KSC_8BIT,    CS_KSC_8BIT,    0, (CCCFunc)mz_mbNullConv,    INTL_CHARLEN_CGK},
  460.         {CS_2022_KR,    CS_KSC_8BIT,    0, (CCCFunc)mz_iso2euckr,    0},
  461.         {CS_KSC_8BIT,    CS_2022_KR,        0, (CCCFunc)mz_euckr2iso,    0},
  462.         /* auto-detect Korean conversions                        */
  463.         {CS_KSC_8BIT_AUTO,  CS_KSC_8BIT,1, (CCCFunc)autoKCCC,        0},
  464.          {(CS_2022_KR|CS_AUTO) ,  CS_KSC_8BIT,1, (CCCFunc)autoKCCC,        0},
  465.  
  466.         /*  SIMPLIFIED CHINESE */
  467.         {CS_GB_8BIT,    CS_GB_8BIT,        0, (CCCFunc)mz_gb2gb,        0},
  468.  
  469.         /*  TRADITIONAL CHINESE */
  470.         {CS_CNS_8BIT,    CS_CNS_8BIT,    0, mz_mbNullConv,    INTL_CHARLEN_CNS_8BIT},
  471. #ifdef FEATURE_BIG5CNS
  472.         {CS_BIG5,        CS_CNS_8BIT,    0, mz_b52cns,        0},
  473.         {CS_CNS_8BIT,    CS_BIG5,        0, mz_cns2b5,        0},
  474. #endif
  475.         {CS_BIG5,        CS_BIG5,        0, mz_mbNullConv,    INTL_CHARLEN_CGK},
  476.  
  477.         {CS_USRDEF2,    CS_USRDEF2,        0, NULL,            0},    
  478.  
  479.         /* UNICODE                                           */
  480.         {CS_UTF8,        CS_UTF8,        0, mz_mbNullConv,    INTL_CHARLEN_UTF8},
  481.         {CS_UTF8,        CS_UCS2,        0, (CCCFunc)mz_utf82ucs,    0},
  482.         {CS_UTF8,        CS_UTF7,        0, (CCCFunc)mz_utf82utf7,    0},
  483.         {CS_UTF8,        CS_UCS2_SWAP,    0, (CCCFunc)mz_utf82ucsswap,    0},
  484.         {CS_UTF8,        CS_IMAP4_UTF7,    0, (CCCFunc)mz_utf82imap4utf7,    0},
  485.         {CS_UCS2,        CS_UTF8,        0, (CCCFunc)mz_ucs2utf8,    0},
  486.         {CS_UCS2,        CS_UTF7,        0, (CCCFunc)mz_ucs2utf7,    0},
  487.         {CS_UCS2_SWAP,    CS_UTF8,        0, (CCCFunc)mz_ucs2utf8,    0},
  488.         {CS_UCS2_SWAP,    CS_UTF7,        0, (CCCFunc)mz_ucs2utf7,    0},
  489.         {CS_UTF7,        CS_UTF8,        0, (CCCFunc)mz_utf72utf8,    0},
  490.  
  491.         {CS_LATIN1,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  492.          {CS_LATIN2,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  493.          {CS_8859_5,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  494.          {CS_KOI8_R,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  495.           {CS_8859_7,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  496.           {CS_8859_9,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SINGLEBYTE},
  497.         {CS_SJIS,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_SJIS},
  498.          {CS_EUCJP,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_EUC_JP},
  499.          {CS_KSC_8BIT,    CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_CGK},
  500.          {CS_BIG5,        CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_CGK},
  501.          {CS_CNS_8BIT,    CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_CNS_8BIT},
  502.          {CS_GB_8BIT,    CS_UTF8,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_CGK},
  503.  
  504.           {CS_UTF8,        CS_LATIN1,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  505.          {CS_UTF8,        CS_LATIN2,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  506.          {CS_UTF8,        CS_8859_5,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  507.          {CS_UTF8,        CS_KOI8_R,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  508.           {CS_UTF8,        CS_8859_7,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  509.           {CS_UTF8,        CS_8859_9,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  510.         {CS_UTF8,        CS_SJIS,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  511.          {CS_UTF8,        CS_EUCJP,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  512.          {CS_UTF8,        CS_KSC_8BIT,    0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  513.           {CS_UTF8,        CS_BIG5,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  514.         {CS_UTF8,        CS_CNS_8BIT,    0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  515.          {CS_UTF8,        CS_GB_8BIT,        0, (CCCFunc)mz_AnyToAnyThroughUCS2,    INTL_CHARLEN_UTF8},
  516.  
  517.         {CS_IMAP4_UTF7,    CS_UTF8,        0, (CCCFunc)mz_imap4utf72utf8,    0},
  518.         {0,                0,                0, NULL,            0}
  519.  
  520. };
  521.  
  522. #endif /* XP_UNIX */
  523.  
  524.  
  525. /*
  526.  * this routine is needed to make sure parser and layout see whole
  527.  * characters, not partial characters
  528.  */
  529. PRIVATE unsigned char *
  530. mz_gb2gb(CCCDataObject obj, const unsigned char *gbbuf, int32 gbbufsz)
  531. {
  532.     return mz_hz2gb(obj, gbbuf, gbbufsz);
  533. }
  534. PRIVATE unsigned char *
  535. mz_hz2gb(CCCDataObject obj, const unsigned char *gbbuf, int32 gbbufsz)
  536. {
  537.     unsigned char *start, *p, *q;
  538.     unsigned char *output;
  539.     int i, j, len;
  540.     unsigned char *uncvtbuf = INTL_GetCCCUncvtbuf(obj);
  541.  
  542.     q = output = XP_ALLOC(strlen((char*)uncvtbuf) + gbbufsz + 1);
  543.     if (q == NULL)
  544.         return NULL;
  545.  
  546.     start = NULL;
  547.  
  548.     for (j = 0; j < 2; j++)
  549.     {
  550.         len = 0;
  551.         if (j == 0)
  552.             len = strlen((char *)uncvtbuf);
  553.         if (len)
  554.             p = (unsigned char *) uncvtbuf;
  555.         else
  556.         {
  557.             p = (unsigned char *) gbbuf ;
  558.             len = gbbufsz;
  559.             j = 100;  /* quit this loop next time */
  560.         }
  561.         for (i = 0; i < len;)
  562.         {
  563.             if (start)
  564.             {
  565.                 if (*p == '~' && *(p+1) == '}')   /* switch back to ASCII mode */
  566.                 {
  567.                     for (; start < p; start++)
  568.                         *q++ = *start | 0x80;
  569.                     p += 2;
  570.                     i += 2;
  571.                     start = NULL;
  572.                 }
  573.                 else if (*p == 0x0D && *(p+1) == 0x0A)  /* Unix or Mac return */
  574.                 {
  575.                     for (; start < p; start++)
  576.                         *q++ = *start | 0x80;
  577.                     i += 2;
  578.                     *q++ = *p++;   /* 0x0D  */
  579.                     *q++ = *p++;   /* 0x0A  */
  580.                     start = NULL;   /* reset start if we see normal line return */
  581.                 }
  582.                 else if (*p == 0x0A)  /* Unix or Mac return */
  583.                 {
  584.                     for (; start < p; start++)
  585.                         *q++ = *start | 0x80;
  586.                     i ++;
  587.                     *q++ = *p++;   /* LF  */
  588.                     start = NULL;   /* reset start if we see normal line return */
  589.                 }
  590.                 else if (*p == 0x0D)  /* Unix or Mac return */
  591.                 {
  592.                     for (; start < p; start++)
  593.                         *q++ = *start | 0x80;
  594.                     i ++;
  595.                     *q++ = *p++;   /* LF  */
  596.                     start = NULL;   /* reset start if we see normal line return */
  597.                 }
  598.                 else
  599.                 {
  600.                     i ++ ;
  601.                     p ++ ;
  602.                 }
  603.             }
  604.             else
  605.             {
  606.                 if (*p == '~' && *(p+1) == '{')    /* switch to GB mode */
  607.                 {
  608.                     start = p + 2;
  609.                     p += 2;
  610.                     i += 2;
  611.                 }
  612.                 else if (*p == '~' && *(p+1) == 0x0D && *(p+2) == 0x0A)  /* line-continuation marker */
  613.                 {
  614.                     i += 3;
  615.                     p += 3;
  616.                 }
  617.                 else if (*p == '~' && *(p+1) == 0x0A)  /* line-continuation marker */
  618.                 {
  619.                     i += 2;
  620.                     p += 2;
  621.                 }
  622.                 else if (*p == '~' && *(p+1) == 0x0D)  /* line-continuation marker */
  623.                 {
  624.                     i += 2;
  625.                     p += 2;
  626.                 }
  627.                 else if (*p == '~' && *(p+1) == '~')   /* ~~ means ~ */
  628.                 {
  629.                     *q++ = '~';
  630.                     p += 2;
  631.                     i += 2;
  632.                 }
  633.                 else
  634.                 {
  635.                     i ++;
  636.                     *q++ = *p++;
  637.                 }
  638.             }
  639.         }
  640.     }
  641.     *q = '\0';
  642.     INTL_SetCCCLen(obj, q - output);
  643.     if (start)
  644.     {
  645.  
  646.         /* Consider UNCVTBUF_SIZE is only 8 byte long, it's not enough 
  647.            for HZ anyway. Let's convert leftover to GB first and deal with
  648.            unfinished buffer in the coming block.
  649.         */
  650.         INTL_SetCCCLen(obj, INTL_GetCCCLen(obj) + p - start);
  651.         for (; start < p; start++)
  652.             *q++ = *start | 0x80;
  653.         *q = '\0';
  654.  
  655.         q = uncvtbuf;
  656.         XP_STRCPY((char *)q, "~{");
  657.     }
  658.  
  659.     return output;
  660. }
  661.  
  662.  
  663.  
  664. /*    mz_mbNullConv
  665.  * this routine is needed to make sure parser and layout see whole
  666.  * characters, not partial characters
  667.  */
  668. /* This routine is designed to replace the following routine:
  669.     mz_euc2euc
  670.     mz_b52b5
  671.     mz_cns2cns
  672.     mz_ksc2ksc
  673.     mz_sjis2sjis
  674.     mz_utf82utf8
  675.  
  676.    It should also replace
  677.         mz_gb2gb
  678.    but currently mz_gb2gb also handle hz to gb. We need to move that functionality out of mz_gb2gb
  679.  */
  680. PRIVATE unsigned char *
  681. mz_mbNullConv(CCCDataObject obj, const unsigned char *buf, int32 bufsz)
  682. {
  683.     int32            left_over;
  684.     int32            len;
  685.     unsigned char    *p;
  686.     unsigned char    *ret;
  687.     int32            total;
  688.     intl_CharLenFunc    CharLenFunc = intl_char_len_func[INTL_GetCCCCvtflag(obj)];
  689.     int charlen = 0;
  690.     
  691.     /*    Get the unconverted buffer */
  692.     unsigned char *uncvtbuf = INTL_GetCCCUncvtbuf(obj);
  693.     int32            uncvtsz = strlen((char *)uncvtbuf);
  694.  
  695.     /*  return in the input is nonsense */
  696.     if ((!obj) || (! buf) || (bufsz < 0))
  697.         return NULL;
  698.  
  699.     /*    Allocate Output Buffer */
  700.     total = uncvtsz + bufsz;
  701.     ret = (unsigned char *) XP_ALLOC(total + 1);
  702.     if (!ret)
  703.     {
  704.         INTL_SetCCCRetval(obj, MK_OUT_OF_MEMORY);
  705.         return NULL;
  706.     }
  707.  
  708.     /*    Copy unconverted buffer into the output bufer */
  709.     memcpy(ret, uncvtbuf, uncvtsz);
  710.     /* Copy the current input buffer into the output buffer */
  711.     memcpy(ret+uncvtsz, buf, bufsz);
  712.  
  713.     /*    Walk through the buffer and figure out the left_over length */
  714.     for (p=ret, len=total, left_over=0; len > 0; p += charlen, len -= charlen)
  715.     {
  716.         if((charlen = CharLenFunc(*p)) > 1)
  717.         {    /* count left_over only if it is multibyte char */
  718.             if(charlen > len)    /* count left_over only if the len is less than charlen */
  719.                 left_over = len;
  720.         };
  721.     }
  722.  
  723.     /*    Copy the left over into the uncvtbuf */
  724.     if(left_over)
  725.         memcpy(uncvtbuf, p - charlen, left_over);
  726.     /*  Null terminated the uncvtbuf */
  727.     uncvtbuf[left_over] = '\0';
  728.  
  729.     /* Null terminate the return buffer and set the length */
  730.     INTL_SetCCCLen(obj, total - left_over);
  731.     ret[total - left_over] = 0;
  732.  
  733.     return ret;
  734. }
  735.  
  736. /*
  737.     buf -> mz_mbNullConv -> frombuf -> INTL_TextToUnicode -> ucs2buf
  738.     -> INTL_UnicodeToStr -> tobuf
  739. */
  740. PRIVATE unsigned char* mz_AnyToAnyThroughUCS2(CCCDataObject obj, const unsigned char *buf, int32 bufsz)
  741. {
  742.     /* buffers */
  743.     unsigned char* fromBuf = NULL;
  744.     INTL_Unicode* ucs2Buf = NULL;
  745.     unsigned char* toBuf   = NULL;
  746.     /* buffers' length */
  747.     uint32 ucs2BufLen = 0;
  748.     uint32 fromBufLen = 0;
  749.     uint32 toBufLen   = 0;
  750.     /* from & to csid */
  751.     uint16 fromCsid = INTL_GetCCCFromCSID(obj);
  752.     uint16 toCsid   = INTL_GetCCCToCSID(obj);
  753.  
  754.     /* get the fromBuf */
  755.     if( !( fromBuf = mz_mbNullConv( obj, buf,  bufsz) ) )
  756.         return NULL;
  757.  
  758.     /* map fromBuf -> ucs2Buf */
  759.     fromBufLen = INTL_GetCCCLen(obj);
  760.     ucs2BufLen = INTL_TextToUnicodeLen( fromCsid, fromBuf, fromBufLen );
  761.  
  762.     if( !( ucs2Buf = XP_ALLOC( (ucs2BufLen + 1 ) * 2)) ){
  763.         return NULL;
  764.     }
  765.  
  766.     /* be care, the return value is HOW MANY UNICODE IN THIS UCS2BUF, not how many bytes */
  767.     ucs2BufLen = INTL_TextToUnicode( fromCsid, fromBuf, fromBufLen, ucs2Buf, ucs2BufLen );
  768.  
  769.     /* map ucs2Buf -> toBuf */
  770.     toBufLen = INTL_UnicodeToStrLen( toCsid, ucs2Buf, ucs2BufLen );    /* we get BYTES here :) */
  771.  
  772.     if( !( toBuf = XP_ALLOC( toBufLen + 1 ) ) )
  773.         return NULL;
  774.  
  775.     INTL_UnicodeToStr( toCsid, ucs2Buf, ucs2BufLen, toBuf, toBufLen );
  776.  
  777.  
  778.     /* clean up after myself */
  779.     free( fromBuf );
  780.     free( ucs2Buf );
  781.  
  782.     /* In order to let the caller know how long the buffer is, i have to set its tail NULL. */
  783.     toBuf[ toBufLen ] = 0;
  784.     return toBuf;
  785. }
  786.  
  787.  
  788. PRIVATE int16 intl_CharLen_SJIS(        unsigned char ch)
  789. {
  790.     return (    (((ch >= 0x81) && (ch <= 0x9f)) || ((ch >= 0xe0) && (ch <= 0xfc))) ?    2 : 1);
  791. }
  792. PRIVATE int16 intl_CharLen_EUC_JP(    unsigned char ch)
  793. {
  794.     return (    (((ch >= 0xa1) && (ch <= 0xfe)) || (ch == 0x8e)) ?    2 : ((ch ==0x8f) ?    3 : 1));
  795. }
  796. PRIVATE int16 intl_CharLen_CGK(        unsigned char ch)
  797. {
  798.     return (    ((ch >= 0xa1) && (ch <= 0xfe))  ?    2 :        1);
  799. }    
  800. PRIVATE int16 intl_CharLen_CNS_8BIT(    unsigned char ch)
  801. {
  802.     return (    ((ch >= 0xa1) && (ch <= 0xfe))  ?    2 : ((ch == 0x8e) ?        4 : 1));
  803. }
  804. PRIVATE int16 intl_CharLen_UTF8(        unsigned char ch)
  805. {
  806.     return (    ((ch >= 0xc0) && (ch <= 0xdf))  ?    2 : (((ch >= 0xe0) && (ch <= 0xef)) ?        3 : 1));
  807. }
  808. PRIVATE int16 intl_CharLen_SingleByte( unsigned char ch)
  809. {
  810.     return 1;
  811. }
  812.  
  813.  
  814. /*
  815.  INTL_DefaultWinCharSetID,
  816.    Based on DefaultDocCSID, it determines which Win CSID to use for Display
  817. */
  818. PUBLIC int16 INTL_DefaultWinCharSetID(iDocumentContext context)
  819. {
  820.  
  821.     if (context) {
  822.         INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(context);
  823.         if (INTL_GetCSIWinCSID(csi))
  824.             return INTL_GetCSIWinCSID(csi);
  825.     }
  826.  
  827.     return INTL_DocToWinCharSetID(INTL_DefaultDocCharSetID(context));
  828. }
  829.  
  830. /*
  831.  INTL_DocToWinCharSetID,
  832.    Based on DefaultDocCSID, it determines which Win CSID to use for Display
  833. */
  834. /*
  835.  
  836.     To Do: (ftang)
  837.  
  838.     We should seperate the DocToWinCharSetID logic from the cscvt_t table
  839.     for Cyrillic users. 
  840.  
  841. */
  842. PUBLIC int16 INTL_DocToWinCharSetID(int16 csid)
  843. {
  844.     cscvt_t        *cscvtp;
  845.     int16       from_csid = 0,  to_csid = 0;
  846.  
  847.     from_csid = csid & ~CS_AUTO;    /* remove auto bit  */
  848.  
  849.     /* Look-up conversion method given FROM and TO char. code sets    */
  850.     cscvtp = cscvt_tbl;
  851.     while (cscvtp->from_csid)
  852.     {
  853.         if (cscvtp->from_csid == from_csid)
  854.         {
  855. /*
  856.  * disgusting hack...
  857.  */
  858. #ifdef XP_UNIX
  859.             if ((cscvtp->to_csid == CS_CNS_8BIT) && haveBig5) {
  860.                 cscvtp++;
  861.                 continue;
  862.             }
  863. #endif
  864.             to_csid = cscvtp->to_csid;
  865.             break ;
  866.         }
  867.         cscvtp++;
  868.     }
  869.     return to_csid == 0 ? CS_FE_ASCII: to_csid ;
  870. }
  871.  
  872.  
  873. XP_Bool
  874. INTL_CanAutoSelect(int16 csid)
  875. {
  876.     register cscvt_t        *cscvtp;
  877.  
  878.     cscvtp = cscvt_tbl;
  879.     while (cscvtp->from_csid) {
  880.         if (cscvtp->from_csid == csid) {
  881.             return (cscvtp->autoselect);    
  882.         }
  883.         cscvtp++;
  884.     }
  885.     return FALSE;
  886. }
  887.  
  888.  
  889. PUBLIC int16
  890. INTL_DefaultTextAttributeCharSetID(iDocumentContext context)
  891. {
  892.     if (context)
  893.     {
  894.         INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(context);
  895.         if (INTL_GetCSIWinCSID(c))
  896.             return INTL_GetCSIWinCSID(c);
  897.     }
  898.  
  899.     return INTL_DefaultWinCharSetID(context);
  900. }
  901.  
  902. void
  903. INTL_ReportFontCharSets(int16 *charsets)
  904. {
  905.     uint16    len;
  906.  
  907.     if (!charsets)
  908.     {
  909.         return;
  910.     }
  911.  
  912.     if (availableFontCharSets)
  913.     {
  914.         free(availableFontCharSets);
  915.     }
  916.  
  917.     availableFontCharSets = charsets;
  918.  
  919.     while (*charsets)
  920.     {
  921.         if (*charsets == CS_X_BIG5)
  922.         {
  923.             haveBig5 = 1;
  924.         }
  925.         charsets++;
  926.     }
  927.     len = (charsets - availableFontCharSets);
  928.  
  929. #ifdef XP_UNIX
  930.     INTL_SetUnicodeCSIDList(len, availableFontCharSets);
  931.  
  932. #endif
  933.  
  934. }
  935.  
  936. /*    Code for CSID Iterator */
  937.  
  938. #define NUMOFCSIDINITERATOR 15
  939. struct INTL_CSIDIteratorPriv
  940. {
  941.     int16 cur;
  942.     int16 csidlist[NUMOFCSIDINITERATOR];
  943. };
  944. typedef struct INTL_CSIDIteratorPriv INTL_CSIDIteratorPriv;
  945.  
  946. #ifdef MOZ_MAIL_NEWS
  947.  
  948. PRIVATE void intl_FillTryIMAP4SearchIterator(INTL_CSIDIteratorPriv* p, int16 csid);
  949. PRIVATE void intl_FillTryIMAP4SearchIterator(INTL_CSIDIteratorPriv* p, int16 csid)
  950. {    
  951.     int idx = 0;
  952.     cscvt_t        *cscvtp = cscvt_tbl;
  953.     p->csidlist[idx++] = INTL_DefaultMailCharSetID(csid);    /* add mailcsid first */
  954.     p->csidlist[idx++] = INTL_DefaultNewsCharSetID(csid);    /* If the news csid is different add it */
  955.     if(p->csidlist[0] == p->csidlist[1])
  956.         idx--;
  957.     /* Add all the csid that we know how to convert to (Without CS_AUTO bit on */
  958.     while (cscvtp->from_csid)
  959.     {
  960.         if ( (cscvtp->from_csid & ~CS_AUTO) == (csid & ~CS_AUTO))
  961.         {    
  962.             int16 foundcsid = cscvtp->to_csid & ~CS_AUTO;
  963.             XP_Bool notInTheList = TRUE;
  964.             int i;
  965.             for(i = 0; i < idx ;i++)
  966.             {
  967.                 if(foundcsid == p->csidlist[i])
  968.                     notInTheList = FALSE;
  969.             }        
  970.             if(notInTheList)
  971.             {
  972.                 p->csidlist[idx++] = foundcsid;
  973.                 XP_ASSERT(NUMOFCSIDINITERATOR == idx);
  974.                 if(NUMOFCSIDINITERATOR == idx)
  975.                     break;
  976.             }
  977.         }
  978.         cscvtp++;
  979.     }
  980.     p->csidlist[idx] = 0;    /* terminate the list by 0 */
  981. }
  982.  
  983. PUBLIC void INTL_CSIDIteratorCreate( INTL_CSIDIterator* iterator, int16 csid, int flag)
  984. {
  985.     INTL_CSIDIteratorPriv* priv = 
  986.         (INTL_CSIDIteratorPriv*) XP_ALLOC(sizeof(INTL_CSIDIteratorPriv));
  987.     *iterator = (INTL_CSIDIterator) priv;
  988.     if(priv)
  989.     {
  990.         priv->cur = 0;
  991.         switch(flag)
  992.         {
  993.             case csiditerate_TryIMAP4Search:
  994.                 intl_FillTryIMAP4SearchIterator    (priv,     (int16)(csid & ~CS_AUTO));
  995.             break;
  996.             default:
  997.                 XP_ASSERT(FALSE);
  998.             break;
  999.         }
  1000.     }
  1001.     return;
  1002. }
  1003.  
  1004. #endif  /* MOZ_MAIL_NEWS */
  1005.  
  1006. PUBLIC void INTL_CSIDIteratorDestroy(INTL_CSIDIterator* iterator)
  1007. {
  1008.     INTL_CSIDIteratorPriv* priv = (INTL_CSIDIteratorPriv*) *iterator;
  1009.     *iterator = NULL;
  1010.     XP_FREE(priv);
  1011. }
  1012.  
  1013. PUBLIC XP_Bool INTL_CSIDIteratorNext( INTL_CSIDIterator* iterator, int16* pCsid)
  1014. {
  1015.     INTL_CSIDIteratorPriv* priv = (INTL_CSIDIteratorPriv*) *iterator;
  1016.     int16 csid = priv->csidlist[(priv->cur)++];
  1017.     if(0 == csid)
  1018.     {
  1019.         return FALSE;
  1020.     }
  1021.     else
  1022.     {
  1023.         *pCsid = csid;
  1024.         return TRUE;
  1025.     }
  1026. }
  1027.  
  1028.  
  1029. #ifdef XP_OS2
  1030. /*
  1031.  * Map Netscape charset to OS/2 codepage
  1032.  */
  1033.  
  1034. /*
  1035.  * This is tricker then you think. For a given charset, first entry should
  1036.  * be windows codepage, second entry should be OS/2 codepage.
  1037.  */
  1038.  
  1039. static uint16 CS2CodePage[] = {
  1040.     CS_LATIN1     , 1004,  /*    2 */
  1041.     CS_ASCII      , 1252,  /*    1 */
  1042.     CS_UTF8       , 1208,  /*  290 */
  1043.     CS_SJIS       ,  943,  /*  260 */
  1044.     CS_8859_3     ,  913,  /*   14 */
  1045.     CS_8859_4     ,  914,  /*   15 */
  1046.     CS_8859_5     ,  915,  /*   16 ISO Cyrillic */
  1047.     CS_8859_6     , 1089,  /*   17 ISO Arabic */
  1048.     CS_8859_7     ,  813,  /*   18 ISO Greek */
  1049.     CS_8859_8     ,  916,  /*   19 ISO Hebrew */
  1050.     CS_8859_9     ,  920,  /*   20 */
  1051.     CS_BIG5       ,  950,  /*  263 */
  1052.     CS_GB2312     , 1386,  /*  287 */
  1053.     CS_CP_1250    , 1250,  /*   44 CS_CP_1250 is window Centrl Europe */
  1054.     CS_CP_1251    , 1251,  /*   41 CS_CP_1251 is window Cyrillic */
  1055.     CS_LATIN2     ,  912,  /*   10 */
  1056.     CS_CP_1253    , 1253,  /*   43 CS_CP_1253 is window Greek */
  1057.     CS_CP_1254    , 1254,  /*   45 CS_CP_1254 is window Turkish */
  1058.     CS_CP_1257    , 1257,  /*   61  Windows Baltic */
  1059.     CS_CP_1258    , 1258,  /*   62  Windows Vietnamese */
  1060.     CS_CP_850     ,  850,  /*   53  PC Latin 1 */
  1061.     CS_CP_852     ,  852,  /*   54  PC Latin 2 */
  1062.     CS_CP_855     ,  855,  /*   55  PC Cyrillic */
  1063.     CS_CP_857     ,  857,  /*   56  PC Turkish */
  1064.     CS_CP_862     ,  862,  /*   57  PC Hebrew */
  1065.     CS_CP_864     ,  864,  /*   58  PC Arabic */
  1066.     CS_CP_866     ,  866,  /*   59  PC Russian */
  1067.     CS_CP_874     ,  874,  /*   60  PC Thai    */
  1068.     CS_EUCJP      ,  930,  /*  261 */
  1069.     CS_GB_8BIT    , 1386,  /*  264 */
  1070.     CS_KOI8_R     ,  878,  /*   39 */
  1071.     CS_KSC5601    ,  949,  /*  284 */
  1072.     CS_MAC_CE     , 1282,  /*   11 */
  1073.     CS_MAC_CYRILLIC, 1283, /*   40 */
  1074.     CS_MAC_GREEK  , 1280,  /*   42 */
  1075.     CS_MAC_ROMAN  , 1275,  /*    6 */
  1076.     CS_MAC_TURKISH, 1281,  /*   46 */
  1077.     CS_UCS2       , 1200,  /*  810 */
  1078.     CS_USRDEF2    , 1252,  /*   38 */
  1079.     0,              0,
  1080. };
  1081.  
  1082. /*
  1083.  * MapCpToCsNum: Search table and return netscape codeset name
  1084.  */
  1085. uint16  INTL_MapCpToCsNum(uint16 cpid) {
  1086.     uint16 * up;
  1087.  
  1088.     up = CS2CodePage;
  1089.     while (*up) {
  1090.         if (up[1] == cpid) {
  1091.             return up[0];
  1092.         }
  1093.         up += 2;
  1094.     }
  1095.     return 0;
  1096. }
  1097.  
  1098.  
  1099. /*
  1100.  * MapCsToCpNum: Search table and return codepage
  1101.  */
  1102. uint16  INTL_MapCsToCpNum(uint16 csid) {
  1103.     uint16 * up;
  1104.  
  1105.     up = CS2CodePage;
  1106.     while (*up) {
  1107.         if (up[0] == csid) {
  1108.             return up[1];
  1109.         }
  1110.         up += 2;
  1111.     }
  1112.     return 0;
  1113. }
  1114.  
  1115.  
  1116. /*
  1117.  * Map from process codepage to default charset
  1118.  */
  1119. int16 INTL_MenuFontCSID(void) {
  1120.         ULONG   codepage, xxx;
  1121.  
  1122.     DosQueryCp(4, &codepage, &xxx);
  1123.     return INTL_MapCpToCsNum(codepage);
  1124. }
  1125.  
  1126.  
  1127. /*
  1128.  * This returns the ID for the
  1129.  */
  1130. int   INTL_MenuFontID() {
  1131.         return 0;
  1132. }
  1133.  
  1134. #endif /* XP_OS2 */
  1135.