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

  1. /* -*- Mode: C++; tab-width: 8; 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. /*    cvchcode.c    */
  19.  
  20. #include "intlpriv.h"
  21. #include "xp.h"
  22. #include "intl_csi.h"
  23. #include "libi18n.h"
  24.  
  25. int16  PeekMetaCharsetTag (char *, uint32);
  26.  
  27. /*
  28.  * DocumentContext access to creating a
  29.  * Character Code Converter
  30.  *
  31.  * This should be split into two layers:
  32.  *  1) a non-DocumentContext access to creating a Character Code Converter
  33.  *  2) a DocumentContext interface to above
  34.  */
  35. PUBLIC CCCDataObject
  36. INTL_CreateDocumentCCC(INTL_CharSetInfo c, uint16 default_doc_csid)
  37. {
  38.     CCCDataObject obj;
  39.  
  40.     /* 
  41.      * create the CCC object
  42.      */
  43.     obj = INTL_CreateCharCodeConverter();;
  44.     if (obj == NULL)
  45.         return(NULL);
  46.     INTL_SetCCCDefaultCSID(obj, default_doc_csid);
  47.  
  48.     /*
  49.      * if we know the doc_csid then get the converter
  50.      */
  51.     if (DOC_CSID_KNOWN(INTL_GetCSIDocCSID(c)))
  52.     {
  53.         (void) INTL_GetCharCodeConverter(INTL_GetCSIDocCSID(c), 0, obj);
  54.         XP_ASSERT(INTL_GetCSIWinCSID(c) == INTL_GetCCCToCSID(obj));
  55.     }
  56.     else {
  57.         /* we know what the default converter is but do not install
  58.          * it yet. Wait until the first block and see if we determine
  59.          * what the charset is from that block.
  60.          */
  61.     }
  62.  
  63.     return obj;
  64. }
  65.  
  66. PUBLIC void INTL_CCCReportMetaCharsetTag(MWContext *context, char *charset_tag)
  67. {
  68.  
  69.     INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(context);
  70.  
  71.     INTL_CSIReportMetaCharsetTag(c, charset_tag, context->type);
  72. }
  73.  
  74. #ifdef MOZ_MAIL_NEWS
  75.  
  76. #if 0
  77. /* 
  78.  INTL_ConvWinToMailCharCode
  79.    Converts 8bit encoding to 7bit mail encoding. It decides which 7bit and 8bit encoding 
  80.    to use based on current default language.
  81.  input:
  82.    char *pSrc;              // Source display buffer
  83.  output:
  84.    char *pDest;             //  Destination buffer
  85.                             // pDest == NULL means either conversion fail
  86.                             // or does OneToOne conversion
  87. */
  88. PUBLIC
  89. unsigned char *INTL_ConvWinToMailCharCode(iDocumentContext context, unsigned char *pSrc, uint32 block_size)
  90. {
  91.     CCCDataObject    obj;
  92.     unsigned char *pDest;
  93.     int16 wincsid;
  94.     CCCFunc cvtfunc;
  95.  
  96.     obj = INTL_CreateCharCodeConverter();
  97.     if (obj == NULL)
  98.         return NULL;
  99.  
  100.     wincsid =  INTL_DefaultWinCharSetID(context);
  101.     /* Converts 8bit Window codeset to 7bit Mail Codeset.   */
  102.     (void) INTL_GetCharCodeConverter(wincsid, INTL_DefaultMailCharSetID(wincsid), obj);
  103.  
  104.     cvtfunc = INTL_GetCCCCvtfunc(obj);
  105.     if (cvtfunc)
  106.         pDest = (unsigned char *)cvtfunc(obj, pSrc, block_size);
  107.     else
  108.         pDest = NULL ;
  109.  
  110.     XP_FREE(obj);
  111.  
  112.     if (pDest == pSrc)  /* converted to input buffer           */
  113.     {                           /* no additional memory been allocated */
  114.         return NULL;
  115.     }
  116.     return pDest ;
  117. }
  118.  
  119.  
  120. #endif /* if 0 */
  121.  
  122.  
  123. PRIVATE void
  124. mail_report_autodetect(void *closure, CCCDataObject obj, uint16 doc_csid)
  125. {
  126.     iDocumentContext doc_context = (iDocumentContext)closure;
  127.     INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(doc_context);
  128.  
  129.     INTL_SetCSIDocCSID(c, doc_csid);
  130.     INTL_SetCSIWinCSID(c, INTL_GetCCCToCSID(obj));
  131. }
  132.  
  133. #endif  /* MOZ_MAIL_NEWS */
  134.  
  135. #ifndef XP_WIN
  136. #ifndef XP_MAC
  137. /*
  138.  * FE_DefaultDocCharSetID - get the UI charset encoding setting
  139.  *
  140.  * gets the currently selected charset encoding for this document 
  141.  * (not the global default, not the detected document encoding)
  142.  *
  143.  */
  144. uint16
  145. FE_DefaultDocCharSetID(iDocumentContext context)
  146. {
  147.     uint16 csid;
  148.  
  149.     /* need to implement a FE_DefaultDocCharSetID() which only returns
  150.        the FE default, ignoring the doc_csid in the the context. 
  151.        The Current INTL_DefaultDocCharSetID
  152.        tries to be smart and return the doc_csid if it is known, 
  153.        which causes a problem in HERE !!
  154.     */
  155. #ifdef REAL_FIX_AFTER_B3
  156.     /* ftang, bstell: Need to change to this code in early 4.0 B4 cycle */
  157.     csid = FE_DefaultDocCharSetID(context);      /* Need to implement FE_DefaultDocCharSetID before active this */
  158.  
  159.     if((CS_JIS == csid) || (CS_EUCJP == csid) || (CS_SJIS == csid) || 
  160.         (CS_KSC_8BIT == csid) ||   (CS_2022_KR == csid))
  161.     {
  162.         csid |= CS_AUTO;
  163.     }
  164. #else /* 4.0 B3 temp fix */
  165.     INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(context);
  166.  
  167.     csid = INTL_GetCSIDocCSID(c);
  168.     if (csid == 0) {
  169.         csid = INTL_DefaultDocCharSetID(context);
  170.     }
  171. #ifdef MOZ_MAIL_NEWS
  172.     else
  173.     {
  174.         csid = INTL_DefaultMailCharSetID(csid);
  175.         /* Turn on the auto converter in case people do receive SJIS mail */
  176.         if((CS_JIS == csid) || (CS_EUCJP == csid) || (CS_SJIS == csid) || 
  177.             (CS_KSC_8BIT == csid) ||   (CS_2022_KR == csid))
  178.         {
  179.             csid |= CS_AUTO;
  180.         }
  181.     }
  182. #endif  /* MOZ_MAIL_NEWS */
  183. #endif
  184.     return csid;
  185. }
  186. #endif /*XP_MAC*/
  187. #endif 
  188.  
  189. #ifdef MOZ_MAIL_NEWS
  190.  
  191. /* 
  192.  INTL_ConvMailToWinCharCode
  193.    Converts mail encoding to display charset which is used by current window. 
  194.    It decides which Display charset to use based on current default language.
  195.  input:
  196.    iDocumentContext context;     the context (window ID)
  197.    char *pSrc;          // Source buffer
  198.    uint32 block_size;      the length of the source buffer
  199.  output:
  200.    char *pDest;         //  Destination buffer
  201.                         // pDest == NULL means either conversion fail
  202.                         // or does OneToOne conversion
  203. */
  204. PUBLIC
  205. unsigned char *INTL_ConvMailToWinCharCode(iDocumentContext context,
  206.     unsigned char *pSrc, uint32 block_size)
  207. {
  208.     CCCDataObject    obj;
  209.     unsigned char *pDest;
  210.     Stream stream;
  211.     CCCFunc cvtfunc;
  212.     int16 csid;
  213.  
  214.     obj = INTL_CreateCharCodeConverter();
  215.     if (obj == NULL)
  216.         return 0;
  217.  
  218.     (void) memset(&stream, 0, sizeof(stream));
  219.     stream.window_id = context;
  220.  
  221.     csid = FE_DefaultDocCharSetID(context);
  222.  
  223.     /* Converts 7bit news codeset to 8bit windows Codeset.   */
  224.     (void) INTL_GetCharCodeConverter(csid, 0, obj);
  225.  
  226.  
  227.     INTL_SetCCCReportAutoDetect(obj, mail_report_autodetect, context );
  228.  
  229.     cvtfunc = INTL_GetCCCCvtfunc(obj);
  230.     if (cvtfunc)
  231.         pDest = (unsigned char *)cvtfunc(obj, pSrc, block_size);
  232.     else
  233.         pDest = NULL ;
  234.  
  235.     XP_FREE(obj);
  236.     if (pSrc == pDest)
  237.         return NULL ;
  238.     return pDest ;
  239. }
  240. #endif /* MOZ_MAIL_NEWS */
  241.  
  242.  
  243. #if defined(MOZ_MAIL_COMPOSE) || defined(MOZ_MAIL_NEWS)
  244. /*
  245.     This is the ugly hack for Korean News and Mail
  246.     Our libmsg code assume mail and news use the same code.
  247.     Unfortunately, Korean use different encoding in news and mail
  248.     We have to tell the DocToMailCoverter convert to different encoding
  249.     according to the reciver.
  250.  
  251.     Problem 1:
  252.     It is easy to decide which encoding we should send if the receipt is
  253.     only Newsgroup or only email. But what should we do if the receipt 
  254.     include both newsgroup and personal address ?
  255.     
  256.         Currently we always send News encoding if the recipt include
  257.     Newsgroup.
  258.  
  259.     Problem 2:
  260.     There are no way I can pass such information to the code between
  261.     msgsendp.cpp and msgsend.cpp. So I create such a hack here. 
  262.  
  263. */
  264. static XP_Bool intl_message_to_newsgroup = FALSE;
  265. PUBLIC
  266. void
  267. INTL_MessageSendToNews(XP_Bool toNews)
  268. {
  269.     intl_message_to_newsgroup = toNews;
  270. }
  271.  
  272.  
  273.  
  274. PUBLIC
  275. CCCDataObject
  276. INTL_CreateDocToMailConverter(iDocumentContext context, XP_Bool isHTML, unsigned char *buffer, uint32 buffer_size)
  277. {
  278.       CCCDataObject selfObj;
  279.       int16 p_doc_csid = CS_DEFAULT;
  280.       CCCFunc cvtfunc;
  281.     INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(context);
  282.  
  283.       /* Ok!! let's create the object here
  284.          We need the conversion obj to keep the state information */
  285.       selfObj = INTL_CreateCharCodeConverter();
  286.       if(selfObj == NULL)
  287.            return NULL;
  288.  
  289.               /* First, let's determine the from_csid and to_csid */
  290.               /* It is a TEXT_HTML !!! Let's use our PeekMetaCharsetTag to get a csid */
  291.       if(isHTML)
  292.                p_doc_csid = PeekMetaCharsetTag((char*) buffer, buffer_size);
  293.  
  294.       if(p_doc_csid == CS_DEFAULT)
  295.       {
  296.               /* got default, try to get the doc_csid from context */
  297.               if((context == 0 ) || (INTL_GetCSIDocCSID(c) == CS_DEFAULT))
  298.                       p_doc_csid = INTL_DefaultDocCharSetID(context);
  299.               else
  300.                       p_doc_csid = INTL_GetCSIDocCSID(c);
  301. #ifdef XP_MAC   
  302.             /* To Make Macintosh happe when there is a HTML Mail composer send
  303.                out plain text file. It put the MacRoman text into the temp file and then let this 
  304.                function load it. Because I change the mac version of INTL_DefaultDocCharSetID() so now
  305.                it listen to the front window to tell me which doc csid it is. It is Latin1 in the
  306.                case email. But the data is really MacRoman. So we add this hack here. Which only change
  307.                the doccsid if it is not HTML
  308.              */ 
  309.                               
  310.             if(! isHTML)
  311.             {
  312.                 switch(p_doc_csid)
  313.                 {
  314.                     case CS_LATIN1:
  315.                         p_doc_csid = CS_MAC_ROMAN; 
  316.                         break;
  317.                     case CS_LATIN2:
  318.                         p_doc_csid = CS_MAC_CE; 
  319.                         break;
  320.                     case CS_8859_5:
  321.                     case CS_KOI8_R:
  322.                         p_doc_csid = CS_MAC_CYRILLIC; 
  323.                         break;
  324.                     case CS_8859_7:
  325.                         p_doc_csid = CS_MAC_GREEK; 
  326.                         break;
  327.                     case CS_8859_9:
  328.                         p_doc_csid = CS_MAC_TURKISH; 
  329.                         break;
  330.                     default:
  331.                         break;
  332.                 }
  333.             } 
  334. #endif
  335.  
  336.               /* The doc_csid from the context (or default) has CS_AUTO bit. */
  337.               /* So let's try to call the auto detection function */
  338.               /* ftang add this: The CS_AUTO is still buggy, */
  339.               if(
  340.                   (CS_JIS == p_doc_csid) || (CS_SJIS == p_doc_csid) || (CS_EUCJP == p_doc_csid) ||
  341.                   (CS_KSC_8BIT == p_doc_csid) || (CS_2022_KR == p_doc_csid)  ||
  342.                   (CS_JIS_AUTO == p_doc_csid) || (CS_SJIS_AUTO == p_doc_csid) || (CS_EUCJP_AUTO == p_doc_csid) ||
  343.                   (CS_KSC_8BIT_AUTO == p_doc_csid) /* || (CS_2022_KR_AUTO == p_doc_csid) */                  
  344.                 )
  345.               {
  346.                  uint16 default_csid = INTL_DefaultDocCharSetID(context);
  347.  
  348.                  switch(p_doc_csid & ~CS_AUTO)
  349.                  {
  350.                      case CS_JIS:
  351.                      case CS_SJIS:
  352.                      case CS_EUCJP:
  353.                           p_doc_csid = intl_detect_JCSID((uint16)(default_csid&~CS_AUTO), buffer, buffer_size);
  354.                           break;
  355.                      case CS_KSC_8BIT:
  356.                      case CS_2022_KR:
  357.                           p_doc_csid = intl_detect_KCSID((uint16)(default_csid&~CS_AUTO), buffer, buffer_size);
  358.                           break;
  359.                      /* Probably need to take care UCS2 / UTF8 and UTF7 here */
  360.                      case CS_BIG5:
  361.                      case CS_CNS_8BIT:
  362.                      case CS_UTF8:
  363.                      case CS_UTF7:
  364.                      case CS_UCS2:
  365.                      case CS_UCS2_SWAP:
  366.                      default:
  367.                          XP_ASSERT(FALSE);
  368.                  }
  369.               }
  370.       }
  371.       /* Now, we get the converter */
  372.       (void) INTL_GetCharCodeConverter(p_doc_csid, 
  373. #ifdef MOZ_MAIL_NEWS
  374.                                        (intl_message_to_newsgroup ? 
  375.                                         INTL_DefaultNewsCharSetID(p_doc_csid) :
  376.                                         INTL_DefaultMailCharSetID(p_doc_csid)), 
  377. #else /* must be MOZ_MAIL_COMPOSE */
  378.                                         INTL_DefaultMailCharSetID(p_doc_csid), 
  379. #endif /* MOZ_MAIL_NEWS */
  380.                                        selfObj);
  381.       /* If the cvtfunc == NULL, we don't need to do conversion */
  382.       cvtfunc = INTL_GetCCCCvtfunc(selfObj);
  383.       if(! (cvtfunc) )
  384.       {
  385.                 XP_FREE(selfObj);
  386.               return NULL;
  387.       }
  388.       else
  389.               return selfObj;
  390. }
  391.  
  392. #endif /* MOZ_MAIL_COMPOSE */
  393.