home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libi18n / is2euckr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  6.1 KB  |  188 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. /*    is2euckr.c    */
  19.  
  20. #include "intlpriv.h"
  21.  
  22.  
  23. extern int MK_OUT_OF_MEMORY;
  24.  
  25.  
  26. /* net_iso2euckr(obj, isobuf, isobufsz, uncvtbuf)
  27.  * Args:
  28.  *    isobuf:        Ptr to a buf of iso-2022-kr chars
  29.  *    isobufsz:    Size in bytes of isobuf
  30.  *    jismode:    Ptr to encoding mode, use as arg for next call to
  31.  *        mz_iso2euckr() for rest of current 2022-kr data.  First call should
  32.  *        initialize mode to ASCII (0).                    
  33.  *    uncvtbuf:    If entire buffer was converted, uncvtbuf[0] will be nul,
  34.  *        else this points to iso-2022-kr chars that were NOT converted
  35.  *        and mz_iso2euckr() with additional iso-2022-kr chars appended.
  36.  * Return:
  37.  *    Returns NULL on failure, otherwise it returns a pointer to a buffer of
  38.  *    converted EUC-KR characters.  Caller must XP_FREE() this memory.
  39.  *
  40.  * Description:
  41.  *
  42.  *    Allocate destination buffer (for EUC-KR).
  43.  *
  44.  *    Set mode state based upon ESC sequence and SO/SI.
  45.  *
  46.  *  If mode is KSC 5601, set 8th bits of next 2 bytes.
  47.  *
  48.  *    If any other mode, then assume ASCII and strip the 8th bit.
  49.  *
  50.  *    If either 2022-kr buffer does not contain complete char or EUC-KR buffer
  51.  *    is full, then return unconverted 2022-kr to caller.  Caller should
  52.  *    append more data and recall mz_iso2euckr.
  53.  */
  54.  
  55.  
  56. MODULE_PRIVATE unsigned char *
  57. mz_iso2euckr(    CCCDataObject        obj,
  58.             const unsigned char    *isobuf,    /* 2022-kr buffer for conversion */
  59.             int32                isobufsz)    /* 2022-kr buffer size in bytes    */
  60. {
  61.      unsigned char            *tobuf = NULL;
  62.      int32                    tobufsz;
  63.      unsigned char    *tobufp, *isop;        /* current byte in bufs    */
  64.      unsigned char    *tobufep, *isoep;    /* end of buffers        */
  65.      int32                    uncvtlen;
  66.     unsigned char *uncvtbuf = INTL_GetCCCUncvtbuf(obj);
  67.  
  68. #define euckrbufsz    tobufsz
  69. #define euckrbuf        tobuf
  70. #define euckrp        tobufp
  71. #define euckrep        tobufep
  72.                                          /* Allocate a dest buffer:        */
  73.         /* 2022-kr is usually longer than EUC-KR because of ESC seq.
  74.          *
  75.          * In the worst case (all ASCII), converted EUC-KR will be the same
  76.          * length as the original 2022-kr + 1 for nul byte
  77.          */
  78.     uncvtlen = strlen((char *)uncvtbuf);
  79.     tobufsz = isobufsz + uncvtlen + 1;
  80.  
  81.     if (!tobufsz) {
  82.         return NULL;
  83.     }
  84.  
  85.     if ((tobuf = (unsigned char *)XP_ALLOC(tobufsz)) == (unsigned char *)NULL) {
  86.         INTL_SetCCCRetval(obj, MK_OUT_OF_MEMORY);
  87.         return(NULL);
  88.     }
  89.                                         /* Initialize pointers, etc.    */
  90.      isop = (unsigned char *)isobuf;
  91.      isoep = isop + isobufsz - 1;
  92.  
  93. #define uncvtp    tobufp    /* use tobufp as temp */                  
  94.                             /* If prev. unconverted chars, append unconverted
  95.                              * chars w/new chars and try to process.
  96.                              */
  97.      if (uncvtbuf[0] != '\0') {
  98.          uncvtp = uncvtbuf + uncvtlen;
  99.          while (uncvtp < (uncvtbuf + UNCVTBUF_SIZE) &&
  100.                                                         isop <= isoep)
  101.              *uncvtp++ = *isop++;
  102.          *uncvtp = '\0';                        /* nul terminate    */
  103.          isop = uncvtbuf;                /* process unconverted first */
  104.          isoep = uncvtp - 1;
  105.      }
  106. #undef uncvtp
  107.      
  108.      tobufp = tobuf;
  109.      tobufep = tobufp + tobufsz - 2;        /* save space for terminating null */
  110.      
  111. WHILELOOP:     
  112.     INTL_SetCCCJismode(obj, KSC_5601_87);  /* jliu doesn't want to change Tony's code too much*/
  113.                             /* While 2022-kr data && space in EUC-KR buf. */
  114.      while ((tobufp <= tobufep) && (isop <= isoep)) {
  115.  
  116.         if( isop[0] == ESC && isoep - isop > 3 && ( isop[1] == '$' && isop[2] == ')' 
  117.             && isop[3] == 'C' ) ){
  118.             /* eat that ESC seq. */
  119.             isop += 4;
  120.         } else if (*isop == SO) {
  121.             /* obj->jismode |= SHIFT_OUT; */
  122.             INTL_SetCCCJismode(obj, INTL_GetCCCJismode(obj) | SHIFT_OUT);
  123.             isop++;
  124.         } else if (*isop == SI) {
  125.             INTL_SetCCCJismode(obj, INTL_GetCCCJismode(obj) & (~SHIFT_OUT));
  126.             isop++;
  127.         } else if (INTL_GetCCCJismode(obj) == (KSC_5601_87 | SHIFT_OUT)) {
  128.             if(*isop == 0x20)  /* jliu */
  129.             {
  130.                 *euckrp++ = *isop++ ;
  131.             }
  132.              else
  133.             {
  134.                 if ((isop+1) > isoep)        /* Incomplete 2Byte char in JIS buf? */
  135.                      break;
  136.  
  137.                 *euckrp++ = *isop++ | 0x80;
  138.                 *euckrp++ = *isop++ | 0x80;
  139.             }
  140.         } else if ((0xA1 <= *isop) && (*isop <= 0xFE)) {
  141.                 /*    Somehow we hit EUC_KR data, let it through */
  142.                 if ((isop+1) > isoep)        /* Incomplete 2Byte char in JIS buf? */
  143.                      break;
  144.                 *euckrp++ = *isop++ ;
  145.                 *euckrp++ = *isop++ ;
  146.         } else {
  147.                                             /* Unknown type: no conversion    */
  148.             *euckrp++ = *isop++ & 0x7f;
  149.         }
  150.     }
  151.     
  152.      if (uncvtbuf[0] != '\0') {
  153.                                         /* Just processed unconverted chars:
  154.                                          * isop pts to 1st unprocessed char in
  155.                                           * isobuf.  Some may have been processed
  156.                                           * while processing unconverted chars,
  157.                                           * so set up ptrs not to process them
  158.                                           * twice.
  159.                                           */
  160.                                         /* If nothing was converted, this can
  161.                                          * only happen if there was not
  162.                                          * enough 2022-kr data.  Stop and get
  163.                                          * more data.
  164.                                          */
  165.         if (isop == uncvtbuf) {    /* Nothing converted */
  166.             *tobufp = '\0';
  167.             return(NULL);
  168.         }
  169.          isoep = (unsigned char *)isobuf + isobufsz - 1 ;
  170.          isop = (unsigned char *)isobuf + (isop - uncvtbuf - uncvtlen);
  171.          uncvtbuf[0] = '\0';            /* No more uncoverted chars.    */
  172.          goto WHILELOOP;                    /* Process new data                */
  173.      }
  174.  
  175.     *tobufp = '\0';                        /* null terminate dest. data */
  176.     INTL_SetCCCLen(obj,  tobufp - tobuf);            /* length not counting null    */
  177.  
  178.      if (isop <= isoep) {                /* unconverted 2022-kr?        */
  179.         tobufp = uncvtbuf;                /* reuse the tobufp as a TEMP */
  180.          while (isop <= isoep)
  181.              *tobufp++ = *isop++;
  182.          *tobufp = '\0';                    /* null terminate        */
  183.      }
  184.     return(tobuf);
  185. }
  186.  
  187.  
  188.