annotate Modules/_iconv_codec.c @ 27998:e27f58a50737 legacy-trunk

SF bug #690377: Dud footnote reference in distutils docs
author Raymond Hettinger <python@rcn.com>
date Fri, 21 Feb 2003 02:47:09 +0000
parents 1afafed9fa77
children facff522e744
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
1 /*
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
2 * _iconv_codec.c
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
3 *
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
4 * libiconv adaptor for Python iconvcodec
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
5 *
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
6 * Author : Hye-Shik Chang <perky@FreeBSD.org>
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
7 * Created : 17 January 2003
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
8 */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
9
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
10 #include "Python.h"
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
11 #include <string.h>
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
12 #include <iconv.h>
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
13
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
14 static const char *__version__ = "$Revision$";
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
15
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
16 #if Py_USING_UNICODE
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
17 # if Py_UNICODE_SIZE == 2
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
18 # ifdef __GNU_LIBRARY__
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
19 # define UNICODE_ENCODING "ucs-2"
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
20 # else
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
21 # define UNICODE_ENCODING "ucs-2-internal"
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
22 # endif
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
23 # define MBENCODED_LENGTH_MAX 4
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
24 # elif Py_UNICODE_SIZE == 4
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
25 # ifdef __GNU_LIBRARY__
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
26 # define UNICODE_ENCODING "ucs-4"
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
27 # else
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
28 # define UNICODE_ENCODING "ucs-4-internal"
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
29 # endif
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
30 # define MBENCODED_LENGTH_MAX 6
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
31 # endif
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
32 #else
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
33 # error "Unicode is not available"
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
34 #endif
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
35
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
36 typedef struct {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
37 PyObject_HEAD
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
38 iconv_t enchdl, dechdl;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
39 char *encoding;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
40 } iconvcodecObject;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
41 PyDoc_STRVAR(iconvcodec_doc, "iconvcodec object");
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
42
27678
261915a6c685 Use size_t instead of int for various variables to prevent
Walter Dörwald <walter@livinglogic.de>
parents: 27555
diff changeset
43 /* does the chosen internal encoding require
27536
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
44 * byteswapping to get native endianness?
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
45 * 0=no, 1=yes, -1=unknown */
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
46 static int byteswap = -1;
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
47
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
48 #define ERROR_STRICT (PyObject *)(1)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
49 #define ERROR_IGNORE (PyObject *)(2)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
50 #define ERROR_REPLACE (PyObject *)(3)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
51 #define ERROR_MAX ERROR_REPLACE
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
52
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
53 #define REPLACEMENT_CHAR_DECODE 0xFFFD
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
54 #define REPLACEMENT_CHAR_ENCODE '?'
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
55
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
56 #define DEFAULT_ENCODING "utf-8"
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
57
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
58
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
59 static PyObject *
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
60 get_errorcallback(const char *errors)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
61 {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
62 if (errors == NULL || strcmp(errors, "strict") == 0)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
63 return ERROR_STRICT;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
64 else if (strcmp(errors, "ignore") == 0)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
65 return ERROR_IGNORE;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
66 else if (strcmp(errors, "replace") == 0)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
67 return ERROR_REPLACE;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
68 else
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
69 return PyCodec_LookupError(errors);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
70 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
71
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
72
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
73 PyDoc_STRVAR(iconvcodec_encode__doc__,
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
74 "I.encode(unicode, [,errors]) -> (string, length consumed)\n\
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
75 \n\
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
76 Return an encoded string version of `unicode'. errors may be given to\n\
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
77 set a different error handling scheme. Default is 'strict' meaning that\n\
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
78 encoding errors raise a UnicodeEncodeError. Other possible values are\n\
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
79 'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name\n\
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
80 registered with codecs.register_error that can handle UnicodeEncodeErrors.");
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
81
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
82 static PyObject *
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
83 iconvcodec_encode(iconvcodecObject *self, PyObject *args, PyObject *kwargs)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
84 {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
85 static char *kwlist[] = { "input", "errors", NULL };
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
86 Py_UNICODE *input;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
87 int inputlen;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
88 char *errors = NULL/*strict*/, *out, *out_top;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
89 const char *inp, *inp_top;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
90 size_t inplen, inplen_total, outlen, outlen_total, estep;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
91 PyObject *outputobj = NULL, *errorcb = NULL,
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
92 *exceptionobj = NULL;
27551
d3af1e793243 Initialize swappedinput to silence the compiler warning about
Walter Dörwald <walter@livinglogic.de>
parents: 27536
diff changeset
93 Py_UNICODE *swappedinput = NULL;
27536
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
94 int swapi;
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
95
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
96 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "u#|s:encode",
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
97 kwlist, &input, &inputlen, &errors))
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
98 return NULL; /* TypeError */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
99
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
100 errorcb = get_errorcallback(errors);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
101 if (errorcb == NULL)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
102 return NULL; /* LookupError or something else from error handler */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
103
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
104 inp = inp_top = (char *)input;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
105 inplen = inplen_total = (size_t)(inputlen * Py_UNICODE_SIZE);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
106
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
107 outlen = inputlen * MBENCODED_LENGTH_MAX;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
108 if (outlen < 16)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
109 outlen = 16; /* for iso-2022 codecs */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
110
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
111 outputobj = PyString_FromStringAndSize(NULL, outlen);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
112 if (outputobj == NULL)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
113 return NULL;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
114 out = out_top = PyString_AS_STRING(outputobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
115 outlen_total = outlen;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
116
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
117 estep = inputlen * Py_UNICODE_SIZE / 2;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
118
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
119 #define RESIZE_OUTBUFFER(size) { \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
120 size_t toadd = (size); \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
121 outlen_total += toadd; \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
122 outlen += toadd; \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
123 if (_PyString_Resize(&outputobj, outlen_total) == -1) \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
124 goto errorexit; \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
125 out = PyString_AS_STRING(outputobj) + (out - out_top); \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
126 out_top = PyString_AS_STRING(outputobj); \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
127 }
27536
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
128 if (byteswap) {
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
129 swappedinput = PyMem_Malloc(inplen);
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
130 if (swappedinput == NULL)
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
131 return NULL;
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
132 for (swapi = 0; swapi<inputlen; ++swapi)
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
133 {
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
134 Py_UNICODE c = input[swapi];
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
135 #if Py_UNICODE_SIZE == 2
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
136 c = ((char *)&c)[0]<<8 | ((char *)&c)[1];
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
137 #else
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
138 c = ((char *)&c)[0]<<24 | ((char *)&c)[1]<<16 |
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
139 ((char *)&c)[2]<<8 | ((char *)&c)[3];
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
140 #endif
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
141 swappedinput[swapi] = c;
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
142 }
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
143 inp = inp_top = (char *)swappedinput;
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
144 }
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
145
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
146 while (inplen > 0) {
27936
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
147 if (iconv(self->enchdl, (char**)&inp, &inplen, &out, &outlen)
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
148 == (size_t)-1)
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
149 {
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
150 char reason[128];
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
151 int errpos;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
152
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
153 if (errno == E2BIG) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
154 RESIZE_OUTBUFFER(estep);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
155 continue;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
156 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
157
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
158 if (errorcb == ERROR_IGNORE || errorcb == ERROR_REPLACE) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
159 inplen -= Py_UNICODE_SIZE;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
160 inp += Py_UNICODE_SIZE;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
161 if (errorcb == ERROR_REPLACE) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
162 if (outlen < 1)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
163 RESIZE_OUTBUFFER(errno == EINVAL ? 1 : estep);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
164 outlen--;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
165 *out++ = REPLACEMENT_CHAR_ENCODE;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
166 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
167 if (errno == EINVAL) break;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
168 else continue;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
169 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
170
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
171 errpos = (int)(inp - inp_top) / Py_UNICODE_SIZE;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
172 sprintf(reason, "Undefined character map from "
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
173 #if Py_UNICODE_SIZE == 2
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
174 "\\u%04x"
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
175 #elif Py_UNICODE_SIZE == 4
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
176 "\\u%08x"
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
177 #endif
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
178 , *(Py_UNICODE *)inp);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
179
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
180 if (exceptionobj == NULL) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
181 if ((exceptionobj = PyUnicodeEncodeError_Create(
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
182 self->encoding, input, inputlen,
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
183 errpos, errpos + 1, reason)) == NULL)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
184 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
185 } else {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
186 if (PyUnicodeEncodeError_SetStart(exceptionobj, errpos) != 0)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
187 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
188 if (PyUnicodeEncodeError_SetEnd(exceptionobj, errpos + 1) != 0)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
189 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
190 if (PyUnicodeEncodeError_SetReason(exceptionobj, reason) != 0)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
191 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
192 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
193
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
194 if (errorcb == ERROR_STRICT) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
195 PyCodec_StrictErrors(exceptionobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
196 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
197 } else {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
198 PyObject *argsobj, *retobj, *retuni;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
199 long newpos;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
200
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
201 argsobj = PyTuple_New(1);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
202 if (argsobj == NULL)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
203 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
204 PyTuple_SET_ITEM(argsobj, 0, exceptionobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
205 Py_INCREF(exceptionobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
206 retobj = PyObject_CallObject(errorcb, argsobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
207 Py_DECREF(argsobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
208 if (retobj == NULL)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
209 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
210
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
211 if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 ||
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
212 !PyUnicode_Check((retuni = PyTuple_GET_ITEM(retobj, 0))) ||
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
213 !PyInt_Check(PyTuple_GET_ITEM(retobj, 1))) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
214 Py_DECREF(retobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
215 PyErr_SetString(PyExc_ValueError, "encoding error handler "
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
216 "must return (unicode, int) tuple");
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
217 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
218 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
219 if (PyUnicode_GET_SIZE(retuni) > 0) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
220 #define errorexit errorexit_cbpad
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
221 PyObject *retstr = NULL;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
222 int retstrsize;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
223
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
224 retstr = PyUnicode_AsEncodedString(
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
225 retuni, self->encoding, NULL);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
226 if (retstr == NULL || !PyString_Check(retstr))
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
227 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
228
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
229 retstrsize = PyString_GET_SIZE(retstr);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
230 if (outlen < retstrsize)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
231 RESIZE_OUTBUFFER(errno == EINVAL || retstrsize > estep
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
232 ? retstrsize - outlen : estep);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
233
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
234 memcpy(out, PyString_AS_STRING(retstr), retstrsize);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
235 out += retstrsize;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
236 outlen -= retstrsize;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
237 #undef errorexit
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
238 if (0) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
239 errorexit_cbpad: Py_XDECREF(retobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
240 Py_XDECREF(retstr);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
241 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
242 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
243 Py_DECREF(retstr);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
244 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
245
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
246 newpos = PyInt_AS_LONG(PyTuple_GET_ITEM(retobj, 1));
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
247 Py_DECREF(retobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
248
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
249 if (newpos < 0)
27555
c267f28724dd Change the treatment of positions returned by PEP293
Walter Dörwald <walter@livinglogic.de>
parents: 27551
diff changeset
250 newpos = inputlen + newpos;
c267f28724dd Change the treatment of positions returned by PEP293
Walter Dörwald <walter@livinglogic.de>
parents: 27551
diff changeset
251 if (newpos < 0 || newpos > inputlen) {
27936
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
252 PyErr_Format(PyExc_IndexError,
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
253 "position %ld from error handler out of bounds",
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
254 newpos);
27555
c267f28724dd Change the treatment of positions returned by PEP293
Walter Dörwald <walter@livinglogic.de>
parents: 27551
diff changeset
255 goto errorexit;
c267f28724dd Change the treatment of positions returned by PEP293
Walter Dörwald <walter@livinglogic.de>
parents: 27551
diff changeset
256 }
c267f28724dd Change the treatment of positions returned by PEP293
Walter Dörwald <walter@livinglogic.de>
parents: 27551
diff changeset
257 if (newpos == inputlen)
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
258 break;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
259 inp = inp_top + Py_UNICODE_SIZE * newpos;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
260 inplen = inplen_total - Py_UNICODE_SIZE * newpos;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
261 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
262 } else
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
263 break;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
264 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
265 #undef RESIZE_OUTBUFFER
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
266
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
267 {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
268 PyObject *rettup;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
269 int finalsize;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
270
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
271 finalsize = (int)(out - out_top);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
272
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
273 if (finalsize != outlen_total) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
274 if (_PyString_Resize(&outputobj, finalsize) == -1)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
275 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
276 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
277
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
278 if (errorcb > ERROR_MAX) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
279 Py_DECREF(errorcb);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
280 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
281 Py_XDECREF(exceptionobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
282
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
283 rettup = PyTuple_New(2);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
284 if (rettup == NULL) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
285 Py_DECREF(outputobj);
27536
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
286 if (byteswap)
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
287 PyMem_Free(swappedinput);
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
288 return NULL;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
289 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
290 PyTuple_SET_ITEM(rettup, 0, outputobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
291 PyTuple_SET_ITEM(rettup, 1, PyInt_FromLong(inputlen));
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
292 return rettup;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
293 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
294
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
295 errorexit:
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
296 Py_XDECREF(outputobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
297 if (errorcb > ERROR_MAX) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
298 Py_DECREF(errorcb);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
299 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
300 Py_XDECREF(exceptionobj);
27536
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
301 if (byteswap)
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
302 PyMem_Free(swappedinput);
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
303
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
304 return NULL;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
305 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
306
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
307 PyDoc_STRVAR(iconvcodec_decode__doc__,
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
308 "I.decode(string, [,errors]) -> (unicodeobject, length consumed)\n\
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
309 \n\
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
310 Decodes `string' using I, an iconvcodec instance. errors may be given\n\
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
311 to set a different error handling scheme. Default is 'strict' meaning\n\
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
312 that encoding errors raise a UnicodeDecodeError. Other possible values\n\
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
313 are 'ignore' and 'replace' as well as any other name registerd with\n\
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
314 codecs.register_error that is able to handle UnicodeDecodeErrors.");
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
315
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
316 static PyObject *
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
317 iconvcodec_decode(iconvcodecObject *self, PyObject *args, PyObject *kwargs)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
318 {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
319 static char *kwlist[] = { "input", "errors", NULL };
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
320 char *errors = NULL/*strict*/, *out, *out_top;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
321 const char *inp, *inp_top;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
322 int inplen_int;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
323 size_t inplen, inplen_total, outlen, outlen_total, estep;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
324 PyObject *outputobj = NULL, *errorcb = NULL,
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
325 *exceptionobj = NULL;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
326
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
327 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|s:decode",
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
328 kwlist, &inp, &inplen_int, &errors))
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
329 return NULL; /* TypeError */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
330
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
331 errorcb = get_errorcallback(errors);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
332 if (errorcb == NULL)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
333 return NULL; /* LookupError or something else from error handler */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
334
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
335 inp_top = inp;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
336 inplen_total = inplen = (size_t)inplen_int;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
337
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
338 outputobj = PyUnicode_FromUnicode(NULL, inplen);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
339 if (outputobj == NULL)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
340 return NULL;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
341 outlen_total = outlen = PyUnicode_GET_DATA_SIZE(outputobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
342 out = out_top = (char *)PyUnicode_AS_UNICODE(outputobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
343
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
344 estep = outlen / 2;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
345
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
346 #define RESIZE_OUTBUFFER(size) { \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
347 size_t toadd = (size); \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
348 outlen_total += toadd; \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
349 outlen += toadd; \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
350 if (PyUnicode_Resize(&outputobj, outlen_total/Py_UNICODE_SIZE) == -1) \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
351 goto errorexit; \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
352 out = (char *)PyUnicode_AS_UNICODE(outputobj) + (out - out_top); \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
353 out_top = (char *)PyUnicode_AS_UNICODE(outputobj); \
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
354 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
355 while (inplen > 0) {
27536
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
356 char *oldout = out;
27678
261915a6c685 Use size_t instead of int for various variables to prevent
Walter Dörwald <walter@livinglogic.de>
parents: 27555
diff changeset
357 size_t res = iconv(self->dechdl, (char**)&inp, &inplen, &out, &outlen);
27536
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
358
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
359 if (byteswap) {
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
360 while (oldout < out)
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
361 {
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
362 char c0 = oldout[0];
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
363 #if Py_UNICODE_SIZE == 2
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
364 oldout[0] = oldout[1];
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
365 oldout[1] = c0;
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
366 #else
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
367 char c1 = oldout[1];
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
368 oldout[0] = oldout[3];
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
369 oldout[1] = oldout[2];
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
370 oldout[2] = c1;
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
371 oldout[3] = c0;
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
372 #endif
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
373 oldout += sizeof(Py_UNICODE);
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
374 }
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
375 }
27678
261915a6c685 Use size_t instead of int for various variables to prevent
Walter Dörwald <walter@livinglogic.de>
parents: 27555
diff changeset
376 if (res == (size_t)-1) {
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
377 char reason[128], *reasonpos = (char *)reason;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
378 int errpos;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
379
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
380 if (errno == E2BIG) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
381 RESIZE_OUTBUFFER(estep);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
382 continue;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
383 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
384
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
385 if (errorcb == ERROR_IGNORE || errorcb == ERROR_REPLACE) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
386 inplen--; inp++;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
387 if (errorcb == ERROR_REPLACE) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
388 Py_UNICODE *replp;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
389
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
390 if (outlen < Py_UNICODE_SIZE)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
391 RESIZE_OUTBUFFER(
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
392 errno == EINVAL || Py_UNICODE_SIZE > estep
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
393 ? Py_UNICODE_SIZE : estep);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
394
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
395 /* some compilers hate casted lvalue */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
396 replp = (Py_UNICODE *)out;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
397 assert((long)replp % Py_UNICODE_SIZE == 0);/* aligned? */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
398 *replp = REPLACEMENT_CHAR_DECODE;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
399
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
400 out += Py_UNICODE_SIZE;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
401 outlen -= Py_UNICODE_SIZE;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
402 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
403 if (errno == EINVAL) break;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
404 else continue;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
405 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
406
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
407 errpos = (int)(inp - inp_top);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
408 reasonpos += sprintf(reason, "Invalid multibyte sequence \\x%02x",
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
409 (unsigned char)*inp);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
410 if (inplen > 1) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
411 reasonpos += sprintf(reasonpos,
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
412 "\\x%02x", (unsigned char)*(inp+1));
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
413 if (inplen > 2)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
414 sprintf(reasonpos, "\\x%02x", (unsigned char)*(inp+2));
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
415 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
416
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
417 if (exceptionobj == NULL) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
418 exceptionobj = PyUnicodeDecodeError_Create(
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
419 self->encoding, inp_top, inplen_total,
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
420 errpos, errpos + 1, reason);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
421 if (exceptionobj == NULL)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
422 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
423 } else {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
424 if (PyUnicodeDecodeError_SetStart(exceptionobj, errpos) != 0)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
425 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
426 if (PyUnicodeDecodeError_SetEnd(exceptionobj, errpos + 1) != 0)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
427 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
428 if (PyUnicodeDecodeError_SetReason(exceptionobj, reason) != 0)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
429 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
430 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
431
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
432 if (errorcb == ERROR_STRICT) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
433 PyCodec_StrictErrors(exceptionobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
434 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
435 } else {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
436 PyObject *argsobj, *retobj, *retuni;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
437 long newpos;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
438
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
439 argsobj = PyTuple_New(1);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
440 if (argsobj == NULL)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
441 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
442 PyTuple_SET_ITEM(argsobj, 0, exceptionobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
443 Py_INCREF(exceptionobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
444 retobj = PyObject_CallObject(errorcb, argsobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
445 Py_DECREF(argsobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
446 if (retobj == NULL)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
447 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
448
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
449 if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 ||
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
450 !PyUnicode_Check((retuni = PyTuple_GET_ITEM(retobj, 0))) ||
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
451 !PyInt_Check(PyTuple_GET_ITEM(retobj, 1))) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
452 Py_DECREF(retobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
453 PyErr_SetString(PyExc_ValueError, "decoding error handler "
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
454 "must return (unicode, int) tuple");
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
455 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
456 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
457 if (PyUnicode_GET_SIZE(retuni) > 0) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
458 #define errorexit errorexit_cbpad
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
459 size_t retunisize;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
460
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
461 retunisize = PyUnicode_GET_DATA_SIZE(retuni);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
462 if (outlen < retunisize)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
463 RESIZE_OUTBUFFER(errno == EINVAL || retunisize > estep
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
464 ? retunisize - outlen : estep);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
465
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
466 memcpy(out, PyUnicode_AS_DATA(retuni), retunisize);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
467 out += retunisize;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
468 outlen -= retunisize;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
469 #undef errorexit
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
470 if (0) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
471 errorexit_cbpad: Py_DECREF(retobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
472 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
473 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
474 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
475
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
476 newpos = PyInt_AS_LONG(PyTuple_GET_ITEM(retobj, 1));
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
477 Py_DECREF(retobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
478
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
479 if (newpos < 0)
27555
c267f28724dd Change the treatment of positions returned by PEP293
Walter Dörwald <walter@livinglogic.de>
parents: 27551
diff changeset
480 newpos = inplen_total + newpos;
c267f28724dd Change the treatment of positions returned by PEP293
Walter Dörwald <walter@livinglogic.de>
parents: 27551
diff changeset
481 if (newpos < 0 || newpos > inplen_total) {
27936
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
482 PyErr_Format(PyExc_IndexError,
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
483 "position %ld from error handler out of bounds",
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
484 newpos);
27555
c267f28724dd Change the treatment of positions returned by PEP293
Walter Dörwald <walter@livinglogic.de>
parents: 27551
diff changeset
485 goto errorexit;
c267f28724dd Change the treatment of positions returned by PEP293
Walter Dörwald <walter@livinglogic.de>
parents: 27551
diff changeset
486 }
c267f28724dd Change the treatment of positions returned by PEP293
Walter Dörwald <walter@livinglogic.de>
parents: 27551
diff changeset
487 if (newpos == inplen_total)
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
488 break;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
489 inp = inp_top + newpos;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
490 inplen = inplen_total - newpos;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
491 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
492 } else
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
493 break;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
494 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
495 #undef RESIZE_OUTBUFFER
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
496
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
497 {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
498 PyObject *rettup;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
499 int finalsize;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
500
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
501 finalsize = (int)(out - out_top);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
502 if (finalsize != outlen_total) {
27936
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
503 if (PyUnicode_Resize(&outputobj, finalsize / Py_UNICODE_SIZE)
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
504 == -1)
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
505 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
506 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
507
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
508 if (errorcb > ERROR_MAX) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
509 Py_DECREF(errorcb);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
510 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
511 Py_XDECREF(exceptionobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
512
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
513 rettup = PyTuple_New(2);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
514 if (rettup == NULL) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
515 Py_DECREF(outputobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
516 return NULL;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
517 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
518 PyTuple_SET_ITEM(rettup, 0, outputobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
519 PyTuple_SET_ITEM(rettup, 1, PyInt_FromLong(inplen_total));
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
520 return rettup;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
521 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
522
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
523 errorexit:
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
524 Py_XDECREF(outputobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
525 if (errorcb > ERROR_MAX) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
526 Py_DECREF(errorcb);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
527 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
528 Py_XDECREF(exceptionobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
529
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
530 return NULL;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
531 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
532
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
533 static struct PyMethodDef iconvcodec_methods[] = {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
534 {"encode", (PyCFunction)iconvcodec_encode,
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
535 METH_VARARGS | METH_KEYWORDS,
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
536 iconvcodec_encode__doc__},
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
537 {"decode", (PyCFunction)iconvcodec_decode,
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
538 METH_VARARGS | METH_KEYWORDS,
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
539 iconvcodec_decode__doc__},
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
540 {NULL, NULL},
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
541 };
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
542
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
543 static PyObject *
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
544 iconvcodec_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
545 {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
546 PyObject *encobj = NULL;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
547 iconvcodecObject *new = NULL;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
548
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
549 new = (iconvcodecObject *)type->tp_alloc(type, 0);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
550 if (new == NULL)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
551 return NULL;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
552
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
553 new->encoding = NULL;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
554 new->enchdl = new->dechdl = (iconv_t)(-1);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
555
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
556 encobj = PyObject_GetAttrString((PyObject *)new, "encoding");
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
557 if (encobj == NULL) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
558 PyErr_Clear();
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
559 new->encoding = PyMem_Malloc(sizeof(DEFAULT_ENCODING));
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
560 strcpy(new->encoding, DEFAULT_ENCODING);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
561 } else if (!PyString_Check(encobj)) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
562 Py_DECREF(encobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
563 PyErr_SetString(PyExc_TypeError,
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
564 "`encoding' attribute must be a string.");
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
565 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
566 } else {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
567 new->encoding = PyMem_Malloc(PyString_GET_SIZE(encobj) + 1);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
568 strcpy(new->encoding, PyString_AS_STRING(encobj));
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
569 Py_DECREF(encobj);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
570 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
571
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
572 new->dechdl = iconv_open(UNICODE_ENCODING, new->encoding);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
573 if (new->dechdl == (iconv_t)(-1)) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
574 PyErr_SetString(PyExc_ValueError, "unsupported decoding");
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
575 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
576 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
577
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
578 new->enchdl = iconv_open(new->encoding, UNICODE_ENCODING);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
579 if (new->enchdl == (iconv_t)(-1)) {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
580 PyErr_SetString(PyExc_ValueError, "unsupported encoding");
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
581 iconv_close(new->dechdl);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
582 new->dechdl = (iconv_t)(-1);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
583 goto errorexit;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
584 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
585
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
586 return (PyObject *)new;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
587
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
588 errorexit:
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
589 Py_XDECREF(new);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
590
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
591 return NULL;
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
592 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
593
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
594 static void
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
595 iconvcodec_dealloc(iconvcodecObject *self)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
596 {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
597 if (self->enchdl != (iconv_t)-1)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
598 iconv_close(self->enchdl);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
599 if (self->dechdl != (iconv_t)-1)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
600 iconv_close(self->dechdl);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
601 if (self->encoding != NULL)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
602 PyMem_Free(self->encoding);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
603
27412
550c15c4919b Fix reference counting of iconvcodec_Type. Fixes #670715.
Martin v. Löwis <martin@v.loewis.de>
parents: 27401
diff changeset
604 self->ob_type->tp_free((PyObject *)self);
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
605 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
606
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
607 static PyObject *
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
608 iconvcodec_repr(PyObject *self)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
609 {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
610 return PyString_FromFormat("<iconvcodec encoding='%s'>",
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
611 ((iconvcodecObject *)self)->encoding);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
612 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
613
27683
ed1d4e797109 Remove forward static reference since it is not required
Neal Norwitz <nnorwitz@gmail.com>
parents: 27678
diff changeset
614 static PyTypeObject iconvcodec_Type = {
27806
e8878c8f54df Patch #676839: Cygwin _iconv_codec module patch
Jason Tishler <jason@tishler.net>
parents: 27683
diff changeset
615 PyObject_HEAD_INIT(NULL)
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
616 0, /* Number of items for varobject */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
617 "iconvcodec", /* Name of this type */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
618 sizeof(iconvcodecObject), /* Basic object size */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
619 0, /* Item size for varobject */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
620 (destructor)iconvcodec_dealloc, /* tp_dealloc */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
621 0, /* tp_print */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
622 0, /* tp_getattr */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
623 0, /* tp_setattr */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
624 0, /* tp_compare */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
625 iconvcodec_repr, /* tp_repr */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
626 0, /* tp_as_number */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
627 0, /* tp_as_sequence */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
628 0, /* tp_as_mapping */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
629 0, /* tp_hash */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
630 0, /* tp_call */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
631 0, /* tp_str */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
632 PyObject_GenericGetAttr, /* tp_getattro */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
633 0, /* tp_setattro */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
634 0, /* tp_as_buffer */
27412
550c15c4919b Fix reference counting of iconvcodec_Type. Fixes #670715.
Martin v. Löwis <martin@v.loewis.de>
parents: 27401
diff changeset
635 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
636 iconvcodec_doc, /* tp_doc */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
637 0, /* tp_traverse */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
638 0, /* tp_clear */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
639 0, /* tp_richcompare */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
640 0, /* tp_weaklistoffset */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
641 0, /* tp_iter */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
642 0, /* tp_iterext */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
643 iconvcodec_methods, /* tp_methods */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
644 0, /* tp_members */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
645 0, /* tp_getset */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
646 0, /* tp_base */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
647 0, /* tp_dict */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
648 0, /* tp_descr_get */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
649 0, /* tp_descr_set */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
650 0, /* tp_dictoffset */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
651 0, /* tp_init */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
652 PyType_GenericAlloc, /* tp_alloc */
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
653 iconvcodec_new, /* tp_new */
27412
550c15c4919b Fix reference counting of iconvcodec_Type. Fixes #670715.
Martin v. Löwis <martin@v.loewis.de>
parents: 27401
diff changeset
654 PyObject_Del, /* tp_free */
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
655 };
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
656
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
657 static struct PyMethodDef _iconv_codec_methods[] = {
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
658 {NULL, NULL},
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
659 };
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
660
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
661 void
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
662 init_iconv_codec(void)
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
663 {
27398
47958c99452d Add _iconv_codec to Setup.dist. Use PyModule_ functions.
Martin v. Löwis <martin@v.loewis.de>
parents: 27396
diff changeset
664 PyObject *m;
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
665
27536
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
666 char in = 1;
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
667 char *inptr = &in;
27678
261915a6c685 Use size_t instead of int for various variables to prevent
Walter Dörwald <walter@livinglogic.de>
parents: 27555
diff changeset
668 size_t insize = 1;
27536
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
669 Py_UNICODE out = 0;
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
670 char *outptr = (char *)&out;
27678
261915a6c685 Use size_t instead of int for various variables to prevent
Walter Dörwald <walter@livinglogic.de>
parents: 27555
diff changeset
671 size_t outsize = sizeof(out);
261915a6c685 Use size_t instead of int for various variables to prevent
Walter Dörwald <walter@livinglogic.de>
parents: 27555
diff changeset
672 size_t res;
27536
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
673
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
674 iconv_t hdl = iconv_open(UNICODE_ENCODING, "ASCII");
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
675
27936
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
676 if (hdl == (iconv_t)-1) {
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
677 PyErr_SetString(PyExc_RuntimeError,
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
678 "can't initialize the _iconv_codec module: iconv_open() failed");
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
679 return;
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
680 }
27536
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
681
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
682 res = iconv(hdl, &inptr, &insize, &outptr, &outsize);
27936
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
683 if (res == (size_t)-1) {
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
684 PyErr_SetString(PyExc_RuntimeError,
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
685 "can't initialize the _iconv_codec module: iconv() failed");
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
686 return;
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
687 }
27536
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
688
27936
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
689 /* Check whether conv() returned native endianess or not for the chosen
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
690 encoding */
27536
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
691 if (out == 0x1)
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
692 byteswap = 0;
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
693 #if Py_UNICODE_SIZE == 2
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
694 else if (out == 0x0100)
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
695 #else
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
696 else if (out == 0x01000000)
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
697 #endif
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
698 byteswap = 1;
27936
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
699 else {
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
700 iconv_close(hdl);
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
701 PyErr_SetString(PyExc_RuntimeError,
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
702 "can't initialize the _iconv_codec module: mixed endianess");
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
703 return;
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
704 }
27536
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
705 iconv_close(hdl);
cbc86028d9f3 Check whether the choosen encoding requires byte swapping
Walter Dörwald <walter@livinglogic.de>
parents: 27412
diff changeset
706
27806
e8878c8f54df Patch #676839: Cygwin _iconv_codec module patch
Jason Tishler <jason@tishler.net>
parents: 27683
diff changeset
707 iconvcodec_Type.ob_type = &PyType_Type;
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
708 m = Py_InitModule("_iconv_codec", _iconv_codec_methods);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
709
27398
47958c99452d Add _iconv_codec to Setup.dist. Use PyModule_ functions.
Martin v. Löwis <martin@v.loewis.de>
parents: 27396
diff changeset
710 PyModule_AddStringConstant(m, "__version__", (char*)__version__);
27412
550c15c4919b Fix reference counting of iconvcodec_Type. Fixes #670715.
Martin v. Löwis <martin@v.loewis.de>
parents: 27401
diff changeset
711 Py_INCREF(&iconvcodec_Type);
27398
47958c99452d Add _iconv_codec to Setup.dist. Use PyModule_ functions.
Martin v. Löwis <martin@v.loewis.de>
parents: 27396
diff changeset
712 PyModule_AddObject(m, "iconvcodec", (PyObject *)(&iconvcodec_Type));
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
713 PyModule_AddStringConstant(m, "internal_encoding", UNICODE_ENCODING);
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
714
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
715 if (PyErr_Occurred())
27936
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
716 PyErr_SetString(PyExc_RuntimeError,
1afafed9fa77 Fold some long lines.
Guido van Rossum <guido@python.org>
parents: 27806
diff changeset
717 "can't initialize the _iconv_codec module");
27396
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
718 }
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
719
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
720 /*
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
721 * ex: ts=8 sts=4 et
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
722 * $Id$
f1dd90357dcb Patch #670715: Universal Unicode Codec for POSIX iconv.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
723 */