1 /*
2 * Copyright (C) 2024 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 #include "test.h"
16 #include <errno.h>
17 #include <iconv.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #define BUFFER_SIZE 200
22
23 static int g_encodeNum = 77;
24 static char *g_encodeArray[] = {
25 "utf8", "wchart", "ucs2be", "ucs2le", "utf16be", "utf16le", "ucs4be", "utf32be",
26 "ucs4le", "utf32le", "ascii", "usascii", "iso646", "iso646us", "utf16", "ucs4",
27 "utf32", "ucs2", "eucjp", "shiftjis", "sjis", "cp932", "iso2022jp", "gb18030",
28 "gbk", "gb2312", "big5", "bigfive", "cp950", "big5hkscs", "euckr", "ksc5601",
29 "ksx1001", "cp949", "iso88591", "latin1", "iso88592", "iso88593", "iso88594", "iso88595",
30 "iso88596", "iso88597", "iso88598", "iso88599", "iso885910", "iso885911", "tis620", "iso885913",
31 "iso885914", "iso885915", "latin9", "iso885916", "cp1250", "windows1250", "cp1251", "windows1251",
32 "cp1252", "windows1252", "cp1253", "windows1253", "cp1254", "windows1254", "cp1255", "windows1255",
33 "cp1256", "windows1256", "cp1257", "windows1257", "cp1258", "windows1258", "koi8r", "koi8u",
34 "cp437", "cp850", "cp866", "cp1047", "ibm1047"};
35 static int g_excludeToEncodeNum = 11;
36 static char *g_excludeToEncodeArray[] = {"gb18030", "gbk", "gb2312", "big5", "bigfive", "cp950",
37 "big5hkscs", "euckr", "ksc5601", "ksx1001", "cp949"};
38 struct IconvParam {
39 char *to;
40 char *from;
41 char *input;
42 size_t inputLen;
43 char *output;
44 size_t outputLen;
45 };
CloseIconv(iconv_t cd)46 void CloseIconv(iconv_t cd)
47 {
48 if (iconv_close(cd)) {
49 printf("closed iconv failed, error: %s \n", strerror(errno));
50 }
51 }
52
IconvTest(struct IconvParam *param)53 int IconvTest(struct IconvParam *param)
54 {
55 iconv_t cd = iconv_open(param->to, param->from);
56 if (cd == (iconv_t)-1) {
57 t_error("iconv opened failed, from: %s, to: %s, error: %s \n", param->from, param->to, strerror(errno));
58 CloseIconv(cd);
59 return 1;
60 }
61 char *input = param->input;
62 size_t inputLen = param->inputLen;
63 char *output = param->output;
64 size_t outputLen = param->outputLen;
65 if (iconv(cd, &input, &inputLen, &output, &outputLen)) {
66 t_error("iconv converted failed, from: %s, to: %s, error: %s \n", param->from, param->to, strerror(errno));
67 CloseIconv(cd);
68 return 1;
69 }
70 param->outputLen = outputLen;
71 CloseIconv(cd);
72 return 0;
73 }
74
IsExcludeToEncode(char *ecode)75 int IsExcludeToEncode(char *ecode)
76 {
77 for (int i = 0; i < g_excludeToEncodeNum; i++) {
78 if (strcmp(ecode, g_excludeToEncodeArray[i]) == 0) {
79 return 0;
80 }
81 }
82 return 1;
83 }
84
CompareIconvResult(char *to, char *from, char *src, size_t srcLen)85 void CompareIconvResult(char *to, char *from, char *src, size_t srcLen)
86 {
87 if (IsExcludeToEncode(to) == 0) {
88 return;
89 }
90 struct IconvParam param;
91 param.input = src;
92 param.inputLen = srcLen;
93 char output[BUFFER_SIZE];
94 param.output = output;
95 param.outputLen = BUFFER_SIZE;
96 param.to = to;
97 param.from = from;
98 if (IconvTest(¶m)) {
99 return;
100 }
101
102 if (IsExcludeToEncode(from) == 0) {
103 return;
104 }
105 param.input = param.output;
106 param.inputLen = BUFFER_SIZE - param.outputLen;
107 char newOutput[BUFFER_SIZE];
108 param.output = newOutput;
109 param.outputLen = BUFFER_SIZE;
110 param.to = from;
111 param.from = to;
112 if (IconvTest(¶m)) {
113 return;
114 }
115
116 if (srcLen != BUFFER_SIZE - param.outputLen) {
117 t_error("compare error,from: %s, to: %s, newOutput: %s,\n", from, to, param.output);
118 return;
119 }
120 char *l = src;
121 char *r = param.output;
122 size_t step = sizeof(char);
123 for (size_t i = 0; i < srcLen; i += step) {
124 if (*l != *r) {
125 t_error("compare error,from: %s, to: %s, newOutput: %s,\n", from, to, param.output);
126 return;
127 }
128 l++;
129 r++;
130 }
131 }
132
main(void)133 int main(void)
134 {
135 struct IconvParam param;
136 char *str = "Hello world";
137 for (int i = 0; i < g_encodeNum; i++) {
138 char *from = g_encodeArray[i];
139 char *input = str;
140 size_t inputLen = strlen(input);
141
142 if (IsExcludeToEncode(from) != 0) {
143 param.input = input;
144 param.inputLen = inputLen;
145 char output[BUFFER_SIZE];
146 param.output = output;
147 param.outputLen = BUFFER_SIZE;
148 param.to = from;
149 param.from = "utf8";
150 if (IconvTest(¶m)) {
151 continue;
152 }
153 input = param.output;
154 inputLen = BUFFER_SIZE - param.outputLen;
155 }
156
157 for (int j = 0; j < g_encodeNum; j++) {
158 char *to = g_encodeArray[j];
159 CompareIconvResult(to, from, input, inputLen);
160 }
161 }
162
163 return t_status;
164 }