17db96d56Sopenharmony_ci/* 27db96d56Sopenharmony_ci * cjkcodecs.h: common header for cjkcodecs 37db96d56Sopenharmony_ci * 47db96d56Sopenharmony_ci * Written by Hye-Shik Chang <perky@FreeBSD.org> 57db96d56Sopenharmony_ci */ 67db96d56Sopenharmony_ci 77db96d56Sopenharmony_ci#ifndef _CJKCODECS_H_ 87db96d56Sopenharmony_ci#define _CJKCODECS_H_ 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN 117db96d56Sopenharmony_ci#include "Python.h" 127db96d56Sopenharmony_ci#include "multibytecodec.h" 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci/* a unicode "undefined" code point */ 167db96d56Sopenharmony_ci#define UNIINV 0xFFFE 177db96d56Sopenharmony_ci 187db96d56Sopenharmony_ci/* internal-use DBCS code points which aren't used by any charsets */ 197db96d56Sopenharmony_ci#define NOCHAR 0xFFFF 207db96d56Sopenharmony_ci#define MULTIC 0xFFFE 217db96d56Sopenharmony_ci#define DBCINV 0xFFFD 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_ci/* shorter macros to save source size of mapping tables */ 247db96d56Sopenharmony_ci#define U UNIINV 257db96d56Sopenharmony_ci#define N NOCHAR 267db96d56Sopenharmony_ci#define M MULTIC 277db96d56Sopenharmony_ci#define D DBCINV 287db96d56Sopenharmony_ci 297db96d56Sopenharmony_cistruct dbcs_index { 307db96d56Sopenharmony_ci const ucs2_t *map; 317db96d56Sopenharmony_ci unsigned char bottom, top; 327db96d56Sopenharmony_ci}; 337db96d56Sopenharmony_citypedef struct dbcs_index decode_map; 347db96d56Sopenharmony_ci 357db96d56Sopenharmony_cistruct widedbcs_index { 367db96d56Sopenharmony_ci const Py_UCS4 *map; 377db96d56Sopenharmony_ci unsigned char bottom, top; 387db96d56Sopenharmony_ci}; 397db96d56Sopenharmony_citypedef struct widedbcs_index widedecode_map; 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_cistruct unim_index { 427db96d56Sopenharmony_ci const DBCHAR *map; 437db96d56Sopenharmony_ci unsigned char bottom, top; 447db96d56Sopenharmony_ci}; 457db96d56Sopenharmony_citypedef struct unim_index encode_map; 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_cistruct unim_index_bytebased { 487db96d56Sopenharmony_ci const unsigned char *map; 497db96d56Sopenharmony_ci unsigned char bottom, top; 507db96d56Sopenharmony_ci}; 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_cistruct dbcs_map { 537db96d56Sopenharmony_ci const char *charset; 547db96d56Sopenharmony_ci const struct unim_index *encmap; 557db96d56Sopenharmony_ci const struct dbcs_index *decmap; 567db96d56Sopenharmony_ci}; 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_cistruct pair_encodemap { 597db96d56Sopenharmony_ci Py_UCS4 uniseq; 607db96d56Sopenharmony_ci DBCHAR code; 617db96d56Sopenharmony_ci}; 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_cistatic const MultibyteCodec *codec_list; 647db96d56Sopenharmony_cistatic const struct dbcs_map *mapping_list; 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_ci#define CODEC_INIT(encoding) \ 677db96d56Sopenharmony_ci static int encoding##_codec_init(const void *config) 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_ci#define ENCODER_INIT(encoding) \ 707db96d56Sopenharmony_ci static int encoding##_encode_init( \ 717db96d56Sopenharmony_ci MultibyteCodec_State *state, const void *config) 727db96d56Sopenharmony_ci#define ENCODER(encoding) \ 737db96d56Sopenharmony_ci static Py_ssize_t encoding##_encode( \ 747db96d56Sopenharmony_ci MultibyteCodec_State *state, const void *config, \ 757db96d56Sopenharmony_ci int kind, const void *data, \ 767db96d56Sopenharmony_ci Py_ssize_t *inpos, Py_ssize_t inlen, \ 777db96d56Sopenharmony_ci unsigned char **outbuf, Py_ssize_t outleft, int flags) 787db96d56Sopenharmony_ci#define ENCODER_RESET(encoding) \ 797db96d56Sopenharmony_ci static Py_ssize_t encoding##_encode_reset( \ 807db96d56Sopenharmony_ci MultibyteCodec_State *state, const void *config, \ 817db96d56Sopenharmony_ci unsigned char **outbuf, Py_ssize_t outleft) 827db96d56Sopenharmony_ci 837db96d56Sopenharmony_ci#define DECODER_INIT(encoding) \ 847db96d56Sopenharmony_ci static int encoding##_decode_init( \ 857db96d56Sopenharmony_ci MultibyteCodec_State *state, const void *config) 867db96d56Sopenharmony_ci#define DECODER(encoding) \ 877db96d56Sopenharmony_ci static Py_ssize_t encoding##_decode( \ 887db96d56Sopenharmony_ci MultibyteCodec_State *state, const void *config, \ 897db96d56Sopenharmony_ci const unsigned char **inbuf, Py_ssize_t inleft, \ 907db96d56Sopenharmony_ci _PyUnicodeWriter *writer) 917db96d56Sopenharmony_ci#define DECODER_RESET(encoding) \ 927db96d56Sopenharmony_ci static Py_ssize_t encoding##_decode_reset( \ 937db96d56Sopenharmony_ci MultibyteCodec_State *state, const void *config) 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_ci#define NEXT_IN(i) \ 967db96d56Sopenharmony_ci do { \ 977db96d56Sopenharmony_ci (*inbuf) += (i); \ 987db96d56Sopenharmony_ci (inleft) -= (i); \ 997db96d56Sopenharmony_ci } while (0) 1007db96d56Sopenharmony_ci#define NEXT_INCHAR(i) \ 1017db96d56Sopenharmony_ci do { \ 1027db96d56Sopenharmony_ci (*inpos) += (i); \ 1037db96d56Sopenharmony_ci } while (0) 1047db96d56Sopenharmony_ci#define NEXT_OUT(o) \ 1057db96d56Sopenharmony_ci do { \ 1067db96d56Sopenharmony_ci (*outbuf) += (o); \ 1077db96d56Sopenharmony_ci (outleft) -= (o); \ 1087db96d56Sopenharmony_ci } while (0) 1097db96d56Sopenharmony_ci#define NEXT(i, o) \ 1107db96d56Sopenharmony_ci do { \ 1117db96d56Sopenharmony_ci NEXT_INCHAR(i); \ 1127db96d56Sopenharmony_ci NEXT_OUT(o); \ 1137db96d56Sopenharmony_ci } while (0) 1147db96d56Sopenharmony_ci 1157db96d56Sopenharmony_ci#define REQUIRE_INBUF(n) \ 1167db96d56Sopenharmony_ci do { \ 1177db96d56Sopenharmony_ci if (inleft < (n)) \ 1187db96d56Sopenharmony_ci return MBERR_TOOFEW; \ 1197db96d56Sopenharmony_ci } while (0) 1207db96d56Sopenharmony_ci 1217db96d56Sopenharmony_ci#define REQUIRE_OUTBUF(n) \ 1227db96d56Sopenharmony_ci do { \ 1237db96d56Sopenharmony_ci if (outleft < (n)) \ 1247db96d56Sopenharmony_ci return MBERR_TOOSMALL; \ 1257db96d56Sopenharmony_ci } while (0) 1267db96d56Sopenharmony_ci 1277db96d56Sopenharmony_ci#define INBYTE1 ((*inbuf)[0]) 1287db96d56Sopenharmony_ci#define INBYTE2 ((*inbuf)[1]) 1297db96d56Sopenharmony_ci#define INBYTE3 ((*inbuf)[2]) 1307db96d56Sopenharmony_ci#define INBYTE4 ((*inbuf)[3]) 1317db96d56Sopenharmony_ci 1327db96d56Sopenharmony_ci#define INCHAR1 (PyUnicode_READ(kind, data, *inpos)) 1337db96d56Sopenharmony_ci#define INCHAR2 (PyUnicode_READ(kind, data, *inpos + 1)) 1347db96d56Sopenharmony_ci 1357db96d56Sopenharmony_ci#define OUTCHAR(c) \ 1367db96d56Sopenharmony_ci do { \ 1377db96d56Sopenharmony_ci if (_PyUnicodeWriter_WriteChar(writer, (c)) < 0) \ 1387db96d56Sopenharmony_ci return MBERR_EXCEPTION; \ 1397db96d56Sopenharmony_ci } while (0) 1407db96d56Sopenharmony_ci 1417db96d56Sopenharmony_ci#define OUTCHAR2(c1, c2) \ 1427db96d56Sopenharmony_ci do { \ 1437db96d56Sopenharmony_ci Py_UCS4 _c1 = (c1); \ 1447db96d56Sopenharmony_ci Py_UCS4 _c2 = (c2); \ 1457db96d56Sopenharmony_ci if (_PyUnicodeWriter_Prepare(writer, 2, Py_MAX(_c1, c2)) < 0) \ 1467db96d56Sopenharmony_ci return MBERR_EXCEPTION; \ 1477db96d56Sopenharmony_ci PyUnicode_WRITE(writer->kind, writer->data, writer->pos, _c1); \ 1487db96d56Sopenharmony_ci PyUnicode_WRITE(writer->kind, writer->data, writer->pos + 1, _c2); \ 1497db96d56Sopenharmony_ci writer->pos += 2; \ 1507db96d56Sopenharmony_ci } while (0) 1517db96d56Sopenharmony_ci 1527db96d56Sopenharmony_ci#define OUTBYTEI(c, i) \ 1537db96d56Sopenharmony_ci do { \ 1547db96d56Sopenharmony_ci assert((unsigned char)(c) == (c)); \ 1557db96d56Sopenharmony_ci ((*outbuf)[i]) = (c); \ 1567db96d56Sopenharmony_ci } while (0) 1577db96d56Sopenharmony_ci 1587db96d56Sopenharmony_ci#define OUTBYTE1(c) OUTBYTEI(c, 0) 1597db96d56Sopenharmony_ci#define OUTBYTE2(c) OUTBYTEI(c, 1) 1607db96d56Sopenharmony_ci#define OUTBYTE3(c) OUTBYTEI(c, 2) 1617db96d56Sopenharmony_ci#define OUTBYTE4(c) OUTBYTEI(c, 3) 1627db96d56Sopenharmony_ci 1637db96d56Sopenharmony_ci#define WRITEBYTE1(c1) \ 1647db96d56Sopenharmony_ci do { \ 1657db96d56Sopenharmony_ci REQUIRE_OUTBUF(1); \ 1667db96d56Sopenharmony_ci OUTBYTE1(c1); \ 1677db96d56Sopenharmony_ci } while (0) 1687db96d56Sopenharmony_ci#define WRITEBYTE2(c1, c2) \ 1697db96d56Sopenharmony_ci do { \ 1707db96d56Sopenharmony_ci REQUIRE_OUTBUF(2); \ 1717db96d56Sopenharmony_ci OUTBYTE1(c1); \ 1727db96d56Sopenharmony_ci OUTBYTE2(c2); \ 1737db96d56Sopenharmony_ci } while (0) 1747db96d56Sopenharmony_ci#define WRITEBYTE3(c1, c2, c3) \ 1757db96d56Sopenharmony_ci do { \ 1767db96d56Sopenharmony_ci REQUIRE_OUTBUF(3); \ 1777db96d56Sopenharmony_ci OUTBYTE1(c1); \ 1787db96d56Sopenharmony_ci OUTBYTE2(c2); \ 1797db96d56Sopenharmony_ci OUTBYTE3(c3); \ 1807db96d56Sopenharmony_ci } while (0) 1817db96d56Sopenharmony_ci#define WRITEBYTE4(c1, c2, c3, c4) \ 1827db96d56Sopenharmony_ci do { \ 1837db96d56Sopenharmony_ci REQUIRE_OUTBUF(4); \ 1847db96d56Sopenharmony_ci OUTBYTE1(c1); \ 1857db96d56Sopenharmony_ci OUTBYTE2(c2); \ 1867db96d56Sopenharmony_ci OUTBYTE3(c3); \ 1877db96d56Sopenharmony_ci OUTBYTE4(c4); \ 1887db96d56Sopenharmony_ci } while (0) 1897db96d56Sopenharmony_ci 1907db96d56Sopenharmony_ci#define _TRYMAP_ENC(m, assi, val) \ 1917db96d56Sopenharmony_ci ((m)->map != NULL && (val) >= (m)->bottom && \ 1927db96d56Sopenharmony_ci (val)<= (m)->top && ((assi) = (m)->map[(val) - \ 1937db96d56Sopenharmony_ci (m)->bottom]) != NOCHAR) 1947db96d56Sopenharmony_ci#define TRYMAP_ENC(charset, assi, uni) \ 1957db96d56Sopenharmony_ci _TRYMAP_ENC(&charset##_encmap[(uni) >> 8], assi, (uni) & 0xff) 1967db96d56Sopenharmony_ci 1977db96d56Sopenharmony_ci#define _TRYMAP_DEC(m, assi, val) \ 1987db96d56Sopenharmony_ci ((m)->map != NULL && \ 1997db96d56Sopenharmony_ci (val) >= (m)->bottom && \ 2007db96d56Sopenharmony_ci (val)<= (m)->top && \ 2017db96d56Sopenharmony_ci ((assi) = (m)->map[(val) - (m)->bottom]) != UNIINV) 2027db96d56Sopenharmony_ci#define TRYMAP_DEC(charset, assi, c1, c2) \ 2037db96d56Sopenharmony_ci _TRYMAP_DEC(&charset##_decmap[c1], assi, c2) 2047db96d56Sopenharmony_ci 2057db96d56Sopenharmony_ci#define BEGIN_MAPPINGS_LIST static const struct dbcs_map _mapping_list[] = { 2067db96d56Sopenharmony_ci#define MAPPING_ENCONLY(enc) {#enc, (void*)enc##_encmap, NULL}, 2077db96d56Sopenharmony_ci#define MAPPING_DECONLY(enc) {#enc, NULL, (void*)enc##_decmap}, 2087db96d56Sopenharmony_ci#define MAPPING_ENCDEC(enc) {#enc, (void*)enc##_encmap, (void*)enc##_decmap}, 2097db96d56Sopenharmony_ci#define END_MAPPINGS_LIST \ 2107db96d56Sopenharmony_ci {"", NULL, NULL} }; \ 2117db96d56Sopenharmony_ci static const struct dbcs_map *mapping_list = \ 2127db96d56Sopenharmony_ci (const struct dbcs_map *)_mapping_list; 2137db96d56Sopenharmony_ci 2147db96d56Sopenharmony_ci#define BEGIN_CODECS_LIST static const MultibyteCodec _codec_list[] = { 2157db96d56Sopenharmony_ci#define _STATEFUL_METHODS(enc) \ 2167db96d56Sopenharmony_ci enc##_encode, \ 2177db96d56Sopenharmony_ci enc##_encode_init, \ 2187db96d56Sopenharmony_ci enc##_encode_reset, \ 2197db96d56Sopenharmony_ci enc##_decode, \ 2207db96d56Sopenharmony_ci enc##_decode_init, \ 2217db96d56Sopenharmony_ci enc##_decode_reset, 2227db96d56Sopenharmony_ci#define _STATELESS_METHODS(enc) \ 2237db96d56Sopenharmony_ci enc##_encode, NULL, NULL, \ 2247db96d56Sopenharmony_ci enc##_decode, NULL, NULL, 2257db96d56Sopenharmony_ci#define CODEC_STATEFUL(enc) { \ 2267db96d56Sopenharmony_ci #enc, NULL, NULL, \ 2277db96d56Sopenharmony_ci _STATEFUL_METHODS(enc) \ 2287db96d56Sopenharmony_ci}, 2297db96d56Sopenharmony_ci#define CODEC_STATELESS(enc) { \ 2307db96d56Sopenharmony_ci #enc, NULL, NULL, \ 2317db96d56Sopenharmony_ci _STATELESS_METHODS(enc) \ 2327db96d56Sopenharmony_ci}, 2337db96d56Sopenharmony_ci#define CODEC_STATELESS_WINIT(enc) { \ 2347db96d56Sopenharmony_ci #enc, NULL, \ 2357db96d56Sopenharmony_ci enc##_codec_init, \ 2367db96d56Sopenharmony_ci _STATELESS_METHODS(enc) \ 2377db96d56Sopenharmony_ci}, 2387db96d56Sopenharmony_ci#define END_CODECS_LIST \ 2397db96d56Sopenharmony_ci {"", NULL,} }; \ 2407db96d56Sopenharmony_ci static const MultibyteCodec *codec_list = \ 2417db96d56Sopenharmony_ci (const MultibyteCodec *)_codec_list; 2427db96d56Sopenharmony_ci 2437db96d56Sopenharmony_ci 2447db96d56Sopenharmony_ci 2457db96d56Sopenharmony_cistatic PyObject * 2467db96d56Sopenharmony_cigetmultibytecodec(void) 2477db96d56Sopenharmony_ci{ 2487db96d56Sopenharmony_ci PyObject *mod = PyImport_ImportModuleNoBlock("_multibytecodec"); 2497db96d56Sopenharmony_ci if (mod == NULL) { 2507db96d56Sopenharmony_ci return NULL; 2517db96d56Sopenharmony_ci } 2527db96d56Sopenharmony_ci 2537db96d56Sopenharmony_ci PyObject *cofunc = PyObject_GetAttrString(mod, "__create_codec"); 2547db96d56Sopenharmony_ci Py_DECREF(mod); 2557db96d56Sopenharmony_ci return cofunc; 2567db96d56Sopenharmony_ci} 2577db96d56Sopenharmony_ci 2587db96d56Sopenharmony_cistatic PyObject * 2597db96d56Sopenharmony_cigetcodec(PyObject *self, PyObject *encoding) 2607db96d56Sopenharmony_ci{ 2617db96d56Sopenharmony_ci PyObject *codecobj, *r, *cofunc; 2627db96d56Sopenharmony_ci const MultibyteCodec *codec; 2637db96d56Sopenharmony_ci const char *enc; 2647db96d56Sopenharmony_ci 2657db96d56Sopenharmony_ci if (!PyUnicode_Check(encoding)) { 2667db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 2677db96d56Sopenharmony_ci "encoding name must be a string."); 2687db96d56Sopenharmony_ci return NULL; 2697db96d56Sopenharmony_ci } 2707db96d56Sopenharmony_ci enc = PyUnicode_AsUTF8(encoding); 2717db96d56Sopenharmony_ci if (enc == NULL) 2727db96d56Sopenharmony_ci return NULL; 2737db96d56Sopenharmony_ci 2747db96d56Sopenharmony_ci cofunc = getmultibytecodec(); 2757db96d56Sopenharmony_ci if (cofunc == NULL) 2767db96d56Sopenharmony_ci return NULL; 2777db96d56Sopenharmony_ci 2787db96d56Sopenharmony_ci for (codec = codec_list; codec->encoding[0]; codec++) 2797db96d56Sopenharmony_ci if (strcmp(codec->encoding, enc) == 0) 2807db96d56Sopenharmony_ci break; 2817db96d56Sopenharmony_ci 2827db96d56Sopenharmony_ci if (codec->encoding[0] == '\0') { 2837db96d56Sopenharmony_ci PyErr_SetString(PyExc_LookupError, 2847db96d56Sopenharmony_ci "no such codec is supported."); 2857db96d56Sopenharmony_ci return NULL; 2867db96d56Sopenharmony_ci } 2877db96d56Sopenharmony_ci 2887db96d56Sopenharmony_ci codecobj = PyCapsule_New((void *)codec, PyMultibyteCodec_CAPSULE_NAME, NULL); 2897db96d56Sopenharmony_ci if (codecobj == NULL) 2907db96d56Sopenharmony_ci return NULL; 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_ci r = PyObject_CallOneArg(cofunc, codecobj); 2937db96d56Sopenharmony_ci Py_DECREF(codecobj); 2947db96d56Sopenharmony_ci Py_DECREF(cofunc); 2957db96d56Sopenharmony_ci 2967db96d56Sopenharmony_ci return r; 2977db96d56Sopenharmony_ci} 2987db96d56Sopenharmony_ci 2997db96d56Sopenharmony_ci 3007db96d56Sopenharmony_cistatic int 3017db96d56Sopenharmony_ciregister_maps(PyObject *module) 3027db96d56Sopenharmony_ci{ 3037db96d56Sopenharmony_ci const struct dbcs_map *h; 3047db96d56Sopenharmony_ci 3057db96d56Sopenharmony_ci for (h = mapping_list; h->charset[0] != '\0'; h++) { 3067db96d56Sopenharmony_ci char mhname[256] = "__map_"; 3077db96d56Sopenharmony_ci strcpy(mhname + sizeof("__map_") - 1, h->charset); 3087db96d56Sopenharmony_ci 3097db96d56Sopenharmony_ci PyObject *capsule = PyCapsule_New((void *)h, 3107db96d56Sopenharmony_ci PyMultibyteCodec_CAPSULE_NAME, NULL); 3117db96d56Sopenharmony_ci if (capsule == NULL) { 3127db96d56Sopenharmony_ci return -1; 3137db96d56Sopenharmony_ci } 3147db96d56Sopenharmony_ci if (PyModule_AddObject(module, mhname, capsule) < 0) { 3157db96d56Sopenharmony_ci Py_DECREF(capsule); 3167db96d56Sopenharmony_ci return -1; 3177db96d56Sopenharmony_ci } 3187db96d56Sopenharmony_ci } 3197db96d56Sopenharmony_ci return 0; 3207db96d56Sopenharmony_ci} 3217db96d56Sopenharmony_ci 3227db96d56Sopenharmony_ci#ifdef USING_BINARY_PAIR_SEARCH 3237db96d56Sopenharmony_cistatic DBCHAR 3247db96d56Sopenharmony_cifind_pairencmap(ucs2_t body, ucs2_t modifier, 3257db96d56Sopenharmony_ci const struct pair_encodemap *haystack, int haystacksize) 3267db96d56Sopenharmony_ci{ 3277db96d56Sopenharmony_ci int pos, min, max; 3287db96d56Sopenharmony_ci Py_UCS4 value = body << 16 | modifier; 3297db96d56Sopenharmony_ci 3307db96d56Sopenharmony_ci min = 0; 3317db96d56Sopenharmony_ci max = haystacksize; 3327db96d56Sopenharmony_ci 3337db96d56Sopenharmony_ci for (pos = haystacksize >> 1; min != max; pos = (min + max) >> 1) { 3347db96d56Sopenharmony_ci if (value < haystack[pos].uniseq) { 3357db96d56Sopenharmony_ci if (max != pos) { 3367db96d56Sopenharmony_ci max = pos; 3377db96d56Sopenharmony_ci continue; 3387db96d56Sopenharmony_ci } 3397db96d56Sopenharmony_ci } 3407db96d56Sopenharmony_ci else if (value > haystack[pos].uniseq) { 3417db96d56Sopenharmony_ci if (min != pos) { 3427db96d56Sopenharmony_ci min = pos; 3437db96d56Sopenharmony_ci continue; 3447db96d56Sopenharmony_ci } 3457db96d56Sopenharmony_ci } 3467db96d56Sopenharmony_ci break; 3477db96d56Sopenharmony_ci } 3487db96d56Sopenharmony_ci 3497db96d56Sopenharmony_ci if (value == haystack[pos].uniseq) { 3507db96d56Sopenharmony_ci return haystack[pos].code; 3517db96d56Sopenharmony_ci } 3527db96d56Sopenharmony_ci return DBCINV; 3537db96d56Sopenharmony_ci} 3547db96d56Sopenharmony_ci#endif 3557db96d56Sopenharmony_ci 3567db96d56Sopenharmony_ci#ifdef USING_IMPORTED_MAPS 3577db96d56Sopenharmony_ci#define IMPORT_MAP(locale, charset, encmap, decmap) \ 3587db96d56Sopenharmony_ci importmap("_codecs_" #locale, "__map_" #charset, \ 3597db96d56Sopenharmony_ci (const void**)encmap, (const void**)decmap) 3607db96d56Sopenharmony_ci 3617db96d56Sopenharmony_cistatic int 3627db96d56Sopenharmony_ciimportmap(const char *modname, const char *symbol, 3637db96d56Sopenharmony_ci const void **encmap, const void **decmap) 3647db96d56Sopenharmony_ci{ 3657db96d56Sopenharmony_ci PyObject *o, *mod; 3667db96d56Sopenharmony_ci 3677db96d56Sopenharmony_ci mod = PyImport_ImportModule(modname); 3687db96d56Sopenharmony_ci if (mod == NULL) 3697db96d56Sopenharmony_ci return -1; 3707db96d56Sopenharmony_ci 3717db96d56Sopenharmony_ci o = PyObject_GetAttrString(mod, symbol); 3727db96d56Sopenharmony_ci if (o == NULL) 3737db96d56Sopenharmony_ci goto errorexit; 3747db96d56Sopenharmony_ci else if (!PyCapsule_IsValid(o, PyMultibyteCodec_CAPSULE_NAME)) { 3757db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 3767db96d56Sopenharmony_ci "map data must be a Capsule."); 3777db96d56Sopenharmony_ci goto errorexit; 3787db96d56Sopenharmony_ci } 3797db96d56Sopenharmony_ci else { 3807db96d56Sopenharmony_ci struct dbcs_map *map; 3817db96d56Sopenharmony_ci map = PyCapsule_GetPointer(o, PyMultibyteCodec_CAPSULE_NAME); 3827db96d56Sopenharmony_ci if (encmap != NULL) 3837db96d56Sopenharmony_ci *encmap = map->encmap; 3847db96d56Sopenharmony_ci if (decmap != NULL) 3857db96d56Sopenharmony_ci *decmap = map->decmap; 3867db96d56Sopenharmony_ci Py_DECREF(o); 3877db96d56Sopenharmony_ci } 3887db96d56Sopenharmony_ci 3897db96d56Sopenharmony_ci Py_DECREF(mod); 3907db96d56Sopenharmony_ci return 0; 3917db96d56Sopenharmony_ci 3927db96d56Sopenharmony_cierrorexit: 3937db96d56Sopenharmony_ci Py_DECREF(mod); 3947db96d56Sopenharmony_ci return -1; 3957db96d56Sopenharmony_ci} 3967db96d56Sopenharmony_ci#endif 3977db96d56Sopenharmony_ci 3987db96d56Sopenharmony_cistatic int 3997db96d56Sopenharmony_ci_cjk_exec(PyObject *module) 4007db96d56Sopenharmony_ci{ 4017db96d56Sopenharmony_ci return register_maps(module); 4027db96d56Sopenharmony_ci} 4037db96d56Sopenharmony_ci 4047db96d56Sopenharmony_ci 4057db96d56Sopenharmony_cistatic struct PyMethodDef _cjk_methods[] = { 4067db96d56Sopenharmony_ci {"getcodec", (PyCFunction)getcodec, METH_O, ""}, 4077db96d56Sopenharmony_ci {NULL, NULL}, 4087db96d56Sopenharmony_ci}; 4097db96d56Sopenharmony_ci 4107db96d56Sopenharmony_cistatic PyModuleDef_Slot _cjk_slots[] = { 4117db96d56Sopenharmony_ci {Py_mod_exec, _cjk_exec}, 4127db96d56Sopenharmony_ci {0, NULL} 4137db96d56Sopenharmony_ci}; 4147db96d56Sopenharmony_ci 4157db96d56Sopenharmony_ci#define I_AM_A_MODULE_FOR(loc) \ 4167db96d56Sopenharmony_ci static struct PyModuleDef _cjk_module = { \ 4177db96d56Sopenharmony_ci PyModuleDef_HEAD_INIT, \ 4187db96d56Sopenharmony_ci .m_name = "_codecs_"#loc, \ 4197db96d56Sopenharmony_ci .m_size = 0, \ 4207db96d56Sopenharmony_ci .m_methods = _cjk_methods, \ 4217db96d56Sopenharmony_ci .m_slots = _cjk_slots, \ 4227db96d56Sopenharmony_ci }; \ 4237db96d56Sopenharmony_ci \ 4247db96d56Sopenharmony_ci PyMODINIT_FUNC \ 4257db96d56Sopenharmony_ci PyInit__codecs_##loc(void) \ 4267db96d56Sopenharmony_ci { \ 4277db96d56Sopenharmony_ci return PyModuleDef_Init(&_cjk_module); \ 4287db96d56Sopenharmony_ci } 4297db96d56Sopenharmony_ci 4307db96d56Sopenharmony_ci#endif 431