1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136: #include <assert.h>
137: #include <gconv.h>
138: #include <string.h>
139: #define __need_size_t
140: #define __need_NULL
141: #include <stddef.h>
142:
143: #ifndef STATIC_GCONV
144: # include <dlfcn.h>
145: #endif
146:
147: #include <sysdep.h>
148:
149: #ifndef DL_CALL_FCT
150: # define DL_CALL_FCT(fct, args) fct args
151: #endif
152:
153:
154: #if DEFINE_INIT
155: # ifndef FROM_DIRECTION
156: # define FROM_DIRECTION_VAL NULL
157: # define TO_DIRECTION_VAL ((void *) ~((uintptr_t) 0))
158: # define FROM_DIRECTION (step->__data == FROM_DIRECTION_VAL)
159: # endif
160: #else
161: # ifndef FROM_DIRECTION
162: # error "FROM_DIRECTION must be provided if non-default init is used"
163: # endif
164: #endif
165:
166:
167:
168: #ifndef MAX_NEEDED_FROM
169: # define MAX_NEEDED_FROM MIN_NEEDED_FROM
170: #endif
171:
172:
173: #ifndef MAX_NEEDED_TO
174: # define MAX_NEEDED_TO MIN_NEEDED_TO
175: #endif
176:
177:
178: #ifndef FROM_LOOP_MIN_NEEDED_FROM
179: # define FROM_LOOP_MIN_NEEDED_FROM MIN_NEEDED_FROM
180: #endif
181: #ifndef FROM_LOOP_MAX_NEEDED_FROM
182: # define FROM_LOOP_MAX_NEEDED_FROM MAX_NEEDED_FROM
183: #endif
184: #ifndef FROM_LOOP_MIN_NEEDED_TO
185: # define FROM_LOOP_MIN_NEEDED_TO MIN_NEEDED_TO
186: #endif
187: #ifndef FROM_LOOP_MAX_NEEDED_TO
188: # define FROM_LOOP_MAX_NEEDED_TO MAX_NEEDED_TO
189: #endif
190: #ifndef TO_LOOP_MIN_NEEDED_FROM
191: # define TO_LOOP_MIN_NEEDED_FROM MIN_NEEDED_TO
192: #endif
193: #ifndef TO_LOOP_MAX_NEEDED_FROM
194: # define TO_LOOP_MAX_NEEDED_FROM MAX_NEEDED_TO
195: #endif
196: #ifndef TO_LOOP_MIN_NEEDED_TO
197: # define TO_LOOP_MIN_NEEDED_TO MIN_NEEDED_FROM
198: #endif
199: #ifndef TO_LOOP_MAX_NEEDED_TO
200: # define TO_LOOP_MAX_NEEDED_TO MAX_NEEDED_FROM
201: #endif
202:
203:
204:
205:
206:
207: #ifdef _STRING_ARCH_unaligned
208:
209: # define get16u(addr) *((__const uint16_t *) (addr))
210: # define get32u(addr) *((__const uint32_t *) (addr))
211:
212:
213: # define put16u(addr, val) *((uint16_t *) (addr)) = (val)
214: # define put32u(addr, val) *((uint32_t *) (addr)) = (val)
215: #else
216:
217: # if __BYTE_ORDER == __LITTLE_ENDIAN
218: # define get16u(addr) \
219: (((__const unsigned char *) (addr))[1] << 8 \
220: | ((__const unsigned char *) (addr))[0])
221: # define get32u(addr) \
222: (((((__const unsigned char *) (addr))[3] << 8 \
223: | ((__const unsigned char *) (addr))[2]) << 8 \
224: | ((__const unsigned char *) (addr))[1]) << 8 \
225: | ((__const unsigned char *) (addr))[0])
226:
227: # define put16u(addr, val) \
228: ({ uint16_t __val = (val); \
229: ((unsigned char *) (addr))[0] = __val; \
230: ((unsigned char *) (addr))[1] = __val >> 8; \
231: (void) 0; })
232: # define put32u(addr, val) \
233: ({ uint32_t __val = (val); \
234: ((unsigned char *) (addr))[0] = __val; \
235: __val >>= 8; \
236: ((unsigned char *) (addr))[1] = __val; \
237: __val >>= 8; \
238: ((unsigned char *) (addr))[2] = __val; \
239: __val >>= 8; \
240: ((unsigned char *) (addr))[3] = __val; \
241: (void) 0; })
242: # else
243: # define get16u(addr) \
244: (((__const unsigned char *) (addr))[0] << 8 \
245: | ((__const unsigned char *) (addr))[1])
246: # define get32u(addr) \
247: (((((__const unsigned char *) (addr))[0] << 8 \
248: | ((__const unsigned char *) (addr))[1]) << 8 \
249: | ((__const unsigned char *) (addr))[2]) << 8 \
250: | ((__const unsigned char *) (addr))[3])
251:
252: # define put16u(addr, val) \
253: ({ uint16_t __val = (val); \
254: ((unsigned char *) (addr))[1] = __val; \
255: ((unsigned char *) (addr))[0] = __val >> 8; \
256: (void) 0; })
257: # define put32u(addr, val) \
258: ({ uint32_t __val = (val); \
259: ((unsigned char *) (addr))[3] = __val; \
260: __val >>= 8; \
261: ((unsigned char *) (addr))[2] = __val; \
262: __val >>= 8; \
263: ((unsigned char *) (addr))[1] = __val; \
264: __val >>= 8; \
265: ((unsigned char *) (addr))[0] = __val; \
266: (void) 0; })
267: # endif
268: #endif
269:
270:
271:
272:
273: #if !defined RESET_INPUT_BUFFER && !defined SAVE_RESET_STATE
274: # if FROM_LOOP_MIN_NEEDED_FROM == FROM_LOOP_MAX_NEEDED_FROM \
275: && FROM_LOOP_MIN_NEEDED_TO == FROM_LOOP_MAX_NEEDED_TO \
276: && TO_LOOP_MIN_NEEDED_FROM == TO_LOOP_MAX_NEEDED_FROM \
277: && TO_LOOP_MIN_NEEDED_TO == TO_LOOP_MAX_NEEDED_TO
278:
279:
280:
281:
282: # define RESET_INPUT_BUFFER \
283: if (FROM_DIRECTION) \
284: { \
285: if (FROM_LOOP_MIN_NEEDED_FROM % FROM_LOOP_MIN_NEEDED_TO == 0) \
286: *inptrp -= (outbuf - outerr) \
287: * (FROM_LOOP_MIN_NEEDED_FROM / FROM_LOOP_MIN_NEEDED_TO); \
288: else if (FROM_LOOP_MIN_NEEDED_TO % FROM_LOOP_MIN_NEEDED_FROM == 0) \
289: *inptrp -= (outbuf - outerr) \
290: / (FROM_LOOP_MIN_NEEDED_TO / FROM_LOOP_MIN_NEEDED_FROM \
291: ? : 1); \
292: else \
293: *inptrp -= ((outbuf - outerr) / FROM_LOOP_MIN_NEEDED_TO) \
294: * FROM_LOOP_MIN_NEEDED_FROM; \
295: } \
296: else \
297: { \
298: if (TO_LOOP_MIN_NEEDED_FROM % TO_LOOP_MIN_NEEDED_TO == 0) \
299: *inptrp -= (outbuf - outerr) \
300: * (TO_LOOP_MIN_NEEDED_FROM / TO_LOOP_MIN_NEEDED_TO); \
301: else if (TO_LOOP_MIN_NEEDED_TO % TO_LOOP_MIN_NEEDED_FROM == 0) \
302: *inptrp -= (outbuf - outerr) \
303: / (TO_LOOP_MIN_NEEDED_TO / TO_LOOP_MIN_NEEDED_FROM ? : 1); \
304: else \
305: *inptrp -= ((outbuf - outerr) / TO_LOOP_MIN_NEEDED_TO) \
306: * TO_LOOP_MIN_NEEDED_FROM; \
307: }
308: # endif
309: #endif
310:
311:
312:
313:
314: #if DEFINE_INIT
315: # ifndef CHARSET_NAME
316: # error "CHARSET_NAME not defined"
317: # endif
318:
319: extern int gconv_init (struct __gconv_step *step);
320: int
321: gconv_init (struct __gconv_step *step)
322: {
323:
324: if (strcmp (step->__from_name, CHARSET_NAME) == 0)
325: {
326: step->__data = FROM_DIRECTION_VAL;
327:
328: step->__min_needed_from = FROM_LOOP_MIN_NEEDED_FROM;
329: step->__max_needed_from = FROM_LOOP_MAX_NEEDED_FROM;
330: step->__min_needed_to = FROM_LOOP_MIN_NEEDED_TO;
331: step->__max_needed_to = FROM_LOOP_MAX_NEEDED_TO;
332:
333: #ifdef FROM_ONEBYTE
334: step->__btowc_fct = FROM_ONEBYTE;
335: #endif
336: }
337: else if (__builtin_expect (strcmp (step->__to_name, CHARSET_NAME), 0) == 0)
338: {
339: step->__data = TO_DIRECTION_VAL;
340:
341: step->__min_needed_from = TO_LOOP_MIN_NEEDED_FROM;
342: step->__max_needed_from = TO_LOOP_MAX_NEEDED_FROM;
343: step->__min_needed_to = TO_LOOP_MIN_NEEDED_TO;
344: step->__max_needed_to = TO_LOOP_MAX_NEEDED_TO;
345: }
346: else
347: return __GCONV_NOCONV;
348:
349: #ifdef SAVE_RESET_STATE
350: step->__stateful = 1;
351: #else
352: step->__stateful = 0;
353: #endif
354:
355: return __GCONV_OK;
356: }
357: #endif
358:
359:
360:
361:
362:
363: #if DEFINE_FINI
364: #endif
365:
366:
367:
368:
369: #ifndef EXTRA_LOOP_ARGS
370: # define EXTRA_LOOP_ARGS
371: #endif
372:
373:
374:
375: #ifndef FUNCTION_NAME
376: # define FUNCTION_NAME gconv
377: #endif
378:
379:
380: #define SINGLE(fct) SINGLE2 (fct)
381: #define SINGLE2(fct) fct##_single
382:
383:
384: extern int FUNCTION_NAME (struct __gconv_step *step,
385: struct __gconv_step_data *data,
386: const unsigned char **inptrp,
387: const unsigned char *inend,
388: unsigned char **outbufstart, size_t *irreversible,
389: int do_flush, int consume_incomplete);
390: int
391: FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
392: const unsigned char **inptrp, const unsigned char *inend,
393: unsigned char **outbufstart, size_t *irreversible, int do_flush,
394: int consume_incomplete)
395: {
396: struct __gconv_step *next_step = step + 1;
397: struct __gconv_step_data *next_data = data + 1;
398: __gconv_fct fct = NULL;
399: int status;
400:
401: if ((data->__flags & __GCONV_IS_LAST) == 0)
402: {
403: fct = next_step->__fct;
404: #ifdef PTR_DEMANGLE
405: if (next_step->__shlib_handle != NULL)
406: PTR_DEMANGLE (fct);
407: #endif
408: }
409:
410:
411:
412:
413: if (__builtin_expect (do_flush, 0))
414: {
415:
416: assert (outbufstart == NULL);
417:
418: status = __GCONV_OK;
419:
420: #ifdef EMIT_SHIFT_TO_INIT
421: if (do_flush == 1)
422: {
423:
424: unsigned char *outbuf = data->__outbuf;
425: unsigned char *outstart = outbuf;
426: unsigned char *outend = data->__outbufend;
427:
428: # ifdef PREPARE_LOOP
429: PREPARE_LOOP
430: # endif
431:
432: # ifdef SAVE_RESET_STATE
433: SAVE_RESET_STATE (1);
434: # endif
435:
436:
437: EMIT_SHIFT_TO_INIT;
438:
439:
440:
441:
442:
443:
444: if (status == __GCONV_OK)
445: {
446: if (data->__flags & __GCONV_IS_LAST)
447:
448: data->__outbuf = outbuf;
449: else
450: {
451:
452: if (outbuf > outstart)
453: {
454: const unsigned char *outerr = outstart;
455: int result;
456:
457: result = DL_CALL_FCT (fct, (next_step, next_data,
458: &outerr, outbuf, NULL,
459: irreversible, 0,
460: consume_incomplete));
461:
462: if (result != __GCONV_EMPTY_INPUT)
463: {
464: if (__builtin_expect (outerr != outbuf, 0))
465: {
466:
467: outbuf = outstart;
468:
469:
470: # ifdef SAVE_RESET_STATE
471: SAVE_RESET_STATE (0);
472: # endif
473: }
474:
475:
476: status = result;
477: }
478: }
479:
480: if (status == __GCONV_OK)
481:
482: status = DL_CALL_FCT (fct, (next_step, next_data, NULL,
483: NULL, NULL, irreversible, 1,
484: consume_incomplete));
485: }
486: }
487: }
488: else
489: #endif
490: {
491:
492:
493:
494: memset (data->__statep, '\0', sizeof (*data->__statep));
495:
496: if (! (data->__flags & __GCONV_IS_LAST))
497:
498: status = DL_CALL_FCT (fct, (next_step, next_data, NULL, NULL,
499: NULL, irreversible, do_flush,
500: consume_incomplete));
501: }
502: }
503: else
504: {
505:
506: const unsigned char *inptr = *inptrp;
507: unsigned char *outbuf = (__builtin_expect (outbufstart == NULL, 1)
508: ? data->__outbuf : *outbufstart);
509: unsigned char *outend = data->__outbufend;
510: unsigned char *outstart;
511:
512:
513: size_t lirreversible = 0;
514: size_t *lirreversiblep = irreversible ? &lirreversible : NULL;
515:
516:
517:
518:
519:
520:
521:
522:
523:
524:
525: #define POSSIBLY_UNALIGNED \
526: (!defined _STRING_ARCH_unaligned \
527: && (((FROM_LOOP_MIN_NEEDED_FROM != 1 \
528: && FROM_LOOP_MAX_NEEDED_FROM % FROM_LOOP_MIN_NEEDED_FROM == 0) \
529: && (FROM_LOOP_MIN_NEEDED_TO != 1 \
530: && FROM_LOOP_MAX_NEEDED_TO % FROM_LOOP_MIN_NEEDED_TO == 0)) \
531: || ((TO_LOOP_MIN_NEEDED_FROM != 1 \
532: && TO_LOOP_MAX_NEEDED_FROM % TO_LOOP_MIN_NEEDED_FROM == 0) \
533: && (TO_LOOP_MIN_NEEDED_TO != 1 \
534: && TO_LOOP_MAX_NEEDED_TO % TO_LOOP_MIN_NEEDED_TO == 0))))
535: #if POSSIBLY_UNALIGNED
536: int unaligned;
537: # define GEN_unaligned(name) GEN_unaligned2 (name)
538: # define GEN_unaligned2(name) name##_unaligned
539: #else
540: # def