Thu, 22 Jan 2015 13:21:57 +0100
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 }