intl/uconv/ucvcn/nsGBKConvUtil.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsGBKConvUtil.h"
     7 #include "gbku.h"
     8 #include "nsDebug.h"
     9 #define MAX_GBK_LENGTH 24066 /* (0xfe-0x80)*(0xfe-0x3f) */
    10 //--------------------------------------------------------------------
    11 // nsGBKConvUtil
    12 //--------------------------------------------------------------------
    14 static const char16_t gGBKToUnicodeTable[MAX_GBK_LENGTH] = {
    15 #include "cp936map.h"
    16 };
    17 static const uint16_t gUnicodeToGBKTable[0xA000-0x4e00] = {
    18 #include "cp936invmap.h"
    19 };
    21 bool nsGBKConvUtil::UnicodeToGBKChar(
    22   char16_t aChar, bool aToGL, char* 
    23   aOutByte1, char* aOutByte2)
    24 {
    25   bool found=false;
    26   *aOutByte1 = *aOutByte2 = 0;
    27   if(UNICHAR_IN_RANGE(0xd800, aChar, 0xdfff))
    28   {
    29     // surrogate is not in here
    30     return false;
    31   }
    32   if(UNICHAR_IN_RANGE(0x4e00, aChar, 0x9FFF))
    33   {
    34     uint16_t item = gUnicodeToGBKTable[aChar - 0x4e00];
    35     if(item != 0) 
    36     {
    37       *aOutByte1 = item >> 8;
    38       *aOutByte2 = item & 0x00FF;
    39       found = true;
    40     } else {
    41       return false;
    42     }
    43   } else {
    44     // ugly linear search
    45     for( int32_t i = 0; i < MAX_GBK_LENGTH; i++ )
    46     {
    47       if( aChar == gGBKToUnicodeTable[i])
    48       {
    49         *aOutByte1 = (i /  0x00BF + 0x0081) ;
    50         *aOutByte2 = (i %  0x00BF + 0x0040) ;
    51         found = true;
    52         break;
    53       }
    54     }
    55   }
    56   if(! found)
    57     return false;
    59   if(aToGL) {
    60     // to GL, we only return if it is in the range 
    61     if(UINT8_IN_RANGE(0xA1, *aOutByte1, 0xFE) &&
    62        UINT8_IN_RANGE(0xA1, *aOutByte2, 0xFE))
    63     {
    64       // mask them to GL 
    65       *aOutByte1 &= 0x7F;
    66       *aOutByte2 &= 0x7F;
    67     } else {
    68       // if it does not fit into 0xa1-0xfe 0xa1-0xfe range that mean
    69       // it is not a GB2312 character, we cannot map to GL 
    70       *aOutByte1 = 0x00;
    71       *aOutByte2 = 0x00;
    72       return false;
    73     }
    74   }
    75   return true;
    76 }
    77 char16_t nsGBKConvUtil::GBKCharToUnicode(char aByte1, char aByte2)
    78 {
    79   NS_ASSERTION(UINT8_IN_RANGE(0x81,aByte1, 0xFE), "first byte out of range");
    80   NS_ASSERTION(UINT8_IN_RANGE(0x40,aByte2, 0xFE), "second byte out of range");
    82   uint8_t i1 = (uint8_t)aByte1;
    83   uint8_t i2 = (uint8_t)aByte2;
    84   uint16_t idx = (i1 - 0x0081) * 0x00bf + i2 - 0x0040 ;
    86   NS_ASSERTION(idx < MAX_GBK_LENGTH, "ARB");
    87   // play it safe- add if statement here ot protect ARB
    88   // probably not necessary
    89   if(idx < MAX_GBK_LENGTH)
    90     return gGBKToUnicodeTable[ idx ];
    91   else
    92     return UCS2_NO_MAPPING;
    93 }

mercurial