1570af302Sopenharmony_ci/*
2570af302Sopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4570af302Sopenharmony_ci * you may not use this file except in compliance with the License.
5570af302Sopenharmony_ci * You may obtain a copy of the License at
6570af302Sopenharmony_ci *
7570af302Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8570af302Sopenharmony_ci *
9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12570af302Sopenharmony_ci * See the License for the specific language governing permissions and
13570af302Sopenharmony_ci * limitations under the License.
14570af302Sopenharmony_ci */
15570af302Sopenharmony_ci#include "test.h"
16570af302Sopenharmony_ci#include <errno.h>
17570af302Sopenharmony_ci#include <iconv.h>
18570af302Sopenharmony_ci#include <stdio.h>
19570af302Sopenharmony_ci#include <stdlib.h>
20570af302Sopenharmony_ci#include <string.h>
21570af302Sopenharmony_ci#define BUFFER_SIZE 200
22570af302Sopenharmony_ci
23570af302Sopenharmony_cistatic int g_encodeNum = 77;
24570af302Sopenharmony_cistatic char *g_encodeArray[] = {
25570af302Sopenharmony_ci    "utf8",      "wchart",      "ucs2be",   "ucs2le",      "utf16be",   "utf16le",     "ucs4be",    "utf32be",
26570af302Sopenharmony_ci    "ucs4le",    "utf32le",     "ascii",    "usascii",     "iso646",    "iso646us",    "utf16",     "ucs4",
27570af302Sopenharmony_ci    "utf32",     "ucs2",        "eucjp",    "shiftjis",    "sjis",      "cp932",       "iso2022jp", "gb18030",
28570af302Sopenharmony_ci    "gbk",       "gb2312",      "big5",     "bigfive",     "cp950",     "big5hkscs",   "euckr",     "ksc5601",
29570af302Sopenharmony_ci    "ksx1001",   "cp949",       "iso88591", "latin1",      "iso88592",  "iso88593",    "iso88594",  "iso88595",
30570af302Sopenharmony_ci    "iso88596",  "iso88597",    "iso88598", "iso88599",    "iso885910", "iso885911",   "tis620",    "iso885913",
31570af302Sopenharmony_ci    "iso885914", "iso885915",   "latin9",   "iso885916",   "cp1250",    "windows1250", "cp1251",    "windows1251",
32570af302Sopenharmony_ci    "cp1252",    "windows1252", "cp1253",   "windows1253", "cp1254",    "windows1254", "cp1255",    "windows1255",
33570af302Sopenharmony_ci    "cp1256",    "windows1256", "cp1257",   "windows1257", "cp1258",    "windows1258", "koi8r",     "koi8u",
34570af302Sopenharmony_ci    "cp437",     "cp850",       "cp866",    "cp1047",      "ibm1047"};
35570af302Sopenharmony_cistatic int g_excludeToEncodeNum = 11;
36570af302Sopenharmony_cistatic char *g_excludeToEncodeArray[] = {"gb18030",   "gbk",   "gb2312",  "big5",    "bigfive", "cp950",
37570af302Sopenharmony_ci                                         "big5hkscs", "euckr", "ksc5601", "ksx1001", "cp949"};
38570af302Sopenharmony_cistruct IconvParam {
39570af302Sopenharmony_ci    char *to;
40570af302Sopenharmony_ci    char *from;
41570af302Sopenharmony_ci    char *input;
42570af302Sopenharmony_ci    size_t inputLen;
43570af302Sopenharmony_ci    char *output;
44570af302Sopenharmony_ci    size_t outputLen;
45570af302Sopenharmony_ci};
46570af302Sopenharmony_civoid CloseIconv(iconv_t cd)
47570af302Sopenharmony_ci{
48570af302Sopenharmony_ci    if (iconv_close(cd)) {
49570af302Sopenharmony_ci        printf("closed iconv failed, error: %s \n", strerror(errno));
50570af302Sopenharmony_ci    }
51570af302Sopenharmony_ci}
52570af302Sopenharmony_ci
53570af302Sopenharmony_ciint IconvTest(struct IconvParam *param)
54570af302Sopenharmony_ci{
55570af302Sopenharmony_ci    iconv_t cd = iconv_open(param->to, param->from);
56570af302Sopenharmony_ci    if (cd == (iconv_t)-1) {
57570af302Sopenharmony_ci        t_error("iconv opened failed, from: %s, to: %s, error: %s \n", param->from, param->to, strerror(errno));
58570af302Sopenharmony_ci        CloseIconv(cd);
59570af302Sopenharmony_ci        return 1;
60570af302Sopenharmony_ci    }
61570af302Sopenharmony_ci    char *input = param->input;
62570af302Sopenharmony_ci    size_t inputLen = param->inputLen;
63570af302Sopenharmony_ci    char *output = param->output;
64570af302Sopenharmony_ci    size_t outputLen = param->outputLen;
65570af302Sopenharmony_ci    if (iconv(cd, &input, &inputLen, &output, &outputLen)) {
66570af302Sopenharmony_ci        t_error("iconv converted failed, from: %s, to: %s, error: %s \n", param->from, param->to, strerror(errno));
67570af302Sopenharmony_ci        CloseIconv(cd);
68570af302Sopenharmony_ci        return 1;
69570af302Sopenharmony_ci    }
70570af302Sopenharmony_ci    param->outputLen = outputLen;
71570af302Sopenharmony_ci    CloseIconv(cd);
72570af302Sopenharmony_ci    return 0;
73570af302Sopenharmony_ci}
74570af302Sopenharmony_ci
75570af302Sopenharmony_ciint IsExcludeToEncode(char *ecode)
76570af302Sopenharmony_ci{
77570af302Sopenharmony_ci    for (int i = 0; i < g_excludeToEncodeNum; i++) {
78570af302Sopenharmony_ci        if (strcmp(ecode, g_excludeToEncodeArray[i]) == 0) {
79570af302Sopenharmony_ci            return 0;
80570af302Sopenharmony_ci        }
81570af302Sopenharmony_ci    }
82570af302Sopenharmony_ci    return 1;
83570af302Sopenharmony_ci}
84570af302Sopenharmony_ci
85570af302Sopenharmony_civoid CompareIconvResult(char *to, char *from, char *src, size_t srcLen)
86570af302Sopenharmony_ci{
87570af302Sopenharmony_ci    if (IsExcludeToEncode(to) == 0) {
88570af302Sopenharmony_ci        return;
89570af302Sopenharmony_ci    }
90570af302Sopenharmony_ci    struct IconvParam param;
91570af302Sopenharmony_ci    param.input = src;
92570af302Sopenharmony_ci    param.inputLen = srcLen;
93570af302Sopenharmony_ci    char output[BUFFER_SIZE];
94570af302Sopenharmony_ci    param.output = output;
95570af302Sopenharmony_ci    param.outputLen = BUFFER_SIZE;
96570af302Sopenharmony_ci    param.to = to;
97570af302Sopenharmony_ci    param.from = from;
98570af302Sopenharmony_ci    if (IconvTest(&param)) {
99570af302Sopenharmony_ci        return;
100570af302Sopenharmony_ci    }
101570af302Sopenharmony_ci
102570af302Sopenharmony_ci    if (IsExcludeToEncode(from) == 0) {
103570af302Sopenharmony_ci        return;
104570af302Sopenharmony_ci    }
105570af302Sopenharmony_ci    param.input = param.output;
106570af302Sopenharmony_ci    param.inputLen = BUFFER_SIZE - param.outputLen;
107570af302Sopenharmony_ci    char newOutput[BUFFER_SIZE];
108570af302Sopenharmony_ci    param.output = newOutput;
109570af302Sopenharmony_ci    param.outputLen = BUFFER_SIZE;
110570af302Sopenharmony_ci    param.to = from;
111570af302Sopenharmony_ci    param.from = to;
112570af302Sopenharmony_ci    if (IconvTest(&param)) {
113570af302Sopenharmony_ci        return;
114570af302Sopenharmony_ci    }
115570af302Sopenharmony_ci
116570af302Sopenharmony_ci    if (srcLen != BUFFER_SIZE - param.outputLen) {
117570af302Sopenharmony_ci        t_error("compare error,from: %s, to: %s, newOutput: %s,\n", from, to, param.output);
118570af302Sopenharmony_ci        return;
119570af302Sopenharmony_ci    }
120570af302Sopenharmony_ci    char *l = src;
121570af302Sopenharmony_ci    char *r = param.output;
122570af302Sopenharmony_ci    size_t step = sizeof(char);
123570af302Sopenharmony_ci    for (size_t i = 0; i < srcLen; i += step) {
124570af302Sopenharmony_ci        if (*l != *r) {
125570af302Sopenharmony_ci            t_error("compare error,from: %s, to: %s, newOutput: %s,\n", from, to, param.output);
126570af302Sopenharmony_ci            return;
127570af302Sopenharmony_ci        }
128570af302Sopenharmony_ci        l++;
129570af302Sopenharmony_ci        r++;
130570af302Sopenharmony_ci    }
131570af302Sopenharmony_ci}
132570af302Sopenharmony_ci
133570af302Sopenharmony_ciint main(void)
134570af302Sopenharmony_ci{
135570af302Sopenharmony_ci    struct IconvParam param;
136570af302Sopenharmony_ci    char *str = "Hello world";
137570af302Sopenharmony_ci    for (int i = 0; i < g_encodeNum; i++) {
138570af302Sopenharmony_ci        char *from = g_encodeArray[i];
139570af302Sopenharmony_ci        char *input = str;
140570af302Sopenharmony_ci        size_t inputLen = strlen(input);
141570af302Sopenharmony_ci
142570af302Sopenharmony_ci        if (IsExcludeToEncode(from) != 0) {
143570af302Sopenharmony_ci            param.input = input;
144570af302Sopenharmony_ci            param.inputLen = inputLen;
145570af302Sopenharmony_ci            char output[BUFFER_SIZE];
146570af302Sopenharmony_ci            param.output = output;
147570af302Sopenharmony_ci            param.outputLen = BUFFER_SIZE;
148570af302Sopenharmony_ci            param.to = from;
149570af302Sopenharmony_ci            param.from = "utf8";
150570af302Sopenharmony_ci            if (IconvTest(&param)) {
151570af302Sopenharmony_ci                continue;
152570af302Sopenharmony_ci            }
153570af302Sopenharmony_ci            input = param.output;
154570af302Sopenharmony_ci            inputLen = BUFFER_SIZE - param.outputLen;
155570af302Sopenharmony_ci        }
156570af302Sopenharmony_ci
157570af302Sopenharmony_ci        for (int j = 0; j < g_encodeNum; j++) {
158570af302Sopenharmony_ci            char *to = g_encodeArray[j];
159570af302Sopenharmony_ci            CompareIconvResult(to, from, input, inputLen);
160570af302Sopenharmony_ci        }
161570af302Sopenharmony_ci    }
162570af302Sopenharmony_ci
163570af302Sopenharmony_ci    return t_status;
164570af302Sopenharmony_ci}