PyObject *PyUnicode_EncodeMBCS(const Py_UNICODE *p, Py_ssize_t size, const char *errors){ PyObject *repr = NULL; int ret; #ifdef NEED_RETRY retry: if (size > INT_MAX) ret = encode_mbcs(&repr, p, INT_MAX); else#endif ret = encode_mbcs(&repr, p, (int)size); if (ret < 0) { Py_XDECREF(repr); return NULL; } #ifdef NEED_RETRY if (size > INT_MAX) { p += INT_MAX; size -= INT_MAX; goto retry; }#endif return repr;} PyObject *PyUnicode_AsMBCSString(PyObject *unicode){ if (!PyUnicode_Check(unicode)) { PyErr_BadArgument(); return NULL; } return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), NULL);} #undef NEED_RETRY #endif /* MS_WINDOWS */ /* --- Character Mapping Codec -------------------------------------------- */ PyObject *PyUnicode_DecodeCharmap(const char *s, Py_ssize_t size, PyObject *mapping, const char *errors){ const char *starts = s; Py_ssize_t startinpos; Py_ssize_t endinpos; Py_ssize_t outpos; const char *e; PyUnicodeObject *v; Py_UNICODE *p; Py_ssize_t extrachars = 0; PyObject *errorHandler = NULL; PyObject *exc = NULL; Py_UNICODE *mapstring = NULL; Py_ssize_t maplen = 0; /* Default to Latin-1 */ if (mapping == NULL) return PyUnicode_DecodeLatin1(s, size, errors); v = _PyUnicode_New(size); if (v == NULL) goto onError; if (size == 0) return (PyObject *)v; p = PyUnicode_AS_UNICODE(v); e = s + size; if (PyUnicode_CheckExact(mapping)) { mapstring = PyUnicode_AS_UNICODE(mapping); maplen = PyUnicode_GET_SIZE(mapping); while (s < e) { unsigned char ch = *s; Py_UNICODE x = 0xfffe; /* illegal value */ if (ch < maplen) x = mapstring[ch]; if (x == 0xfffe) { /* undefined mapping */ outpos = p-PyUnicode_AS_UNICODE(v); startinpos = s-starts; endinpos = startinpos+1; if (unicode_decode_call_errorhandler( errors, &errorHandler, "charmap", "character maps to <undefined>", starts, size, &startinpos, &endinpos, &exc, &s, (PyObject **)&v, &outpos, &p)) { goto onError; } continue; } *p++ = x; ++s; } } else { while (s < e) { unsigned char ch = *s; PyObject *w, *x; /* Get mapping (char ordinal -> integer, Unicode char or None) */ w = PyInt_FromLong((long)ch); if (w == NULL) goto onError; x = PyObject_GetItem(mapping, w); Py_DECREF(w); if (x == NULL) { if (PyErr_ExceptionMatches(PyExc_LookupError)) { /* No mapping found means: mapping is undefined. */ PyErr_Clear(); x = Py_None; Py_INCREF(x); } else goto onError; } /* Apply mapping */ if (PyInt_Check(x)) { long value = PyInt_AS_LONG(x); if (value < 0 || value > 65535) { PyErr_SetString(PyExc_TypeError, "character mapping must be in range(65536)"); Py_DECREF(x); goto onError; } *p++ = (Py_UNICODE)value; } else if (x == Py_None) { /* undefined mapping */ outpos = p-PyUnicode_AS_UNICODE(v); startinpos = s-starts; endinpos = startinpos+1; if (unicode_decode_call_errorhandler( errors, &errorHandler, "charmap", "character maps to <undefined>", starts, size, &startinpos, &endinpos, &exc, &s, (PyObject **)&v, &outpos, &p)) { Py_DECREF(x); goto onError; } Py_DECREF(x); continue; } else if (PyUnicode_Check(x)) { Py_ssize_t targetsize = PyUnicode_GET_SIZE(x); if (targetsize == 1) /* 1-1 mapping */ *p++ = *PyUnicode_AS_UNICODE(x); else if (targetsize > 1) { /* 1-n mapping */ if (targetsize > extrachars) { /* resize first */ Py_ssize_t oldpos = p - PyUnicode_AS_UNICODE(v); Py_ssize_t needed = (targetsize - extrachars) + \ (targetsize << 2); extrachars += needed; /* XXX overflow detection missing */ if (_PyUnicode_Resize(&v, PyUnicode_GET_SIZE(v) + needed) < 0) { Py_DECREF(x); goto onError; } p = PyUnicode_AS_UNICODE(v) + oldpos; } Py_UNICODE_COPY(p, PyUnicode_AS_UNICODE(x), targetsize); p += targetsize; extrachars -= targetsize; } /* 1-0 mapping: skip the character */ } else { /* wrong return value */ PyErr_SetString(PyExc_TypeError, "character mapping must return integer, None or unicode"); Py_DECREF(x); goto onError; } Py_DECREF(x); ++s; } } if (p - PyUnicode_AS_UNICODE(v) < PyUnicode_GET_SIZE(v)) if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0) goto onError; Py_XDECREF(errorHandler); Py_XDECREF(exc); return (PyObject *)v; onError: Py_XDECREF(errorHandler); Py_XDECREF(exc); Py_XDECREF(v); return NULL;} /* Charmap encoding: the lookup table */ struct encoding_map{ PyObject_HEAD unsigned char level1[32]; int count2, count3; unsigned char level23[1];}; static PyObject*encoding_map_size(PyObject *obj, PyObject* args){ struct encoding_map *map = (struct encoding_map*)obj; return PyInt_FromLong(sizeof(*map) - 1 + 16*map->count2 + 128*map->count3);} static PyMethodDef encoding_map_methods[] = { {"size", encoding_map_size, METH_NOARGS, PyDoc_STR("Return the size (in bytes) of this object") }, { 0 }}; static voidencoding_map_dealloc(PyObject* o){ PyObject_FREE(o);} static PyTypeObject EncodingMapType = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ "EncodingMap", /*tp_name*/ sizeof(struct encoding_map), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ encoding_map_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ encoding_map_methods, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ 0, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/}; PyObject*PyUnicode_BuildEncodingMap(PyObject* string){ Py_UNICODE *decode; PyObject *result; struct encoding_map *mresult; int i; int need_dict = 0; unsigned char level1[32]; unsigned char level2[512]; unsigned char *mlevel1, *mlevel2, *mlevel3; int count2 = 0, count3 = 0; if (!PyUnicode_Check(string) || PyUnicode_GetSize(string) != 256) { PyErr_BadArgument(); return NULL; } decode = PyUnicode_AS_UNICODE(string); memset(level1, 0xFF, sizeof level1); memset(level2, 0xFF, sizeof level2); /* If there isn't a one-to-one mapping of NULL to \0, or if there are non-BMP characters, we need to use a mapping dictionary. */ if (decode[0] != 0) need_dict = 1; for (i = 1; i < 256; i++) { int l1, l2; if (decode[i] == 0 #ifdef Py_UNICODE_WIDE || decode[i] > 0xFFFF #endif ) { need_dict = 1; break; } if (decode[i] == 0xFFFE) /* unmapped character */ continue; l1 = decode[i] >> 11; l2 = decode[i] >> 7; if (level1[l1] == 0xFF) level1[l1] = count2++; if (level2[l2] == 0xFF) level2[l2] = count3++; } if (count2 >= 0xFF || count3 >= 0xFF) need_dict = 1; if (need_dict) { PyObject *result = PyDict_New(); PyObject *key, *value; if (!result) return NULL; for (i = 0; i < 256; i++) { key = value = NULL; key = PyInt_FromLong(decode[i]); value = PyInt_FromLong(i); if (!key || !value) goto failed1; if (PyDict_SetItem(result, key, value) == -1) goto failed1; Py_DECREF(key); Py_DECREF(value); } return result; failed1: Py_XDECREF(key); Py_XDECREF(value); Py_DECREF(result); return NULL; } /* Create a three-level trie */ result = PyObject_MALLOC(sizeof(struct encoding_map) + 16*count2 + 128*count3 - 1); if (!result) return PyErr_NoMemory(); PyObject_Init(result, &EncodingMapType); mresult = (struct encoding_map*)result; mresult->count2 = count2; mresult->count3 = count3; mlevel1 = mresult->level1; mlevel2 = mresult->level23; mlevel3 = mresult->level23 + 16*count2; memcpy(mlevel1, level1, 32); memset(mlevel2, 0xFF, 16*count2); memset(mlevel3, 0, 128*count3); count3 = 0; for (i = 1; i < 256; i++) { int o1, o2, o3, i2, i3; if (decode[i] == 0xFFFE) /* unmapped character */ continue; o1 = decode[i]>>11; o2 = (decode[i]>>7) & 0xF; i2 = 16*mlevel1[o1] + o2; if (mlevel2[i2] == 0xFF) mlevel2[i2] = count3++; o3 = decode[i] & 0x7F; i3 = 128*mlevel2[i2] + o3; mlevel3[i3] = i; } return result;} static intencoding_map_lookup(Py_UNICODE c, PyObject *mapping){ struct encoding_map *map = (struct encoding_map*)mapping; int l1 = c>>11; int l2 = (c>>7) & 0xF; int l3 = c & 0x7F; int i; #ifdef Py_UNICODE_WIDE if (c > 0xFFFF) { return -1; }#endif if (c == 0) return 0; /* level 1*/ i = map->level1[l1]; if (i == 0xFF) { return -1; } /* level 2*/ i = map->level23[16*i+l2]; if (i == 0xFF) { return -1; } /* level 3 */ i = map->level23[16*map->count2 + 128*i + l3]; if (i == 0) { return -1; } return i;} /* Lookup the character ch in the mapping. If the character can't be found, Py_None is returned (or NULL, if another error occurred). */static PyObject *charmapencode_lookup(Py_UNICODE c, PyObject *mapping){ PyObject *w = PyInt_FromLong((long)c); PyObject *x; if (w == NULL) return NULL; x = PyObject_GetItem(mapping, w); Py_DECREF(w); if (x == NULL) { if (PyErr_ExceptionMatches(PyExc_LookupError)) { /* No mapping found means: mapping is undefined. */ PyErr_Clear(); x = Py_None; Py_INCREF(x); return x; } else return NULL; } else if (x == Py_None) return x; else if (PyInt_Check(x)) { long value = PyInt_AS_LONG(x); if (value < 0 || value > 255) { PyErr_SetString(PyExc_TypeError, "character mapping must be in range(256)"); Py_DECREF(x); return NULL; } return x; } else if (PyString_Check(x)) return x; else { /* wrong return value */ PyErr_SetString(PyExc_TypeError, "character mapping must return integer, None or str"); Py_DECREF(x); return NULL; }} static intcharmapencode_resize(PyObject **outobj, Py_ssize_t *outpos, Py_ssize_t requiredsize){ Py_ssize_t outsize = PyString_GET_SIZE(*outobj); /* exponentially overallocate to minimize reallocations */ if (requiredsize < 2*outsize) requiredsize = 2*outsize; if (_PyString_Resize(outobj, requiredsize)) { return 0; } return 1;} typedef enum charmapencode_result { enc_SUCCESS, enc_FAILED, enc_EXCEPTION }charmapencode_result;/* lookup the character, put the result in the output string and adjust various state variables. Reallocate the output string if not enough space is available. Return a new reference to the object that was put in the output buffer, or Py_None, if the mapping was undefined (in which case no character was written) or NULL, if a reallocation error occurred. The caller must decref the result */staticcharmapencode_result charmapencode_output(Py_UNICODE c, PyObject *mapping, PyObject **outobj, Py_ssize_t *outpos){ PyObject *rep; char *outstart; Py_ssize_t outsize = PyString_GET_SIZE(*outobj); Lines 3001–3500 of 8067. Previous lines Load more
PyObject *PyUnicode_EncodeMBCS(const Py_UNICODE *p, Py_ssize_t size, const char *errors) { PyObject *repr = NULL; int ret; #ifdef NEED_RETRY retry: if (size > INT_MAX) ret = encode_mbcs(&repr, p, INT_MAX); else #endif ret = encode_mbcs(&repr, p, (int)size); if (ret < 0) { Py_XDECREF(repr); return NULL; } #ifdef NEED_RETRY if (size > INT_MAX) { p += INT_MAX; size -= INT_MAX; goto retry; } #endif return repr; } PyObject *PyUnicode_AsMBCSString(PyObject *unicode) { if (!PyUnicode_Check(unicode)) { PyErr_BadArgument(); return NULL; } return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), NULL); } #undef NEED_RETRY #endif /* MS_WINDOWS */ /* --- Character Mapping Codec -------------------------------------------- */ PyObject *PyUnicode_DecodeCharmap(const char *s, Py_ssize_t size, PyObject *mapping, const char *errors) { const char *starts = s; Py_ssize_t startinpos; Py_ssize_t endinpos; Py_ssize_t outpos; const char *e; PyUnicodeObject *v; Py_UNICODE *p; Py_ssize_t extrachars = 0; PyObject *errorHandler = NULL; PyObject *exc = NULL; Py_UNICODE *mapstring = NULL; Py_ssize_t maplen = 0; /* Default to Latin-1 */ if (mapping == NULL) return PyUnicode_DecodeLatin1(s, size, errors); v = _PyUnicode_New(size); if (v == NULL) goto onError; if (size == 0) return (PyObject *)v; p = PyUnicode_AS_UNICODE(v); e = s + size; if (PyUnicode_CheckExact(mapping)) { mapstring = PyUnicode_AS_UNICODE(mapping); maplen = PyUnicode_GET_SIZE(mapping); while (s < e) { unsigned char ch = *s; Py_UNICODE x = 0xfffe; /* illegal value */ if (ch < maplen) x = mapstring[ch]; if (x == 0xfffe) { /* undefined mapping */ outpos = p-PyUnicode_AS_UNICODE(v); startinpos = s-starts; endinpos = startinpos+1; if (unicode_decode_call_errorhandler( errors, &errorHandler, "charmap", "character maps to <undefined>", starts, size, &startinpos, &endinpos, &exc, &s, (PyObject **)&v, &outpos, &p)) { goto onError; } continue; } *p++ = x; ++s; } } else { while (s < e) { unsigned char ch = *s; PyObject *w, *x; /* Get mapping (char ordinal -> integer, Unicode char or None) */ w = PyInt_FromLong((long)ch); if (w == NULL) goto onError; x = PyObject_GetItem(mapping, w); Py_DECREF(w); if (x == NULL) { if (PyErr_ExceptionMatches(PyExc_LookupError)) { /* No mapping found means: mapping is undefined. */ PyErr_Clear(); x = Py_None; Py_INCREF(x); } else goto onError; } /* Apply mapping */ if (PyInt_Check(x)) { long value = PyInt_AS_LONG(x); if (value < 0 || value > 65535) { PyErr_SetString(PyExc_TypeError, "character mapping must be in range(65536)"); Py_DECREF(x); goto onError; } *p++ = (Py_UNICODE)value; } else if (x == Py_None) { /* undefined mapping */ outpos = p-PyUnicode_AS_UNICODE(v); startinpos = s-starts; endinpos = startinpos+1; if (unicode_decode_call_errorhandler( errors, &errorHandler, "charmap", "character maps to <undefined>", starts, size, &startinpos, &endinpos, &exc, &s, (PyObject **)&v, &outpos, &p)) { Py_DECREF(x); goto onError; } Py_DECREF(x); continue; } else if (PyUnicode_Check(x)) { Py_ssize_t targetsize = PyUnicode_GET_SIZE(x); if (targetsize == 1) /* 1-1 mapping */ *p++ = *PyUnicode_AS_UNICODE(x); else if (targetsize > 1) { /* 1-n mapping */ if (targetsize > extrachars) { /* resize first */ Py_ssize_t oldpos = p - PyUnicode_AS_UNICODE(v); Py_ssize_t needed = (targetsize - extrachars) + \ (targetsize << 2); extrachars += needed; /* XXX overflow detection missing */ if (_PyUnicode_Resize(&v, PyUnicode_GET_SIZE(v) + needed) < 0) { Py_DECREF(x); goto onError; } p = PyUnicode_AS_UNICODE(v) + oldpos; } Py_UNICODE_COPY(p, PyUnicode_AS_UNICODE(x), targetsize); p += targetsize; extrachars -= targetsize; } /* 1-0 mapping: skip the character */ } else { /* wrong return value */ PyErr_SetString(PyExc_TypeError, "character mapping must return integer, None or unicode"); Py_DECREF(x); goto onError; } Py_DECREF(x); ++s; } } if (p - PyUnicode_AS_UNICODE(v) < PyUnicode_GET_SIZE(v)) if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0) goto onError; Py_XDECREF(errorHandler); Py_XDECREF(exc); return (PyObject *)v; onError: Py_XDECREF(errorHandler); Py_XDECREF(exc); Py_XDECREF(v); return NULL; } /* Charmap encoding: the lookup table */ struct encoding_map{ PyObject_HEAD unsigned char level1[32]; int count2, count3; unsigned char level23[1]; }; static PyObject* encoding_map_size(PyObject *obj, PyObject* args) { struct encoding_map *map = (struct encoding_map*)obj; return PyInt_FromLong(sizeof(*map) - 1 + 16*map->count2 + 128*map->count3); } static PyMethodDef encoding_map_methods[] = { {"size", encoding_map_size, METH_NOARGS, PyDoc_STR("Return the size (in bytes) of this object") }, { 0 } }; static void encoding_map_dealloc(PyObject* o) { PyObject_FREE(o); } static PyTypeObject EncodingMapType = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ "EncodingMap", /*tp_name*/ sizeof(struct encoding_map), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ encoding_map_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ encoding_map_methods, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ 0, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ }; PyObject* PyUnicode_BuildEncodingMap(PyObject* string) { Py_UNICODE *decode; PyObject *result; struct encoding_map *mresult; int i; int need_dict = 0; unsigned char level1[32]; unsigned char level2[512]; unsigned char *mlevel1, *mlevel2, *mlevel3; int count2 = 0, count3 = 0; if (!PyUnicode_Check(string) || PyUnicode_GetSize(string) != 256) { PyErr_BadArgument(); return NULL; } decode = PyUnicode_AS_UNICODE(string); memset(level1, 0xFF, sizeof level1); memset(level2, 0xFF, sizeof level2); /* If there isn't a one-to-one mapping of NULL to \0, or if there are non-BMP characters, we need to use a mapping dictionary. */ if (decode[0] != 0) need_dict = 1; for (i = 1; i < 256; i++) { int l1, l2; if (decode[i] == 0 #ifdef Py_UNICODE_WIDE || decode[i] > 0xFFFF #endif ) { need_dict = 1; break; } if (decode[i] == 0xFFFE) /* unmapped character */ continue; l1 = decode[i] >> 11; l2 = decode[i] >> 7; if (level1[l1] == 0xFF) level1[l1] = count2++; if (level2[l2] == 0xFF) level2[l2] = count3++; } if (count2 >= 0xFF || count3 >= 0xFF) need_dict = 1; if (need_dict) { PyObject *result = PyDict_New(); PyObject *key, *value; if (!result) return NULL; for (i = 0; i < 256; i++) { key = value = NULL; key = PyInt_FromLong(decode[i]); value = PyInt_FromLong(i); if (!key || !value) goto failed1; if (PyDict_SetItem(result, key, value) == -1) goto failed1; Py_DECREF(key); Py_DECREF(value); } return result; failed1: Py_XDECREF(key); Py_XDECREF(value); Py_DECREF(result); return NULL; } /* Create a three-level trie */ result = PyObject_MALLOC(sizeof(struct encoding_map) + 16*count2 + 128*count3 - 1); if (!result) return PyErr_NoMemory(); PyObject_Init(result, &EncodingMapType); mresult = (struct encoding_map*)result; mresult->count2 = count2; mresult->count3 = count3; mlevel1 = mresult->level1; mlevel2 = mresult->level23; mlevel3 = mresult->level23 + 16*count2; memcpy(mlevel1, level1, 32); memset(mlevel2, 0xFF, 16*count2); memset(mlevel3, 0, 128*count3); count3 = 0; for (i = 1; i < 256; i++) { int o1, o2, o3, i2, i3; if (decode[i] == 0xFFFE) /* unmapped character */ continue; o1 = decode[i]>>11; o2 = (decode[i]>>7) & 0xF; i2 = 16*mlevel1[o1] + o2; if (mlevel2[i2] == 0xFF) mlevel2[i2] = count3++; o3 = decode[i] & 0x7F; i3 = 128*mlevel2[i2] + o3; mlevel3[i3] = i; } return result; } static int encoding_map_lookup(Py_UNICODE c, PyObject *mapping) { struct encoding_map *map = (struct encoding_map*)mapping; int l1 = c>>11; int l2 = (c>>7) & 0xF; int l3 = c & 0x7F; int i; #ifdef Py_UNICODE_WIDE if (c > 0xFFFF) { return -1; } #endif if (c == 0) return 0; /* level 1*/ i = map->level1[l1]; if (i == 0xFF) { return -1; } /* level 2*/ i = map->level23[16*i+l2]; if (i == 0xFF) { return -1; } /* level 3 */ i = map->level23[16*map->count2 + 128*i + l3]; if (i == 0) { return -1; } return i; } /* Lookup the character ch in the mapping. If the character can't be found, Py_None is returned (or NULL, if another error occurred). */ static PyObject *charmapencode_lookup(Py_UNICODE c, PyObject *mapping) { PyObject *w = PyInt_FromLong((long)c); PyObject *x; if (w == NULL) return NULL; x = PyObject_GetItem(mapping, w); Py_DECREF(w); if (x == NULL) { if (PyErr_ExceptionMatches(PyExc_LookupError)) { /* No mapping found means: mapping is undefined. */ PyErr_Clear(); x = Py_None; Py_INCREF(x); return x; } else return NULL; } else if (x == Py_None) return x; else if (PyInt_Check(x)) { long value = PyInt_AS_LONG(x); if (value < 0 || value > 255) { PyErr_SetString(PyExc_TypeError, "character mapping must be in range(256)"); Py_DECREF(x); return NULL; } return x; } else if (PyString_Check(x)) return x; else { /* wrong return value */ PyErr_SetString(PyExc_TypeError, "character mapping must return integer, None or str"); Py_DECREF(x); return NULL; } } static int charmapencode_resize(PyObject **outobj, Py_ssize_t *outpos, Py_ssize_t requiredsize) { Py_ssize_t outsize = PyString_GET_SIZE(*outobj); /* exponentially overallocate to minimize reallocations */ if (requiredsize < 2*outsize) requiredsize = 2*outsize; if (_PyString_Resize(outobj, requiredsize)) { return 0; } return 1; } typedef enum charmapencode_result { enc_SUCCESS, enc_FAILED, enc_EXCEPTION }charmapencode_result; /* lookup the character, put the result in the output string and adjust various state variables. Reallocate the output string if not enough space is available. Return a new reference to the object that was put in the output buffer, or Py_None, if the mapping was undefined (in which case no character was written) or NULL, if a reallocation error occurred. The caller must decref the result */ static charmapencode_result charmapencode_output(Py_UNICODE c, PyObject *mapping, PyObject **outobj, Py_ssize_t *outpos) { PyObject *rep; char *outstart; Py_ssize_t outsize = PyString_GET_SIZE(*outobj);