home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libi18n / sjis2euc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  5.8 KB  |  175 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. /*    sjis2euc.c    */
  19.  
  20. #include "intlpriv.h"
  21.  
  22.  
  23. extern int MK_OUT_OF_MEMORY;
  24.  
  25.  
  26.                                     /* SJIS to EUC Algorithm.        */
  27. #define TwoByteSJIS2EUC(sjisp, eucp, offset) {                    \
  28.      *eucp = ((*sjisp++ - offset) << 1) | 0x80; /* 1st EUC byte */ \
  29.      if (*sjisp < 0x9F) {            /* check 2nd SJIS byte */    \
  30.          *eucp++ -= 1;                /* adjust 1st EUC byte */    \
  31.          if (*sjisp > 0x7F)                                        \
  32.              *eucp++ = (*sjisp++ - 0x20) | 0x80;                    \
  33.          else                                                    \
  34.              *eucp++ = (*sjisp++ - 0x1F) | 0x80;                    \
  35.      } else {                                                    \
  36.          eucp++;                                                    \
  37.          *eucp++ = (*sjisp++ - 0x7E) | 0x80;                        \
  38.      }                                                            \
  39. }
  40.                 
  41. /* net_sjis2euc(sjisbuf, sjisbufsz)
  42.  * Args:
  43.  *    sjisbuf:    Ptr to a buf of SJIS chars
  44.  *    sjisbufsz:    Size in bytes of sjisbuf
  45.  *    uncvtbuf:    If entire buffer was converted, uncvtbuf[0] will be nul,
  46.  *        else this points to SJIS chars that were NOT converted
  47.  *        and mz_sjis2euc() with additional SJIS chars appended.
  48.  * Return:
  49.  *    Returns NULL on failure, otherwise it returns a pointer to a buffer of
  50.  *    converted SJIS characters.  Caller must XP_FREE() this memory.
  51.  *
  52.  * Description:
  53.  *     Allocate destination EUC buffer.
  54.  *
  55.  *     If byte in ASCII range, just copy it to EUC buffer.
  56.  *     If Half-width SJIS katakana (1 byte), convert to Half-width EUC katakana.
  57.  *     If 2-byte SJIS, convert to 2-byte EUC.
  58.  *     Otherwise assume user-defined SJIS, just copy 2 bytes.
  59.  *
  60.  *    If either SJIS buffer does not contain complete SJIS char or EUC buffer
  61.  *    is full, then return unconverted SJIS to caller.  Caller should
  62.  *    append more data and recall mz_sjis2euc.
  63.  */
  64.  
  65.  
  66. MODULE_PRIVATE unsigned char *
  67. mz_sjis2euc(    CCCDataObject        obj,
  68.             const unsigned char    *sjisbuf,    /* SJIS buf for conversion    */
  69.             int32                sjisbufsz)    /* SJIS buf size in bytes    */
  70. {
  71.      unsigned char            *tobuf = NULL;
  72.      int32                    tobufsz;
  73.      register unsigned char    *sjisp, *tobufp;    /* current byte in bufs    */
  74.      register unsigned char    *sjisep, *tobufep;    /* end of buffers        */
  75.      int32                    uncvtlen;
  76.     unsigned char *uncvtbuf = INTL_GetCCCUncvtbuf(obj);
  77.      
  78.                                          /* Allocate a EUC buffer:        */
  79.         /* In the worst case ( all Half-width Kanas ), the converted    */
  80.         /* EUC will be 2X the size of the SJIS + 1 for nul byte            */
  81.     uncvtlen = strlen((char *)uncvtbuf);
  82.     tobufsz = ((sjisbufsz  + uncvtlen) << 1) + 1;
  83.     if ((tobuf = (unsigned char *)XP_ALLOC(tobufsz)) == (unsigned char *)NULL) {
  84.         INTL_SetCCCRetval(obj, MK_OUT_OF_MEMORY);
  85.         return(NULL);
  86.     }
  87.                                         /* Initialize pointers, etc.    */
  88.      sjisp = (unsigned char *)sjisbuf;
  89.      sjisep = sjisp + sjisbufsz - 1;
  90.  
  91. #define uncvtp    tobufp    /* use tobufp as temp */     
  92.                             /* If prev. unconverted chars, append unconverted
  93.                              * chars w/new chars and try to process.
  94.                              */
  95.      if (uncvtbuf[0] != '\0') {
  96.          uncvtp = uncvtbuf + uncvtlen;
  97.          while (uncvtp < (uncvtbuf + UNCVTBUF_SIZE) &&
  98.                                                     sjisp <= sjisep)
  99.              *uncvtp++ = *sjisp++;
  100.          *uncvtp = '\0';                        /* nul terminate    */
  101.          sjisp = uncvtbuf;                /* process unconverted first */
  102.          sjisep = uncvtp - 1;
  103.      }
  104. #undef uncvtp
  105.      
  106.      tobufp = tobuf;
  107.      tobufep = tobufp + tobufsz - 1;        /* save space for terminating null */
  108.  
  109. WHILELOOP:     
  110.                                     /* While SJIS data && space in EUC buf. */
  111.      while ((sjisp <= sjisep) && (tobufp <= tobufep)) {
  112.         if (*sjisp < 0x80) {
  113.                                          /* ASCII/JIS-Roman                 */
  114.              *tobufp++ = *sjisp++;
  115.  
  116.          } else if (*sjisp < 0xA0) {
  117.                                          /* 1st byte of 2-byte low SJIS. */
  118.              if (sjisp+1 > sjisep)        /* No 2nd byte in SJIS buffer?    */
  119.                  break;
  120.  
  121.              TwoByteSJIS2EUC(sjisp, tobufp, 0x70);
  122.  
  123.          } else if (*sjisp==0xA0) {
  124.                                         /* SJIS half-width space.    */
  125.                                         /* Just treat like Roman??    */
  126.              *tobufp++ = *sjisp++;
  127.  
  128.          } else if (*sjisp < 0xE0) {
  129.                                         /* SJIS half-width katakana        */
  130.             *tobufp++ = SS2;
  131.             *tobufp++ = *sjisp | 0x80;    /* Set 8th bit for EUC & SJIS */
  132.             sjisp++;
  133.  
  134.          } else if (*sjisp < 0xF0) {
  135.                                         /* 1st byte of 2-byte high SJIS */
  136.              if (sjisp+1 > sjisep)        /* No 2nd byte in SJIS buffer? */
  137.                  break;
  138.  
  139.              TwoByteSJIS2EUC(sjisp, tobufp, 0xB0);
  140.          } else {
  141.                                         /* User Defined SJIS: copy bytes */
  142.              if (sjisp+1 > sjisep)        /* No 2nd byte in SJIS buf?    */
  143.                  break;
  144.  
  145.              *tobufp++ = *sjisp++;            /* Just copy 2 bytes.    */
  146.              *tobufp++ = *sjisp++;
  147.          }
  148.      }
  149.      
  150.      if (uncvtbuf[0] != '\0') {
  151.                                          /* jisp pts to 1st unprocessed char in
  152.                                           * jisbuf.  Some may have been processed
  153.                                           * while processing unconverted chars,
  154.                                           * so set up ptrs not to process them
  155.                                           * twice.
  156.                                           */
  157.          sjisp = (unsigned char *)sjisbuf + (sjisp - uncvtbuf - uncvtlen);
  158.          sjisep = (unsigned char *)sjisbuf + sjisbufsz - 1;
  159.          uncvtbuf[0] = '\0';        /* No more uncoverted chars.    */
  160.          goto WHILELOOP;                    /* Process new data                */
  161.      }
  162.  
  163.     *tobufp = '\0';                        /* null terminate EUC data */
  164.     INTL_SetCCCLen(obj,  tobufp - tobuf);            /* length not counting null    */
  165.  
  166.      if (sjisp <= sjisep) {                /* uncoverted SJIS?        */
  167.         tobufp = uncvtbuf;            /* reuse the tobufp as a TEMP */
  168.          while (sjisp <= sjisep)
  169.              *tobufp++ = *sjisp++;
  170.          *tobufp = '\0';                    /* null terminate        */
  171.      }
  172.     return(tobuf);
  173. }
  174.  
  175.