ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Algorithm-FEC/FEC.xs
(Generate patch)

Comparing Algorithm-FEC/FEC.xs (file contents):
Revision 1.1 by root, Tue Sep 9 05:52:49 2003 UTC vs.
Revision 1.8 by root, Sun Dec 23 14:56:09 2007 UTC

26 26
27 void **b_addr; 27 void **b_addr;
28 void **b_mmap; 28 void **b_mmap;
29 int *b_sz; 29 int *b_sz;
30 SV **b_sv; 30 SV **b_sv;
31} *Convert__FEC; 31 int *idx; /* the decoding indices */
32} *Algorithm__FEC;
32 33
33static void 34static void
34chk_array (SV *sv, int size, const char *func, const char *var) 35chk_array (SV *sv, int size, const char *func, const char *var)
35{ 36{
36 if (!SvROK (sv) 37 if (!SvROK (sv)
37 || SvTYPE (SvRV (sv)) != SVt_PVAV 38 || SvTYPE (SvRV (sv)) != SVt_PVAV
38 || av_len ((AV *)SvRV (sv)) != size - 1) 39 || av_len ((AV *)SvRV (sv)) != size - 1)
39 croak ("%s: %s must be a reference to an array of size %d", size); 40 croak ("%s: %s (%s) must be a reference to an array of size %d (is %s)", func, SvPV_nolen (sv), var, size);
40} 41}
41 42
42static void 43static void
43free_files (struct state *self) 44free_files (struct state *self)
44{ 45{
53 54
54 Safefree (self->b_addr); self->b_addr = 0; 55 Safefree (self->b_addr); self->b_addr = 0;
55 Safefree (self->b_mmap); self->b_mmap = 0; 56 Safefree (self->b_mmap); self->b_mmap = 0;
56 Safefree (self->b_sz ); self->b_sz = 0; 57 Safefree (self->b_sz ); self->b_sz = 0;
57 Safefree (self->b_sv ); self->b_sv = 0; 58 Safefree (self->b_sv ); self->b_sv = 0;
59 Safefree (self->idx ); self->idx = 0;
58} 60}
59 61
60static void 62static void
61realloc_files (struct state *self) 63realloc_files (struct state *self)
62{ 64{
67 Newz (0, self->b_sz , self->dp, int); 69 Newz (0, self->b_sz , self->dp, int);
68 Newz (0, self->b_sv , self->dp, SV *); 70 Newz (0, self->b_sv , self->dp, SV *);
69} 71}
70 72
71static void 73static void
72force_addrs (struct state *self) 74force_addrs (struct state *self, int dp)
73{ 75{
74 int i; 76 int i;
75 77
76 for (i = 0; i < self->dp; i++) 78 for (i = 0; i < dp; i++)
77 if (self->b_sv[i]) 79 if (self->b_sv[i])
78 { 80 {
79 STRLEN size; 81 STRLEN size;
80 self->b_addr[i] = SvPV (self->b_sv[i], size); 82 self->b_addr[i] = SvPV (self->b_sv[i], size);
81 83
82 if (size != self->sz) 84 if (size != self->sz)
83 croak ("block #%d (a string) has size %d, not %d", i, (int)size, self->sz); 85 croak ("block #%d (a string) has size %d, not %d", i, (int)size, self->sz);
84 } else if (!self->b_mmap[i]) { 86 } else if (!self->b_mmap[i]) {
85 croak ("block #%d neither string nor file, did set_encode_blocks fail and you ignored it?", i); 87 croak ("block #%d neither string nor file, did set_blocks fail and you ignored it?", i);
86 } 88 }
87} 89}
88 90
89static void 91static void
90open_file (struct state *self, int idx, SV *sv, int rw) 92open_file (struct state *self, int idx, SV *sv, int rw)
140 142
141 for (i = 0; i < self->dp; i++) 143 for (i = 0; i < self->dp; i++)
142 open_file (self, i, *av_fetch (av, i, 1), rw); 144 open_file (self, i, *av_fetch (av, i, 1), rw);
143} 145}
144 146
145MODULE = Convert::FEC PACKAGE = Convert::FEC 147MODULE = Algorithm::FEC PACKAGE = Algorithm::FEC
146 148
147PROTOTYPES: ENABLE 149PROTOTYPES: ENABLE
148 150
149Convert::FEC 151Algorithm::FEC
150new(class, data_packets, encoded_packets, blocksize) 152new(class, data_packets, encoded_packets, blocksize)
151 SV * class 153 SV * class
152 int data_packets 154 int data_packets
153 int encoded_packets 155 int encoded_packets
154 int blocksize 156 int blocksize
180 OUTPUT: 182 OUTPUT:
181 RETVAL 183 RETVAL
182 184
183void 185void
184set_encode_blocks (self, blocks) 186set_encode_blocks (self, blocks)
185 Convert::FEC self 187 Algorithm::FEC self
186 SV * blocks 188 SV * blocks
187 CODE: 189 CODE:
188 190
189 free_files (self); 191 free_files (self);
190 192
191 if (SvOK (blocks)) 193 if (SvOK (blocks))
192 { 194 {
193 chk_array (blocks, self->dp, "encode", "blocks"); 195 chk_array (blocks, self->dp, "set_encode_blocks", "blocks");
194 open_files (self, (AV *)SvRV (blocks), 0); 196 open_files (self, (AV *)SvRV (blocks), 0);
195 } 197 }
196 198
197SV * 199SV *
198encode (self, block_index) 200encode (self, block_index)
199 Convert::FEC self 201 Algorithm::FEC self
200 int block_index 202 int block_index
201 CODE: 203 CODE:
202 204
203 if (block_index < 0 || self->ep <= block_index) 205 if (block_index < 0 || self->ep <= block_index)
204 croak ("encode: block_index %d out of range, must be 0 <= block_index < %d", 206 croak ("encode: block_index %d out of range, must be 0 <= block_index < %d",
205 block_index, self->ep); 207 block_index, self->ep);
206 208
207 if (!self->b_addr) 209 if (!self->b_addr)
208 croak ("no blocks specified by a preceding call to set_encode_blocks"); 210 croak ("no blocks specified by a preceding call to set_encode_blocks");
209 211
210 force_addrs (self); 212 force_addrs (self, self->dp);
211 213
212 RETVAL = newSV (self->sz); 214 RETVAL = newSV (self->sz);
213 if (!RETVAL) 215 if (!RETVAL)
214 croak ("unable to allocate result block (out of memory)"); 216 croak ("unable to allocate result block (out of memory)");
217
215 SvPOK_only (RETVAL); 218 SvPOK_only (RETVAL);
216 SvCUR_set (RETVAL, self->sz); 219 SvCUR_set (RETVAL, self->sz);
217 220
218 self->imp->fec_encode (self->code, self->b_addr, 221 self->imp->fec_encode (self->code, self->b_addr,
219 SvPVX (RETVAL), block_index, self->sz); 222 SvPVX (RETVAL), block_index, self->sz);
220 223
221 OUTPUT: 224 OUTPUT:
222 RETVAL 225 RETVAL
223 226
224void 227void
225decode (self, blocks, indices) 228set_decode_blocks (self, blocks, indices)
226 Convert::FEC self 229 Algorithm::FEC self
227 SV * blocks 230 SV * blocks
228 SV * indices 231 SV * indices
232 ALIAS:
233 shuffle = 1
229 CODE: 234 CODE:
230{ 235{
231 int i; 236 int i;
232 int *idx; 237 int *idx;
233 238
234 chk_array (blocks, self->dp, "decode", "blocks"); 239 chk_array (blocks, self->dp, "set_decode_blocks", "blocks");
235 chk_array (indices, self->dp, "decode", "indices"); 240 chk_array (indices, self->dp, "set_decode_blocks", "indices");
236 open_files (self, (AV *)SvRV (blocks), 1);
237
238 force_addrs (self);
239 241
240 Newz (0, idx, self->dp, int); 242 Newz (0, idx, self->dp, int);
241 243
242 /* copy and check */ 244 /* copy and check */
243 for (i = 0; i < self->dp; i++) 245 for (i = 0; i < self->dp; i++)
244 { 246 {
245 SV *a = *av_fetch ((AV *)SvRV (indices), i, 1); 247 idx[i] = SvIV (*av_fetch ((AV *)SvRV (indices), i, 1));
246 idx[i] = SvIV (a);
247 sv_setiv (a, i);
248 248
249 if (idx[i] < 0 || idx[i] >= self->ep) 249 if (idx[i] < 0 || idx[i] >= self->ep)
250 { 250 {
251 Safefree (idx); 251 Safefree (idx);
252 croak ("index %d in array out of bounds (0 <= %d < %d != true)", 252 croak ("index %d in array out of bounds (0 <= %d < %d != true)",
257 /* 257 /*
258 * do the same shuffling as fec_decode does here, 258 * do the same shuffling as fec_decode does here,
259 * so we know the order. 259 * so we know the order.
260 */ 260 */
261 for (i = 0; i < self->dp; i++) 261 for (i = 0; i < self->dp; i++)
262 if (idx[i] < self->dp && idx[i] != i) 262 while (idx[i] < self->dp && idx[i] != i)
263 { 263 {
264 int c = idx[i];
265 SV **a, **b; 264 SV **a, **b, **e, **f;
266 int d; 265 int d;
267 void *p; 266 void *p;
268 SV *s; 267 SV *s;
268 int j = idx[i];
269 269
270 if (idx[c] == c) 270 if (idx[j] == j)
271 { 271 {
272 Safefree (idx); 272 Safefree (idx);
273 croak ("error while shuffling, duplicate indices?"); 273 croak ("error while shuffling, duplicate indices?");
274 } 274 }
275 275
276 a = av_fetch ((AV *)SvRV (indices), i, 1); 276 a = av_fetch ((AV *)SvRV (indices), i, 1);
277 b = av_fetch ((AV *)SvRV (indices), c, 1); 277 b = av_fetch ((AV *)SvRV (indices), j, 1);
278 e = av_fetch ((AV *)SvRV (blocks ), i, 1);
279 f = av_fetch ((AV *)SvRV (blocks ), j, 1);
278 280
279 d = idx[i]; idx[i] = idx[c]; idx[c] = d; 281 d = idx[i]; idx[i] = idx[j]; idx[j] = d;
280 p = self->b_addr[i]; self->b_addr[i] = self->b_addr[c]; self->b_addr[c] = p;
281 s = *a; *a = *b; *b = s; 282 s = *a; *a = *b; *b = s;
283 s = *e; *e = *f; *f = s;
282 } 284 }
283 285
286 if (ix)
287 Safefree (idx);
288 else
289 {
290 open_files (self, (AV *)SvRV (blocks), 1);
291 self->idx = idx;
292 }
293}
294
295void
296decode (self)
297 Algorithm::FEC self
298 CODE:
299
300 if (!self->idx)
301 croak ("index array must be set by a prior call to set_decode_blocks");
302
303 force_addrs (self, self->dp);
284 self->imp->fec_decode (self->code, self->b_addr, idx, self->sz); 304 self->imp->fec_decode (self->code, self->b_addr, self->idx, self->sz);
285
286 Safefree (idx);
287
288 free_files (self); 305 free_files (self);
289}
290 306
291void 307void
292copy_block (srcblock, dstblock) 308copy (self, srcblock, dstblock)
309 Algorithm::FEC self
293 SV * srcblock 310 SV * srcblock
294 SV * dstblock 311 SV * dstblock
295 CODE: 312 CODE:
296 croak ("urgs"); 313 realloc_files (self);
314 open_file (self, 0, srcblock, 0);
315 open_file (self, 1, dstblock, 1);
316 force_addrs (self, 2);
317 Copy (self->b_addr[0], self->b_addr[1], self->sz, char);
318 free_files (self);
297 319
298void 320void
299DESTROY(self) 321DESTROY(self)
300 Convert::FEC self 322 Algorithm::FEC self
301 CODE: 323 CODE:
302 self->imp->fec_free (self->code); 324 self->imp->fec_free (self->code);
303 free_files (self); 325 free_files (self);
304 Safefree(self); 326 Safefree(self);
305 327

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines