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
10 extern "C" {
11 #endif
12 
13 #ifdef uint16_t
14 typedef uint16_t ucs2_t, DBCHAR;
15 #else
16 typedef 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  */
26 typedef struct {
27     unsigned char c[8];
28 } MultibyteCodec_State;
29 
30 typedef int (*mbcodec_init)(const void *config);
31 typedef Py_ssize_t (*mbencode_func)(MultibyteCodec_State *state,
32                         const void *config,
33                         int kind, void *data,
34                         Py_ssize_t *inpos, Py_ssize_t inlen,
35                         unsigned char **outbuf, Py_ssize_t outleft,
36                         int flags);
37 typedef int (*mbencodeinit_func)(MultibyteCodec_State *state,
38                                  const void *config);
39 typedef Py_ssize_t (*mbencodereset_func)(MultibyteCodec_State *state,
40                         const void *config,
41                         unsigned char **outbuf, Py_ssize_t outleft);
42 typedef Py_ssize_t (*mbdecode_func)(MultibyteCodec_State *state,
43                         const void *config,
44                         const unsigned char **inbuf, Py_ssize_t inleft,
45                         _PyUnicodeWriter *writer);
46 typedef int (*mbdecodeinit_func)(MultibyteCodec_State *state,
47                                  const void *config);
48 typedef Py_ssize_t (*mbdecodereset_func)(MultibyteCodec_State *state,
49                                          const void *config);
50 
51 typedef 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 
63 typedef struct {
64     PyObject_HEAD
65     MultibyteCodec *codec;
66 } MultibyteCodecObject;
67 
68 #define MultibyteCodec_Check(op) ((op)->ob_type == &MultibyteCodec_Type)
69 
70 #define _MultibyteStatefulCodec_HEAD            \
71     PyObject_HEAD                               \
72     MultibyteCodec *codec;                      \
73     MultibyteCodec_State state;                 \
74     PyObject *errors;
75 typedef struct {
76     _MultibyteStatefulCodec_HEAD
77 } MultibyteStatefulCodecContext;
78 
79 #define MAXENCPENDING   2
80 #define _MultibyteStatefulEncoder_HEAD          \
81     _MultibyteStatefulCodec_HEAD                \
82     PyObject *pending;
83 typedef 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;
92 typedef struct {
93     _MultibyteStatefulDecoder_HEAD
94 } MultibyteStatefulDecoderContext;
95 
96 typedef struct {
97     _MultibyteStatefulEncoder_HEAD
98 } MultibyteIncrementalEncoderObject;
99 
100 typedef struct {
101     _MultibyteStatefulDecoder_HEAD
102 } MultibyteIncrementalDecoderObject;
103 
104 typedef struct {
105     _MultibyteStatefulDecoder_HEAD
106     PyObject *stream;
107 } MultibyteStreamReaderObject;
108 
109 typedef 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