7 | 7 |
#include <ctype.h>
|
8 | 8 |
#include "cloudpinyin.h"
|
9 | 9 |
|
10 | |
char* GoogleParsePinyin(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue)
|
11 | |
{
|
12 | |
char *start = NULL, *end = NULL;
|
13 | |
if (!queue->str) {
|
14 | |
return NULL;
|
15 | |
}
|
16 | |
if ((start = strstr(queue->str, "\",[\"")) != NULL)
|
17 | |
{
|
18 | |
start += strlen( "\",[\"");
|
|
10 |
static inline boolean ishex(char ch)
|
|
11 |
{
|
|
12 |
if ((ch >= '0' && ch <= '9') || (ch >='a' && ch <='f') || (ch >='A' && ch <='F'))
|
|
13 |
return true;
|
|
14 |
return false;
|
|
15 |
}
|
|
16 |
|
|
17 |
static inline unsigned char tohex(char ch)
|
|
18 |
{
|
|
19 |
if (ch >= '0' && ch <= '9')
|
|
20 |
return ch - '0';
|
|
21 |
if (ch >='a' && ch <='f')
|
|
22 |
return ch - 'a' + 10;
|
|
23 |
if (ch >='A' && ch <='F')
|
|
24 |
return ch - 'A' + 10;
|
|
25 |
return 0;
|
|
26 |
}
|
|
27 |
|
|
28 |
void SogouParseKey(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue)
|
|
29 |
{
|
|
30 |
char* str = fcitx_utils_trim(queue->str);
|
|
31 |
const char* ime_patch_key = "ime_patch_key = \"";
|
|
32 |
size_t len = strlen(str);
|
|
33 |
if (len == SOGOU_KEY_LENGTH + strlen(ime_patch_key) + 1
|
|
34 |
&& strncmp(str, ime_patch_key, strlen(ime_patch_key)) == 0
|
|
35 |
&& str[len - 1] == '\"') {
|
|
36 |
sscanf(str,"ime_patch_key = \"%s\"", cloudpinyin->key);
|
|
37 |
cloudpinyin->initialized = true;
|
|
38 |
cloudpinyin->key[SOGOU_KEY_LENGTH] = '\0';
|
|
39 |
}
|
|
40 |
|
|
41 |
free(str);
|
|
42 |
}
|
|
43 |
|
|
44 |
char* MapSogouStringToHalf(const char* string)
|
|
45 |
{
|
|
46 |
const char* s = string;
|
|
47 |
const char* sn;
|
|
48 |
size_t len = strlen(string);
|
|
49 |
char* half = fcitx_utils_malloc0(sizeof(char) * (len + 1));
|
|
50 |
char* halfp = half;
|
|
51 |
int upperCount = 0;
|
|
52 |
|
|
53 |
while (*s) {
|
|
54 |
unsigned int chr = 0;
|
|
55 |
|
|
56 |
sn = fcitx_utf8_get_char(s, &chr);
|
|
57 |
|
|
58 |
/* from A to Z */
|
|
59 |
if ((chr >= 0xff21 && chr <= 0xff3a) || (chr >= 0xff41 && chr <= 0xff5a)) {
|
|
60 |
*halfp = (char) (chr & 0xff) + 0x20;
|
|
61 |
if (isupper(*halfp))
|
|
62 |
upperCount ++;
|
|
63 |
halfp ++;
|
|
64 |
}
|
|
65 |
else {
|
|
66 |
while(s < sn) {
|
|
67 |
*halfp = *s;
|
|
68 |
if (isupper(*halfp))
|
|
69 |
upperCount ++;
|
|
70 |
s++;
|
|
71 |
halfp++;
|
|
72 |
}
|
|
73 |
}
|
|
74 |
|
|
75 |
s = sn;
|
|
76 |
}
|
|
77 |
if (*half && isupper(*half) && upperCount == 1) {
|
|
78 |
*half = tolower(*half);
|
|
79 |
}
|
|
80 |
return half;
|
|
81 |
}
|
|
82 |
|
|
83 |
char* SogouParsePinyin(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue)
|
|
84 |
{
|
|
85 |
char *start = NULL, *end = NULL;
|
|
86 |
if ((start = strchr(queue->str, '"')) != NULL && (end = strstr(queue->str, "%EF%BC%9A")) != NULL)
|
|
87 |
{
|
|
88 |
start ++;
|
|
89 |
if (start < end)
|
|
90 |
{
|
|
91 |
size_t length = end - start;
|
|
92 |
int conv_length;
|
|
93 |
char *unescapedstring = curl_easy_unescape(queue->curl, start, length, &conv_length);
|
|
94 |
char *realstring = MapSogouStringToHalf(unescapedstring);
|
|
95 |
curl_free(unescapedstring);
|
|
96 |
return realstring;
|
|
97 |
}
|
|
98 |
}
|
|
99 |
return NULL;
|
|
100 |
}
|
|
101 |
|
|
102 |
void QQParseKey(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue)
|
|
103 |
{
|
|
104 |
char* str = fcitx_utils_trim(queue->str);
|
|
105 |
const char* ime_patch_key = "{\"key\":\"";
|
|
106 |
if (strncmp(str, ime_patch_key, strlen(ime_patch_key)) == 0)
|
|
107 |
{
|
|
108 |
if (sscanf(str,"{\"key\":\"%32s\",\"ret\":\"suc\"}", cloudpinyin->key) > 0)
|
|
109 |
{
|
|
110 |
cloudpinyin->initialized = true;
|
|
111 |
cloudpinyin->key[QQ_KEY_LENGTH] = '\0';
|
|
112 |
}
|
|
113 |
}
|
|
114 |
|
|
115 |
free(str);
|
|
116 |
}
|
|
117 |
|
|
118 |
char* QQParsePinyin(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue)
|
|
119 |
{
|
|
120 |
char *start = NULL, *end = NULL;
|
|
121 |
if ((start = strstr(queue->str, "\"rs\":[\"")) != NULL)
|
|
122 |
{
|
|
123 |
start += strlen( "\"rs\":[\"");
|
19 | 124 |
if ((end = strstr(start, "\"")) != NULL)
|
20 | 125 |
{
|
21 | 126 |
size_t length = end - start;
|
22 | 127 |
char *realstring = fcitx_utils_malloc0(sizeof(char) * (length + 1));
|
23 | 128 |
strncpy(realstring, start, length);
|
24 | 129 |
realstring[length] = '\0';
|
25 | |
if (fcitx_utf8_check_string(realstring)) {
|
26 | |
return realstring;
|
27 | |
} else {
|
28 | |
free(realstring);
|
29 | |
return NULL;
|
30 | |
}
|
31 | |
}
|
32 | |
}
|
33 | |
return NULL;
|
34 | |
}
|
35 | |
|
36 | |
char* BaiduParsePinyin(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue)
|
37 | |
{
|
38 | |
char *start = NULL, *end = NULL;
|
39 | |
if (!queue->str) {
|
40 | |
return NULL;
|
41 | |
}
|
42 | |
if ((start = strstr(queue->str, "[[\"")) != NULL)
|
43 | |
{
|
44 | |
start += strlen( "[[\"");
|
45 | |
if ((end = strstr(start, "\",")) != NULL)
|
|
130 |
return realstring;
|
|
131 |
}
|
|
132 |
}
|
|
133 |
return NULL;
|
|
134 |
}
|
|
135 |
|
|
136 |
char* GoogleParsePinyin(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue)
|
|
137 |
{
|
|
138 |
char *start = NULL, *end = NULL;
|
|
139 |
if ((start = strstr(queue->str, "\",[\"")) != NULL)
|
|
140 |
{
|
|
141 |
start += strlen( "\",[\"");
|
|
142 |
if ((end = strstr(start, "\"")) != NULL)
|
46 | 143 |
{
|
47 | 144 |
size_t length = end - start;
|
48 | 145 |
char *realstring = fcitx_utils_malloc0(sizeof(char) * (length + 1));
|
49 | 146 |
strncpy(realstring, start, length);
|
50 | 147 |
realstring[length] = '\0';
|
51 | |
if (fcitx_utf8_check_string(realstring)) {
|
|
148 |
return realstring;
|
|
149 |
}
|
|
150 |
}
|
|
151 |
return NULL;
|
|
152 |
}
|
|
153 |
|
|
154 |
char* BaiduParsePinyin(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue)
|
|
155 |
{
|
|
156 |
char *start = NULL, *end = NULL;
|
|
157 |
static iconv_t conv = 0;
|
|
158 |
if (conv == 0)
|
|
159 |
conv = iconv_open("utf-8", "utf-16be");
|
|
160 |
|
|
161 |
if (conv == (iconv_t)(-1))
|
|
162 |
return NULL;
|
|
163 |
if ((start = strstr(queue->str, "[[[\"")) != NULL)
|
|
164 |
{
|
|
165 |
start += strlen( "[[[\"");
|
|
166 |
if ((end = strstr(start, "\",")) != NULL)
|
|
167 |
{
|
|
168 |
size_t length = end - start;
|
|
169 |
if (length % 6 != 0 || length == 0)
|
|
170 |
return NULL;
|
|
171 |
|
|
172 |
size_t i = 0, j = 0;
|
|
173 |
char* buf = fcitx_utils_malloc0((length / 6 + 1) * 2);
|
|
174 |
while (i < length)
|
|
175 |
{
|
|
176 |
if (start[i] == '\\' && start[i+1] == 'u')
|
|
177 |
{
|
|
178 |
if (ishex(start[i+2]) && ishex(start[i+3]) && ishex(start[i+4]) && ishex(start[i+5]))
|
|
179 |
{
|
|
180 |
buf[j++] = (tohex(start[i+2]) << 4) | tohex(start[i+3]);
|
|
181 |
buf[j++] = (tohex(start[i+4]) << 4) | tohex(start[i+5]);
|
|
182 |
}
|
|
183 |
else
|
|
184 |
break;
|
|
185 |
}
|
|
186 |
|
|
187 |
i += 6;
|
|
188 |
}
|
|
189 |
|
|
190 |
if (i != length)
|
|
191 |
{
|
|
192 |
free(buf);
|
|
193 |
return NULL;
|
|
194 |
}
|
|
195 |
buf[j++] = 0;
|
|
196 |
buf[j++] = 0;
|
|
197 |
size_t len = UTF8_MAX_LENGTH * (length / 6) * sizeof(char);
|
|
198 |
char* realstring = fcitx_utils_malloc0(UTF8_MAX_LENGTH * (length / 6) * sizeof(char));
|
|
199 |
IconvStr p = buf; char *pp = realstring;
|
|
200 |
iconv(conv, &p, &j, &pp, &len);
|
|
201 |
|
|
202 |
free(buf);
|
|
203 |
if (fcitx_utf8_check_string(realstring))
|
52 | 204 |
return realstring;
|
53 | |
} else {
|
|
205 |
else
|
|
206 |
{
|
54 | 207 |
free(realstring);
|
55 | 208 |
return NULL;
|
56 | 209 |
}
|