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 uint32_t
14typedef uint32_t ucs4_t;
15#else
16typedef unsigned int ucs4_t;
17#endif
18
19#ifdef uint16_t
20typedef uint16_t ucs2_t, DBCHAR;
21#else
22typedef unsigned short ucs2_t, DBCHAR;
23#endif
24
25typedef union {
26    void *p;
27    int i;
28    unsigned char c[8];
29    ucs2_t u2[4];
30    ucs4_t u4[2];
31} MultibyteCodec_State;
32
33typedef int (*mbcodec_init)(const void *config);
34typedef Py_ssize_t (*mbencode_func)(MultibyteCodec_State *state,
35                        const void *config,
36                        const Py_UNICODE **inbuf, Py_ssize_t inleft,
37                        unsigned char **outbuf, Py_ssize_t outleft,
38                        int flags);
39typedef int (*mbencodeinit_func)(MultibyteCodec_State *state,
40                                 const void *config);
41typedef Py_ssize_t (*mbencodereset_func)(MultibyteCodec_State *state,
42                        const void *config,
43                        unsigned char **outbuf, Py_ssize_t outleft);
44typedef Py_ssize_t (*mbdecode_func)(MultibyteCodec_State *state,
45                        const void *config,
46                        const unsigned char **inbuf, Py_ssize_t inleft,
47                        Py_UNICODE **outbuf, Py_ssize_t outleft);
48typedef int (*mbdecodeinit_func)(MultibyteCodec_State *state,
49                                 const void *config);
50typedef Py_ssize_t (*mbdecodereset_func)(MultibyteCodec_State *state,
51                                         const void *config);
52
53typedef struct {
54    const char *encoding;
55    const void *config;
56    mbcodec_init codecinit;
57    mbencode_func encode;
58    mbencodeinit_func encinit;
59    mbencodereset_func encreset;
60    mbdecode_func decode;
61    mbdecodeinit_func decinit;
62    mbdecodereset_func decreset;
63} MultibyteCodec;
64
65typedef struct {
66    PyObject_HEAD
67    MultibyteCodec *codec;
68} MultibyteCodecObject;
69
70#define MultibyteCodec_Check(op) ((op)->ob_type == &MultibyteCodec_Type)
71
72#define _MultibyteStatefulCodec_HEAD            \
73    PyObject_HEAD                               \
74    MultibyteCodec *codec;                      \
75    MultibyteCodec_State state;                 \
76    PyObject *errors;
77typedef struct {
78    _MultibyteStatefulCodec_HEAD
79} MultibyteStatefulCodecContext;
80
81#define MAXENCPENDING   2
82#define _MultibyteStatefulEncoder_HEAD          \
83    _MultibyteStatefulCodec_HEAD                \
84    Py_UNICODE pending[MAXENCPENDING];          \
85    Py_ssize_t pendingsize;
86typedef struct {
87    _MultibyteStatefulEncoder_HEAD
88} MultibyteStatefulEncoderContext;
89
90#define MAXDECPENDING   8
91#define _MultibyteStatefulDecoder_HEAD          \
92    _MultibyteStatefulCodec_HEAD                \
93    unsigned char pending[MAXDECPENDING];       \
94    Py_ssize_t pendingsize;
95typedef struct {
96    _MultibyteStatefulDecoder_HEAD
97} MultibyteStatefulDecoderContext;
98
99typedef struct {
100    _MultibyteStatefulEncoder_HEAD
101} MultibyteIncrementalEncoderObject;
102
103typedef struct {
104    _MultibyteStatefulDecoder_HEAD
105} MultibyteIncrementalDecoderObject;
106
107typedef struct {
108    _MultibyteStatefulDecoder_HEAD
109    PyObject *stream;
110} MultibyteStreamReaderObject;
111
112typedef struct {
113    _MultibyteStatefulEncoder_HEAD
114    PyObject *stream;
115} MultibyteStreamWriterObject;
116
117/* positive values for illegal sequences */
118#define MBERR_TOOSMALL          (-1) /* insufficient output buffer space */
119#define MBERR_TOOFEW            (-2) /* incomplete input buffer */
120#define MBERR_INTERNAL          (-3) /* internal runtime error */
121
122#define ERROR_STRICT            (PyObject *)(1)
123#define ERROR_IGNORE            (PyObject *)(2)
124#define ERROR_REPLACE           (PyObject *)(3)
125#define ERROR_ISCUSTOM(p)       ((p) < ERROR_STRICT || ERROR_REPLACE < (p))
126#define ERROR_DECREF(p) do {                    \
127    if (p != NULL && ERROR_ISCUSTOM(p)) {       \
128        Py_DECREF(p);                           \
129    }                                           \
130} while (0);
131
132#define MBENC_FLUSH             0x0001 /* encode all characters encodable */
133#define MBENC_MAX               MBENC_FLUSH
134
135#define PyMultibyteCodec_CAPSULE_NAME "multibytecodec.__map_*"
136
137
138#ifdef __cplusplus
139}
140#endif
141#endif
142