1/*
2 * multibytecodec.h: Common Multibyte Codec Implementation
3 *
4 * Written by Hye-Shik Chang <perky@FreeBSD.org>
5 */
6
7#ifndef _PYTHON_MULTIBYTECODEC_H_
8#define _PYTHON_MULTIBYTECODEC_H_
9#ifdef __cplusplus
10extern "C" {
11#endif
12
13#ifdef uint16_t
14typedef uint16_t ucs2_t, DBCHAR;
15#else
16typedef unsigned short ucs2_t, DBCHAR;
17#endif
18
19/*
20 * A struct that provides 8 bytes of state for multibyte
21 * codecs. Codecs are free to use this how they want. Note: if you
22 * need to add a new field to this struct, ensure that its byte order
23 * is independent of CPU endianness so that the return value of
24 * getstate doesn't differ between little and big endian CPUs.
25 */
26typedef struct {
27    unsigned char c[8];
28} MultibyteCodec_State;
29
30typedef int (*mbcodec_init)(const void *config);
31typedef Py_ssize_t (*mbencode_func)(MultibyteCodec_State *state,
32                        const void *config,
33                        int kind, const void *data,
34                        Py_ssize_t *inpos, Py_ssize_t inlen,
35                        unsigned char **outbuf, Py_ssize_t outleft,
36                        int flags);
37typedef int (*mbencodeinit_func)(MultibyteCodec_State *state,
38                                 const void *config);
39typedef Py_ssize_t (*mbencodereset_func)(MultibyteCodec_State *state,
40                        const void *config,
41                        unsigned char **outbuf, Py_ssize_t outleft);
42typedef Py_ssize_t (*mbdecode_func)(MultibyteCodec_State *state,
43                        const void *config,
44                        const unsigned char **inbuf, Py_ssize_t inleft,
45                        _PyUnicodeWriter *writer);
46typedef int (*mbdecodeinit_func)(MultibyteCodec_State *state,
47                                 const void *config);
48typedef Py_ssize_t (*mbdecodereset_func)(MultibyteCodec_State *state,
49                                         const void *config);
50
51typedef struct {
52    const char *encoding;
53    const void *config;
54    mbcodec_init codecinit;
55    mbencode_func encode;
56    mbencodeinit_func encinit;
57    mbencodereset_func encreset;
58    mbdecode_func decode;
59    mbdecodeinit_func decinit;
60    mbdecodereset_func decreset;
61} MultibyteCodec;
62
63typedef struct {
64    PyObject_HEAD
65    MultibyteCodec *codec;
66} MultibyteCodecObject;
67
68#define MultibyteCodec_Check(state, op) Py_IS_TYPE((op), state->multibytecodec_type)
69
70#define _MultibyteStatefulCodec_HEAD            \
71    PyObject_HEAD                               \
72    MultibyteCodec *codec;                      \
73    MultibyteCodec_State state;                 \
74    PyObject *errors;
75typedef struct {
76    _MultibyteStatefulCodec_HEAD
77} MultibyteStatefulCodecContext;
78
79#define MAXENCPENDING   2
80#define _MultibyteStatefulEncoder_HEAD          \
81    _MultibyteStatefulCodec_HEAD                \
82    PyObject *pending;
83typedef struct {
84    _MultibyteStatefulEncoder_HEAD
85} MultibyteStatefulEncoderContext;
86
87#define MAXDECPENDING   8
88#define _MultibyteStatefulDecoder_HEAD          \
89    _MultibyteStatefulCodec_HEAD                \
90    unsigned char pending[MAXDECPENDING];       \
91    Py_ssize_t pendingsize;
92typedef struct {
93    _MultibyteStatefulDecoder_HEAD
94} MultibyteStatefulDecoderContext;
95
96typedef struct {
97    _MultibyteStatefulEncoder_HEAD
98} MultibyteIncrementalEncoderObject;
99
100typedef struct {
101    _MultibyteStatefulDecoder_HEAD
102} MultibyteIncrementalDecoderObject;
103
104typedef struct {
105    _MultibyteStatefulDecoder_HEAD
106    PyObject *stream;
107} MultibyteStreamReaderObject;
108
109typedef struct {
110    _MultibyteStatefulEncoder_HEAD
111    PyObject *stream;
112} MultibyteStreamWriterObject;
113
114/* positive values for illegal sequences */
115#define MBERR_TOOSMALL          (-1) /* insufficient output buffer space */
116#define MBERR_TOOFEW            (-2) /* incomplete input buffer */
117#define MBERR_INTERNAL          (-3) /* internal runtime error */
118#define MBERR_EXCEPTION         (-4) /* an exception has been raised */
119
120#define ERROR_STRICT            (PyObject *)(1)
121#define ERROR_IGNORE            (PyObject *)(2)
122#define ERROR_REPLACE           (PyObject *)(3)
123#define ERROR_ISCUSTOM(p)       ((p) < ERROR_STRICT || ERROR_REPLACE < (p))
124#define ERROR_DECREF(p)                             \
125    do {                                            \
126        if (p != NULL && ERROR_ISCUSTOM(p))         \
127            Py_DECREF(p);                           \
128    } while (0);
129
130#define MBENC_FLUSH             0x0001 /* encode all characters encodable */
131#define MBENC_MAX               MBENC_FLUSH
132
133#define PyMultibyteCodec_CAPSULE_NAME "multibytecodec.__map_*"
134
135
136#ifdef __cplusplus
137}
138#endif
139#endif
140