intl/uconv/ucvcn/nsGBKConvUtil.cpp

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

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

mercurial