• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ecmascript/base/utf_helper.h"
17 #include "ecmascript/tests/test_helper.h"
18 
19 using namespace panda::ecmascript;
20 using namespace panda::ecmascript::base;
21 using namespace panda::ecmascript::base::utf_helper;
22 
23 namespace panda::test {
24 class UtfHelperTest : public testing::Test {
25 public:
SetUpTestCase()26     static void SetUpTestCase()
27     {
28         GTEST_LOG_(INFO) << "SetUpTestCase";
29     }
30 
TearDownTestCase()31     static void TearDownTestCase()
32     {
33         GTEST_LOG_(INFO) << "TearDownCase";
34     }
35 
SetUp()36     void SetUp() override
37     {
38         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
39     }
40 
TearDown()41     void TearDown() override
42     {
43         TestHelper::DestroyEcmaVMWithScope(instance, scope);
44     }
45 
46     EcmaVM *instance {nullptr};
47     EcmaHandleScope *scope {nullptr};
48     JSThread *thread {nullptr};
49 };
50 
51 /*
52 * @tc.name: CombineTwoU16
53 * @tc.desc: Enter a pair of UTF16-encoded surrogate pair corresponding to the lead surrogates and trail surrogates,
54 *           and return the corresponding Unicode codepoint value.
55 * @tc.type: FUNC
56 */
HWTEST_F_L0(UtfHelperTest,CombineTwoU16)57 HWTEST_F_L0(UtfHelperTest, CombineTwoU16)
58 {
59     uint16_t leadSur= 0xD800;
60     uint16_t trailSur = 0xDC00;
61     uint32_t codePoint = static_cast<uint32_t>(((leadSur - 0xD800U) << 10)|(trailSur - 0xDc00U)) + 0x10000U;
62     uint32_t utfHelperCodePoint = CombineTwoU16(leadSur, trailSur);
63     EXPECT_EQ(codePoint, utfHelperCodePoint);
64     EXPECT_EQ(codePoint, static_cast<uint32_t>(0x10000));
65     trailSur = 0xDFFF;
66     codePoint = static_cast<uint32_t>(((leadSur - 0xD800U) << 10) | (trailSur - 0xDC00U))+ 0x10000U;
67     utfHelperCodePoint = CombineTwoU16(leadSur, trailSur);
68     EXPECT_EQ(codePoint, utfHelperCodePoint);
69     EXPECT_EQ(codePoint, static_cast<uint32_t>(0x103FF));
70     leadSur = 0xDBFF;
71     codePoint = static_cast<uint32_t>(((leadSur - 0xD800U) << 10) | (trailSur - 0xDC00U)) + 0x10000U;
72     utfHelperCodePoint = CombineTwoU16(leadSur, trailSur);
73     EXPECT_EQ(codePoint, utfHelperCodePoint);
74     EXPECT_EQ(codePoint, static_cast<uint32_t>(0x10FFFF));
75     trailSur = 0xDC00;
76     codePoint = static_cast<uint32_t>(((leadSur - 0xD800U) << 10) | (trailSur - 0xDC00U)) + 0x10000U;
77     utfHelperCodePoint = CombineTwoU16(leadSur, trailSur);
78     EXPECT_EQ(codePoint, utfHelperCodePoint);
79     EXPECT_EQ(codePoint, static_cast<uint32_t>(0x10FC00));
80     leadSur= 0xD950;
81     trailSur= 0xDF21;
82     codePoint = static_cast<uint32_t>(((leadSur - 0xD800U)<< 10) | (trailSur - 0xDC00U)) + 0x10000U;
83     utfHelperCodePoint = CombineTwoU16(leadSur, trailSur);
84     EXPECT_EQ(codePoint, utfHelperCodePoint);
85     EXPECT_EQ(codePoint, static_cast<uint32_t>(0x64321));
86 }
87 
88 /*
89 * @tc.name: UTF16Decode
90 * @tc.desc: Enter a pair of UTF16-encoded surrogate pair corresponding to the lead surrogates and trail surrogates,
91             Decodes them into corresponding Unicode codepoint values and returns.
92 * @tc.type: FUNC
93 */
HWTEST_F_L0(UtfHelperTest,UTF16Decode)94 HWTEST_F_L0(UtfHelperTest, UTF16Decode)
95 {
96     uint16_t lead = 0xD950;
97     uint16_t trail = 0xDF21;
98     EXPECT_TRUE(lead >= DECODE_LEAD_LOW && lead <= DECODE_LEAD_HIGH);
99     EXPECT_TRUE(trail >= DECODE_TRAIL_LOW && trail <= DECODE_TRAIL_HIGH);
100     uint32_t codePoint = utf_helper::UTF16Decode(lead, trail);
101     EXPECT_EQ(codePoint, 0x64321U);
102     lead = 0xD85D;
103     trail = 0xDFCC;
104     EXPECT_TRUE(lead >= DECODE_LEAD_LOW && lead <= DECODE_LEAD_HIGH);
105     EXPECT_TRUE(trail >= DECODE_TRAIL_LOW && trail <= DECODE_TRAIL_HIGH);
106     codePoint = utf_helper::UTF16Decode(lead, trail);
107     EXPECT_EQ(codePoint, 0x277CCU);
108 }
109 
110 /*
111  * @tc.name: IsValidUTF8
112  * @tc.desc: Judge whether an input group of symbols is a valid UTF8 coding sequence.
113  * @tc.type: FUNC
114  */
HWTEST_F_L0(UtfHelperTest,IsValidUTF8)115 HWTEST_F_L0(UtfHelperTest, IsValidUTF8)
116 {
117     const std::vector<uint8_t> utfDataOneBitVaild1 = {0x00}; // //0xxxxxxx
118     const std::vector<uint8_t> utfDataOneBitVaild2 = {BIT_MASK_1 - 0x01};
119     const std::vector<uint8_t> utfDataOneBitUnvaild = {BIT_MASK_1};
120     EXPECT_TRUE(utf_helper::IsValidUTF8(utfDataOneBitVaild1));
121     EXPECT_TRUE(utf_helper::IsValidUTF8(utfDataOneBitVaild2));
122     EXPECT_FALSE(utf_helper::IsValidUTF8(utfDataOneBitUnvaild));
123     const std::vector<uint8_t> utfDataTwoBitVaild1 = {BIT_MASK_2, BIT_MASK_1}; // 110xxxxx 10xxxxxx
124     const std::vector<uint8_t> utfDataTwoBitVaild2 = {BIT_MASK_3 - 0x01, BIT_MASK_2 - 0x01};
125     const std::vector<uint8_t> utfDataTwoBitUnvaild1 = {BIT_MASK_2, BIT_MASK_2};
126     const std::vector<uint8_t> utfDataTwoBitUnvaild2 = {BIT_MASK_3, BIT_MASK_1};
127     EXPECT_TRUE(utf_helper::IsValidUTF8(utfDataTwoBitVaild1));
128     EXPECT_TRUE(utf_helper::IsValidUTF8(utfDataTwoBitVaild2));
129     EXPECT_FALSE(utf_helper::IsValidUTF8(utfDataTwoBitUnvaild1));
130     EXPECT_FALSE(utf_helper::IsValidUTF8(utfDataTwoBitUnvaild2));
131     const std::vector<uint8_t> utfDataThreeBitVaild1 = {BIT_MASK_3, BIT_MASK_1, BIT_MASK_1};
132     const std::vector<uint8_t>utfDataThreeBitVaild2 = {BIT_MASK_4 - 0x01, BIT_MASK_2 - 0x01, BIT_MASK_2 - 0x01};
133     const std::vector<uint8_t>utfDataThreeBitUnvaild1 = {BIT_MASK_3, BIT_MASK_1, BIT_MASK_2};
134     const std::vector<uint8_t>utfDataThreeBitUnvaild2 = {BIT_MASK_3, BIT_MASK_2, BIT_MASK_1};
135     const std::vector<uint8_t>utfDataThreeBitUnvaild3 = {BIT_MASK_4, BIT_MASK_1, BIT_MASK_1};
136     const std::vector<uint8_t>utfDataThreeBitUnvaild4 = {BIT_MASK_4, BIT_MASK_2, BIT_MASK_2};
137     EXPECT_TRUE(utf_helper::IsValidUTF8(utfDataThreeBitVaild1));
138     EXPECT_TRUE(utf_helper::IsValidUTF8(utfDataThreeBitVaild2));
139     EXPECT_FALSE(utf_helper::IsValidUTF8(utfDataThreeBitUnvaild1));
140     EXPECT_FALSE(utf_helper::IsValidUTF8(utfDataThreeBitUnvaild2));
141     EXPECT_FALSE(utf_helper::IsValidUTF8(utfDataThreeBitUnvaild3));
142     EXPECT_FALSE(utf_helper::IsValidUTF8(utfDataThreeBitUnvaild4));
143     const std::vector<uint8_t>utfDataFourBitVaild1 = {BIT_MASK_4, BIT_MASK_1, BIT_MASK_1, BIT_MASK_1};
144     const std::vector<uint8_t> utfDataFourBitVaild2 =
145         {BIT_MASK_5 - 0x01, BIT_MASK_2 - 0x01, BIT_MASK_2 - 0x01, BIT_MASK_2 - 0x01};
146     const std::vector<uint8_t>utfDataFourBitUnvaild1 = {BIT_MASK_4, BIT_MASK_1, BIT_MASK_1, BIT_MASK_2};
147     const std::vector<uint8_t>utfDataFourBitUnvaild2 = {BIT_MASK_4, BIT_MASK_1, BIT_MASK_2, BIT_MASK_1};
148     const std::vector<uint8_t>utfDataFourBitUnvaild3 = {BIT_MASK_4, BIT_MASK_2, BIT_MASK_1, BIT_MASK_1};
149     const std::vector<uint8_t>utfDataFourBitUnvaild4 = {BIT_MASK_5, BIT_MASK_1, BIT_MASK_1, BIT_MASK_1};
150     const std::vector<uint8_t>utfDataFourBitUnvaild5 = {BIT_MASK_5, BIT_MASK_2, BIT_MASK_2, BIT_MASK_2};
151     EXPECT_TRUE(utf_helper::IsValidUTF8(utfDataFourBitVaild1));
152     EXPECT_TRUE(utf_helper::IsValidUTF8(utfDataFourBitVaild2));
153     EXPECT_FALSE(utf_helper::IsValidUTF8(utfDataFourBitUnvaild1));
154     EXPECT_FALSE(utf_helper::IsValidUTF8(utfDataFourBitUnvaild2));
155     EXPECT_FALSE(utf_helper::IsValidUTF8(utfDataFourBitUnvaild3));
156     EXPECT_FALSE(utf_helper::IsValidUTF8(utfDataFourBitUnvaild4));
157     EXPECT_FALSE(utf_helper::IsValidUTF8(utfDataFourBitUnvaild5));
158 }
159 
160 /*
161 * @tc.name: ConvertUtf16ToUtf8
162 * @tc.desc: Converts a UTF16 encoding sequence encoding a character into a UTF8 encoding sequence,
163 *           and returns the sequence and the byte length of the sequence. The parameter "modify"
164 *           indicates whether to perform special conversion for 0.
165 * @tc.type: FUNC
166 */
HWTEST_F_L0(UtfHelperTest,ConvertUtf16ToUtf8_001)167 HWTEST_F_L0(UtfHelperTest, ConvertUtf16ToUtf8_001)
168 {
169     // codePoint lie in [0,0x7F]--->UTF-8(length:1)
170     {
171         uint16_t utf16Data0 = 0x00;
172         uint16_t utf16Data1= 0x00;
173         Utf8Char utf8Char = ConvertUtf16ToUtf8(utf16Data0, utf16Data1, false);
174         Utf8Char utf8CharTemp = {0, {0x00U}};
175         EXPECT_EQ(utf8Char.n, utf8CharTemp.n);
176         EXPECT_EQ(utf8Char.ch, utf8CharTemp.ch);
177     }
178 
179     // special case for \u0000 ==> Co80- 1100'0000 1000'0000
180     {
181         uint16_t utf16Data0 = 0x00;
182         uint16_t utf16Data1= 0x00;
183         Utf8Char utf8Char = ConvertUtf16ToUtf8(utf16Data0, utf16Data1, true);
184         Utf8Char utf8CharTemp = {2, {UTF8_2B_FIRST, UTF8_2B_SECOND}};
185         EXPECT_EQ(utf8Char.n, utf8CharTemp.n);
186         EXPECT_EQ(utf8Char.ch, utf8CharTemp.ch);
187         utf16Data0 = 0x7F;
188         utf8Char = ConvertUtf16ToUtf8(utf16Data0, utf16Data1, false);
189         utf8CharTemp = {1, {0x7F}};
190         EXPECT_EQ(utf8Char.n, utf8CharTemp.n);
191         EXPECT_EQ(utf8Char.ch, utf8CharTemp.ch);
192 
193         // codePoint lie in [0x80,0x7FF]--> UTF-8(length:2)
194         utf16Data0 = 0x80;
195         utf8Char = ConvertUtf16ToUtf8(utf16Data0, utf16Data1, false);
196         utf8CharTemp = {2, {UTF8_2B_FIRST + 0x02U, UTF8_2B_SECOND}};
197         EXPECT_EQ(utf8Char.n, utf8CharTemp.n);
198         EXPECT_EQ(utf8Char.ch, utf8CharTemp.ch);
199         utf16Data0 = 0x7FF;
200         utf8Char = ConvertUtf16ToUtf8(utf16Data0, utf16Data1, false);
201         utf8CharTemp = {2, {BIT_MASK_3 - 0x01, BIT_MASK_2 - 0x01}};
202         EXPECT_EQ(utf8Char.n, utf8CharTemp.n);
203         EXPECT_EQ(utf8Char.ch, utf8CharTemp.ch);
204     }
205 
206     // codePoint lie in [0xD800,0xDFFF]--> UTF-8(length:3)
207     {
208         uint16_t utf16Data0 = 0xD800;
209         uint16_t utf16Data1= 0x00;
210         Utf8Char utf8Char = ConvertUtf16ToUtf8(utf16Data0, utf16Data1, false);
211         Utf8Char utf8CharTemp = {3, {UTF8_3B_FIRST | static_cast<uint8_t>(0xD800 >> 12),
212                             UTF8_3B_SECOND | (static_cast<uint8_t>(0xD800 >> 6) & utf::MASK_6BIT),
213                             UTF8_3B_THIRD | (static_cast<uint8_t>(0xD800) & utf::MASK_6BIT)}};
214         EXPECT_EQ(utf8Char.n, utf8CharTemp.n);
215         EXPECT_EQ(utf8Char.ch, utf8CharTemp.ch);
216         utf16Data0 = 0xDFFF;
217         utf8Char = ConvertUtf16ToUtf8(utf16Data0, utf16Data1, false);
218         utf8CharTemp = {3, {UTF8_3B_FIRST | static_cast<uint8_t>(0xDFFF >> 12),
219                             UTF8_3B_SECOND | (static_cast<uint8_t>(0xDFFF >> 6) & utf::MASK_6BIT),
220                             UTF8_3B_THIRD | (static_cast<uint8_t>(0xDFFF) & utf::MASK_6BIT)}};
221         EXPECT_EQ(utf8Char.n, utf8CharTemp.n);
222         EXPECT_EQ(utf8Char.ch, utf8CharTemp.ch);
223     }
224 }
225 
HWTEST_F_L0(UtfHelperTest,ConvertUtf16ToUtf8_002)226 HWTEST_F_L0(UtfHelperTest, ConvertUtf16ToUtf8_002)
227 {
228     // codePoint lie in [0x800,0xD7FF]&&[0xE000,0xFFFF]-->UTF-8(length:3)
229     uint16_t utf16Data0 = 0x800;
230     uint16_t utf16Data1= 0x00;
231     Utf8Char utf8Char = ConvertUtf16ToUtf8(utf16Data0, utf16Data1, false);
232     Utf8Char utf8CharTemp = {3, {UTF8_3B_FIRST | static_cast<uint8_t>(0x800 >> 12),
233                                  UTF8_3B_SECOND | (static_cast<uint8_t>(0x800 >> 6) & utf::MASK_6BIT),
234                                  UTF8_3B_THIRD | (static_cast<uint8_t>(0x800) & utf::MASK_6BIT)}};
235     EXPECT_EQ(utf8Char.n, utf8CharTemp.n);
236     EXPECT_EQ(utf8Char.ch, utf8CharTemp.ch);
237     utf16Data0 = 0xD7FF;
238     utf8Char = ConvertUtf16ToUtf8(utf16Data0, utf16Data1, false);
239     utf8CharTemp = {3, {UTF8_3B_FIRST | static_cast<uint8_t>(0xD7FF>>12),
240                         UTF8_3B_SECOND | (static_cast<uint8_t>(0xD7FF >> 6) & utf::MASK_6BIT),
241                         UTF8_3B_THIRD | (static_cast<uint8_t>(0xD7FF) & utf::MASK_6BIT)}};
242     EXPECT_EQ(utf8Char.n, utf8CharTemp.n);
243     EXPECT_EQ(utf8Char.ch, utf8CharTemp.ch);
244     utf16Data0= 0xE000;
245     utf8Char = ConvertUtf16ToUtf8(utf16Data0, utf16Data1, false);
246     utf8CharTemp = {3, {UTF8_3B_FIRST | static_cast<uint8_t>(0xE000 >> 12),
247                         UTF8_3B_SECOND | (static_cast<uint8_t>(0xE000 >> 6)& utf::MASK_6BIT),
248                         UTF8_3B_THIRD | (static_cast<uint8_t>(0xE000) & utf::MASK_6BIT)}};
249     EXPECT_EQ(utf8Char.n, utf8CharTemp.n);
250     EXPECT_EQ(utf8Char.ch, utf8CharTemp.ch);
251     utf16Data0 = 0xFFFF;
252     utf8Char = ConvertUtf16ToUtf8(utf16Data0, utf16Data1, false);
253     utf8CharTemp = {3, {UTF8_3B_FIRST | static_cast<uint8_t>(0xFFFF >> 12),
254                         UTF8_3B_SECOND | (static_cast<uint8_t>(0xFFFF >> 6)& utf::MASK_6BIT),
255                         UTF8_3B_THIRD | (static_cast<uint8_t>(0xFFFF) & utf::MASK_6BIT)}};
256     EXPECT_EQ(utf8Char.n, utf8CharTemp.n);
257     EXPECT_EQ(utf8Char.ch, utf8CharTemp.ch);
258 }
259 
HWTEST_F_L0(UtfHelperTest,ConvertUtf16ToUtf8_003)260 HWTEST_F_L0(UtfHelperTest, ConvertUtf16ToUtf8_003)
261 {
262     // codePoint lie in [0x10000,0x10FFFF] --> UTF-8(length:4)
263     {
264         uint16_t utf16Data0 = 0xD800;
265         uint16_t utf16Data1= 0xDC00;
266         Utf8Char utf8Char = ConvertUtf16ToUtf8(utf16Data0, utf16Data1, false);
267         uint32_t codePoint = CombineTwoU16(utf16Data0, utf16Data1);
268         Utf8Char utf8CharTemp = {4, {static_cast<uint8_t>((codePoint >> 18) | UTF8_4B_FIRST),
269                             static_cast<uint8_t>(((codePoint >> 12) & utf::MASK_6BIT) | utf::MASK1),
270                             static_cast<uint8_t>(((codePoint >> 6) & utf::MASK_6BIT) | utf::MASK1),
271                             static_cast<uint8_t>((codePoint & utf::MASK_6BIT) | utf::MASK1)}};
272         EXPECT_EQ(utf8Char.n, utf8CharTemp.n);
273         EXPECT_EQ(utf8Char.ch, utf8CharTemp.ch);
274     }
275 
276     // 0xD950 0xDF21 --> 0x64321 --> 0xf1 0xa4 0x8c 0xa1
277     {
278         uint16_t utf16Data0 = 0xD950;
279         uint16_t utf16Data1 = 0xDF21;
280         Utf8Char utf8Char = ConvertUtf16ToUtf8(utf16Data0, utf16Data1, false);
281         uint32_t codePoint = CombineTwoU16(utf16Data0, utf16Data1);
282         Utf8Char utf8CharTemp = {4, {static_cast<uint8_t>((codePoint >> 18) | UTF8_4B_FIRST),
283                             static_cast<uint8_t>(((codePoint >> 12)& utf::MASK_6BIT)| utf::MASK1),
284                             static_cast<uint8_t>(((codePoint >> 6)& utf::MASK_6BIT) | utf::MASK1),
285         static_cast<uint8_t>((codePoint & utf::MASK_6BIT) | utf::MASK1)}};
286         EXPECT_EQ(utf8Char.n, utf8CharTemp.n);
287         EXPECT_EQ(utf8Char.ch, utf8CharTemp.ch);
288         utf8CharTemp = {4, {0xf1, 0xa4, 0x8c, 0xa1}};
289         EXPECT_EQ(utf8Char.n, utf8CharTemp.n);
290         EXPECT_EQ(utf8Char.ch, utf8CharTemp.ch);
291     }
292 }
293 
294 /*
295 * @tc.name: Utf16ToUtf8Size
296 * @tc.desc: Enter a string of UTF16 coded sequences and return the length of the sequence converted into UTF8 coded
297 *           sequences. "length" indicates the length of the input UTF16 sequence, and "modify" indicates whether
298 *           to perform special conversion for.
299 * @tc.type: FUNC
300 */
HWTEST_F_L0(UtfHelperTest,Utf16ToUtf8Size_001)301 HWTEST_F_L0(UtfHelperTest, Utf16ToUtf8Size_001)
302 {
303     // when utf16 data length is only 1 and code in 0xd800-0xdfff, means that is a single code point, it needs to be
304     // represented by three UTF8 code.
305     uint32_t length = 0;
306     uint16_t utf16Value1[1] = {0xD800};
307     const uint16_t *utf16ValuePtr1 = utf16Value1;
308     length = Utf16ToUtf8Size(utf16ValuePtr1, 1, false);
309     EXPECT_EQ(length - 1, UtfLength::THREE);
310     length = 1;
311     uint16_t utf16Value2[1] = {0xDFFF};
312     const uint16_t *utf16ValuePtr2 = utf16Value2;
313     length = Utf16ToUtf8Size(utf16ValuePtr2, 1, false);
314     EXPECT_EQ(length - 1, UtfLength::THREE);
315 
316     // special case for U+0000 => c0 80
317     uint16_t utf16Value3[1] = {0x00};
318     const uint16_t *utf16ValuePtr3 = utf16Value3;
319     length = Utf16ToUtf8Size(utf16ValuePtr3, 1, false);
320     EXPECT_EQ(length - 1, 0U);
321     length = Utf16ToUtf8Size(utf16ValuePtr3, 1, true);
322     EXPECT_EQ(length - 1, 2U);
323 
324     // code point lie in [0x00, 0x7F], it needs to be represented by one UTF8 code.
325     uint16_t utf16Value4[1] = {0x00};
326     uint16_t utf16Value5[1] = {0x7F};
327     const uint16_t *utf16ValuePtr4 = utf16Value4;
328     const uint16_t *utf16ValuePtr5 = utf16Value5;
329     length = Utf16ToUtf8Size(utf16ValuePtr4, 1, false);
330     EXPECT_EQ(length - 1, 0U);
331     length = Utf16ToUtf8Size(utf16ValuePtr5, 1, false);
332     EXPECT_EQ(length - 1, 1U);
333 
334     // code point lie in [0x80, 0x7FF], it needs to be represented by two UTF8 code,
335     uint16_t utf16Value6[1] = {0x80};
336     uint16_t utf16Value7[1] = {0x7FF};
337     const uint16_t *utf16ValuePtr6 = utf16Value6;
338     const uint16_t *utf16ValuePtr7 = utf16Value7;
339     length = Utf16ToUtf8Size(utf16ValuePtr6, 1, false);
340     EXPECT_EQ(length - 1, 2U);
341     length = Utf16ToUtf8Size(utf16ValuePtr7, 1, false);
342     EXPECT_EQ(length - 1, 2U);
343     // code point lie in [0x800, 0xD7FF] or [0xDCoo, 0xFFFF], it needs to be represented by three UTF8 code.
344     uint16_t utf16Value8[1] = {0x800};
345     uint16_t utf16Value9[1] = {0xD7FF};
346     uint16_t utf16Value10[1] = {0xDC00};
347     uint16_t utf16Value11[1] = {0xFFFF};
348     const uint16_t *utf16ValuePtr8 = utf16Value8;
349     const uint16_t *utf16ValuePtr9 = utf16Value9;
350     const uint16_t *utf16ValuePtr10 = utf16Value10;
351     const uint16_t *utf16ValuePtr11 = utf16Value11;
352     length = Utf16ToUtf8Size(utf16ValuePtr8, 1, false);
353     EXPECT_EQ(length - 1, 3U);
354     length = Utf16ToUtf8Size(utf16ValuePtr9, 1, false);
355     EXPECT_EQ(length - 1, 3U);
356     length = Utf16ToUtf8Size(utf16ValuePtr10, 1, false);
357     EXPECT_EQ(length-1, 3U);
358     length = Utf16ToUtf8Size(utf16ValuePtr11, 1, false);
359     EXPECT_EQ(length - 1, 3U);
360 }
361 
HWTEST_F_L0(UtfHelperTest,Utf16ToUtf8Size_002)362 HWTEST_F_L0(UtfHelperTest, Utf16ToUtf8Size_002)
363 {
364     // The trail value is valid, located in [0xDc00, 0xDFFF].It needs to be represented by four UTF8 code.
365     uint16_t utf16Value12[2] = {0xD800, 0xDc00};
366     uint16_t utf16Value13[2] = {0xD800, 0xDFFF};
367     uint16_t utf16Value14[2] = {0xDBFF, 0xDC00};
368     uint16_t utf16Value15[2] = {0xDBFF, 0xDFFF};
369     const uint16_t *utf16ValuePtr12 = utf16Value12;
370     const uint16_t *utf16ValuePtr13 = utf16Value13;
371     const uint16_t *utf16ValuePtr14 = utf16Value14;
372     const uint16_t *utf16ValuePtr15 = utf16Value15;
373     uint32_t length = Utf16ToUtf8Size(utf16ValuePtr12, 2, false);
374     EXPECT_EQ(length - 1, 4U);
375     length = Utf16ToUtf8Size(utf16ValuePtr13, 2, false);
376     EXPECT_EQ(length- 1, 4U);
377     length = Utf16ToUtf8Size(utf16ValuePtr14, 2, false);
378     EXPECT_EQ(length - 1, 4U);
379     length = Utf16ToUtf8Size(utf16ValuePtr15, 2, false);
380     EXPECT_EQ(length - 1, 4U);
381 
382     // The trail value of Bad sequence is invalid, not located in [0xDC00, 0xDFFF].
383     // Need to return 6 bytes length
384     uint16_t utf16Value16[2] = {0xD800, 0xDBFF};
385     uint16_t utf16Value17[2] = {0xDC00, 0xDFFF};
386     const uint16_t *utf16ValuePtr16 = utf16Value16;
387     const uint16_t *utf16ValuePtr17 = utf16Value17;
388     length = Utf16ToUtf8Size(utf16ValuePtr16, 2, false);
389     EXPECT_EQ(length- 1, 6U);
390     length = Utf16ToUtf8Size(utf16ValuePtr17, 2, false);
391     EXPECT_EQ(length-1, 6U);
392 
393     // 0(or 2)+ 1+ 2 + 3 + 4 = 10(or 12)
394     uint16_t utf16Value18[6] = {0x00, 0x7F, 0x80, 0x800, 0xD800, 0xDC00};
395     const uint16_t *utf16ValuePtr18 = utf16Value18;
396     length = Utf16ToUtf8Size(utf16ValuePtr18, 6, false);
397     EXPECT_EQ(length - 1, 10U);
398     length = Utf16ToUtf8Size(utf16ValuePtr18, 6, true);
399     EXPECT_EQ(length - 1, 12U);
400 }
401 
402 /*
403 * @tc.name: ConvertUtf8ToUtf16Pair
404 * @tc.desc: Converts a UTF8 encoding sequence encoding a character into a UTF16 encoding sequence, and returns the
405 *           sequence and the byte length of the UTF16 encoding sequence. The parameter "combine" identifies whether
406 *           to return a pr0xy pair of Unicode values in the secondary plane, or the Unicode value itself.
407 * @tc.type: FUNC
408 */
HWTEST_F_L0(UtfHelperTest,ConvertUtf8ToUtf16Pair)409 HWTEST_F_L0(UtfHelperTest, ConvertUtf8ToUtf16Pair)
410 {
411     // code point lie in [0x00, 0x7F], the length of utf8 code element byte is 1
412     uint8_t utf8Value1[1] = {0x00};
413     uint8_t utf8Value2[1] = {UTF8_1B_MAX};
414     const uint8_t *utf8ValuePtr1 = utf8Value1;
415     const uint8_t *utf8ValuePtr2 = utf8Value2;
416     std::pair<uint32_t, size_t> utf16Res = ConvertUtf8ToUtf16Pair(utf8ValuePtr1);
417     std::pair<uint32_t, size_t> utf16Value = {utf8Value1[0], 1};
418     EXPECT_EQ(utf16Res, utf16Value);
419     utf16Res = ConvertUtf8ToUtf16Pair(utf8ValuePtr2);
420     utf16Value = {utf8Value2[0], 1};
421     EXPECT_EQ(utf16Res, utf16Value);
422     // code point lie in [0x80, 0x7FF], the length of utf8 code element byte is 2
423     uint8_t utf8Value3[2] = {0xc2, 0x80}; // 0x80
424     uint8_t utf8Value4[2] = {0xDF, 0x7F}; // 0x7FF
425     const uint8_t *utf8ValuePtr3 = utf8Value3;
426     const uint8_t *utf8ValuePtr4 = utf8Value4;
427     utf16Res = ConvertUtf8ToUtf16Pair(utf8ValuePtr3);
428     utf16Value = {0x80, 2};
429     EXPECT_EQ(utf16Res, utf16Value);
430     utf16Res = ConvertUtf8ToUtf16Pair(utf8ValuePtr4);
431     utf16Value = {0x7FF, 2};
432     EXPECT_EQ(utf16Res, utf16Value);
433 
434     // code point lie in [0x800, 0xD7FF] or [0xDC00,0xFFFF], the length of utf8 code element byte is 3.
435     // when code point lie in [0xD800, 0xDBFF], due to the use of UCS-2, it corresponds to 3 utf8 symbols.
436     uint8_t utf8Value5[3] = {0xE0, 0xA0, 0x80}; // 0x800
437     uint8_t utf8Value6[3] = {0xEF, 0xBF, 0xBF}; // 0xD7FF
438     const uint8_t *utf8ValuePtr5 = utf8Value5;
439     const uint8_t *utf8ValuePtr6 = utf8Value6;
440     utf16Res = ConvertUtf8ToUtf16Pair(utf8ValuePtr5);
441     utf16Value = {0x800, 3};
442     EXPECT_EQ(utf16Res, utf16Value);
443     utf16Res = ConvertUtf8ToUtf16Pair(utf8ValuePtr6);
444     utf16Value = {0xFFFF, 3};
445     EXPECT_EQ(utf16Res, utf16Value);
446     // code point lie in [0x10000, 0x10FFFF], the length of utf8 code element byte is 4.
447     uint8_t utf8Value9[4] = {0xF0, 0x90, 0x80, 0x80}; // 0x10000
448     uint8_t utf8Value10[4] = {0xF4, 0x8F, 0xBF, 0xBF}; // 0x10FFFF
449     const uint8_t *utf8ValuePtr9 = utf8Value9;
450     const uint8_t *utf8ValuePtr10 = utf8Value10;
451     utf16Res = ConvertUtf8ToUtf16Pair(utf8ValuePtr9);
452     utf16Value = {0xD800 << 16 | 0xDC00U, 4};
453     EXPECT_EQ(utf16Res, utf16Value);
454     utf16Res = ConvertUtf8ToUtf16Pair(utf8ValuePtr10);
455     utf16Value = {0xDBFF << 16 | 0xDFFF, 4};
456     EXPECT_EQ(utf16Res, utf16Value);
457     utf16Res = ConvertUtf8ToUtf16Pair(utf8ValuePtr9, true);
458     utf16Value = {0x10000, 4};
459     EXPECT_EQ(utf16Res, utf16Value);
460     utf16Res = ConvertUtf8ToUtf16Pair(utf8ValuePtr10, true);
461     utf16Value = {0x10FFFF, 4};
462     EXPECT_EQ(utf16Res, utf16Value);
463 }
464 
465 /*
466 * @tc.name: Utf8ToUtf16Size
467 * @tc.desc: Enter a string of UTF8 coded sequences and return the length of the sequence converted into UTF16 coded
468 *           sequences.
469 * @tc.type: FUNC
470 */
HWTEST_F_L0(UtfHelperTest,Utf8ToUtf16Size)471 HWTEST_F_L0(UtfHelperTest, Utf8ToUtf16Size)
472 {
473     // when code point lie in (0x00, 0xFFFF], the required utf16 code element length is 1.
474     uint8_t utf8ValueOneByteMin[1] = {0x00};
475     uint8_t utf8ValueOneByteMax[4] = {0xEF, 0xBF, 0xBF, 0x00}; // 0xFFFF
476     const uint8_t *utf8ValueOneByteMinPtr = utf8ValueOneByteMin;
477     const uint8_t *utf8ValueOneByteMaxPtr = utf8ValueOneByteMax;
478     size_t length = Utf8ToUtf16Size(utf8ValueOneByteMinPtr, sizeof(utf8ValueOneByteMin));
479     EXPECT_EQ(length, 1U);
480     length = Utf8ToUtf16Size(utf8ValueOneByteMaxPtr, sizeof(utf8ValueOneByteMax));
481     EXPECT_EQ(length, 2U);
482     // when code point lie in [0x10000, 0x10FFFF], the required utf16 code element length is 2.
483     const uint8_t utf8ValueTwoBytesMin[5] = {0xF0, 0x90, 0x80, 0x80, 0x00}; // 0x10000
484     const uint8_t utf8ValueTwoBytesMax[5] = {0xF4, 0x8F, 0xBF, 0xBF, 0x00}; // 0x10FFFF
485     const uint8_t *utf8ValueTwoBytesMinPtr = utf8ValueTwoBytesMin;
486     const uint8_t *utf8ValueTwoBytesMaxPtr = utf8ValueTwoBytesMax;
487     length = Utf8ToUtf16Size(utf8ValueTwoBytesMinPtr, sizeof(utf8ValueTwoBytesMin));
488     EXPECT_EQ(length, 3U);
489     length = Utf8ToUtf16Size(utf8ValueTwoBytesMaxPtr, sizeof(utf8ValueTwoBytesMax));
490     EXPECT_EQ(length, 3U);
491     uint8_t utf8Value[12] = {
492         0xEF, 0xBF, 0xBF, 0xF0,
493         0x90, 0x80, 0x80, 0xF4,
494         0x8F, 0xBF, 0xBF, 0x00};
495     const uint8_t *utf8ValuePtr = utf8Value;
496     length = Utf8ToUtf16Size(utf8ValuePtr, sizeof(utf8Value));
497     EXPECT_EQ(length, 6U);
498 }
499 
500 /*
501 * @tc.name: ConvertRegionUtf16ToUtf8
502 * @tc.desc: Input aUTF16-encoded sequence (thelength is "utf16Len"), convert part of the sequence into a UTF8-encoded
503 *           sequence, and save it to "utf8Out"(the maximum length is "utf8Len"). The start parameter indicates the
504 *           start position of the conversion. Whether to perform special processing for O in the "modify" parameter.
505 * @tc.type: FUNC
506 */
HWTEST_F_L0(UtfHelperTest,ConvertRegionUtf16ToUtf8)507 HWTEST_F_L0(UtfHelperTest, ConvertRegionUtf16ToUtf8)
508 {
509     size_t utf16Len = 8;
510     size_t utf8Len = 100;
511     size_t start = 0;
512     bool modify = false;
513     uint16_t utf16Value[8] = {
514         0x00, // 0 or 2 (special case for \u0000 ==> C080 - 1100'0000 1000'0000)
515         0x7F, // 1(0x00, 0x7F]
516         0x7FF, // 2 [0x80, 0x7FF]
517         0x800, // 3 [0x800, 0xD7FF]
518         0xD800, // 3 [0xD800, 0xDFFF]
519         0xFFFF, // 3 [0xE000, 0xFFFF]
520         0xD800, 0xDFFF}; // 4 [0x10000, 0x10FFFF]
521     const uint16_t *utf16ValuePtr = utf16Value;
522     uint8_t *utf8Out = (uint8_t*)malloc(utf8Len);
523     size_t utf8Pos = ConvertRegionUtf16ToUtf8(utf16ValuePtr, utf8Out, utf16Len, utf8Len, start, modify);
524     // 0 + 1 + 2 +(3 *3)+ 4= 16
525     EXPECT_EQ(utf8Pos, 16U);
526     // 2 + 1 + 2 +(3 * 3)+ 4 = 18
527     modify = true;
528     utf8Pos = ConvertRegionUtf16ToUtf8(utf16ValuePtr, utf8Out, utf16Len, utf8Len, start, modify);
529     EXPECT_EQ(utf8Pos, 18U);
530     free(utf8Out);
531 }
532 
533 /*
534 * @tc.name: ConvertRegionUtf8ToUtf16
535 * @tc.desc: Input a UTF8-encoded sequence, convert part of the sequence into a UTF8-encoded sequence, and save it to
536 *           "utf16Out"(the maximum length is "utf16Len"), The start parameter indicates the start position of the
537 *           conversion.
538 * @tc.type: FUNC
539 */
HWTEST_F_L0(UtfHelperTest,ConvertRegionUtf8ToUtf16)540 HWTEST_F_L0(UtfHelperTest, ConvertRegionUtf8ToUtf16)
541 {
542     size_t utf16Len = 100;
543     size_t start = 0;
544     uint8_t utf8Value[10] = {
545         0x7F, // 1-length UTF16 encoding
546         0xDF, 0xBF, // 1-length UTF16 encoding
547         0xEF, 0xBF, 0xBF, // 1-length UTF16 encoding
548         0xF4, 0x8F, 0xBF, 0xBF}; // 2-length UTF16 encoding
549     const uint8_t *utf8ValuePtr = utf8Value;
550     uint16_t *utf16Out = (uint16_t*)malloc(utf16Len);
551     size_t outPos = ConvertRegionUtf8ToUtf16(utf8ValuePtr, utf16Out, sizeof(utf8Value), utf16Len, start);
552     // 1 + 1 + 1 + 2 = 5s
553     EXPECT_EQ(outPos, 5U);
554     // 1 + 2 = 3
555     start = 3;
556     outPos = ConvertRegionUtf8ToUtf16(utf8ValuePtr, utf16Out, sizeof(utf8Value), utf16Len, start);
557     EXPECT_EQ(outPos, 3U);
558 
559     // When "start" is in the middle of a symbol sequence
560     start = 2;
561     outPos = ConvertRegionUtf8ToUtf16(utf8ValuePtr, utf16Out, sizeof(utf8Value), utf16Len, start);
562     EXPECT_EQ(outPos, 0U);
563     start = 4;
564     outPos = ConvertRegionUtf8ToUtf16(utf8ValuePtr, utf16Out, sizeof(utf8Value), utf16Len, start);
565     EXPECT_EQ(outPos, 0U);
566     start = 7;
567     outPos = ConvertRegionUtf8ToUtf16(utf8ValuePtr, utf16Out, sizeof(utf8Value), utf16Len, start);
568     EXPECT_EQ(outPos, 0U);
569     free(utf16Out);
570 }
571 } // namespace panda:test
572