1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21: #include <dlfcn.h>
22: #include <stdint.h>
23: #include <gconv.h>
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39: #include "jisx0213.h"
40:
41:
42: #define CHARSET_NAME "EUC-JISX0213//"
43: #define FROM_LOOP from_euc_jisx0213
44: #define TO_LOOP to_euc_jisx0213
45: #define DEFINE_INIT 1
46: #define DEFINE_FINI 1
47: #define FROM_LOOP_MIN_NEEDED_FROM 1
48: #define FROM_LOOP_MAX_NEEDED_FROM 3
49: #define FROM_LOOP_MIN_NEEDED_TO 4
50: #define FROM_LOOP_MAX_NEEDED_TO 8
51: #define TO_LOOP_MIN_NEEDED_FROM 4
52: #define TO_LOOP_MAX_NEEDED_FROM 4
53: #define TO_LOOP_MIN_NEEDED_TO 1
54: #define TO_LOOP_MAX_NEEDED_TO 3
55: #define PREPARE_LOOP \
56: int saved_state; \
57: int *statep = &data->__statep->__count;
58: #define EXTRA_LOOP_ARGS , statep
59:
60:
61:
62:
63: #define SAVE_RESET_STATE(Save) \
64: if (Save) \
65: saved_state = *statep; \
66: else \
67: *statep = saved_state
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78: #define EMIT_SHIFT_TO_INIT \
79: if (data->__statep->__count != 0) \
80: { \
81: if (FROM_DIRECTION) \
82: { \
83: if (__builtin_expect (outbuf + 4 <= outend, 1)) \
84: { \
85: \
86: *((uint32_t *) outbuf) = data->__statep->__count >> 3; \
87: outbuf += sizeof (uint32_t); \
88: data->__statep->__count = 0; \
89: } \
90: else \
91: \
92: status = __GCONV_FULL_OUTPUT; \
93: } \
94: else \
95: { \
96: if (__builtin_expect (outbuf + 2 <= outend, 1)) \
97: { \
98: \
99: uint32_t lasttwo = data->__statep->__count >> 3; \
100: *outbuf++ = (lasttwo >> 8) & 0xff; \
101: *outbuf++ = lasttwo & 0xff; \
102: data->__statep->__count = 0; \
103: } \
104: else \
105: \
106: status = __GCONV_FULL_OUTPUT; \
107: } \
108: }
109:
110:
111:
112: #define MIN_NEEDED_INPUT FROM_LOOP_MIN_NEEDED_FROM
113: #define MAX_NEEDED_INPUT FROM_LOOP_MAX_NEEDED_FROM
114: #define MIN_NEEDED_OUTPUT FROM_LOOP_MIN_NEEDED_TO
115: #define MAX_NEEDED_OUTPUT FROM_LOOP_MAX_NEEDED_TO
116: #define LOOPFCT FROM_LOOP
117: #define BODY \
118: { \
119: uint32_t ch; \
120: \
121: \
122: ch = *statep >> 3; \
123: if (__builtin_expect (ch == 0, 1)) \
124: { \
125: \
126: ch = *inptr; \
127: \
128: if (ch < 0x80) \
129: \
130: ++inptr; \
131: else if ((ch >= 0xa1 && ch <= 0xfe) || ch == 0x8e || ch == 0x8f) \
132: { \
133: \
134: uint32_t ch2; \
135: \
136: if (__builtin_expect (inptr + 1 >= inend, 0)) \
137: { \
138: \
139: result = __GCONV_INCOMPLETE_INPUT; \
140: break; \
141: } \
142: \
143: ch2 = inptr[1]; \
144: \
145: \
146: if (__builtin_expect (ch2 < 0xa1 || ch2 > 0xfe, 0)) \
147: { \
148: \
149: STANDARD_FROM_LOOP_ERR_HANDLER (1); \
150: } \
151: \
152: if (ch == 0x8e) \
153: { \
154: \
155: if (__builtin_expect (ch2 > 0xdf, 0)) \
156: STANDARD_FROM_LOOP_ERR_HANDLER (1); \
157: \
158: ch = ch2 + 0xfec0; \
159: inptr += 2; \
160: } \
161: else \
162: { \
163: const unsigned char *endp; \
164: \
165: if (ch == 0x8f) \
166: { \
167: \
168: uint32_t ch3; \
169: \
170: if (__builtin_expect (inptr + 2 >= inend, 0)) \
171: { \
172: \
173: result = __GCONV_INCOMPLETE_INPUT; \
174: break; \
175: } \
176: \
177: ch3 = inptr[2]; \
178: endp = inptr + 3; \
179: \
180: ch = jisx0213_to_ucs4 (0x200 - 0x80 + ch2, ch3 ^ 0x80); \
181: } \
182: else \
183: { \
184: \
185: endp = inptr + 2; \
186: \
187: ch = jisx0213_to_ucs4 (0x100 - 0x80 + ch, ch2 ^ 0x80); \
188: } \
189: \
190: if (ch == 0) \
191: \
192: STANDARD_FROM_LOOP_ERR_HANDLER (1); \
193: \
194: inptr = endp; \
195: \
196: if (ch < 0x80) \
197: { \
198: \
199: uint32_t u1 = __jisx0213_to_ucs_combining[ch - 1][0]; \
200: uint32_t u2 = __jisx0213_to_ucs_combining[ch - 1][1]; \
201: \
202: put32 (outptr, u1); \
203: outptr += 4; \
204: \
205: \
206: if (outptr + 4 <= outend) \
207: { \
208: put32 (outptr, u2); \
209: outptr += 4; \
210: continue; \
211: } \
212: \
213:
214: \
215: *statep = u2 << 3; \
216: \
217: result = __GCONV_FULL_OUTPUT; \
218: break; \
219: } \
220: } \
221: } \
222: else \
223: { \
224: \
225: STANDARD_FROM_LOOP_ERR_HANDLER (1); \
226: } \
227: } \
228: \
229: put32 (outptr, ch); \
230: outptr += 4; \
231: }
232: #define LOOP_NEED_FLAGS
233: #define EXTRA_LOOP_DECLS , int *statep
234: #define ONEBYTE_BODY \
235: { \
236: if (c < 0x80) \
237: return c; \
238: else \
239: return WEOF; \
240: }
241: #include <iconv/loop.c>
242:
243:
244:
245:
246:
247: static const struct
248: {
249: uint16_t base;
250: uint16_t composed;
251: } comp_table_data[] =
252: {
253: #define COMP_TABLE_IDX_02E5 0
254: #define COMP_TABLE_LEN_02E5 1
255: { 0xabe4, 0xabe5 },
256: #define COMP_TABLE_IDX_02E9 (COMP_TABLE_IDX_02E5 + COMP_TABLE_LEN_02E5)
257: #define COMP_TABLE_LEN_02E9 1
258: { 0xabe0, 0xabe6 },
259: #define COMP_TABLE_IDX_0300 (COMP_TABLE_IDX_02E9 + COMP_TABLE_LEN_02E9)
260: #define COMP_TABLE_LEN_0300 5
261: { 0xa9dc, 0xabc4 },
262: { 0xabb8, 0xabc8 },
263: { 0xabb7, 0xabca },
264: { 0xabb0, 0xabcc },
265: { 0xabc3, 0xabce },
266: #define COMP_TABLE_IDX_0301 (COMP_TABLE_IDX_0300 + COMP_TABLE_LEN_0300)
267: #define COMP_TABLE_LEN_0301 4
268: { 0xabb8, 0xabc9 },
269: { 0xabb7, 0xabcb },
270: { 0xabb0, 0xabcd },
271: { 0xabc3, 0xabcf },
272: #define COMP_TABLE_IDX_309A (COMP_TABLE_IDX_0301 + COMP_TABLE_LEN_0301)
273: #define COMP_TABLE_LEN_309A 14
274: { 0xa4ab, 0xa4f7 },
275: { 0xa4ad, 0xa4f8 },
276: { 0xa4af, 0xa4f9 },
277: { 0xa4b1, 0xa4fa },
278: { 0xa4b3, 0xa4fb },
279: { 0xa5ab, 0xa5f7 },
280: { 0xa5ad, 0xa5f8 },
281: { 0xa5af, 0xa5f9 },
282: { 0xa5b1, 0xa5fa },
283: { 0xa5b3, 0xa5fb },
284: { 0xa5bb, 0xa5fc },
285: { 0xa5c4, 0xa5fd },
286: { 0xa5c8, 0xa5fe },
287: { 0xa6f5, 0xa6f8 },
288: };
289:
290: #define MIN_NEEDED_INPUT TO_LOOP_MIN_NEEDED_FROM
291: #define MAX_NEEDED_INPUT TO_LOOP_MAX_NEEDED_FROM
292: #define MIN_NEEDED_OUTPUT TO_LOOP_MIN_NEEDED_TO
293: #define MAX_NEEDED_OUTPUT TO_LOOP_MAX_NEEDED_TO
294: #define LOOPFCT TO_LOOP
295: #define BODY \
296: { \
297: uint32_t ch = get32 (inptr); \
298: \
299: if ((*statep >> 3) != 0) \
300: { \
301: \
302: uint16_t lasttwo = *statep >> 3; \
303: unsigned int idx; \
304: unsigned int len; \
305: \
306: if (ch == 0x02e5) \
307: idx = COMP_TABLE_IDX_02E5, len = COMP_TABLE_LEN_02E5; \
308: else if (ch == 0x02e9) \
309: idx = COMP_TABLE_IDX_02E9, len = COMP_TABLE_LEN_02E9; \
310: else if (ch == 0x0300) \
311: idx = COMP_TABLE_IDX_0300, len = COMP_TABLE_LEN_0300; \
312: else if (ch == 0x0301) \
313: idx = COMP_TABLE_IDX_0301, len = COMP_TABLE_LEN_0301; \
314: else if (ch == 0x309a) \
315: idx = COMP_TABLE_IDX_309A, len = COMP_TABLE_LEN_309A; \
316: else \
317: goto not_combining; \
318: \
319: do \
320: if (comp_table_data[idx].base == lasttwo) \
321: break; \
322: while (++idx, --len > 0); \
323: \
324: if (len > 0) \
325: { \
326: \
327: if (__builtin_expect (outptr + 1 >= outend, 0)) \
328: { \
329: result = __GCONV_FULL_OUTPUT; \
330: break; \
331: } \
332: lasttwo = comp_table_data[idx].composed; \
333: *outptr++ = (lasttwo >> 8) & 0xff; \
334: *outptr++ = lasttwo & 0xff; \
335: *statep = 0; \
336: inptr += 4; \
337: continue; \
338: } \
339: \
340: not_combining: \
341: \
342: if (__builtin_expect (outptr + 1 >= outend, 0)) \
343: { \
344: result = __GCONV_FULL_OUTPUT; \
345: break; \
346: } \
347: *outptr++ = (lasttwo >> 8) & 0xff; \
348: *outptr++ = lasttwo & 0xff; \
349: *statep = 0; \
350: continue; \
351: } \
352: \
353: if (ch < 0x80) \
354: \
355: *outptr++ = ch; \
356: else if (ch >= 0xff61 && ch <= 0xff9f) \
357: { \
358: \
359: if (__builtin_expect (outptr + 1 >= outend, 0)) \
360: { \
361: result = __GCONV_FULL_OUTPUT; \
362: break; \
363: } \
364: *outptr++ = 0x8e; \
365: *outptr++ = ch - 0xfec0; \
366: } \
367: else \
368: { \
369: uint32_t jch = ucs4_to_jisx0213 (ch); \
370: if (jch == 0) \
371: { \
372: UNICODE_TAG_HANDLER (ch, 4); \
373: \
374: \
375: STANDARD_TO_LOOP_ERR_HANDLER (4); \
376: } \
377: \
378: if (jch & 0x0080) \
379: { \
380: \
381: \
382: \
383: assert ((jch & 0x8000) == 0); \
384: \
385: *statep = (jch | 0x8080) << 3; \
386: inptr += 4; \
387: continue; \
388: } \
389: \
390: if (jch & 0x8000) \
391: { \
392: \
393: if (__builtin_expect (outptr + 2 >= outend, 0)) \
394: { \
395: result = __GCONV_FULL_OUTPUT; \
396: break; \
397: } \
398: *outptr++ = 0x8f; \
399: } \
400: else \
401: { \
402: \
403: if (__builtin_expect (outptr + 1 >= outend, 0)) \
404: { \
405: result = __GCONV_FULL_OUTPUT; \
406: break; \
407: } \
408: } \
409: *outptr++ = (jch >> 8) | 0x80; \
410: *outptr++ = (jch & 0xff) | 0x80; \
411: } \
412: \
413: inptr += 4; \
414: }
415: #define LOOP_NEED_FLAGS
416: #define EXTRA_LOOP_DECLS , int *statep
417: #include <iconv/loop.c>
418:
419:
420:
421: #include <iconv/skeleton.c>