Esempio n. 1
0
/* Entry point for serialization. Dumps generic SVs and delegates
 * to more specialized functions for RVs, etc. */
void
ddl_dump_sv(pTHX_ ddl_encoder_t *enc, SV *src)
{
  SvGETMAGIC(src);

  /* dump strings */
  if (SvPOKp(src)) {
    STRLEN len;
    char *str = SvPV(src, len);
    BUF_SIZE_ASSERT(enc, 2 + len);
    ddl_dump_pv(aTHX_ enc, str, len, SvUTF8(src));
  }
  /* dump floats */
  else if (SvNOKp(src)) {
    BUF_SIZE_ASSERT(enc, NV_DIG + 32);
    Gconvert(SvNVX(src), NV_DIG, 0, enc->pos);
    enc->pos += strlen(enc->pos);
  }
  /* dump ints */
  else if (SvIOKp(src)) {
    /* we assume we can always read an IV as a UV and vice versa
     * we assume two's complement
     * we assume no aliasing issues in the union */
    if (SvIsUV(src) ? SvUVX(src) <= 59000
                    : SvIVX(src) <= 59000 && SvIVX(src) >= -59000)
    {
      /* optimise the "small number case"
       * code will likely be branchless and use only a single multiplication
       * works for numbers up to 59074 */
      I32 i = SvIVX(src);
      U32 u;
      char digit, nz = 0;

      BUF_SIZE_ASSERT(enc, 6);

      *enc->pos = '-'; enc->pos += i < 0 ? 1 : 0;
      u = i < 0 ? -i : i;

      /* convert to 4.28 fixed-point representation */
      u *= ((0xfffffff + 10000) / 10000); /* 10**5, 5 fractional digits */

      /* now output digit by digit, each time masking out the integer part
       * and multiplying by 5 while moving the decimal point one to the right,
       * resulting in a net multiplication by 10.
       * we always write the digit to memory but conditionally increment
       * the pointer, to enable the use of conditional move instructions. */
      digit = u >> 28; *enc->pos = digit + '0'; enc->pos += (nz = nz || digit); u = (u & 0xfffffffUL) * 5;
      digit = u >> 27; *enc->pos = digit + '0'; enc->pos += (nz = nz || digit); u = (u & 0x7ffffffUL) * 5;
      digit = u >> 26; *enc->pos = digit + '0'; enc->pos += (nz = nz || digit); u = (u & 0x3ffffffUL) * 5;
      digit = u >> 25; *enc->pos = digit + '0'; enc->pos += (nz = nz || digit); u = (u & 0x1ffffffUL) * 5;
      digit = u >> 24; *enc->pos = digit + '0'; enc->pos += 1; /* correctly generate '0' */
    }
    else {
Esempio n. 2
0
int
ithread_mg_get(pTHX_ SV *sv, MAGIC *mg)
{
    ithread *thread = (ithread *) mg->mg_ptr;
    SvIVX(sv) = PTR2IV(thread);
    SvIOK_on(sv);
    return 0;
}
static void
modify_event_perl(plcb_IOPROCS *async, plcb_EVENT *cevent, short flags)
{
    SV **tmpsv;
    tmpsv = av_fetch(cevent->pl_event, PLCB_EVIDX_FD, 1);

    if (SvIOK(*tmpsv)) {
        SvIVX(*tmpsv) = cevent->fd;
    } else {
        sv_setiv(*tmpsv, cevent->fd);
    }

    SvIVX(async->flags_sv) = flags;
    /* Figure out the proper masks */

    SvIVX(async->sched_r_sv) = flags & LCB_READ_EVENT && (cevent->flags & LCB_READ_EVENT) == 0;
    SvIVX(async->sched_w_sv) = flags & LCB_WRITE_EVENT && (cevent->flags & LCB_WRITE_EVENT) == 0;
    SvIVX(async->stop_r_sv) = (flags & LCB_READ_EVENT) == 0  && cevent->flags & LCB_READ_EVENT;
    SvIVX(async->stop_w_sv) = (flags & LCB_WRITE_EVENT) == 0 && cevent->flags & LCB_WRITE_EVENT;


    cb_args_noret(async->cv_evmod, 0, 7,
        async->userdata, cevent->rv_event, async->flags_sv,
        async->sched_r_sv, async->sched_w_sv,
        async->stop_r_sv, async->stop_w_sv);

    cevent->flags = flags;
    tmpsv = av_fetch(cevent->pl_event, PLCB_EVIDX_WATCHFLAGS, 1);
    SvIVX(*tmpsv) = cevent->flags;
}
static void
modify_timer_perl(plcb_IOPROCS *async, plcb_EVENT *cevent, uint32_t usecs,
    int action)
{
    SvNVX(async->usec_sv) = (double) usecs / 1000000;
    SvIVX(async->action_sv) = action;
    cb_args_noret(async->cv_timermod, 0, 4,
        async->userdata, cevent->rv_event, async->action_sv, async->usec_sv);
}
Esempio n. 5
0
UV
Perl_sv_uv(pTHX_ SV *sv)
{
    PERL_ARGS_ASSERT_SV_UV;

    if (SvIOK(sv)) {
        if (SvIsUV(sv))
            return SvUVX(sv);
        return (UV)SvIVX(sv);
    }
    return sv_2uv(sv);
}
Esempio n. 6
0
IV
Perl_sv_iv(pTHX_ SV *sv)
{
    PERL_ARGS_ASSERT_SV_IV;

    if (SvIOK(sv)) {
        if (SvIsUV(sv))
            return (IV)SvUVX(sv);
        return SvIVX(sv);
    }
    return sv_2iv(sv);
}
Esempio n. 7
0
static JSBool
perlarray_enumerate(
    JSContext *cx,
    JSObject *obj,
    JSIterateOp enum_op,
    jsval *statep,
    jsid  *idp
) {
    dTHX;
    SV *ref = (SV *)JS_GetPrivate(cx, obj);
    AV *av = (AV *)SvRV(ref);

    PJS_ARRAY_CHECK

    if(enum_op == JSENUMERATE_INIT) {
	SV *cc = newSViv(0);
	*statep = PRIVATE_TO_JSVAL(cc);
	if(idp) {
	    I32 alen = av_len(av);
	    *idp = INT_TO_JSVAL(alen + 1);
	}
	return JS_TRUE;
    }
    if(enum_op == JSENUMERATE_NEXT) {
	SV *cc = (SV *)JSVAL_TO_PRIVATE(*statep);
	I32 alen = av_len(av);
	I32 curr;
	if(!SvIOK(cc)) {
	    JS_ReportError(cx, "Wrong Array iterator");
	    return JS_FALSE;
	}
	curr = (I32)SvIVX(cc);
	if(curr > alen) { // At end
	    *statep = JSVAL_NULL;
	    sv_free(cc);
	} else {
	    jsval key = INT_TO_JSVAL(curr);
	    SvIV_set(cc, (IV)(curr+1));
	    return JS_ValueToId(cx, key, idp);
	}
    }
    return JS_TRUE;
}
Esempio n. 8
0
       * resulting in a net multiplication by 10.
       * we always write the digit to memory but conditionally increment
       * the pointer, to enable the use of conditional move instructions. */
      digit = u >> 28; *enc->pos = digit + '0'; enc->pos += (nz = nz || digit); u = (u & 0xfffffffUL) * 5;
      digit = u >> 27; *enc->pos = digit + '0'; enc->pos += (nz = nz || digit); u = (u & 0x7ffffffUL) * 5;
      digit = u >> 26; *enc->pos = digit + '0'; enc->pos += (nz = nz || digit); u = (u & 0x3ffffffUL) * 5;
      digit = u >> 25; *enc->pos = digit + '0'; enc->pos += (nz = nz || digit); u = (u & 0x1ffffffUL) * 5;
      digit = u >> 24; *enc->pos = digit + '0'; enc->pos += 1; /* correctly generate '0' */
    }
    else {
      /* large integer, use the (rather slow) snprintf way. */
      BUF_SIZE_ASSERT(enc, IVUV_MAXCHARS);
      enc->pos +=
         SvIsUV(src)
            ? snprintf(enc->pos, IVUV_MAXCHARS, "%"UVuf, (UV)SvUVX(src))
            : snprintf(enc->pos, IVUV_MAXCHARS, "%"IVdf, (IV)SvIVX(src));
    }
  } /* end is an integer */
  /* undef */
  else if (!SvOK(src)) {
    ddl_buf_cat_str_s(enc, "undef");
  }
  /* dump references */
  else if (SvROK(src))
    ddl_dump_rv(aTHX_ enc, SvRV(src));
  else {
    croak("Attempting to dump unsupported or invalid SV");
  }
}

Esempio n. 9
0
int
do_aspawn(SV* really, SV **mark, SV **sp)
{
 char   **a,
        *tmps;
 struct inheritance inherit;
 pid_t  pid;
 int    status,
        fd,
        nFd,
        fdMap[3];
 SV     *sv,
        **p_sv;
 STRLEN	n_a;

    status = FAIL;
    if (sp > mark)
    {
       Newx(PL_Argv, sp - mark + 1, char*);
       a = PL_Argv;
       while (++mark <= sp)
       {
           if (*mark)
              *a++ = SvPVx(*mark, n_a);
           else
              *a++ = "";
       }
       inherit.flags        = SPAWN_SETGROUP;
       inherit.pgroup       = SPAWN_NEWPGROUP;
       fdMap[STDIN_FILENO]  = Perl_stdin_fd;
       fdMap[STDOUT_FILENO] = Perl_stdout_fd;
       fdMap[STDERR_FILENO] = STDERR_FILENO;
       nFd                  = 3;
       *a = NULL;
       /*-----------------------------------------------------*/
       /* Will execvp() use PATH?                             */
       /*-----------------------------------------------------*/
       if (*PL_Argv[0] != '/')
           TAINT_ENV();
       if (really && *(tmps = SvPV(really, n_a)))
           pid = spawnp(tmps, nFd, fdMap, &inherit,
                        (const char **) PL_Argv,
                        (const char **) environ);
       else
           pid = spawnp(PL_Argv[0], nFd, fdMap, &inherit,
                        (const char **) PL_Argv,
                        (const char **) environ);
       if (pid < 0)
       {
          status = FAIL;
          if (ckWARN(WARN_EXEC))
             warner(WARN_EXEC,"Can't exec \"%s\": %s",
                    PL_Argv[0],
                    Strerror(errno));
       }
       else
       {
          /*------------------------------------------------*/
          /* If the file descriptors have been remapped then*/
          /* we've been called following a my_popen request */
          /* therefore we don't want to wait for spawnned   */
          /* program to complete. We need to set the fdpid  */
          /* value to the value of the spawnned process' pid*/
          /*------------------------------------------------*/
          fd = 0;
          if (Perl_stdin_fd != STDIN_FILENO)
             fd = Perl_stdin_fd;
          else
             if (Perl_stdout_fd != STDOUT_FILENO)
                fd = Perl_stdout_fd;
          if (fd != 0)
          {
             /*---------------------------------------------*/
             /* Get the fd of the other end of the pipe,    */
             /* use this to reference the fdpid which will  */
             /* be used by my_pclose                        */
             /*---------------------------------------------*/
             close(fd);
             MUTEX_LOCK(&PL_fdpid_mutex);
             p_sv  = av_fetch(PL_fdpid,fd,TRUE);
             fd    = (int) SvIVX(*p_sv);
             SvREFCNT_dec(*p_sv);
             *p_sv = &PL_sv_undef;
             sv    = *av_fetch(PL_fdpid,fd,TRUE);
             MUTEX_UNLOCK(&PL_fdpid_mutex);
             (void) SvUPGRADE(sv, SVt_IV);
             SvIVX(sv) = pid;
             status    = 0;
          }
          else
             wait4pid(pid, &status, 0);
       }
       do_execfree();
    }
SV * parse_in_chunks(char * filepath, size_t filesize) {
    char *buf;
    size_t bytes_read = 0;
    int max_buf = 1000;
    char *err_msg;
    int block = BLOCK_HEADER;
    int cur_event_type = 0;
    int event_type = 0;
    char event_block = 0;
    char *brnl, *breq;
    AV * data;
    AV * datawrapper;
    AV * events;
    char *line;
    char * nl = "\n";
    char * eq = "=";
    int rewind_pos = 0;
    size_t cur_fpos = 0;
    SV * pbuf;
    SV * pmax_buf;

    AV * HANDLERS = get_av("Opsview::Utils::NDOLogsImporter::HANDLERS", 0);
    AV * INPUT_DATA_TYPE = get_av("Opsview::Utils::NDOLogsImporter::INPUT_DATA_TYPE", 0);

    int init_last_pos;
    int init_block;

    if ( first_read ) {
        if ( ! ( fh = PerlIO_open( filepath, "rb" ) ) ) {
            croak("Could not open file: %s\n", strerror(errno));
        }

        bytes_left = filesize;
        init_last_pos = prev_pos = first_read = 0;
        init_block = block = BLOCK_HEADER;
    } else {
        init_block = block = BLOCK_EVENTS;
        init_last_pos = prev_pos;
    }

    read_begin:


    brnl = NULL;
    breq = NULL;

    pbuf = get_sv("Opsview::Utils::NDOLogsImporter::PARSE_BUF", 0);
    pmax_buf = get_sv("Opsview::Utils::NDOLogsImporter::MAX_BUF_SIZE", 0);

    buf = SvPVX(pbuf);
    max_buf = SvIVX(pmax_buf);

    if ( max_buf < 1024 * 1024 && ! automated_tests ) {
        max_buf = 1024*1024;
        SvIV_set( pmax_buf, max_buf );
        SvGROW( pbuf, max_buf + 1);
        SvCUR_set( pbuf, max_buf);
    }

    if ( bytes_left > 0 ) {

        bytes_read = PerlIO_read(fh, buf + prev_pos, max_buf-prev_pos);
        cur_fpos = PerlIO_tell(fh);

        if ( bytes_read < 0 ) {
            err_msg = strerror(errno);

            PerlIO_close( fh );

            croak("Could not read file: %s\n", err_msg);
        }

        bytes_left -= bytes_read;

        events = (AV *)sv_2mortal((SV *)newAV());

        rewind_pos = last_999(buf+prev_pos, bytes_read);
        prev_pos = bytes_read + prev_pos - rewind_pos;
        buf[prev_pos] = '\0';

        // avg ratio events:file_size = 0.21%
        if ( prev_pos > 1000 ) {
            av_extend( events, (int)(prev_pos * 0.0021) );
        }


        for ( line = strtok_r(buf, nl, &brnl); line != NULL; line = strtok_r(NULL, nl, &brnl) )
        {
            switch(block) {
                case BLOCK_HEADER:
                    {
                        if ( strEQ(line, "STARTDATADUMP") ) {
                            block = BLOCK_EVENTS;
                        }
                    }
                    break;

                case BLOCK_EVENTS:
                    {
                        if ( strEQ(line, "1000") ) { /* NDO_API_ENDDATADUMP */
                            block = BLOCK_FOOTER;
                            continue;
                        }

                        cur_event_type = atoi(line);

                        /* ignore events we are not handling */
                        if ( !  av_exists(HANDLERS, cur_event_type) ) {
                            block = BLOCK_IGNORE_EVENT;
                            continue;
                        }

                        event_block = BLOCK_EVENT_STARTED;
                        if ( cur_event_type != event_type ) {
                            datawrapper = (AV *)sv_2mortal((SV *)newAV());
                            data = (AV *)sv_2mortal((SV *)newAV());

                            av_push( events, newSViv( cur_event_type ) );
                            av_push( datawrapper, newRV( (SV *)data ) );
                            av_push( events, newRV( (SV *)datawrapper ) );

                            event_type = cur_event_type;
                        } else {
                            data = (AV *)sv_2mortal((SV *)newAV());

                            av_push( datawrapper, newRV( (SV *)data ) );
                        }

                        block = BLOCK_EVENT; 
                    }
                    break;

                case BLOCK_EVENT:
                    {
                        if ( strEQ(line, "999") ) { /* NDO_API_ENDDATA */
                            block = BLOCK_EVENTS;
                            event_block = BLOCK_EVENT_ENDED;
                        } else {
                            char *k;
                            char *v;
                            int key;
                            int key_type = 0;
                            int v_len = 0;

                            k = strtok_r(line, eq, &breq); 
                            v = strtok_r(NULL, "\0", &breq);

                            key = atoi(k);
                            /* invalid key, skip parsing */
                            if ( key == 0 ) {
                                goto remove_invalid;
                            }

                            SV ** const k_type = av_fetch(INPUT_DATA_TYPE, key, 0 ); 
                            if ( k_type ) {
                                key_type = SvIVx( *k_type );
                            }

                            if ( v ) {
                                if ( key_type & 1 ) {
                                   v_len = ndo_unescape_buffer( v ); 
                                } else {
                                    v_len = strlen(v);
                                }
                            }

                            if ( key_type & 2 ) {
                                AV * datanstptr;
                                SV ** const datanst = av_fetch(data, key, 0 ); 
                                if ( datanst ) {
                                    datanstptr = (AV *)SvRV( *datanst );
                                } else {
                                    datanstptr = (AV *)sv_2mortal((SV *)newAV());

                                    av_store( data, key, newRV( (SV *)datanstptr ) );
                                }

                                if ( v ) { 
                                    av_push( datanstptr, newSVpvn(v, v_len) );
                                } else {
                                    av_push( datanstptr, newSVpvn("", 0) );
                                }

                            } else {
                                if ( v ) { 
                                    av_store( data, key, newSVpvn(v, v_len) );
                                } else {
                                    av_store( data, key, newSVpvn("", 0) );
                                }
                            }
                        }
                    }
                    break;

                case BLOCK_FOOTER:
                    {
                        if ( strEQ(line, "GOODBYE") ) {
                            block = BLOCK_HEADER;
                        }
                    }
                    break;

                case BLOCK_IGNORE_EVENT:
                    {
                        if ( strEQ(line, "999") ) { /* NDO_API_ENDDATA */
                            block = BLOCK_EVENTS; // go back to EVENTS
                            continue;
                        }
                    }
                    break;
            }
        };

        /* there were some events */
        if ( event_block != BLOCK_HEADER ) {
            if ( event_block != BLOCK_EVENT_ENDED ) {
                remove_invalid:
                    av_pop( datawrapper );
            }

            /* remove whole block if the last block has no events */
            if ( av_len( datawrapper ) == -1 ) {
                av_pop( events );
                av_pop( events );
            }
        }


        if ( av_len(events) > 0 ) {
            if ( rewind_pos > 0 && cur_fpos < filesize ) {
                memmove(buf, buf+prev_pos+1, rewind_pos-1);
            }

            prev_pos = rewind_pos - 1;

            return newRV_inc((SV *) events);
        } else {

            if ( cur_fpos < filesize && event_block != BLOCK_HEADER && event_block != BLOCK_EVENT_ENDED ) {
                int new_max_buf = max_buf * 2;

                SvIV_set( pmax_buf, new_max_buf );
                SvGROW( pbuf, new_max_buf + 1);
                SvCUR_set( pbuf, new_max_buf);
                //start again as previous buffer would be tokenized already
                prev_pos = 0;
                block = init_block;
                event_type = 0;


                PerlIO_close( fh );
                if ( ! ( fh = PerlIO_open( filepath, "rb" ) ) ) {
                    croak("Could not re-open file: %s\n", strerror(errno));
                }
                PerlIO_seek(fh, cur_fpos-bytes_read-init_last_pos, SEEK_SET);
                bytes_left += bytes_read + init_last_pos;

                goto read_begin; 
            }
        }
    }

    parser_reset_iterator();

    return &PL_sv_undef;
}