1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22: #include <assert.h>
23: #include <dlfcn.h>
24: #include <stddef.h>
25: #include <sys/param.h>
26:
27: #include <gconv_int.h>
28: #include <sysdep.h>
29:
30:
31: int
32: internal_function
33: __gconv (__gconv_t cd, const unsigned char **inbuf,
34: const unsigned char *inbufend, unsigned char **outbuf,
35: unsigned char *outbufend, size_t *irreversible)
36: {
37: size_t last_step;
38: int result;
39:
40: if (cd == (__gconv_t) -1L)
41: return __GCONV_ILLEGAL_DESCRIPTOR;
42:
43: last_step = cd->__nsteps - 1;
44:
45: assert (irreversible != NULL);
46: *irreversible = 0;
47:
48: cd->__data[last_step].__outbuf = outbuf != NULL ? *outbuf : NULL;
49: cd->__data[last_step].__outbufend = outbufend;
50:
51: __gconv_fct fct = cd->__steps->__fct;
52: #ifdef PTR_DEMANGLE
53: if (cd->__steps->__shlib_handle != NULL)
54: PTR_DEMANGLE (fct);
55: #endif
56:
57: if (inbuf == NULL || *inbuf == NULL)
58: {
59:
60: result = DL_CALL_FCT (fct,
61: (cd->__steps, cd->__data, NULL, NULL, NULL,
62: irreversible,
63: cd->__data[last_step].__outbuf == NULL ? 2 : 1,
64: 0));
65:
66:
67: if (result == __GCONV_OK)
68: for (size_t cnt = 0; cnt <= last_step; ++cnt)
69: cd->__data[cnt].__invocation_counter = 0;
70: }
71: else
72: {
73: const unsigned char *last_start;
74:
75: assert (outbuf != NULL && *outbuf != NULL);
76:
77: do
78: {
79: last_start = *inbuf;
80: result = DL_CALL_FCT (fct,
81: (cd->__steps, cd->__data, inbuf, inbufend,
82: NULL, irreversible, 0, 0));
83: }
84: while (result == __GCONV_EMPTY_INPUT && last_start != *inbuf
85: && *inbuf + cd->__steps->__min_needed_from <= inbufend);
86: }
87:
88: if (outbuf != NULL && *outbuf != NULL)
89: *outbuf = cd->__data[last_step].__outbuf;
90:
91: return result;
92: }