Array-Splice

 view release on metacpan or  search on metacpan

lib/Array/Splice.xs  view on Meta::CPAN

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"


MODULE = Array::Splice		PACKAGE = Array::Splice		

void
_splice(array,offset,length,...)
   SV* array;
   I32 offset;
   I32 length;
INIT:
    AV* ary;
    I32 i;
    I32 newlen;
    I32 after;
    I32 diff;
    SV **tmparyval = 0;
    MAGIC *mg;
    register SV **src;
    register SV **dst;
PPCODE:
   if ( !SvROK(array) || SvTYPE(SvRV(array)) != SVt_PVAV ) {
	croak("first argument to Array::Splice::_splice() not an array");
   }
   ary = (AV*) SvRV(array);

   if ((mg = SvTIED_mg((SV*)ary, 'P'))) {
	croak("Array::Splice::_splice() not implemented for tied arrays");
   }

   i = offset;
   if (offset < 0)
      offset += AvFILLp(ary) + 1;
   if (offset < 0)
      croak(PL_no_aelem, i);
   if (length < 0) {
      length += AvFILLp(ary) - offset + 1;
	if (length < 0)
          length = 0;
   }
   if (offset > AvFILLp(ary) + 1) {
      if (ckWARN(WARN_MISC))
	 warn("Array::Splice::_splice() offset past end of array" );
      offset = AvFILLp(ary) + 1;
    }
    after = AvFILLp(ary) + 1 - (offset + length);

    if (after < 0) {				/* not that much array */
	length += after;			/* offset+length now in array */
	after = 0;
	if (!AvALLOC(ary))
	    av_extend(ary, 0);
    }

    newlen = items - 3;
    diff = newlen - length;

    /* inc refcounts now: avoid problems if they're from the array */
    for (src = &ST(3), i = newlen; i; i--) {
      SvREFCNT_inc(*src++);
    }	 

    if (diff < 0) {				/* shrinking the area */
	if (newlen) {
	    New(451, tmparyval, newlen, SV*);	/* so remember insertion */
	    Copy(&ST(3), tmparyval, newlen, SV*);
	}

	if (GIMME == G_ARRAY) {			/* copy return vals to stack */
	    MEXTEND(SP, length);
   	    src = AvARRAY(ary)+offset;
            i = length;
	    if (AvREAL(ary)) {
		for ( ; i; i--) {
		    PUSHs(sv_2mortal(*src++));	/* free them eventualy */
		}
	    } else {
		for ( ; i; i--) {
		    PUSHs(*src++);	/* don't free them eventualy */
		}
	    }



( run in 1.271 second using v1.01-cache-2.11-cpan-71847e10f99 )