Algorithm-FEC

 view release on metacpan or  search on metacpan

FEC.xs  view on Meta::CPAN


      if (mm == MAP_FAILED)
        croak ("unable to mmap block #%d (wrong offset or size?): %s", idx, strerror (errno));

      self->b_mmap[idx] = mm;
      self->b_addr[idx] = (void *)((char *)mm + (offset - ofs2));
      self->b_sz  [idx] = self->sz + (offset - ofs2);
    }
  else if (sv)
    self->b_sv[idx] = SvREFCNT_inc (sv);
  else
    croak ("unable to open block #%d, must be either string, filehandle, or [filehandle, offset]", idx);
}

static void
open_files (struct state *self, AV *av, int rw)
{
  int i;

  realloc_files (self);

  for (i = 0; i < self->dp; i++)
    open_file (self, i, *av_fetch (av, i, 1), rw);
}

MODULE = Algorithm::FEC		PACKAGE = Algorithm::FEC

PROTOTYPES: ENABLE

Algorithm::FEC
new(class, data_packets, encoded_packets, blocksize)
	SV *	class
	int	data_packets
        int	encoded_packets
        int	blocksize
	CODE:
        void *code;
        struct fec_imp *imp;

        if (data_packets < 2)
          croak ("the number of data packets must be >= 2"); /* for copy_blocks :) */

        if (encoded_packets < data_packets)
          croak ("the number of encoded packets must be >= the number of data packets");

        if (GF_SIZE16 < encoded_packets)
          croak ("the number of encoded packets must be <= %d", GF_SIZE16);

        imp = GF_SIZE8 < encoded_packets ? &fec16_imp : &fec8_imp;

        code = imp->fec_new (data_packets, encoded_packets);
        if (!code)
          croak ("FATAL: unable to create fec state");

        Newz(0, RETVAL, 1, struct state);
        RETVAL->imp = imp;
        RETVAL->code = code;
        RETVAL->sz = blocksize;
        RETVAL->dp = data_packets;
        RETVAL->ep = encoded_packets;
	OUTPUT:
        RETVAL

void
set_encode_blocks (self, blocks)
        Algorithm::FEC self
        SV *	blocks
	CODE:

        free_files (self);

        if (SvOK (blocks))
          {
            chk_array (blocks, self->dp, "set_encode_blocks", "blocks");
            open_files (self, (AV *)SvRV (blocks), 0);
          }

SV *
encode (self, block_index)
        Algorithm::FEC self
        int	block_index
	CODE:

        if (block_index < 0 || self->ep <= block_index)
          croak ("encode: block_index %d out of range, must be 0 <= block_index < %d",
                 block_index, self->ep);

        if (!self->b_addr)
          croak ("no blocks specified by a preceding call to set_encode_blocks");

        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);

        self->imp->fec_encode (self->code, self->b_addr,
                               SvPVX (RETVAL), block_index, self->sz);

        OUTPUT:
        RETVAL

void
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, "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++)
          {
            idx[i] = SvIV (*av_fetch ((AV *)SvRV (indices), i, 1));

            if (idx[i] < 0 || idx[i] >= self->ep)
              {
                Safefree (idx);
                croak ("index %d in array out of bounds (0 <= %d < %d != true)",
                       i, idx[i], self->ep);
              }
          }

        /*
         * do the same shuffling as fec_decode does here,
         * so we know the order.
         */
        for (i = 0; i < self->dp; i++)
          while (idx[i] < self->dp && idx[i] != i)
            {
              SV **a, **b, **e, **f;
              int d;
              void *p;
              SV *s;
              int j = idx[i];

              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), 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;
            }



( run in 1.290 second using v1.01-cache-2.11-cpan-13bb782fe5a )