blob: 3b117e6966a71354f0cf901217df52464f940465 [file] [log] [blame]
Guido van Rossume2d67f92000-03-10 23:09:23 +00001/* ------------------------------------------------------------------------
2
3 _codecs -- Provides access to the codec registry and the builtin
4 codecs.
5
6 This module should never be imported directly. The standard library
7 module "codecs" wraps this builtin module for use within Python.
8
9 The codec registry is accessible via:
10
11 register(search_function) -> None
12
13 lookup(encoding) -> (encoder, decoder, stream_reader, stream_writer)
14
15 The builtin Unicode codecs use the following interface:
16
17 <encoding>_encode(Unicode_object[,errors='strict']) ->
18 (string object, bytes consumed)
19
20 <encoding>_decode(char_buffer_obj[,errors='strict']) ->
21 (Unicode object, bytes consumed)
22
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +000023 <encoding>_encode() interfaces also accept non-Unicode object as
24 input. The objects are then converted to Unicode using
25 PyUnicode_FromObject() prior to applying the conversion.
26
Guido van Rossume2d67f92000-03-10 23:09:23 +000027 These <encoding>s are available: utf_8, unicode_escape,
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +000028 raw_unicode_escape, unicode_internal, latin_1, ascii (7-bit),
29 mbcs (on win32).
30
Guido van Rossume2d67f92000-03-10 23:09:23 +000031
32Written by Marc-Andre Lemburg (mal@lemburg.com).
33
34(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
35
36 ------------------------------------------------------------------------ */
37
38#include "Python.h"
39
40/* --- Registry ----------------------------------------------------------- */
41
42static
43PyObject *codecregister(PyObject *self, PyObject *args)
44{
45 PyObject *search_function;
46
47 if (!PyArg_ParseTuple(args, "O:register", &search_function))
48 goto onError;
49
50 if (PyCodec_Register(search_function))
51 goto onError;
52
53 Py_INCREF(Py_None);
54 return Py_None;
55
56 onError:
57 return NULL;
58}
59
60static
61PyObject *codeclookup(PyObject *self, PyObject *args)
62{
63 char *encoding;
64
65 if (!PyArg_ParseTuple(args, "s:lookup", &encoding))
66 goto onError;
67
68 return _PyCodec_Lookup(encoding);
69
70 onError:
71 return NULL;
72}
73
74/* --- Helpers ------------------------------------------------------------ */
75
76static
77PyObject *codec_tuple(PyObject *unicode,
78 int len)
79{
80 PyObject *v,*w;
81
82 if (unicode == NULL)
83 return NULL;
84 v = PyTuple_New(2);
85 if (v == NULL) {
86 Py_DECREF(unicode);
87 return NULL;
88 }
89 PyTuple_SET_ITEM(v,0,unicode);
90 w = PyInt_FromLong(len);
91 if (w == NULL) {
92 Py_DECREF(v);
93 return NULL;
94 }
95 PyTuple_SET_ITEM(v,1,w);
96 return v;
97}
98
99/* --- Decoder ------------------------------------------------------------ */
100
101static PyObject *
102unicode_internal_decode(PyObject *self,
103 PyObject *args)
104{
105 const char *data;
106 int size;
107 const char *errors = NULL;
108
109 if (!PyArg_ParseTuple(args, "s#|z:unicode_internal_decode",
110 &data, &size, &errors))
111 return NULL;
112
113 return codec_tuple(PyUnicode_FromUnicode((Py_UNICODE *)data,
114 size / sizeof(Py_UNICODE)),
115 size);
116}
117
118static PyObject *
119utf_8_decode(PyObject *self,
120 PyObject *args)
121{
122 const char *data;
123 int size;
124 const char *errors = NULL;
125
126 if (!PyArg_ParseTuple(args, "t#|z:utf_8_decode",
127 &data, &size, &errors))
128 return NULL;
129
130 return codec_tuple(PyUnicode_DecodeUTF8(data, size, errors),
131 size);
132}
133
134static PyObject *
135utf_16_decode(PyObject *self,
136 PyObject *args)
137{
138 const char *data;
139 int size;
140 const char *errors = NULL;
141 int byteorder = 0;
142
143 if (!PyArg_ParseTuple(args, "t#|z:utf_16_decode",
144 &data, &size, &errors))
145 return NULL;
146 return codec_tuple(PyUnicode_DecodeUTF16(data, size, errors, &byteorder),
147 size);
148}
149
150static PyObject *
151utf_16_le_decode(PyObject *self,
152 PyObject *args)
153{
154 const char *data;
155 int size;
156 const char *errors = NULL;
157 int byteorder = -1;
158
159 if (!PyArg_ParseTuple(args, "t#|z:utf_16_le_decode",
160 &data, &size, &errors))
161 return NULL;
162 return codec_tuple(PyUnicode_DecodeUTF16(data, size, errors, &byteorder),
163 size);
164}
165
166static PyObject *
167utf_16_be_decode(PyObject *self,
168 PyObject *args)
169{
170 const char *data;
171 int size;
172 const char *errors = NULL;
173 int byteorder = 1;
174
175 if (!PyArg_ParseTuple(args, "t#|z:utf_16_be_decode",
176 &data, &size, &errors))
177 return NULL;
178 return codec_tuple(PyUnicode_DecodeUTF16(data, size, errors, &byteorder),
179 size);
180}
181
182/* This non-standard version also provides access to the byteorder
183 parameter of the builtin UTF-16 codec.
184
185 It returns a tuple (unicode, bytesread, byteorder) with byteorder
186 being the value in effect at the end of data.
187
188*/
189
190static PyObject *
191utf_16_ex_decode(PyObject *self,
192 PyObject *args)
193{
194 const char *data;
195 int size;
196 const char *errors = NULL;
197 int byteorder = 0;
198 PyObject *unicode, *tuple;
199
200 if (!PyArg_ParseTuple(args, "t#|zi:utf_16_ex_decode",
201 &data, &size, &errors, &byteorder))
202 return NULL;
203
204 unicode = PyUnicode_DecodeUTF16(data, size, errors, &byteorder);
205 if (unicode == NULL)
206 return NULL;
207 tuple = Py_BuildValue("Oii", unicode, size, byteorder);
208 Py_DECREF(unicode);
209 return tuple;
210}
211
212static PyObject *
213unicode_escape_decode(PyObject *self,
214 PyObject *args)
215{
216 const char *data;
217 int size;
218 const char *errors = NULL;
219
220 if (!PyArg_ParseTuple(args, "t#|z:unicode_escape_decode",
221 &data, &size, &errors))
222 return NULL;
223
224 return codec_tuple(PyUnicode_DecodeUnicodeEscape(data, size, errors),
225 size);
226}
227
228static PyObject *
229raw_unicode_escape_decode(PyObject *self,
230 PyObject *args)
231{
232 const char *data;
233 int size;
234 const char *errors = NULL;
235
236 if (!PyArg_ParseTuple(args, "t#|z:raw_unicode_escape_decode",
237 &data, &size, &errors))
238 return NULL;
239
240 return codec_tuple(PyUnicode_DecodeRawUnicodeEscape(data, size, errors),
241 size);
242}
243
244static PyObject *
245latin_1_decode(PyObject *self,
246 PyObject *args)
247{
248 const char *data;
249 int size;
250 const char *errors = NULL;
251
252 if (!PyArg_ParseTuple(args, "t#|z:latin_1_decode",
253 &data, &size, &errors))
254 return NULL;
255
256 return codec_tuple(PyUnicode_DecodeLatin1(data, size, errors),
257 size);
258}
259
260static PyObject *
261ascii_decode(PyObject *self,
262 PyObject *args)
263{
264 const char *data;
265 int size;
266 const char *errors = NULL;
267
268 if (!PyArg_ParseTuple(args, "t#|z:ascii_decode",
269 &data, &size, &errors))
270 return NULL;
271
272 return codec_tuple(PyUnicode_DecodeASCII(data, size, errors),
273 size);
274}
275
276static PyObject *
277charmap_decode(PyObject *self,
278 PyObject *args)
279{
280 const char *data;
281 int size;
282 const char *errors = NULL;
283 PyObject *mapping = NULL;
284
285 if (!PyArg_ParseTuple(args, "t#|zO:charmap_decode",
286 &data, &size, &errors, &mapping))
287 return NULL;
288 if (mapping == Py_None)
289 mapping = NULL;
290
291 return codec_tuple(PyUnicode_DecodeCharmap(data, size, mapping, errors),
292 size);
293}
294
Guido van Rossum24bdb042000-03-28 20:29:59 +0000295#ifdef MS_WIN32
296
297static PyObject *
298mbcs_decode(PyObject *self,
299 PyObject *args)
300{
301 const char *data;
302 int size;
303 const char *errors = NULL;
304
305 if (!PyArg_ParseTuple(args, "t#|z:mbcs_decode",
306 &data, &size, &errors))
307 return NULL;
308
309 return codec_tuple(PyUnicode_DecodeMBCS(data, size, errors),
310 size);
311}
312
313#endif /* MS_WIN32 */
314
Guido van Rossume2d67f92000-03-10 23:09:23 +0000315/* --- Encoder ------------------------------------------------------------ */
316
317static PyObject *
318readbuffer_encode(PyObject *self,
319 PyObject *args)
320{
321 const char *data;
322 int size;
323 const char *errors = NULL;
324
325 if (!PyArg_ParseTuple(args, "s#|z:readbuffer_encode",
326 &data, &size, &errors))
327 return NULL;
328
329 return codec_tuple(PyString_FromStringAndSize(data, size),
330 size);
331}
332
333static PyObject *
334charbuffer_encode(PyObject *self,
335 PyObject *args)
336{
337 const char *data;
338 int size;
339 const char *errors = NULL;
340
341 if (!PyArg_ParseTuple(args, "t#|z:charbuffer_encode",
342 &data, &size, &errors))
343 return NULL;
344
345 return codec_tuple(PyString_FromStringAndSize(data, size),
346 size);
347}
348
349static PyObject *
350utf_8_encode(PyObject *self,
351 PyObject *args)
352{
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000353 PyObject *str, *v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000354 const char *errors = NULL;
355
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000356 if (!PyArg_ParseTuple(args, "O|z:utf_8_encode",
Guido van Rossume2d67f92000-03-10 23:09:23 +0000357 &str, &errors))
358 return NULL;
359
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000360 str = PyUnicode_FromObject(str);
361 if (str == NULL)
362 return NULL;
363 v = codec_tuple(PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(str),
364 PyUnicode_GET_SIZE(str),
365 errors),
366 PyUnicode_GET_SIZE(str));
367 Py_DECREF(str);
368 return v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000369}
370
371/* This version provides access to the byteorder parameter of the
372 builtin UTF-16 codecs as optional third argument. It defaults to 0
373 which means: use the native byte order and prepend the data with a
374 BOM mark.
375
376*/
377
378static PyObject *
379utf_16_encode(PyObject *self,
380 PyObject *args)
381{
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000382 PyObject *str, *v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000383 const char *errors = NULL;
384 int byteorder = 0;
385
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000386 if (!PyArg_ParseTuple(args, "O|zi:utf_16_encode",
Guido van Rossume2d67f92000-03-10 23:09:23 +0000387 &str, &errors, &byteorder))
388 return NULL;
389
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000390 str = PyUnicode_FromObject(str);
391 if (str == NULL)
392 return NULL;
393 v = codec_tuple(PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(str),
394 PyUnicode_GET_SIZE(str),
395 errors,
396 byteorder),
397 PyUnicode_GET_SIZE(str));
398 Py_DECREF(str);
399 return v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000400}
401
402static PyObject *
403utf_16_le_encode(PyObject *self,
404 PyObject *args)
405{
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000406 PyObject *str, *v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000407 const char *errors = NULL;
408
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000409 if (!PyArg_ParseTuple(args, "O|zi:utf_16_le_encode",
Guido van Rossume2d67f92000-03-10 23:09:23 +0000410 &str, &errors))
411 return NULL;
412
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000413 str = PyUnicode_FromObject(str);
414 if (str == NULL)
415 return NULL;
416 v = codec_tuple(PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(str),
Guido van Rossume2d67f92000-03-10 23:09:23 +0000417 PyUnicode_GET_SIZE(str),
418 errors,
419 -1),
420 PyUnicode_GET_SIZE(str));
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000421 Py_DECREF(str);
422 return v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000423}
424
425static PyObject *
426utf_16_be_encode(PyObject *self,
427 PyObject *args)
428{
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000429 PyObject *str, *v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000430 const char *errors = NULL;
431
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000432 if (!PyArg_ParseTuple(args, "O|zi:utf_16_be_encode",
Guido van Rossume2d67f92000-03-10 23:09:23 +0000433 &str, &errors))
434 return NULL;
435
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000436 str = PyUnicode_FromObject(str);
437 if (str == NULL)
438 return NULL;
439 v = codec_tuple(PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(str),
440 PyUnicode_GET_SIZE(str),
441 errors,
442 +1),
443 PyUnicode_GET_SIZE(str));
444 Py_DECREF(str);
445 return v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000446}
447
448static PyObject *
449unicode_escape_encode(PyObject *self,
450 PyObject *args)
451{
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000452 PyObject *str, *v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000453 const char *errors = NULL;
454
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000455 if (!PyArg_ParseTuple(args, "O|z:unicode_escape_encode",
Guido van Rossume2d67f92000-03-10 23:09:23 +0000456 &str, &errors))
457 return NULL;
458
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000459 str = PyUnicode_FromObject(str);
460 if (str == NULL)
461 return NULL;
462 v = codec_tuple(PyUnicode_EncodeUnicodeEscape(PyUnicode_AS_UNICODE(str),
463 PyUnicode_GET_SIZE(str)),
464 PyUnicode_GET_SIZE(str));
465 Py_DECREF(str);
466 return v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000467}
468
469static PyObject *
470raw_unicode_escape_encode(PyObject *self,
471 PyObject *args)
472{
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000473 PyObject *str, *v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000474 const char *errors = NULL;
475
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000476 if (!PyArg_ParseTuple(args, "O|z:raw_unicode_escape_encode",
Guido van Rossume2d67f92000-03-10 23:09:23 +0000477 &str, &errors))
478 return NULL;
479
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000480 str = PyUnicode_FromObject(str);
481 if (str == NULL)
482 return NULL;
483 v = codec_tuple(PyUnicode_EncodeRawUnicodeEscape(
Guido van Rossume2d67f92000-03-10 23:09:23 +0000484 PyUnicode_AS_UNICODE(str),
485 PyUnicode_GET_SIZE(str)),
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000486 PyUnicode_GET_SIZE(str));
487 Py_DECREF(str);
488 return v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000489}
490
491static PyObject *
492latin_1_encode(PyObject *self,
493 PyObject *args)
494{
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000495 PyObject *str, *v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000496 const char *errors = NULL;
497
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000498 if (!PyArg_ParseTuple(args, "O|z:latin_1_encode",
Guido van Rossume2d67f92000-03-10 23:09:23 +0000499 &str, &errors))
500 return NULL;
501
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000502 str = PyUnicode_FromObject(str);
503 if (str == NULL)
504 return NULL;
505 v = codec_tuple(PyUnicode_EncodeLatin1(
Guido van Rossume2d67f92000-03-10 23:09:23 +0000506 PyUnicode_AS_UNICODE(str),
507 PyUnicode_GET_SIZE(str),
508 errors),
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000509 PyUnicode_GET_SIZE(str));
510 Py_DECREF(str);
511 return v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000512}
513
514static PyObject *
515ascii_encode(PyObject *self,
516 PyObject *args)
517{
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000518 PyObject *str, *v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000519 const char *errors = NULL;
520
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000521 if (!PyArg_ParseTuple(args, "O|z:ascii_encode",
Guido van Rossume2d67f92000-03-10 23:09:23 +0000522 &str, &errors))
523 return NULL;
524
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000525 str = PyUnicode_FromObject(str);
526 if (str == NULL)
527 return NULL;
528 v = codec_tuple(PyUnicode_EncodeASCII(
Guido van Rossume2d67f92000-03-10 23:09:23 +0000529 PyUnicode_AS_UNICODE(str),
530 PyUnicode_GET_SIZE(str),
531 errors),
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000532 PyUnicode_GET_SIZE(str));
533 Py_DECREF(str);
534 return v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000535}
536
537static PyObject *
538charmap_encode(PyObject *self,
539 PyObject *args)
540{
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000541 PyObject *str, *v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000542 const char *errors = NULL;
543 PyObject *mapping = NULL;
544
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000545 if (!PyArg_ParseTuple(args, "O|zO:charmap_encode",
Guido van Rossume2d67f92000-03-10 23:09:23 +0000546 &str, &errors, &mapping))
547 return NULL;
548 if (mapping == Py_None)
549 mapping = NULL;
550
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000551 str = PyUnicode_FromObject(str);
552 if (str == NULL)
553 return NULL;
554 v = codec_tuple(PyUnicode_EncodeCharmap(
Guido van Rossume2d67f92000-03-10 23:09:23 +0000555 PyUnicode_AS_UNICODE(str),
556 PyUnicode_GET_SIZE(str),
557 mapping,
558 errors),
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000559 PyUnicode_GET_SIZE(str));
560 Py_DECREF(str);
561 return v;
Guido van Rossume2d67f92000-03-10 23:09:23 +0000562}
563
Guido van Rossum24bdb042000-03-28 20:29:59 +0000564#ifdef MS_WIN32
565
566static PyObject *
567mbcs_encode(PyObject *self,
568 PyObject *args)
569{
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000570 PyObject *str, *v;
Guido van Rossum24bdb042000-03-28 20:29:59 +0000571 const char *errors = NULL;
572
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000573 if (!PyArg_ParseTuple(args, "O|z:mbcs_encode",
Guido van Rossum24bdb042000-03-28 20:29:59 +0000574 &str, &errors))
575 return NULL;
576
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000577 str = PyUnicode_FromObject(str);
578 if (str == NULL)
579 return NULL;
580 v = codec_tuple(PyUnicode_EncodeMBCS(
Guido van Rossum24bdb042000-03-28 20:29:59 +0000581 PyUnicode_AS_UNICODE(str),
582 PyUnicode_GET_SIZE(str),
583 errors),
Marc-André Lemburg5f0e29e2000-07-05 11:24:13 +0000584 PyUnicode_GET_SIZE(str));
585 Py_DECREF(str);
586 return v;
Guido van Rossum24bdb042000-03-28 20:29:59 +0000587}
588
589#endif /* MS_WIN32 */
590
Guido van Rossume2d67f92000-03-10 23:09:23 +0000591/* --- Module API --------------------------------------------------------- */
592
593static PyMethodDef _codecs_functions[] = {
594 {"register", codecregister, 1},
595 {"lookup", codeclookup, 1},
596 {"utf_8_encode", utf_8_encode, 1},
597 {"utf_8_decode", utf_8_decode, 1},
598 {"utf_16_encode", utf_16_encode, 1},
599 {"utf_16_le_encode", utf_16_le_encode, 1},
600 {"utf_16_be_encode", utf_16_be_encode, 1},
601 {"utf_16_decode", utf_16_decode, 1},
602 {"utf_16_le_decode", utf_16_le_decode, 1},
603 {"utf_16_be_decode", utf_16_be_decode, 1},
604 {"utf_16_ex_decode", utf_16_ex_decode, 1},
605 {"unicode_escape_encode", unicode_escape_encode, 1},
606 {"unicode_escape_decode", unicode_escape_decode, 1},
607 {"unicode_internal_encode", readbuffer_encode, 1},
608 {"unicode_internal_decode", unicode_internal_decode, 1},
609 {"raw_unicode_escape_encode", raw_unicode_escape_encode, 1},
610 {"raw_unicode_escape_decode", raw_unicode_escape_decode, 1},
611 {"latin_1_encode", latin_1_encode, 1},
612 {"latin_1_decode", latin_1_decode, 1},
613 {"ascii_encode", ascii_encode, 1},
614 {"ascii_decode", ascii_decode, 1},
615 {"charmap_encode", charmap_encode, 1},
616 {"charmap_decode", charmap_decode, 1},
617 {"readbuffer_encode", readbuffer_encode, 1},
618 {"charbuffer_encode", charbuffer_encode, 1},
Guido van Rossum24bdb042000-03-28 20:29:59 +0000619#ifdef MS_WIN32
620 {"mbcs_encode", mbcs_encode, 1},
621 {"mbcs_decode", mbcs_decode, 1},
622#endif
Guido van Rossume2d67f92000-03-10 23:09:23 +0000623 {NULL, NULL} /* sentinel */
624};
625
626DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000627init_codecs(void)
Guido van Rossume2d67f92000-03-10 23:09:23 +0000628{
629 Py_InitModule("_codecs", _codecs_functions);
630}