|
1 /* -*- Mode: C; tab-width: 4; 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 * A character set converter from Unicode to HZ. |
|
7 * |
|
8 * |
|
9 * @created 08/Sept/1999 |
|
10 * @author Yueheng Xu, Yueheng.Xu@intel.com |
|
11 * Revision History |
|
12 * 04/Oct/1999. Yueheng Xu: Fixed line continuation problem when line |
|
13 * ended by '~'; |
|
14 * Used table UnicodeToGBK[] to speed up the mapping. |
|
15 */ |
|
16 #include "nsUnicodeToHZ.h" |
|
17 #include "gbku.h" |
|
18 //---------------------------------------------------------------------- |
|
19 // Class nsUnicodeToGBK [implementation] |
|
20 #define HZ_STATE_GB 1 |
|
21 #define HZ_STATE_ASCII 2 |
|
22 #define HZ_STATE_TILD 3 |
|
23 #define HZLEAD1 '~' |
|
24 #define HZLEAD2 '{' |
|
25 #define HZLEAD3 '}' |
|
26 #define UNICODE_TILD 0x007E |
|
27 nsUnicodeToHZ::nsUnicodeToHZ() : nsEncoderSupport(6) |
|
28 { |
|
29 mHZState = HZ_STATE_ASCII; // per HZ spec, default to HZ mode |
|
30 } |
|
31 NS_IMETHODIMP nsUnicodeToHZ::ConvertNoBuff( |
|
32 const char16_t * aSrc, |
|
33 int32_t * aSrcLength, |
|
34 char * aDest, |
|
35 int32_t * aDestLength) |
|
36 { |
|
37 int32_t i=0; |
|
38 int32_t iSrcLength = *aSrcLength; |
|
39 int32_t iDestLength = 0; |
|
40 |
|
41 for (i=0;i< iSrcLength;i++) |
|
42 { |
|
43 if(! IS_ASCII(*aSrc)) |
|
44 { |
|
45 // hi byte has something, it is not ASCII, process as a GB |
|
46 if ( mHZState != HZ_STATE_GB ) |
|
47 { |
|
48 // we are adding a '~{' ESC sequence to star a HZ string |
|
49 mHZState = HZ_STATE_GB; |
|
50 aDest[0] = '~'; |
|
51 aDest[1] = '{'; |
|
52 aDest += 2; // increment 2 bytes |
|
53 iDestLength +=2; |
|
54 } |
|
55 if(mUtil.UnicodeToGBKChar(*aSrc, true, &aDest[0], &aDest[1])) { |
|
56 aDest += 2; // increment 2 bytes |
|
57 iDestLength +=2; |
|
58 } else { |
|
59 // some thing that we cannot convert |
|
60 // xxx fix me ftang |
|
61 // error handling here |
|
62 } |
|
63 } else { |
|
64 // this is an ASCII |
|
65 |
|
66 // if we are in HZ mode, end it by adding a '~}' ESC sequence |
|
67 if ( mHZState == HZ_STATE_GB ) |
|
68 { |
|
69 mHZState = HZ_STATE_ASCII; |
|
70 aDest[0] = '~'; |
|
71 aDest[1] = '}'; |
|
72 aDest += 2; // increment 2 bytes |
|
73 iDestLength +=2; |
|
74 } |
|
75 |
|
76 // if this is a regular char '~' , convert it to two '~' |
|
77 if ( *aSrc == UNICODE_TILD ) |
|
78 { |
|
79 aDest[0] = '~'; |
|
80 aDest[1] = '~'; |
|
81 aDest += 2; // increment 2 bytes |
|
82 iDestLength +=2; |
|
83 } else { |
|
84 // other regular ASCII chars convert by normal ways |
|
85 |
|
86 // Is this works for both little endian and big endian machines ? |
|
87 *aDest = (char) ( (char16_t)(*aSrc) ); |
|
88 aDest++; // increment 1 byte |
|
89 iDestLength +=1; |
|
90 } |
|
91 } |
|
92 aSrc++; // increment 2 bytes |
|
93 if ( iDestLength >= (*aDestLength) ) |
|
94 { |
|
95 break; |
|
96 } |
|
97 } |
|
98 *aDestLength = iDestLength; |
|
99 *aSrcLength = i; |
|
100 return NS_OK; |
|
101 } |
|
102 |
|
103 NS_IMETHODIMP nsUnicodeToHZ::FinishNoBuff(char * aDest, int32_t * aDestLength) |
|
104 { |
|
105 if ( mHZState == HZ_STATE_GB ) |
|
106 { |
|
107 // if we are in HZ mode, end it by adding a '~}' ESC sequence |
|
108 mHZState = HZ_STATE_ASCII; |
|
109 aDest[0] = '~'; |
|
110 aDest[1] = '}'; |
|
111 *aDestLength = 2; |
|
112 } else { |
|
113 *aDestLength = 0; |
|
114 } |
|
115 return NS_OK; |
|
116 } |