home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libi18n / intl_csi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  9.5 KB  |  400 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. /*    intl_csi.c    International Character Set Information
  19.  *
  20.  * This file contains the INTL_CSI accessor functions
  21.  *
  22.  * This allows the i18n character set data to be
  23.  * changed without (hopefully) changing all the
  24.  * code that accesses it.
  25.  *
  26.  * UNFORTUNATELY, as of this date Oct. 28, 1996
  27.  * there is not document context so we are still 
  28.  * using the old MWContext.
  29.  * When this is fix all that is needed should
  30.  * be change the USE_REAL_DOCUMENT_CONTEXT flag 
  31.  * and recompile (and test of course).
  32.  */
  33.  
  34. #include "intlpriv.h"
  35. #include "xp.h"
  36. #include "libi18n.h"
  37. #include "intl_csi.h"
  38.  
  39. struct OpaqueINTL_CharSetInfo {
  40.     uint16 doc_csid;
  41.     uint16 http_doc_csid;
  42.     uint16 meta_doc_csid;
  43.     uint16 override_doc_csid;
  44.     uint16 win_csid;
  45.     unsigned char *mime_charset;
  46.     int relayout;
  47. };
  48.  
  49. typedef enum
  50. {
  51.     OVERRIDE_CSID_TYPE,
  52.     HTTP_CSID_TYPE,
  53.     META_CSID_TYPE,
  54.     DOC_CSID_TYPE
  55. } CsidType;
  56.  
  57. PRIVATE uint16 get_charset_tag(char *charset_tag);
  58.  
  59. /*
  60.  *
  61.  *    Setup the character set info
  62.  *
  63.  */
  64. void
  65. INTL_CSIInitialize(INTL_CharSetInfo c, XP_Bool is_metacharset_reload, 
  66.                    char *http_charset, int doc_type, uint16 default_doc_csid)
  67. {
  68.     uint16 http_doc_csid = get_charset_tag(http_charset);
  69.     uint16 win_csid;
  70.  
  71.     XP_ASSERT(NULL != c);
  72.     /*
  73.      * Initiliaze the Character-Set-Info (CSI)
  74.      * (unless if we are doing a meta_charset_reload)
  75.      */
  76.     if (!is_metacharset_reload)
  77.         INTL_CSIReset(c);
  78.  
  79.     /*
  80.      * Setup the CSI with the information we currently know
  81.      */
  82.  
  83.     /* first check if this is a metacharset reload */
  84.     if (is_metacharset_reload)
  85.     {
  86.         INTL_SetCSIRelayoutFlag(c, METACHARSET_RELAYOUTDONE);
  87.     }
  88.     /* Check for a doc csid override */
  89.     else if (DOC_CSID_KNOWN(INTL_GetCSIOverrideDocCSID(c)))
  90.     {
  91.         INTL_SetCSIDocCSID(c, INTL_GetCSIOverrideDocCSID(c));
  92.     }
  93.     /* if we have a HTTP charset tag then use it */
  94.     else if (DOC_CSID_KNOWN(http_doc_csid))
  95.     {
  96.         INTL_SetCSIHTTPDocCSID(c, http_doc_csid);
  97.     } 
  98.     else /* normal case */
  99.     {
  100.         uint16 init_doc_csid = default_doc_csid;
  101.         /*
  102.          * mail/news sometimes has the wrong meta charset
  103.          * so for mail/news we always ignore the meta charset tag
  104.          * which causes us to use the encoding the user set in the
  105.          * encoding menu
  106.          */
  107.         if (!(MAIL_NEWS_TYPE(doc_type)))
  108.             init_doc_csid = CS_DEFAULT;
  109.  
  110. #ifdef XP_UNIX
  111.         /*
  112.          * The PostScript and Text FEs inherit the doc_csid from
  113.          * the parent context in order to pick up the per-window
  114.          * default. Apparently, this already works for some
  115.          * reason on Windows. Don't know about Mac. -- erik
  116.          */
  117.         if ((doc_type != MWContextPostScript) &&
  118.             (doc_type != MWContextText))
  119. #endif /* XP_UNIX */
  120.             INTL_SetCSIDocCSID(c, init_doc_csid /*CS_DEFAULT*/ );
  121.     }
  122.  
  123.     /*
  124.      * alot of code (parsing/layout/FE) wants to know
  125.      * the encoding so we must set something
  126.      */
  127.     if (DOC_CSID_KNOWN(INTL_GetCSIDocCSID(c)))
  128.         win_csid = INTL_DocToWinCharSetID(INTL_GetCSIDocCSID(c));
  129.     else
  130.         win_csid = INTL_DocToWinCharSetID(default_doc_csid);
  131.     INTL_SetCSIWinCSID(c, win_csid); /* true until we know otherwise */
  132. }
  133.  
  134. PRIVATE void
  135. set_csid(INTL_CharSetInfo c, uint16 csid, CsidType type)
  136. {
  137.     XP_ASSERT(NULL != c);
  138.  
  139.     if (OVERRIDE_CSID_TYPE == type)
  140.     {
  141.         c->override_doc_csid = csid;
  142.         c->doc_csid = csid;
  143.     }
  144.     else if (HTTP_CSID_TYPE == type)
  145.     {
  146.         c->http_doc_csid = csid;
  147.         if (CS_DEFAULT == c->override_doc_csid)
  148.             c->doc_csid = csid;
  149.     }
  150.     else if (META_CSID_TYPE == type)
  151.     {
  152.         c->meta_doc_csid = csid;
  153.         if (   (CS_DEFAULT == c->override_doc_csid)
  154.             && (CS_DEFAULT == c->http_doc_csid))
  155.             c->doc_csid = csid;
  156.     }
  157.     else if (DOC_CSID_TYPE == type)
  158.     {
  159.         if (   (CS_DEFAULT == c->override_doc_csid)
  160.             && (CS_DEFAULT == c->http_doc_csid)
  161.             && (CS_DEFAULT == c->meta_doc_csid))
  162.             c->doc_csid = csid;
  163.     }
  164.     else
  165.     {
  166.         XP_ASSERT(0);
  167.     }
  168. }
  169.  
  170. void
  171. INTL_CSIReportMetaCharsetTag(INTL_CharSetInfo c, char *charset_tag, int type)
  172. {
  173.     int16 doc_csid;
  174.  
  175.     XP_ASSERT(charset_tag);
  176.     doc_csid = INTL_CharSetNameToID(charset_tag);
  177.  
  178.     /* ignore invalid tags */
  179.     if (doc_csid == CS_UNKNOWN)
  180.         return;
  181.  
  182.     /* mail and news ignores meta charset tags since some are wrong */
  183.     if (MAIL_NEWS_TYPE(type))
  184.         return;
  185.  
  186.     /* only honor the first (meta or http) charset tag */
  187.     if (INTL_GetCSIRelayoutFlag(c) == METACHARSET_NONE)
  188.     {
  189.         uint16 old_doc_csid = INTL_GetCSIDocCSID(c);
  190.  
  191.         INTL_SetCSIMetaDocCSID(c, doc_csid);
  192.         /* ignore subsequent meta charset tags */
  193.         INTL_SetCSIRelayoutFlag(c, METACHARSET_HASCHARSET);
  194.  
  195.         /* 
  196.          * if we already set up the converter wrong we have to reload
  197.          */
  198.         if (DOC_CSID_KNOWN(old_doc_csid)
  199.             && ((old_doc_csid & ~CS_AUTO) != doc_csid))
  200.             INTL_SetCSIRelayoutFlag(c, METACHARSET_REQUESTRELAYOUT);
  201.         /*
  202.          * if we told the FE the wrong win_csid we have to reload
  203.          * (we had to tell the FE something so it could do layout
  204.          *  while we were looking for the metacharset tag)
  205.          */
  206.         else if (INTL_DocToWinCharSetID(doc_csid) != INTL_GetCSIWinCSID(c))
  207.             INTL_SetCSIRelayoutFlag(c, METACHARSET_REQUESTRELAYOUT);
  208.     }
  209. }
  210.  
  211. PRIVATE uint16 get_charset_tag(char *charset_tag)
  212. {
  213.     uint16 csid;
  214.  
  215.     /* validate the http_charset */
  216.     if ((NULL == charset_tag) || ('\0' == *charset_tag))
  217.         return CS_UNKNOWN;
  218.  
  219.     csid = INTL_CharSetNameToID(charset_tag);
  220.  
  221.     if (CS_DEFAULT == csid)
  222.         csid = CS_UNKNOWN;
  223.  
  224.     return csid;
  225. }
  226.  
  227.  
  228. INTL_CharSetInfo 
  229. LO_GetDocumentCharacterSetInfo(MWContext *context)
  230. {
  231.     XP_ASSERT(context);
  232.     XP_ASSERT(INTL_TAG == context->INTL_tag);
  233.     XP_ASSERT(NULL != context->INTL_CSIInfo);
  234.     return(context->INTL_CSIInfo);
  235. }
  236.  
  237.  
  238. INTL_CharSetInfo
  239. INTL_CSICreate(void)
  240. {
  241.     INTL_CharSetInfo c;
  242.  
  243. #if (defined(DEBUG_bstell) || defined(DEBUG_nhotta) || defined(DEBUG_ftang))
  244. #define BSTELLS_FREE_TRICK_OFFSET 64
  245.     /* I use (abuse) the malloc system to find improper frees */
  246.     {
  247.         char *p;
  248.         p = (char *)XP_CALLOC(1, 
  249.             BSTELLS_FREE_TRICK_OFFSET+sizeof(struct OpaqueINTL_CharSetInfo));
  250.         c = (INTL_CharSetInfo)(p + BSTELLS_FREE_TRICK_OFFSET);
  251.     }
  252. #else
  253.     c = (INTL_CharSetInfo)XP_CALLOC(1, sizeof(struct OpaqueINTL_CharSetInfo));
  254. #endif
  255.     return c;
  256. }
  257.  
  258. void
  259. INTL_CSIDestroy(INTL_CharSetInfo c)
  260. {
  261.     XP_ASSERT(c);
  262. #if (defined(DEBUG_bstell) || defined(DEBUG_nhotta) || defined(DEBUG_ftang))
  263.     {
  264.         char *p = (char *)c;
  265.         XP_FREE(p - BSTELLS_FREE_TRICK_OFFSET);
  266.     }
  267. #else
  268.     XP_FREE(c);
  269. #endif
  270. }
  271.  
  272. void
  273. INTL_CSIReset(INTL_CharSetInfo c)
  274. {
  275.     INTL_SetCSIOverrideDocCSID (c, CS_DEFAULT);
  276.     INTL_SetCSIHTTPDocCSID     (c, CS_DEFAULT);
  277.     INTL_SetCSIMetaDocCSID     (c, CS_DEFAULT);
  278.     INTL_SetCSIDocCSID         (c, CS_DEFAULT);
  279.     INTL_SetCSIWinCSID         (c, CS_DEFAULT);
  280.     INTL_SetCSIMimeCharset(c, NULL);
  281.     INTL_SetCSIRelayoutFlag(c, METACHARSET_NONE);
  282. }
  283.  
  284. /* ----------- CSI CSID ----------- */
  285. /*  Override is strongest. Must set doc_csid */
  286. void
  287. INTL_SetCSIOverrideDocCSID (INTL_CharSetInfo c, int16 doc_csid)
  288. {
  289.     set_csid(c, doc_csid, OVERRIDE_CSID_TYPE);
  290. }
  291.  
  292. /*  Next strongest. Set doc_csid if no override */
  293. void
  294. INTL_SetCSIHTTPDocCSID (INTL_CharSetInfo c, int16 doc_csid)
  295. {
  296.     set_csid(c, doc_csid, HTTP_CSID_TYPE);
  297. }
  298.  
  299. /*  Next strongest. Set doc_csid if no override */
  300. void
  301. INTL_SetCSIMetaDocCSID (INTL_CharSetInfo c, int16 doc_csid)
  302. {
  303.     set_csid(c, doc_csid, META_CSID_TYPE);
  304. }
  305.  
  306. /*  Meta charset is weakest. Only set doc_csid if no http or override */
  307. void
  308. INTL_SetCSIDocCSID (INTL_CharSetInfo c, int16 doc_csid)
  309. {
  310.     set_csid(c, doc_csid, DOC_CSID_TYPE);
  311. }
  312.  
  313. int16
  314. INTL_GetCSIDocCSID(INTL_CharSetInfo c)
  315. {
  316.     XP_ASSERT(c);
  317.     return c->doc_csid;
  318. }
  319.  
  320. int16
  321. INTL_GetCSIMetaDocCSID(INTL_CharSetInfo c)
  322. {
  323.     XP_ASSERT(c);
  324.     return c->meta_doc_csid;
  325. }
  326.  
  327. int16
  328. INTL_GetCSIOverrideDocCSID(INTL_CharSetInfo c)
  329. {
  330.     XP_ASSERT(c);
  331.     return c->override_doc_csid;
  332. }
  333.  
  334. /* ----------- Window CSID ----------- */
  335.  
  336. void
  337. INTL_SetCSIWinCSID(INTL_CharSetInfo c, int16 win_csid)
  338. {
  339.     XP_ASSERT(c);
  340.     c->win_csid = win_csid;
  341. }
  342.  
  343. int16
  344. INTL_GetCSIWinCSID(INTL_CharSetInfo c)
  345. {
  346.     XP_ASSERT(c);
  347.     return c->win_csid;
  348. }
  349.  
  350. /* ----------- Mime CSID ----------- */
  351. char *
  352. INTL_GetCSIMimeCharset (INTL_CharSetInfo c)
  353. {
  354.     XP_ASSERT(c);
  355.     return (char *)c->mime_charset;
  356. }
  357.  
  358. void
  359. INTL_SetCSIMimeCharset(INTL_CharSetInfo c, char *mime_charset)
  360. {
  361.     unsigned char *p;
  362.     XP_ASSERT(c);
  363.  
  364.     if (c->mime_charset)
  365.     {
  366.         XP_FREE(c->mime_charset);
  367.         c->mime_charset = NULL;
  368.     }
  369.  
  370.     if (NULL == mime_charset)
  371.         return;
  372.  
  373.     c->mime_charset = (unsigned char *)XP_STRDUP(mime_charset);
  374.     if (NULL == c->mime_charset)
  375.         return;
  376.  
  377.     /* Legitimate charset names must be in ASCII and case insensitive    */
  378.     /* convert to lower case */
  379.     for (p=c->mime_charset; *p; p++)
  380.         *p = tolower(*p);
  381.     return;
  382. }
  383.  
  384. /* ----------- Relayout Flag ----------- */
  385. int16
  386. INTL_GetCSIRelayoutFlag(INTL_CharSetInfo c)
  387. {
  388.     XP_ASSERT(c);
  389.     return c->relayout;
  390. }
  391.  
  392. void
  393. INTL_SetCSIRelayoutFlag(INTL_CharSetInfo c, int16 relayout)
  394. {
  395.     XP_ASSERT(c);
  396.     c->relayout = relayout;
  397. }
  398.  
  399.  
  400.