| 
									
										
										
										
											2023-11-01 08:44:54 +03:00
										 |  |  | #include "parts.h"
 | 
					
						
							|  |  |  | #include "util.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-29 17:22:39 +02:00
										 |  |  | // === Codecs registration and un-registration ================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_register(PyObject *Py_UNUSED(module), PyObject *search_function) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (PyCodec_Register(search_function) < 0) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_unregister(PyObject *Py_UNUSED(module), PyObject *search_function) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (PyCodec_Unregister(search_function) < 0) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_known_encoding(PyObject *Py_UNUSED(module), PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *NULL_WOULD_RAISE(encoding); // NULL case will be tested
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "z", &encoding)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyCodec_KnownEncoding(encoding) ? Py_True : Py_False; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // === Codecs encoding and decoding interfaces ================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_encode(PyObject *Py_UNUSED(module), PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *input; | 
					
						
							|  |  |  |     const char *NULL_WOULD_RAISE(encoding); // NULL case will be tested
 | 
					
						
							|  |  |  |     const char *errors;                     // can be NULL
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "O|zz", &input, &encoding, &errors)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyCodec_Encode(input, encoding, errors); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_decode(PyObject *Py_UNUSED(module), PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *input; | 
					
						
							|  |  |  |     const char *NULL_WOULD_RAISE(encoding); // NULL case will be tested
 | 
					
						
							|  |  |  |     const char *errors;                     // can be NULL
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "O|zz", &input, &encoding, &errors)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyCodec_Decode(input, encoding, errors); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_encoder(PyObject *Py_UNUSED(module), PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *NULL_WOULD_RAISE(encoding); // NULL case will be tested
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "z", &encoding)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyCodec_Encoder(encoding); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_decoder(PyObject *Py_UNUSED(module), PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *NULL_WOULD_RAISE(encoding); // NULL case will be tested
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "z", &encoding)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyCodec_Decoder(encoding); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_incremental_encoder(PyObject *Py_UNUSED(module), PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *NULL_WOULD_RAISE(encoding); // NULL case will be tested
 | 
					
						
							|  |  |  |     const char *errors;                     // can be NULL
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "zz", &encoding, &errors)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyCodec_IncrementalEncoder(encoding, errors); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_incremental_decoder(PyObject *Py_UNUSED(module), PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *NULL_WOULD_RAISE(encoding); // NULL case will be tested
 | 
					
						
							|  |  |  |     const char *errors;                     // can be NULL
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "zz", &encoding, &errors)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyCodec_IncrementalDecoder(encoding, errors); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_stream_reader(PyObject *Py_UNUSED(module), PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *NULL_WOULD_RAISE(encoding); // NULL case will be tested
 | 
					
						
							|  |  |  |     PyObject *stream; | 
					
						
							|  |  |  |     const char *errors;                     // can be NULL
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "zOz", &encoding, &stream, &errors)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyCodec_StreamReader(encoding, stream, errors); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_stream_writer(PyObject *Py_UNUSED(module), PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *NULL_WOULD_RAISE(encoding); // NULL case will be tested
 | 
					
						
							|  |  |  |     PyObject *stream; | 
					
						
							|  |  |  |     const char *errors;                     // can be NULL
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "zOz", &encoding, &stream, &errors)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyCodec_StreamWriter(encoding, stream, errors); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // === Codecs errors handlers =================================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_register_error(PyObject *Py_UNUSED(module), PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *encoding;   // must not be NULL
 | 
					
						
							|  |  |  |     PyObject *error; | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "sO", &encoding, &error)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (PyCodec_RegisterError(encoding, error) < 0) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_lookup_error(PyObject *Py_UNUSED(module), PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *NULL_WOULD_RAISE(encoding); // NULL case will be tested
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "z", &encoding)) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyCodec_LookupError(encoding); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_strict_errors(PyObject *Py_UNUSED(module), PyObject *exc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(exc != NULL); | 
					
						
							|  |  |  |     return PyCodec_StrictErrors(exc); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_ignore_errors(PyObject *Py_UNUSED(module), PyObject *exc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(exc != NULL); | 
					
						
							|  |  |  |     return PyCodec_IgnoreErrors(exc); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_replace_errors(PyObject *Py_UNUSED(module), PyObject *exc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(exc != NULL); | 
					
						
							|  |  |  |     return PyCodec_ReplaceErrors(exc); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_xmlcharrefreplace_errors(PyObject *Py_UNUSED(module), PyObject *exc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(exc != NULL); | 
					
						
							|  |  |  |     return PyCodec_XMLCharRefReplaceErrors(exc); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | codec_backslashreplace_errors(PyObject *Py_UNUSED(module), PyObject *exc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(exc != NULL); | 
					
						
							|  |  |  |     return PyCodec_BackslashReplaceErrors(exc); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-11-01 08:44:54 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyMethodDef test_methods[] = { | 
					
						
							| 
									
										
										
										
											2024-09-29 17:22:39 +02:00
										 |  |  |     /* codecs registration */ | 
					
						
							|  |  |  |     {"codec_register", codec_register, METH_O}, | 
					
						
							|  |  |  |     {"codec_unregister", codec_unregister, METH_O}, | 
					
						
							|  |  |  |     {"codec_known_encoding", codec_known_encoding, METH_VARARGS}, | 
					
						
							|  |  |  |     /* encoding and decoding interface */ | 
					
						
							|  |  |  |     {"codec_encode", codec_encode, METH_VARARGS}, | 
					
						
							|  |  |  |     {"codec_decode", codec_decode, METH_VARARGS}, | 
					
						
							|  |  |  |     {"codec_encoder", codec_encoder, METH_VARARGS}, | 
					
						
							|  |  |  |     {"codec_decoder", codec_decoder, METH_VARARGS}, | 
					
						
							|  |  |  |     {"codec_incremental_encoder", codec_incremental_encoder, METH_VARARGS}, | 
					
						
							|  |  |  |     {"codec_incremental_decoder", codec_incremental_decoder, METH_VARARGS}, | 
					
						
							|  |  |  |     {"codec_stream_reader", codec_stream_reader, METH_VARARGS}, | 
					
						
							|  |  |  |     {"codec_stream_writer", codec_stream_writer, METH_VARARGS}, | 
					
						
							|  |  |  |     /* error handling */ | 
					
						
							|  |  |  |     {"codec_register_error", codec_register_error, METH_VARARGS}, | 
					
						
							|  |  |  |     {"codec_lookup_error", codec_lookup_error, METH_VARARGS}, | 
					
						
							|  |  |  |     {"codec_strict_errors", codec_strict_errors, METH_O}, | 
					
						
							|  |  |  |     {"codec_ignore_errors", codec_ignore_errors, METH_O}, | 
					
						
							|  |  |  |     {"codec_replace_errors", codec_replace_errors, METH_O}, | 
					
						
							|  |  |  |     {"codec_xmlcharrefreplace_errors", codec_xmlcharrefreplace_errors, METH_O}, | 
					
						
							|  |  |  |     {"codec_backslashreplace_errors", codec_backslashreplace_errors, METH_O}, | 
					
						
							|  |  |  |     // PyCodec_NameReplaceErrors() is tested in _testlimitedcapi/codec.c
 | 
					
						
							|  |  |  |     {NULL, NULL, 0, NULL}, | 
					
						
							| 
									
										
										
										
											2023-11-01 08:44:54 +03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | _PyTestCapi_Init_Codec(PyObject *m) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-09-29 17:22:39 +02:00
										 |  |  |     if (PyModule_AddFunctions(m, test_methods) < 0) { | 
					
						
							| 
									
										
										
										
											2023-11-01 08:44:54 +03:00
										 |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } |