4
4
#include <Python.h>
5
5
#include <structmember.h>
6
6
7
+ #include <alloca.h>
7
8
#include <errno.h>
8
9
#include <stdbool.h>
9
10
#include <string.h>
18
19
typedef struct {
19
20
PyObject_HEAD
20
21
struct bch_control * bch ;
21
- uint8_t * ecc ;
22
- unsigned int data_len ;
23
22
unsigned int * errloc ;
24
23
int nerr ;
25
24
} BCHObject ;
@@ -32,11 +31,6 @@ BCH_dealloc(BCHObject *self)
32
31
self -> bch = NULL ;
33
32
}
34
33
35
- if (self -> ecc ) {
36
- free (self -> ecc );
37
- self -> ecc = NULL ;
38
- }
39
-
40
34
if (self -> errloc ) {
41
35
free (self -> errloc );
42
36
self -> errloc = NULL ;
@@ -79,20 +73,10 @@ BCH_init(BCHObject *self, PyObject *args, PyObject *kwds)
79
73
return -1 ;
80
74
}
81
75
82
- self -> ecc = calloc (1 , self -> bch -> ecc_bytes );
83
- if (!self -> ecc ) {
84
- bch_free (self -> bch );
85
- self -> bch = NULL ;
86
- PyErr_SetString (PyExc_MemoryError , "unable to allocate ecc buffer" );
87
- return -1 ;
88
- }
89
-
90
76
self -> errloc = calloc (1 , sizeof (unsigned int ) * self -> bch -> t );
91
77
if (!self -> errloc ) {
92
78
bch_free (self -> bch );
93
79
self -> bch = NULL ;
94
- free (self -> ecc );
95
- self -> ecc = NULL ;
96
80
PyErr_SetString (PyExc_MemoryError , "unable to allocate errloc buffer" );
97
81
return -1 ;
98
82
}
@@ -114,21 +98,20 @@ BCH_encode(BCHObject *self, PyObject *args, PyObject *kwds)
114
98
return NULL ;
115
99
}
116
100
117
- if (ecc .buf ) {
118
- if (ecc .len != self -> bch -> ecc_bytes ) {
119
- PyErr_Format (PyExc_ValueError , "ecc length must be %d bytes" ,
120
- self -> bch -> ecc_bytes );
121
- return NULL ;
122
- }
123
- memcpy (self -> ecc , ecc .buf , self -> bch -> ecc_bytes );
124
- } else {
125
- memset (self -> ecc , 0 , self -> bch -> ecc_bytes );
101
+ if (!ecc .buf ) {
102
+ ecc .len = self -> bch -> ecc_bytes ;
103
+ ecc .buf = alloca (ecc .len );
104
+ memset (ecc .buf , 0 , ecc .len );
105
+ } else if (ecc .len != self -> bch -> ecc_bytes ) {
106
+ PyErr_Format (PyExc_ValueError , "ecc length must be %d bytes" ,
107
+ self -> bch -> ecc_bytes );
108
+ return NULL ;
126
109
}
127
110
128
111
bch_encode (self -> bch , (uint8_t * ) data .buf , (unsigned int ) data .len ,
129
- self -> ecc );
112
+ ecc . buf );
130
113
131
- return PyBytes_FromStringAndSize ((const char * )self -> ecc ,
114
+ return PyBytes_FromStringAndSize ((const char * ) ecc . buf ,
132
115
self -> bch -> ecc_bytes );
133
116
}
134
117
@@ -146,10 +129,6 @@ BCH_decode(BCHObject *self, PyObject *args, PyObject *kwds)
146
129
return NULL ;
147
130
}
148
131
149
- if (data .buf && self -> data_len <= 0 ) {
150
- self -> data_len = data .len ;
151
- }
152
-
153
132
if (recv_ecc .buf && recv_ecc .len != self -> bch -> ecc_bytes ) {
154
133
PyErr_Format (PyExc_ValueError , "recv_ecc length should be %d bytes" ,
155
134
self -> bch -> ecc_bytes );
@@ -194,7 +173,7 @@ BCH_decode(BCHObject *self, PyObject *args, PyObject *kwds)
194
173
Py_DECREF (syn );
195
174
}
196
175
197
- self -> nerr = bch_decode (self -> bch , data .buf , self -> data_len , recv_ecc .buf ,
176
+ self -> nerr = bch_decode (self -> bch , data .buf , data . len , recv_ecc .buf ,
198
177
calc_ecc .buf , syn ? self -> bch -> syn : NULL , self -> errloc );
199
178
200
179
if (self -> nerr < 0 ) {
@@ -219,7 +198,7 @@ BCH_correct(BCHObject *self, PyObject *args, PyObject *kwds)
219
198
PyObject * result = NULL ;
220
199
221
200
static char * kwlist [] = {"data" , "ecc" , NULL };
222
- if (!PyArg_ParseTupleAndKeywords (args , kwds , "|y* y*" , kwlist , & data ,
201
+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "y*| y*" , kwlist , & data ,
223
202
& ecc )) {
224
203
goto cleanup ;
225
204
}
@@ -240,20 +219,20 @@ BCH_correct(BCHObject *self, PyObject *args, PyObject *kwds)
240
219
241
220
for (int i = 0 ; i < self -> nerr ; i ++ ) {
242
221
unsigned int bitnum = self -> errloc [i ];
243
- if (bitnum >= (self -> data_len + self -> bch -> ecc_bytes ) * 8 ) {
222
+ if (bitnum >= (data . len + self -> bch -> ecc_bytes ) * 8 ) {
244
223
PyErr_SetString (PyExc_IndexError , "uncorrectable error" );
245
224
return NULL ;
246
225
}
247
226
unsigned int byte = bitnum / 8 ;
248
227
unsigned char bit = 1 << (bitnum & 7 );
249
228
250
- if (byte < self -> data_len ) {
229
+ if (byte < data . len ) {
251
230
if (data .buf && !data .readonly ) {
252
231
((uint8_t * ) data .buf )[byte ] ^= bit ;
253
232
}
254
233
} else {
255
234
if (ecc .buf && !ecc .readonly ) {
256
- ((uint8_t * ) ecc .buf )[byte - self -> data_len ] ^= bit ;
235
+ ((uint8_t * ) ecc .buf )[byte - data . len ] ^= bit ;
257
236
}
258
237
}
259
238
}
@@ -363,9 +342,6 @@ BCH_getattr(BCHObject *self, PyObject *name)
363
342
}
364
343
365
344
static PyMemberDef BCH_members [] = {
366
- {"data_len" , T_UINT , offsetof(BCHObject , data_len ), 0 ,
367
- "Read/write; decode data length in bytes. Set this value before\n"
368
- "decoding." },
369
345
{"ecc_bits" , -1 , 0 , READONLY |RESTRICTED ,
370
346
"Readonly; number of ecc bits." },
371
347
{"ecc_bytes" , -1 , 0 , READONLY |RESTRICTED ,
@@ -401,9 +377,7 @@ static PyMethodDef BCH_methods[] = {
401
377
" 'data' and 'recv_ecc'\n"
402
378
" 'recv_ecc' and 'calc_ecc'\n"
403
379
" 'calc_ecc' (as recv_ecc XOR calc_ecc)\n"
404
- " 'syn' (a sequence of 2*t values)\n\n"
405
-
406
- "'data_len' SHOULD be set before calling this function." },
380
+ " 'syn' (a sequence of 2*t values)" },
407
381
{"correct" , (PyCFunction ) BCH_correct , METH_VARARGS | METH_KEYWORDS , "\b\b\b\b"
408
382
"correct(data=None, ecc=None) → None\n"
409
383
"Corrects 'data' and 'ecc' if provided. Buffers must not be\n"
0 commit comments