|
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/. */ |
|
5 |
|
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 //-------------------------------------------------------------------- |
|
13 |
|
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 }; |
|
20 |
|
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; |
|
58 |
|
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"); |
|
81 |
|
82 uint8_t i1 = (uint8_t)aByte1; |
|
83 uint8_t i2 = (uint8_t)aByte2; |
|
84 uint16_t idx = (i1 - 0x0081) * 0x00bf + i2 - 0x0040 ; |
|
85 |
|
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 } |