chiark / gitweb /
selpk.pyx: Fix bad cut-and-paste in the callback property.
[mLib-python] / codec.pyx
CommitLineData
55b42c18
MW
1### -*-pyrex-*-
2###
3### Generic encoder/decoder
4###
5### (c) 2005 Straylight/Edgeware
6###
7
8###----- Licensing notice ---------------------------------------------------
9###
10### This file is part of the Python interface to mLib.
11###
12### mLib/Python is free software; you can redistribute it and/or modify
13### it under the terms of the GNU General Public License as published by
14### the Free Software Foundation; either version 2 of the License, or
15### (at your option) any later version.
16###
17### mLib/Python is distributed in the hope that it will be useful,
18### but WITHOUT ANY WARRANTY; without even the implied warranty of
19### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20### GNU General Public License for more details.
21###
22### You should have received a copy of the GNU General Public License
23### along with mLib/Python; if not, write to the Free Software Foundation,
24### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26###--------------------------------------------------------------------------
27### Base classes.
28
29cdef extern from 'mLib/codec.h':
30
31 ctypedef struct codec
32
33 ctypedef struct codec_class:
34 char *name
35 codec *(*encoder)(unsigned f, char *ind, unsigned max)
36 codec *(*decoder)(unsigned f)
37
38 ctypedef struct codec_ops:
39 codec_class *c
40 int (*code)(codec *c, void *p, size_t, dstr *d)
41 void (*destroy)(codec *c)
42 ctypedef struct codec:
43 codec_ops *ops
44
45 enum:
46 CDCF_LOWERC
47 CDCF_IGNCASE
48 CDCF_NOEQPAD
49 CDCF_IGNEQPAD
50 CDCF_IGNEQMID
51 CDCF_IGNZPAD
52 CDCF_IGNNEWL
2fa7b5db 53 CDCF_IGNSPC
55b42c18
MW
54 CDCF_IGNINVCH
55 CDCF_IGNJUNK
56
57 enum:
58 CDCERR_OK
59 CDCERR_INVCH
60 CDCERR_INVEQPAD
61 CDCERR_INVZPAD
62
63 char *_codec_strerror "codec_strerror"(int err)
64
65class CDCF:
66 LOWERC = CDCF_LOWERC
67 IGNCASE = CDCF_IGNCASE
68 NOEQPAD = CDCF_NOEQPAD
69 IGNEQPAD = CDCF_IGNEQPAD
70 IGNEQMID = CDCF_IGNEQMID
71 IGNZPAD = CDCF_IGNZPAD
72 IGNNEWL = CDCF_IGNNEWL
2fa7b5db 73 IGNSPC = CDCF_IGNSPC
55b42c18
MW
74 IGNINVCH = CDCF_IGNINVCH
75 IGNJUNK = CDCF_IGNJUNK
76
77class CDCERR:
78 OK = CDCERR_OK
79 INVCH = CDCERR_INVCH
80 INVEQPAD = CDCERR_INVEQPAD
81 INVZPAD = CDCERR_INVZPAD
82
83class CodecError (Exception):
84 def __init__(me, err):
85 me.err = err
86 me.msg = _codec_strerror(err)
87 def __str__(me):
88 return me.msg
89
90def codec_strerror(err):
91 return _codec_strerror(err)
92
93cdef int code(codec *c, void *p, size_t len, dstr *d) except -1:
94 cdef int err
95 err = c.ops.code(c, p, len, d)
96 if err:
97 raise CodecError(err)
98 return 0
99
100cdef class _BaseCodec:
101 cdef codec *c
102 def __cinit__(me, *hunoz, **hukairz):
103 me.c = NULL
104 def __init__(me, *hunoz, **hukairz):
105 raise TypeError, 'abstract class'
106 def __dealloc__(me):
107 if me.c is not NULL:
108 me.c.ops.destroy(me.c)
109 cdef code(me, text, int finishp):
110 cdef void *p
78911cdb 111 cdef Py_ssize_t len
55b42c18
MW
112 cdef dstr d
113 cdef int err
114 if me.c is NULL:
115 raise ValueError, 'Encoding finished'
116 DCREATE(&d)
117 try:
704500e1 118 PyObject_AsReadBuffer(text, <cvp *>&p, &len)
55b42c18
MW
119 code(me.c, p, len, &d)
120 if finishp:
121 code(me.c, NULL, 0, &d)
122 me.c.ops.destroy(me.c)
123 me.c = NULL
124 return PyString_FromStringAndSize(d.buf, d.len)
125 finally:
126 dstr_destroy(&d)
127 def done(me):
128 me.code('', True)
129
130cdef class _BaseEncoder (_BaseCodec):
131 def encode(me, text, finishp = False):
132 return me.code(text, finishp)
133
134cdef class _BaseDecoder (_BaseCodec):
135 def decode(me, text, finishp = False):
136 return me.code(text, finishp)
137
138###--------------------------------------------------------------------------
139### Base64.
140
141cdef extern from 'mLib/base64.h':
142 codec_class base64_class
143 codec_class file64_class
144 codec_class base64url_class
145
146cdef class Base64Encoder (_BaseEncoder):
147 def __init__(me, indent = '\n', maxline = 72, flags = CDCF_IGNJUNK):
148 me.c = base64_class.encoder(flags, indent, maxline)
149
150cdef class Base64Decoder (_BaseDecoder):
151 def __init__(me, flags = CDCF_IGNJUNK):
152 me.c = base64_class.decoder(flags)
153
154cdef class File64Encoder (_BaseEncoder):
155 def __init__(me, indent = '\n', maxline = 72, flags = CDCF_IGNJUNK):
156 me.c = file64_class.encoder(flags, indent, maxline)
157
158cdef class File64Decoder (_BaseDecoder):
159 def __init__(me, flags = CDCF_IGNJUNK):
160 me.c = file64_class.decoder(flags)
161
162cdef class Base64URLEncoder (_BaseEncoder):
163 def __init__(me, indent = '\n', maxline = 72, flags = CDCF_IGNJUNK):
164 me.c = base64url_class.encoder(flags, indent, maxline)
165
166cdef class Base64URLDecoder (_BaseDecoder):
167 def __init__(me, flags = CDCF_IGNJUNK):
168 me.c = base64url_class.decoder(flags)
169
170###--------------------------------------------------------------------------
171### Base32.
172
173cdef extern from 'mLib/base32.h':
174 codec_class base32_class
175 codec_class base32hex_class
176
177cdef class Base32Encoder (_BaseEncoder):
178 def __init__(me, indent = '\n', maxline = 72, flags = CDCF_IGNJUNK):
179 me.c = base32_class.encoder(flags, indent, maxline)
180
181cdef class Base32Decoder (_BaseDecoder):
182 def __init__(me, flags = CDCF_IGNJUNK):
183 me.c = base32_class.decoder(flags)
184
185cdef class Base32HexEncoder (_BaseEncoder):
186 def __init__(me, indent = '\n', maxline = 72, flags = CDCF_IGNJUNK):
187 me.c = base32hex_class.encoder(flags, indent, maxline)
188
189cdef class Base32HexDecoder (_BaseDecoder):
190 def __init__(me, flags = CDCF_IGNJUNK):
191 me.c = base32hex_class.decoder(flags)
192
193###--------------------------------------------------------------------------
194### Hex.
195
196cdef extern from 'mLib/hex.h':
197 codec_class hex_class
198
199cdef class HexEncoder (_BaseEncoder):
200 def __init__(me, indent = '\n', maxline = 72,
201 flags = CDCF_IGNJUNK | CDCF_LOWERC):
202 me.c = hex_class.encoder(flags, indent, maxline)
203
204cdef class HexDecoder (_BaseDecoder):
205 def __init__(me, flags = CDCF_IGNJUNK | CDCF_LOWERC):
206 me.c = hex_class.decoder(flags)
207
208###----- That's all, folks --------------------------------------------------