home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libi18n / net_junk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  10.0 KB  |  344 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. /*    net_junk.c    */
  19.  
  20. /*#include "intlpriv.h"*/
  21. #include "xp.h"
  22. #include "intl_csi.h"
  23. #include "libi18n.h"
  24. #include "net_junk.h"
  25. #include "libmocha.h"
  26.  
  27.  
  28. MODULE_PRIVATE int16    PeekMetaCharsetTag (char *, uint32);
  29. MODULE_PRIVATE int16    DetectUCS2 (CCCDataObject, unsigned char *, int32);
  30.  
  31. typedef struct {
  32.     Stream *current_stream;
  33.     Stream *next_stream;
  34.     CCCDataObject obj;
  35. } NetStreamData;
  36.  
  37. extern unsigned char *One2OneCCC(CCCDataObject,unsigned char *,int32);
  38. PRIVATE int net_AutoCharCodeConv (NET_StreamClass *stream, const char *s, int32 l);
  39. PRIVATE int net_1to1CCC (NET_StreamClass *stream, const unsigned char *s, int32 l);
  40.  
  41. PRIVATE void net_CvtCharCodeComplete (NET_StreamClass *stream)
  42. {
  43.     NetStreamData *nsd=stream->data_object;
  44.     unsigned char *uncvtbuf;    
  45.  
  46.     uncvtbuf = INTL_GetCCCUncvtbuf(nsd->obj);
  47.  
  48.     /* pass downstream any uncoverted characters */
  49.     if (uncvtbuf[0] != '\0')
  50.         (*nsd->next_stream->put_block)(nsd->next_stream,
  51.         (const char *)uncvtbuf, strlen((char *)uncvtbuf));
  52.  
  53.     (*nsd->next_stream->complete)(nsd->next_stream);
  54.  
  55.     XP_FREE(nsd->next_stream);
  56.     XP_FREE(nsd->obj);
  57.     XP_FREE(nsd);
  58.     return;
  59. }
  60.  
  61. PRIVATE void net_CvtCharCodeAbort (NET_StreamClass *stream, int status)
  62. {
  63.     NetStreamData *nsd=stream->data_object;    
  64.     (*nsd->next_stream->abort)(nsd->next_stream, status);
  65.  
  66.     XP_FREE(nsd->next_stream);
  67.     XP_FREE(nsd->obj);
  68.     XP_FREE(nsd);
  69.  
  70.     return;
  71. }
  72.  
  73. PRIVATE int
  74. net_CharCodeConv(    NET_StreamClass *stream,
  75.                     const unsigned char    *buf,    /* buffer for conversion    */
  76.                     int32                bufsz)    /* buffer size in bytes        */
  77. {
  78.     NetStreamData *nsd=stream->data_object;
  79.     unsigned char    *tobuf;
  80.     int                rv;
  81.     CCCFunc cvtfunc;    
  82.  
  83.     cvtfunc = INTL_GetCCCCvtfunc(nsd->obj);
  84.  
  85.     tobuf = (unsigned char *)cvtfunc(nsd->obj, buf, bufsz);
  86.  
  87.     if (tobuf) {
  88.         rv = (*nsd->next_stream->put_block) (nsd->next_stream,
  89.                         (const char *)tobuf, INTL_GetCCCLen(nsd->obj));
  90.         if (tobuf != buf)
  91.             XP_FREE(tobuf);
  92.         return(rv);
  93.     } else {
  94.         return(INTL_GetCCCRetval(nsd->obj));
  95.     }
  96. }
  97.  
  98.     /* Null Char Code Conversion module -- pass unconverted data downstream    */
  99. /* PRIVATE */ int
  100. net_NoCharCodeConv (NET_StreamClass *stream, const char *s, int32 l)
  101. {
  102.     NetStreamData*nsd=stream->data_object;    
  103.     return((*nsd->next_stream->put_block)(nsd->next_stream,s,l));
  104. }
  105.  
  106. PRIVATE int
  107. net_AutoCharCodeConv (NET_StreamClass *stream, const char *s, int32 l)
  108. {
  109.     NetStreamData*nsd=stream->data_object;
  110.     int16    doc_csid;
  111.     unsigned char    *tobuf = NULL;
  112.     int                rv;
  113.     CCCFunc cvtfunc;
  114.  
  115.     cvtfunc = INTL_GetCCCCvtfunc(nsd->obj);
  116.  
  117. /* for debugging -- erik */
  118. #if 0
  119.     {
  120.         static FILE *f = NULL;
  121.  
  122.         if (!f)
  123.         {
  124.             f = fopen("/tmp/zzz", "w");
  125.         }
  126.  
  127.         if (f && s && (l > 0))
  128.         {
  129.             (void) fwrite(s, 1, l, f);
  130.         }
  131.     }
  132. #endif /* 0 */
  133.  
  134.     if (cvtfunc != NULL)
  135.         tobuf = (unsigned char *)cvtfunc(nsd->obj, (unsigned char *)s, l);
  136.     else
  137.     {
  138.         /* Look at the first block and see if we determine
  139.          * what the charset is from that block.
  140.          */
  141.  
  142.         /*  Somehow NET_PlainTextConverter() put a "<plaintext>" in the
  143.             first block. Try to bypass that block
  144.             We need this so we can detect UCS2 for the NT UCS2 plantext
  145.         */
  146.         if((l == 11) && (strncmp(s, "<plaintext>", 11)==0))
  147.         {
  148.             return((*nsd->next_stream->put_block)(nsd->next_stream,s,l));
  149.         } 
  150.         /* check for unicode (ucs2) */
  151.         doc_csid = DetectUCS2(nsd->obj, (unsigned char *)s, l);
  152.          if(doc_csid == CS_DEFAULT)
  153.         {
  154.             doc_csid = PeekMetaCharsetTag((char *)s, l) ;
  155.             if (doc_csid == CS_ASCII) /* the header said ascii. */
  156.             {
  157.                 nsd->current_stream->put_block = (MKStreamWriteFunc) net_NoCharCodeConv;
  158.                 return((*nsd->next_stream->put_block)(nsd->next_stream,s,l));
  159.             }
  160.         }
  161.  
  162.         /* We looked at the first block but did not determine
  163.          * what the charset is.  Install the default converter
  164.          * now.  It could be a standard or an auto-detecting converter.
  165.          */
  166.         if (doc_csid != CS_DEFAULT)
  167.         {
  168.             (void) INTL_GetCharCodeConverter(doc_csid, 0, nsd->obj);
  169.             INTL_CallCCCReportAutoDetect(nsd->obj, doc_csid);
  170.         }
  171.         else
  172.             (void) INTL_GetCharCodeConverter(INTL_GetCCCDefaultCSID(nsd->obj),0,nsd->obj);
  173.         cvtfunc = INTL_GetCCCCvtfunc(nsd->obj);
  174.  
  175.         /* If no conversion needed, change put_block module for successive
  176.          * data blocks.  For current data block, return unmodified buffer.
  177.          */
  178.         if (cvtfunc == NULL) 
  179.         {
  180.             return((*nsd->next_stream->put_block)(nsd->next_stream,s,l));
  181.         }
  182.  
  183.         /* For initial block, must call converter directly.  Success calls
  184.          * to the converter will be called directly from net_CharCodeConv()
  185.          */
  186.     }
  187.  
  188.     if (tobuf == NULL)
  189.         tobuf = (unsigned char *)cvtfunc(nsd->obj, (unsigned char *)s, l);
  190.  
  191.     if (tobuf) {
  192.         rv = (*nsd->next_stream->put_block) (nsd->next_stream,
  193.             (const char *)tobuf, INTL_GetCCCLen(nsd->obj));
  194.         if (tobuf != (unsigned char*)s)
  195.             XP_FREE(tobuf);
  196.         return(rv);
  197.     } else {
  198.         return(INTL_GetCCCRetval(nsd->obj));
  199.     }
  200. }
  201.  
  202.     /* One-byte-to-one-byte Char Code Conversion module.
  203.      * Table driven.  Table provided by FE.
  204.      */
  205. PRIVATE int
  206. net_1to1CCC (NET_StreamClass *stream, const unsigned char *s, int32 l)
  207. {
  208.     NetStreamData *nsd=stream->data_object;    
  209.     (void) One2OneCCC (nsd->obj, (unsigned char *)s, l);
  210.     return((*nsd->next_stream->put_block)(nsd->next_stream,
  211.                                 (const char *)s, INTL_GetCCCLen(nsd->obj)));
  212. }
  213.  
  214.  
  215. /*
  216.  * We are always ready for writing, but the next stream might not
  217.  *   be so, since we aren't willing to buffer, tell netlib the
  218.  *   next stream's buffer size
  219.  */
  220. PRIVATE unsigned int net_CvtCharCodeWriteReady (NET_StreamClass *stream)
  221. {
  222.     NetStreamData *nsd=stream->data_object;    
  223.     return ((*nsd->next_stream->is_write_ready)(nsd->next_stream));
  224. }
  225.  
  226. PRIVATE void
  227. net_report_autodetect(void *closure, CCCDataObject obj, uint16 doc_csid)
  228. {
  229.     NetStreamData *nsd = (NetStreamData *)closure;
  230.     iDocumentContext  doc_context = nsd->current_stream->window_id;
  231.     CCCFunc cvtfunc = INTL_GetCCCCvtfunc(obj);
  232.     INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(doc_context);
  233.  
  234.     INTL_SetCSIDocCSID(c, doc_csid);
  235.     /* I hope it is okay, to set the win_csid */
  236.     INTL_SetCSIWinCSID(c, INTL_GetCCCToCSID(obj));
  237.     if (cvtfunc == NULL)
  238.         nsd->current_stream->put_block = (MKStreamWriteFunc) net_NoCharCodeConv;
  239. }
  240.  
  241. PUBLIC Stream *
  242. INTL_ConvCharCode (int         format_out,
  243.                          void       *data_obj,
  244.                          URL_Struct *URL_s,
  245.                          MWContext  *mwcontext)
  246. {
  247.     NetStreamData *nsd;
  248.     CCCDataObject    obj;
  249.     Stream *stream;
  250.     iDocumentContext doc_context = (iDocumentContext)mwcontext;
  251.     INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(doc_context);
  252.     XP_Bool is_metacharset_reload;
  253.     uint16 default_doc_csid = INTL_DefaultDocCharSetID(mwcontext);
  254. /*
  255.     Should this be ?
  256.     uint16 default_doc_csid = FE_DefaultDocCharSetID(mwcontext);
  257. */
  258.  
  259.  
  260.     TRACEMSG(("Setting up display stream. Have URL: %s\n", URL_s->address));
  261.  
  262.     stream = XP_NEW_ZAP(Stream);
  263.     if(stream == NULL)
  264.         return(NULL);
  265.  
  266.     stream->name           = "CharCodeConverter";
  267.     stream->complete       = (MKStreamCompleteFunc) net_CvtCharCodeComplete;
  268.     stream->abort          = (MKStreamAbortFunc) net_CvtCharCodeAbort;
  269.  
  270.     stream->is_write_ready = (MKStreamWriteReadyFunc) net_CvtCharCodeWriteReady;
  271.     stream->window_id      = doc_context;
  272.  
  273.     /* initialize the doc_csid (etc.) unless if this is a reload caused by meta charset */
  274.     if ((NET_RESIZE_RELOAD == URL_s->resize_reload) 
  275.         && (METACHARSET_FORCERELAYOUT == INTL_GetCSIRelayoutFlag(c)))
  276.         is_metacharset_reload = TRUE;
  277.     else
  278.         is_metacharset_reload = FALSE;
  279.  
  280.     INTL_CSIInitialize(c, is_metacharset_reload, URL_s->charset,
  281.                         mwcontext->type, default_doc_csid);
  282.  
  283.     obj = INTL_CreateDocumentCCC(c, default_doc_csid);
  284.     if (obj == NULL) {
  285.         XP_FREE(stream);
  286.         return(NULL);
  287.     }
  288.  
  289.     nsd = XP_NEW_ZAP(NetStreamData);
  290.     if(nsd == NULL) {
  291.         XP_FREE(stream);
  292.         XP_FREE(obj);
  293.         return(NULL);
  294.     }
  295.     nsd->current_stream = stream;
  296.     nsd->obj = obj;
  297.     stream->data_object = nsd;  /* document info object */
  298.     INTL_SetCCCReportAutoDetect(obj, net_report_autodetect, nsd);
  299.  
  300.  
  301.     if (INTL_GetCSIDocCSID(c) == CS_DEFAULT || INTL_GetCSIDocCSID(c) == CS_UNKNOWN)
  302.     {
  303.         /* we know the default converter but do not install it yet. 
  304.          * Instead wait until the first block and see if we can determine
  305.          * what the actual charset is from http/meta tags or from the 
  306.          * first block. By delaying we can avoid a reload if
  307.          * we get a different charset from http/meta tag or the first block.
  308.          */
  309.         stream->put_block    = (MKStreamWriteFunc) net_AutoCharCodeConv;
  310.     }
  311.     else
  312.     {
  313.         if (INTL_GetCCCCvtfunc(obj) == NULL)
  314.             stream->put_block    = (MKStreamWriteFunc) net_NoCharCodeConv;
  315.         else if (INTL_GetCCCCvtfunc(obj) == (CCCFunc)One2OneCCC)
  316.             stream->put_block    = (MKStreamWriteFunc) net_1to1CCC;
  317.         else
  318.             stream->put_block    = (MKStreamWriteFunc) net_CharCodeConv;
  319.     }
  320.  
  321.     TRACEMSG(("Returning stream from NET_CvtCharCodeConverter\n"));
  322.     
  323.     /* remap content type to be to INTERNAL_PARSER
  324.       */
  325.     StrAllocCopy(URL_s->content_type, INTERNAL_PARSER);
  326.  
  327. #ifdef JSDEBUGGER
  328.     nsd->next_stream = LM_StreamBuilder(format_out, NULL, URL_s, mwcontext);
  329. #else
  330.     nsd->next_stream = NET_StreamBuilder(format_out, URL_s, doc_context);
  331. #endif /* JSDEBUGGER */
  332.  
  333.     if(!nsd->next_stream)
  334.       {
  335.         XP_FREE(obj);
  336.         XP_FREE(stream);
  337.         XP_FREE(nsd);
  338.         return(NULL);
  339.       }
  340.  
  341.     return stream;
  342. }
  343.  
  344.