--- Algorithm-FEC/FEC.xs 2003/09/09 05:52:49 1.1 +++ Algorithm-FEC/FEC.xs 2007/12/23 14:56:09 1.8 @@ -28,7 +28,8 @@ void **b_mmap; int *b_sz; SV **b_sv; -} *Convert__FEC; + int *idx; /* the decoding indices */ +} *Algorithm__FEC; static void chk_array (SV *sv, int size, const char *func, const char *var) @@ -36,7 +37,7 @@ if (!SvROK (sv) || SvTYPE (SvRV (sv)) != SVt_PVAV || av_len ((AV *)SvRV (sv)) != size - 1) - croak ("%s: %s must be a reference to an array of size %d", size); + croak ("%s: %s (%s) must be a reference to an array of size %d (is %s)", func, SvPV_nolen (sv), var, size); } static void @@ -55,6 +56,7 @@ Safefree (self->b_mmap); self->b_mmap = 0; Safefree (self->b_sz ); self->b_sz = 0; Safefree (self->b_sv ); self->b_sv = 0; + Safefree (self->idx ); self->idx = 0; } static void @@ -69,11 +71,11 @@ } static void -force_addrs (struct state *self) +force_addrs (struct state *self, int dp) { int i; - for (i = 0; i < self->dp; i++) + for (i = 0; i < dp; i++) if (self->b_sv[i]) { STRLEN size; @@ -82,7 +84,7 @@ if (size != self->sz) croak ("block #%d (a string) has size %d, not %d", i, (int)size, self->sz); } else if (!self->b_mmap[i]) { - croak ("block #%d neither string nor file, did set_encode_blocks fail and you ignored it?", i); + croak ("block #%d neither string nor file, did set_blocks fail and you ignored it?", i); } } @@ -142,11 +144,11 @@ open_file (self, i, *av_fetch (av, i, 1), rw); } -MODULE = Convert::FEC PACKAGE = Convert::FEC +MODULE = Algorithm::FEC PACKAGE = Algorithm::FEC PROTOTYPES: ENABLE -Convert::FEC +Algorithm::FEC new(class, data_packets, encoded_packets, blocksize) SV * class int data_packets @@ -182,7 +184,7 @@ void set_encode_blocks (self, blocks) - Convert::FEC self + Algorithm::FEC self SV * blocks CODE: @@ -190,13 +192,13 @@ if (SvOK (blocks)) { - chk_array (blocks, self->dp, "encode", "blocks"); + chk_array (blocks, self->dp, "set_encode_blocks", "blocks"); open_files (self, (AV *)SvRV (blocks), 0); } SV * encode (self, block_index) - Convert::FEC self + Algorithm::FEC self int block_index CODE: @@ -207,11 +209,12 @@ if (!self->b_addr) croak ("no blocks specified by a preceding call to set_encode_blocks"); - force_addrs (self); + force_addrs (self, self->dp); RETVAL = newSV (self->sz); if (!RETVAL) croak ("unable to allocate result block (out of memory)"); + SvPOK_only (RETVAL); SvCUR_set (RETVAL, self->sz); @@ -222,29 +225,26 @@ RETVAL void -decode (self, blocks, indices) - Convert::FEC self +set_decode_blocks (self, blocks, indices) + Algorithm::FEC self SV * blocks SV * indices + ALIAS: + shuffle = 1 CODE: { int i; int *idx; - chk_array (blocks, self->dp, "decode", "blocks"); - chk_array (indices, self->dp, "decode", "indices"); - open_files (self, (AV *)SvRV (blocks), 1); - - force_addrs (self); + chk_array (blocks, self->dp, "set_decode_blocks", "blocks"); + chk_array (indices, self->dp, "set_decode_blocks", "indices"); Newz (0, idx, self->dp, int); /* copy and check */ for (i = 0; i < self->dp; i++) { - SV *a = *av_fetch ((AV *)SvRV (indices), i, 1); - idx[i] = SvIV (a); - sv_setiv (a, i); + idx[i] = SvIV (*av_fetch ((AV *)SvRV (indices), i, 1)); if (idx[i] < 0 || idx[i] >= self->ep) { @@ -259,45 +259,67 @@ * so we know the order. */ for (i = 0; i < self->dp; i++) - if (idx[i] < self->dp && idx[i] != i) + while (idx[i] < self->dp && idx[i] != i) { - int c = idx[i]; - SV **a, **b; + SV **a, **b, **e, **f; int d; void *p; SV *s; + int j = idx[i]; - if (idx[c] == c) + if (idx[j] == j) { Safefree (idx); croak ("error while shuffling, duplicate indices?"); } a = av_fetch ((AV *)SvRV (indices), i, 1); - b = av_fetch ((AV *)SvRV (indices), c, 1); - - d = idx[i]; idx[i] = idx[c]; idx[c] = d; - p = self->b_addr[i]; self->b_addr[i] = self->b_addr[c]; self->b_addr[c] = p; - s = *a; *a = *b; *b = s; + b = av_fetch ((AV *)SvRV (indices), j, 1); + e = av_fetch ((AV *)SvRV (blocks ), i, 1); + f = av_fetch ((AV *)SvRV (blocks ), j, 1); + + d = idx[i]; idx[i] = idx[j]; idx[j] = d; + s = *a; *a = *b; *b = s; + s = *e; *e = *f; *f = s; } - self->imp->fec_decode (self->code, self->b_addr, idx, self->sz); + if (ix) + Safefree (idx); + else + { + open_files (self, (AV *)SvRV (blocks), 1); + self->idx = idx; + } +} + +void +decode (self) + Algorithm::FEC self + CODE: - Safefree (idx); + if (!self->idx) + croak ("index array must be set by a prior call to set_decode_blocks"); + force_addrs (self, self->dp); + self->imp->fec_decode (self->code, self->b_addr, self->idx, self->sz); free_files (self); -} void -copy_block (srcblock, dstblock) +copy (self, srcblock, dstblock) + Algorithm::FEC self SV * srcblock SV * dstblock CODE: - croak ("urgs"); + realloc_files (self); + open_file (self, 0, srcblock, 0); + open_file (self, 1, dstblock, 1); + force_addrs (self, 2); + Copy (self->b_addr[0], self->b_addr[1], self->sz, char); + free_files (self); void DESTROY(self) - Convert::FEC self + Algorithm::FEC self CODE: self->imp->fec_free (self->code); free_files (self);