Ejemplo n.º 1
0
Handle
Application_get_widget_from_handle( Handle self, SV * handle)
{
   ApiHandle apiHandle;
   if ( SvIOK( handle))
           apiHandle = SvUVX( handle);
   else
      apiHandle = sv_2uv( handle);
   return apc_application_get_handle( self, apiHandle);
}
Ejemplo n.º 2
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 {
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
SV*
plcb_convert_retrieval(PLCB_t *object, AV *docav,
    const char *data, size_t data_len, uint32_t flags)
{
    SV *ret_sv, *input_sv, *flags_sv;
    uint32_t f_common, f_legacy;
    input_sv = newSVpvn(data, data_len);

    f_common = flags & PLCB_CF_MASK;
    f_legacy = flags & PLCB_LF_MASK;
    flags_sv = *av_fetch(docav, PLCB_RETIDX_FMTSPEC, 1);

#define IS_FMT(fbase) f_common == PLCB_CF_##fbase || f_legacy == PLCB_LF_##fbase

    if (object->cv_customdec) {
        ret_sv = custom_convert(docav, object->cv_customdec, input_sv, &flags, CONVERT_IN);
        /* Flags remain unchanged? */

    } else if (IS_FMT(JSON)) {
        SvUTF8_on(input_sv);
        ret_sv = serialize_convert(object->cv_jsondec, input_sv, CONVERT_IN);
        flags = PLCB_CF_JSON;

    } else if (IS_FMT(STORABLE)) {
        ret_sv = serialize_convert(object->cv_deserialize, input_sv, CONVERT_IN);
        flags = PLCB_CF_STORABLE;

    } else if (IS_FMT(UTF8)) {
        SvUTF8_on(input_sv);
        ret_sv = input_sv;
        SvREFCNT_inc(ret_sv);
        flags = PLCB_CF_UTF8;

    } else {
        if (IS_FMT(RAW)) {
            flags = PLCB_CF_RAW;
        } else {
            warn("Unrecognized flags 0x%x. Assuming raw", flags);
        }
        ret_sv = input_sv;
        SvREFCNT_inc(ret_sv);
    }
#undef IS_FMT

    SvREFCNT_dec(input_sv);
    if (SvIOK(flags_sv) == 0 || SvUVX(flags_sv) != flags) {
        sv_setuv(flags_sv, flags);
    }
    return ret_sv;
}
static int
chain_endure(PLCB_t *obj, AV *resobj, const lcb_RESPSTORE *resp)
{
    lcb_MULTICMD_CTX *mctx = NULL;
    lcb_CMDENDURE dcmd = { 0 };
    lcb_durability_opts_t dopts = { 0 };
    char persist_to = 0, replicate_to = 0;
    lcb_error_t err = LCB_SUCCESS;
    SV *optsv;

    optsv = *av_fetch(resobj, PLCB_RETIDX_OPTIONS, 1);
    if (!SvIOK(optsv)) {
        return 0;
    }

    PLCB_GETDURABILITY(SvUVX(optsv), persist_to, replicate_to);
    if (persist_to == 0 && replicate_to == 0) {
        return 0;
    }
    if (persist_to < 0 || replicate_to < 0) {
        dopts.v.v0.cap_max = 1;
    }

    dopts.v.v0.persist_to = persist_to;
    dopts.v.v0.replicate_to = replicate_to;
    LCB_CMD_SET_KEY(&dcmd, resp->key, resp->nkey);
    dcmd.cas = resp->cas;

    mctx = lcb_endure3_ctxnew(obj->instance, &dopts, &err);
    if (mctx == NULL) {
        plcb_doc_set_err(obj, resobj, err);
        return 0;
    }

    err = mctx->addcmd(mctx, (lcb_CMDBASE *)&dcmd);
    if (err != LCB_SUCCESS) {
        mctx->fail(mctx);
        return 0;
    }

    lcb_sched_enter(obj->instance);
    err = mctx->done(mctx, resp->cookie);
    if (err != LCB_SUCCESS) {
        plcb_doc_set_err(obj, resobj, err);
        return 0;
    }

    lcb_sched_leave(obj->instance);
    return 1;
}
Ejemplo n.º 7
0
       * 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 {
      /* 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");
  }
}
Ejemplo n.º 8
0
int
PLCB_args_set(PLCB_t *object, plcb_SINGLEOP *args, lcb_CMDSTORE *scmd, plcb_DOCVAL *vspec)
{
    UV exp = 0;
    SV *dur_sv = NULL;
    int ignore_cas = 0;
    int persist_to = 0, replicate_to = 0;
    plcb_OPTION doc_specs[] = {
        PLCB_KWARG(PLCB_ARG_K_VALUE, SV, &vspec->value),
        PLCB_KWARG(PLCB_ARG_K_EXPIRY, EXP, &exp),
        PLCB_KWARG(PLCB_ARG_K_CAS, CAS, &scmd->cas),
        PLCB_KWARG(PLCB_ARG_K_FMT, U32, &vspec->spec),
        {NULL}
    };
    plcb_OPTION opt_specs[] = {
        PLCB_KWARG(PLCB_ARG_K_IGNORECAS, BOOL, &ignore_cas),
        PLCB_KWARG(PLCB_ARG_K_FRAGMENT, SV, &vspec->value),
        PLCB_KWARG(PLCB_ARG_K_PERSIST, INT, &persist_to),
        PLCB_KWARG(PLCB_ARG_K_REPLICATE, INT, &replicate_to),
        { NULL }
    };

    if (is_append(args->cmdbase)) {
        doc_specs[0].type = PLCB_ARG_T_PAD;
        vspec->spec = PLCB_CF_UTF8;
    } else {
        vspec->spec = PLCB_CF_JSON;
        opt_specs[1].type = PLCB_ARG_T_PAD;
    }

    load_doc_options(object, args->docav, doc_specs);
    if (args->cmdopts) {
        plcb_extract_args(args->cmdopts, opt_specs);
    }

    scmd->exptime = exp;
    if (ignore_cas) {
        scmd->cas = 0;
    }

    if (is_append(args->cmdbase)) {
        scmd->exptime = 0;
    } else if (args->cmdbase == PLCB_CMD_ADD) {
        scmd->cas = 0;
    }

    dur_sv = *av_fetch(args->docav, PLCB_RETIDX_OPTIONS, 1);
    if (SvIOK(dur_sv)) {
        SvUVX(dur_sv) = PLCB_MKDURABILITY(persist_to, replicate_to);
    } else {
        sv_setuv(dur_sv, PLCB_MKDURABILITY(persist_to, replicate_to));
    }

    if (vspec->value == NULL || SvTYPE(vspec->value) == SVt_NULL) {
        die("Must have value!");
    }

    if (is_append(args->cmdbase)) {
        if (vspec->spec != PLCB_CF_UTF8 && vspec->spec != PLCB_CF_RAW) {
            die("append and prepend must use 'raw' or 'utf8' formats");
        }
    }
    return 0;
}