From 9df564dfcbd4b86a7c415edc85efb834a064aecc Mon Sep 17 00:00:00 2001 From: zooko Date: Fri, 9 Nov 2007 04:05:59 +0530 Subject: [PATCH] zfec: make zfec C89 (ANSI C) compatible, patch thanks to Greg Hazel darcs-hash:ed97b58272cd371a187fb2d16efda4e2119daf17 --- zfec/zfec/_fecmodule.c | 57 ++++++++++++++++++++++++------------------ zfec/zfec/fec.c | 10 +++++--- zfec/zfec/fec.h | 8 ++++++ 3 files changed, 47 insertions(+), 28 deletions(-) diff --git a/zfec/zfec/_fecmodule.c b/zfec/zfec/_fecmodule.c index c4da169..629a69e 100644 --- a/zfec/zfec/_fecmodule.c +++ b/zfec/zfec/_fecmodule.c @@ -113,20 +113,23 @@ Encoder_encode(Encoder *self, PyObject *args) { PyObject* desired_blocks_nums = NULL; /* The blocknums of the blocks that should be returned. */ PyObject* result = NULL; - if (!PyArg_ParseTuple(args, "O|O", &inblocks, &desired_blocks_nums)) - return NULL; - - gf* check_blocks_produced[self->mm - self->kk]; /* This is an upper bound -- we will actually use only num_check_blocks_produced of these elements (see below). */ - PyObject* pystrs_produced[self->mm - self->kk]; /* This is an upper bound -- we will actually use only num_check_blocks_produced of these elements (see below). */ + gf** check_blocks_produced = (gf**)alloca(self->mm - self->kk); /* This is an upper bound -- we will actually use only num_check_blocks_produced of these elements (see below). */ + PyObject** pystrs_produced = (PyObject**)alloca(self->mm - self->kk); /* This is an upper bound -- we will actually use only num_check_blocks_produced of these elements (see below). */ unsigned num_check_blocks_produced = 0; /* The first num_check_blocks_produced elements of the check_blocks_produced array and of the pystrs_produced array will be used. */ - const gf* incblocks[self->kk]; + const gf** incblocks = (const gf**)alloca(self->kk); unsigned num_desired_blocks; PyObject* fast_desired_blocks_nums = NULL; PyObject** fast_desired_blocks_nums_items; - unsigned c_desired_blocks_nums[self->mm]; - unsigned c_desired_checkblocks_ids[self->mm - self->kk]; + unsigned* c_desired_blocks_nums = (unsigned*)alloca(self->mm); + unsigned* c_desired_checkblocks_ids = (unsigned*)alloca(self->mm - self->kk); unsigned i; PyObject* fastinblocks = NULL; + PyObject** fastinblocksitems; + Py_ssize_t sz, oldsz = 0; + unsigned char check_block_index = 0; /* index into the check_blocks_produced and (parallel) pystrs_produced arrays */ + + if (!PyArg_ParseTuple(args, "O|O", &inblocks, &desired_blocks_nums)) + return NULL; for (i=0; imm - self->kk; i++) pystrs_produced[i] = NULL; @@ -162,10 +165,10 @@ Encoder_encode(Encoder *self, PyObject *args) { } /* Construct a C array of gf*'s of the input data. */ - PyObject** fastinblocksitems = PySequence_Fast_ITEMS(fastinblocks); + fastinblocksitems = PySequence_Fast_ITEMS(fastinblocks); if (!fastinblocksitems) goto err; - Py_ssize_t sz, oldsz = 0; + for (i=0; ikk; i++) { if (!PyObject_CheckReadBuffer(fastinblocksitems[i])) { py_raise_fec_error("Precondition violation: %u'th item is required to offer the single-segment read character buffer protocol, but it does not.", i); @@ -181,7 +184,7 @@ Encoder_encode(Encoder *self, PyObject *args) { } /* Allocate space for all of the check blocks. */ - unsigned char check_block_index = 0; /* index into the check_blocks_produced and (parallel) pystrs_produced arrays */ + for (i=0; i= self->kk) { c_desired_checkblocks_ids[check_block_index] = c_desired_blocks_nums[i]; @@ -371,18 +374,26 @@ Decoder_decode(Decoder *self, PyObject *args) { PyObject*restrict blocknums; PyObject* result = NULL; + const gf**restrict cblocks = (const gf**restrict)alloca(self->kk); + unsigned* cblocknums = (unsigned*)alloca(self->kk); + gf**restrict recoveredcstrs = (gf**)alloca(self->kk); /* self->kk is actually an upper bound -- we probably won't need all of this space. */ + PyObject**restrict recoveredpystrs = (PyObject**restrict)alloca(self->kk); /* self->kk is actually an upper bound -- we probably won't need all of this space. */ + unsigned i; + PyObject*restrict fastblocknums = NULL; + PyObject*restrict fastblocks; + unsigned needtorecover=0; + PyObject** fastblocksitems; + PyObject** fastblocknumsitems; + Py_ssize_t sz, oldsz = 0; + long tmpl; + unsigned nextrecoveredix=0; + if (!PyArg_ParseTuple(args, "OO", &blocks, &blocknums)) return NULL; - const gf*restrict cblocks[self->kk]; - unsigned cblocknums[self->kk]; - gf*restrict recoveredcstrs[self->kk]; /* self->kk is actually an upper bound -- we probably won't need all of this space. */ - PyObject*restrict recoveredpystrs[self->kk]; /* self->kk is actually an upper bound -- we probably won't need all of this space. */ - unsigned i; for (i=0; ikk; i++) recoveredpystrs[i] = NULL; - PyObject*restrict fastblocknums = NULL; - PyObject*restrict fastblocks = PySequence_Fast(blocks, "First argument was not a sequence."); + fastblocks = PySequence_Fast(blocks, "First argument was not a sequence."); if (!fastblocks) goto err; fastblocknums = PySequence_Fast(blocknums, "Second argument was not a sequence."); @@ -399,20 +410,19 @@ Decoder_decode(Decoder *self, PyObject *args) { } /* Construct a C array of gf*'s of the data and another of C ints of the blocknums. */ - unsigned needtorecover=0; - PyObject** fastblocknumsitems = PySequence_Fast_ITEMS(fastblocknums); + fastblocknumsitems = PySequence_Fast_ITEMS(fastblocknums); if (!fastblocknumsitems) goto err; - PyObject** fastblocksitems = PySequence_Fast_ITEMS(fastblocks); + fastblocksitems = PySequence_Fast_ITEMS(fastblocks); if (!fastblocksitems) goto err; - Py_ssize_t sz, oldsz = 0; + for (i=0; ikk; i++) { if (!PyInt_Check(fastblocknumsitems[i])) { py_raise_fec_error("Precondition violation: second argument is required to contain int."); goto err; } - long tmpl = PyInt_AsLong(fastblocknumsitems[i]); + tmpl = PyInt_AsLong(fastblocknumsitems[i]); if (tmpl < 0 || tmpl > 255) { py_raise_fec_error("Precondition violation: block nums can't be less than zero or greater than 255. %ld\n", tmpl); goto err; @@ -462,7 +472,6 @@ Decoder_decode(Decoder *self, PyObject *args) { fec_decode(self->fec_matrix, cblocks, recoveredcstrs, cblocknums, sz); /* Wrap up both original primary blocks and decoded blocks into a Python list of Python strings. */ - unsigned nextrecoveredix=0; result = PyList_New(self->kk); if (result == NULL) goto err; diff --git a/zfec/zfec/fec.c b/zfec/zfec/fec.c index 5e81dbb..10ea2e6 100644 --- a/zfec/zfec/fec.c +++ b/zfec/zfec/fec.c @@ -494,14 +494,16 @@ build_decode_matrix_into_space(const fec_t*restrict const code, const unsigned*c void fec_decode(const fec_t* code, const gf*restrict const*restrict const inpkts, gf*restrict const*restrict const outpkts, const unsigned*restrict const index, size_t sz) { - gf m_dec[code->k * code->k]; + gf* m_dec = (gf*)alloca(code->k * code->k); + unsigned char outix=0; + unsigned char row=0; + unsigned char col=0; build_decode_matrix_into_space(code, index, code->k, m_dec); - unsigned char outix=0; - for (unsigned char row=0; rowk; row++) { + for (row=0; rowk; row++) { if (index[row] >= code->k) { memset(outpkts[outix], 0, sz); - for (unsigned char col=0; col < code->k; col++) + for (col=0; col < code->k; col++) addmul(outpkts[outix], inpkts[col], m_dec[row * code->k + col], sz); outix++; } diff --git a/zfec/zfec/fec.h b/zfec/zfec/fec.h index 3d81899..3931017 100644 --- a/zfec/zfec/fec.h +++ b/zfec/zfec/fec.h @@ -2,6 +2,14 @@ * zfec -- fast forward error correction library with Python interface */ +#if defined(_MSC_VER) +// actually, some of the flavors (i.e. Enterprise) do support it +//#define restrict __restrict +#define restrict +#define inline __inline +#define alloca _alloca +#endif + typedef unsigned char gf; typedef struct { -- 2.37.2