17db96d56Sopenharmony_ci/*
27db96d56Sopenharmony_ci * multibytecodec.h: Common Multibyte Codec Implementation
37db96d56Sopenharmony_ci *
47db96d56Sopenharmony_ci * Written by Hye-Shik Chang <perky@FreeBSD.org>
57db96d56Sopenharmony_ci */
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci#ifndef _PYTHON_MULTIBYTECODEC_H_
87db96d56Sopenharmony_ci#define _PYTHON_MULTIBYTECODEC_H_
97db96d56Sopenharmony_ci#ifdef __cplusplus
107db96d56Sopenharmony_ciextern "C" {
117db96d56Sopenharmony_ci#endif
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_ci#ifdef uint16_t
147db96d56Sopenharmony_citypedef uint16_t ucs2_t, DBCHAR;
157db96d56Sopenharmony_ci#else
167db96d56Sopenharmony_citypedef unsigned short ucs2_t, DBCHAR;
177db96d56Sopenharmony_ci#endif
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_ci/*
207db96d56Sopenharmony_ci * A struct that provides 8 bytes of state for multibyte
217db96d56Sopenharmony_ci * codecs. Codecs are free to use this how they want. Note: if you
227db96d56Sopenharmony_ci * need to add a new field to this struct, ensure that its byte order
237db96d56Sopenharmony_ci * is independent of CPU endianness so that the return value of
247db96d56Sopenharmony_ci * getstate doesn't differ between little and big endian CPUs.
257db96d56Sopenharmony_ci */
267db96d56Sopenharmony_citypedef struct {
277db96d56Sopenharmony_ci    unsigned char c[8];
287db96d56Sopenharmony_ci} MultibyteCodec_State;
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_citypedef int (*mbcodec_init)(const void *config);
317db96d56Sopenharmony_citypedef Py_ssize_t (*mbencode_func)(MultibyteCodec_State *state,
327db96d56Sopenharmony_ci                        const void *config,
337db96d56Sopenharmony_ci                        int kind, const void *data,
347db96d56Sopenharmony_ci                        Py_ssize_t *inpos, Py_ssize_t inlen,
357db96d56Sopenharmony_ci                        unsigned char **outbuf, Py_ssize_t outleft,
367db96d56Sopenharmony_ci                        int flags);
377db96d56Sopenharmony_citypedef int (*mbencodeinit_func)(MultibyteCodec_State *state,
387db96d56Sopenharmony_ci                                 const void *config);
397db96d56Sopenharmony_citypedef Py_ssize_t (*mbencodereset_func)(MultibyteCodec_State *state,
407db96d56Sopenharmony_ci                        const void *config,
417db96d56Sopenharmony_ci                        unsigned char **outbuf, Py_ssize_t outleft);
427db96d56Sopenharmony_citypedef Py_ssize_t (*mbdecode_func)(MultibyteCodec_State *state,
437db96d56Sopenharmony_ci                        const void *config,
447db96d56Sopenharmony_ci                        const unsigned char **inbuf, Py_ssize_t inleft,
457db96d56Sopenharmony_ci                        _PyUnicodeWriter *writer);
467db96d56Sopenharmony_citypedef int (*mbdecodeinit_func)(MultibyteCodec_State *state,
477db96d56Sopenharmony_ci                                 const void *config);
487db96d56Sopenharmony_citypedef Py_ssize_t (*mbdecodereset_func)(MultibyteCodec_State *state,
497db96d56Sopenharmony_ci                                         const void *config);
507db96d56Sopenharmony_ci
517db96d56Sopenharmony_citypedef struct {
527db96d56Sopenharmony_ci    const char *encoding;
537db96d56Sopenharmony_ci    const void *config;
547db96d56Sopenharmony_ci    mbcodec_init codecinit;
557db96d56Sopenharmony_ci    mbencode_func encode;
567db96d56Sopenharmony_ci    mbencodeinit_func encinit;
577db96d56Sopenharmony_ci    mbencodereset_func encreset;
587db96d56Sopenharmony_ci    mbdecode_func decode;
597db96d56Sopenharmony_ci    mbdecodeinit_func decinit;
607db96d56Sopenharmony_ci    mbdecodereset_func decreset;
617db96d56Sopenharmony_ci} MultibyteCodec;
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_citypedef struct {
647db96d56Sopenharmony_ci    PyObject_HEAD
657db96d56Sopenharmony_ci    MultibyteCodec *codec;
667db96d56Sopenharmony_ci} MultibyteCodecObject;
677db96d56Sopenharmony_ci
687db96d56Sopenharmony_ci#define MultibyteCodec_Check(state, op) Py_IS_TYPE((op), state->multibytecodec_type)
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ci#define _MultibyteStatefulCodec_HEAD            \
717db96d56Sopenharmony_ci    PyObject_HEAD                               \
727db96d56Sopenharmony_ci    MultibyteCodec *codec;                      \
737db96d56Sopenharmony_ci    MultibyteCodec_State state;                 \
747db96d56Sopenharmony_ci    PyObject *errors;
757db96d56Sopenharmony_citypedef struct {
767db96d56Sopenharmony_ci    _MultibyteStatefulCodec_HEAD
777db96d56Sopenharmony_ci} MultibyteStatefulCodecContext;
787db96d56Sopenharmony_ci
797db96d56Sopenharmony_ci#define MAXENCPENDING   2
807db96d56Sopenharmony_ci#define _MultibyteStatefulEncoder_HEAD          \
817db96d56Sopenharmony_ci    _MultibyteStatefulCodec_HEAD                \
827db96d56Sopenharmony_ci    PyObject *pending;
837db96d56Sopenharmony_citypedef struct {
847db96d56Sopenharmony_ci    _MultibyteStatefulEncoder_HEAD
857db96d56Sopenharmony_ci} MultibyteStatefulEncoderContext;
867db96d56Sopenharmony_ci
877db96d56Sopenharmony_ci#define MAXDECPENDING   8
887db96d56Sopenharmony_ci#define _MultibyteStatefulDecoder_HEAD          \
897db96d56Sopenharmony_ci    _MultibyteStatefulCodec_HEAD                \
907db96d56Sopenharmony_ci    unsigned char pending[MAXDECPENDING];       \
917db96d56Sopenharmony_ci    Py_ssize_t pendingsize;
927db96d56Sopenharmony_citypedef struct {
937db96d56Sopenharmony_ci    _MultibyteStatefulDecoder_HEAD
947db96d56Sopenharmony_ci} MultibyteStatefulDecoderContext;
957db96d56Sopenharmony_ci
967db96d56Sopenharmony_citypedef struct {
977db96d56Sopenharmony_ci    _MultibyteStatefulEncoder_HEAD
987db96d56Sopenharmony_ci} MultibyteIncrementalEncoderObject;
997db96d56Sopenharmony_ci
1007db96d56Sopenharmony_citypedef struct {
1017db96d56Sopenharmony_ci    _MultibyteStatefulDecoder_HEAD
1027db96d56Sopenharmony_ci} MultibyteIncrementalDecoderObject;
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_citypedef struct {
1057db96d56Sopenharmony_ci    _MultibyteStatefulDecoder_HEAD
1067db96d56Sopenharmony_ci    PyObject *stream;
1077db96d56Sopenharmony_ci} MultibyteStreamReaderObject;
1087db96d56Sopenharmony_ci
1097db96d56Sopenharmony_citypedef struct {
1107db96d56Sopenharmony_ci    _MultibyteStatefulEncoder_HEAD
1117db96d56Sopenharmony_ci    PyObject *stream;
1127db96d56Sopenharmony_ci} MultibyteStreamWriterObject;
1137db96d56Sopenharmony_ci
1147db96d56Sopenharmony_ci/* positive values for illegal sequences */
1157db96d56Sopenharmony_ci#define MBERR_TOOSMALL          (-1) /* insufficient output buffer space */
1167db96d56Sopenharmony_ci#define MBERR_TOOFEW            (-2) /* incomplete input buffer */
1177db96d56Sopenharmony_ci#define MBERR_INTERNAL          (-3) /* internal runtime error */
1187db96d56Sopenharmony_ci#define MBERR_EXCEPTION         (-4) /* an exception has been raised */
1197db96d56Sopenharmony_ci
1207db96d56Sopenharmony_ci#define ERROR_STRICT            (PyObject *)(1)
1217db96d56Sopenharmony_ci#define ERROR_IGNORE            (PyObject *)(2)
1227db96d56Sopenharmony_ci#define ERROR_REPLACE           (PyObject *)(3)
1237db96d56Sopenharmony_ci#define ERROR_ISCUSTOM(p)       ((p) < ERROR_STRICT || ERROR_REPLACE < (p))
1247db96d56Sopenharmony_ci#define ERROR_DECREF(p)                             \
1257db96d56Sopenharmony_ci    do {                                            \
1267db96d56Sopenharmony_ci        if (p != NULL && ERROR_ISCUSTOM(p))         \
1277db96d56Sopenharmony_ci            Py_DECREF(p);                           \
1287db96d56Sopenharmony_ci    } while (0);
1297db96d56Sopenharmony_ci
1307db96d56Sopenharmony_ci#define MBENC_FLUSH             0x0001 /* encode all characters encodable */
1317db96d56Sopenharmony_ci#define MBENC_MAX               MBENC_FLUSH
1327db96d56Sopenharmony_ci
1337db96d56Sopenharmony_ci#define PyMultibyteCodec_CAPSULE_NAME "multibytecodec.__map_*"
1347db96d56Sopenharmony_ci
1357db96d56Sopenharmony_ci
1367db96d56Sopenharmony_ci#ifdef __cplusplus
1377db96d56Sopenharmony_ci}
1387db96d56Sopenharmony_ci#endif
1397db96d56Sopenharmony_ci#endif
140