blob: a8bc04cd0cdcc82ad8fcce53cc4c7103d653bdec [file] [log] [blame]
/*
* codecentry.h: Common Codec Entry Routines
*
* Written by Hye-Shik Chang <perky@FreeBSD.org>
* $CJKCodecs: codecentry.h,v 1.5 2004/01/17 11:26:10 perky Exp $
*/
#ifdef HAVE_ENCODER_INIT
#define ENCODER_INIT_FUNC(encoding) encoding##_encode_init
#else
#define ENCODER_INIT_FUNC(encoding) NULL
#endif
#ifdef HAVE_ENCODER_RESET
#define ENCODER_RESET_FUNC(encoding) encoding##_encode_reset
#else
#define ENCODER_RESET_FUNC(encoding) NULL
#endif
#ifdef HAVE_DECODER_INIT
#define DECODER_INIT_FUNC(encoding) encoding##_decode_init
#else
#define DECODER_INIT_FUNC(encoding) NULL
#endif
#ifdef HAVE_DECODER_RESET
#define DECODER_RESET_FUNC(encoding) encoding##_decode_reset
#else
#define DECODER_RESET_FUNC(encoding) NULL
#endif
#ifdef STRICT_BUILD
#define BEGIN_CODEC_REGISTRY(encoding) \
__BEGIN_CODEC_REGISTRY(encoding, init_codecs_##encoding##_strict)
#else
#define BEGIN_CODEC_REGISTRY(encoding) \
__BEGIN_CODEC_REGISTRY(encoding, init_codecs_##encoding)
#endif
#define __BEGIN_CODEC_REGISTRY(encoding, initname) \
static MultibyteCodec __codec = { \
#encoding STRICT_SUFX, \
encoding##_encode, \
ENCODER_INIT_FUNC(encoding), \
ENCODER_RESET_FUNC(encoding), \
encoding##_decode, \
DECODER_INIT_FUNC(encoding), \
DECODER_RESET_FUNC(encoding), \
}; \
\
static struct PyMethodDef __methods[] = { \
{NULL, NULL}, \
}; \
\
void \
initname(void) \
{ \
PyObject *codec; \
PyObject *m = NULL, *mod = NULL, *o = NULL; \
\
m = Py_InitModule("_codecs_" #encoding STRICT_SUFX, __methods);
#define MAPOPEN(locale) \
mod = PyImport_ImportModule("_codecs_mapdata_" #locale);\
if (mod == NULL) goto errorexit; \
if (
#define IMPORTMAP_ENCDEC(charset) \
importmap(mod, "__map_" #charset, &charset##encmap, \
&charset##decmap) ||
#define IMPORTMAP_ENC(charset) \
importmap(mod, "__map_" #charset, &charset##encmap, \
NULL) ||
#define IMPORTMAP_DEC(charset) \
importmap(mod, "__map_" #charset, NULL, \
&charset##decmap) ||
#define MAPCLOSE() \
0) goto errorexit; \
Py_DECREF(mod);
#define END_CODEC_REGISTRY(encoding) \
mod = PyImport_ImportModule("_multibytecodec"); \
if (mod == NULL) goto errorexit; \
o = PyObject_GetAttrString(mod, "__create_codec"); \
if (o == NULL || !PyCallable_Check(o)) \
goto errorexit; \
\
codec = createcodec(o, &__codec); \
if (codec == NULL) \
goto errorexit; \
PyModule_AddObject(m, "codec", codec); \
Py_DECREF(o); Py_DECREF(mod); \
\
if (PyErr_Occurred()) \
Py_FatalError("can't initialize the _" #encoding \
STRICT_SUFX " module"); \
\
return; \
\
errorexit: \
Py_XDECREF(m); \
Py_XDECREF(mod); \
Py_XDECREF(o); \
}
#define CODEC_REGISTRY(encoding) \
BEGIN_CODEC_REGISTRY(encoding) \
END_CODEC_REGISTRY(encoding)
#ifdef USING_BINARY_PAIR_SEARCH
static DBCHAR
find_pairencmap(ucs2_t body, ucs2_t modifier,
struct pair_encodemap *haystack, int haystacksize)
{
int pos, min, max;
ucs4_t value = body << 16 | modifier;
min = 0;
max = haystacksize;
for (pos = haystacksize >> 1; min != max; pos = (min + max) >> 1)
if (value < haystack[pos].uniseq) {
if (max == pos) break;
else max = pos;
} else if (value > haystack[pos].uniseq) {
if (min == pos) break;
else min = pos;
} else
break;
if (value == haystack[pos].uniseq)
return haystack[pos].code;
else
return DBCINV;
}
#endif
#ifndef CODEC_WITHOUT_MAPS
static int
importmap(PyObject *mod, const char *symbol,
const struct unim_index **encmap, const struct dbcs_index **decmap)
{
PyObject *o;
o = PyObject_GetAttrString(mod, (char*)symbol);
if (o == NULL)
return -1;
else if (!PyCObject_Check(o)) {
PyErr_SetString(PyExc_ValueError, "map data must be a CObject.");
return -1;
} else {
struct dbcs_map *map;
map = PyCObject_AsVoidPtr(o);
if (encmap != NULL)
*encmap = map->encmap;
if (decmap != NULL)
*decmap = map->decmap;
Py_DECREF(o);
}
return 0;
}
#endif
static PyObject *
createcodec(PyObject *cofunc, MultibyteCodec *codec)
{
PyObject *args, *r;
args = PyTuple_New(1);
if (args == NULL) return NULL;
PyTuple_SET_ITEM(args, 0, PyCObject_FromVoidPtr(codec, NULL));
r = PyObject_CallObject(cofunc, args);
Py_DECREF(args);
return r;
}