void plcb_ctor_conversion_opts(PLCB_t *object, AV *options) { SV **tmpsv; AV *methav; int dummy; #define meth_assert_getpairs(flag, optidx) \ ((object->my_flags & flag) \ ? \ (((tmpsv = av_fetch(options, optidx, 0)) && SvROK(*tmpsv) && \ (methav = (AV*)SvRV(*tmpsv))) \ ? (void*)1 \ : die("Flag %s specified but no methods provided", #flag)) \ : NULL) #define meth_assert_assign(target_field, source_idx, diemsg) \ if((tmpsv = av_fetch(methav, source_idx, 0)) == NULL) { \ die("Nothing in IDX=%d (%s)", source_idx, diemsg); \ } \ if(! ((SvROK(*tmpsv) && SvTYPE(SvRV(*tmpsv)) == SVt_PVCV) ) ) { \ die("Expected CODE reference at IDX=%d: %s",source_idx, diemsg); \ } \ object->target_field = newRV_inc(SvRV(*tmpsv)); if( (tmpsv = av_fetch(options, PLCB_CTORIDX_MYFLAGS, 0)) && SvIOK(*tmpsv)) { object->my_flags = SvUV(*tmpsv); } ctor_extract_methpairs(options, PLCB_CTORIDX_COMP_METHODS, &object->cv_compress, &object->cv_decompress); if ((object->my_flags & PLCBf_USE_COMPRESSION) && object->cv_compress == NULL) { die("Compression requested but no methods provided"); } ctor_extract_methpairs(options, PLCB_CTORIDX_SERIALIZE_METHODS, &object->cv_serialize, &object->cv_deserialize); if ((object->my_flags & PLCBf_USE_STORABLE) && object->cv_serialize == NULL) { die("Serialization requested but no methods provided"); } if ((tmpsv = av_fetch(options, PLCB_CTORIDX_COMP_THRESHOLD, 0)) && SvIOK(*tmpsv)) { object->compress_threshold = SvIV(*tmpsv); } else { object->compress_threshold = 0; } }
void dump_value(pTHX_ SV* val, Buffer* buf) { if (!val) { return; } if (SvIOK(val)) { char str[50]; int len = sprintf(str, "%ld", (long) SvIV(val)); buffer_append(buf, str, len); } else if (SvNOK(val)) { char str[50]; int len = sprintf(str, "%lf", (double) SvNV(val)); buffer_append(buf, str, len); } else if (SvPOK(val)) { STRLEN len; char* str = SvPV(val, len); buffer_append(buf, "\"", 1); buffer_append(buf, str, len); buffer_append(buf, "\"", 1); } else if (SvROK(val)) { SV* rv = SvRV(val); if (SvTYPE(rv) == SVt_PVAV) { dump_array(aTHX_ (AV*) rv, buf); } else if (SvTYPE(rv) == SVt_PVHV) { dump_hash(aTHX_ (HV*) rv, buf); } } }
guint64 amglue_SvU64(SV *sv) { if (SvIOK(sv)) { if (SvIsUV(sv)) { return SvUV(sv); } else if (SvIV(sv) < 0) { croak("Expected an unsigned value, got a negative integer"); return 0; } else { return (guint64)SvIV(sv); } } else if (SvNOK(sv)) { double dv = SvNV(sv); if (dv < 0.0) { croak("Expected an unsigned value, got a negative integer"); return 0; } else if (dv > (double)G_MAXUINT64) { croak("Expected an unsigned 64-bit value or smaller; value out of range"); return 0; } else { return (guint64)dv; } } else { return bigint2uint64(sv); } }
gint64 amglue_SvI64(SV *sv) { if (SvIOK(sv)) { if (SvIsUV(sv)) { return SvUV(sv); } else { return SvIV(sv); } } else if (SvNOK(sv)) { double dv = SvNV(sv); /* preprocessor constants seem to have trouble here, so we convert to gint64 and * back, and if the result differs, then we have lost something. Note that this will * also error out on integer truncation .. which is probably OK */ gint64 iv = (gint64)dv; if (dv != (double)iv) { croak("Expected a signed 64-bit value or smaller; value '%.0f' out of range", (float)dv); return 0; } else { return iv; } } else { return bigint2int64(sv); } }
static void modify_event_perl(PLCBA_t *async, PLCBA_c_event *cevent, PLCBA_evaction_t action, short flags) { SV **tmpsv; tmpsv = av_fetch(cevent->pl_event, PLCBA_EVIDX_FD, 1); if (SvIOK(*tmpsv)) { if (SvIV(*tmpsv) != cevent->fd) { /*file descriptor mismatch!*/ av_delete(cevent->pl_event, PLCBA_EVIDX_DUPFH, G_DISCARD); } } else { sv_setiv(*tmpsv, cevent->fd); } plcb_call_sv_with_args_noret(async->cv_evmod, 1, 3, newRV_inc( (SV*)(cevent->pl_event)), newSViv(action), newSViv(flags)); /*set the current flags*/ if (action != PLCBA_EVACTION_SUSPEND && action != PLCBA_EVACTION_RESUME) { sv_setiv( *(av_fetch(cevent->pl_event, PLCBA_EVIDX_WATCHFLAGS, 1)), flags); } /*set the current state*/ sv_setiv( *(av_fetch(cevent->pl_event, PLCBA_EVIDX_STATEFLAGS, 1)), cevent->state); }
void plcb_ctor_init_common(PLCB_t *object, libcouchbase_t instance, AV *options) { NV timeout_value; SV **tmpsv; object->instance = instance; object->errors = newAV(); if(! (object->ret_stash = gv_stashpv(PLCB_RET_CLASSNAME, 0)) ) { die("Could not load '%s'", PLCB_RET_CLASSNAME); } /*gather instance-related options from the constructor*/ if( (tmpsv = av_fetch(options, PLCB_CTORIDX_TIMEOUT, 0)) && (SvIOK(*tmpsv) || SvNOK(*tmpsv))) { timeout_value = SvNV(*tmpsv); if(!timeout_value) { warn("Cannot use 0 for timeout"); } else { libcouchbase_set_timeout(instance, timeout_value * (1000*1000)); } } if((tmpsv = av_fetch(options, PLCB_CTORIDX_NO_CONNECT, 0)) && SvTRUE(*tmpsv)) { object->my_flags |= PLCBf_NO_CONNECT; } /*maybe more stuff here?*/ }
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; }
int64_t kino_Host_callback_i64(void *vobj, char *method, uint32_t num_args, ...) { va_list args; SV *return_sv; int64_t retval; va_start(args, num_args); return_sv = S_do_callback_sv(vobj, method, num_args, args); va_end(args); if (sizeof(IV) == 8) { retval = (int64_t)SvIV(return_sv); } else { if (SvIOK(return_sv)) { // It's already no more than 32 bits, so don't convert. retval = SvIV(return_sv); } else { // Maybe lossy. double temp = SvNV(return_sv); retval = (int64_t)temp; } } FREETMPS; LEAVE; return retval; }
alpm_pkgreason_t p2c_pkgreason(SV *sv) { STRLEN len; char *rstr; if(SvIOK(sv)){ switch(SvIV(sv)){ case 0: return ALPM_PKG_REASON_EXPLICIT; case 1: return ALPM_PKG_REASON_DEPEND; } croak("integer reasons must be 0 or 1"); }else if(SvPOK(sv)){ rstr = SvPV(sv, len); if(strncmp(rstr, "explicit", len) == 0){ return ALPM_PKG_REASON_EXPLICIT; }else if(strncmp(rstr, "implicit", len) == 0 || strncmp(rstr, "depend", len) == 0){ return ALPM_PKG_REASON_DEPEND; }else{ croak("string reasons can only be explicit or implicit/depend"); } }else{ croak("reasons can only be integers or strings"); } }
inline int sv2int_str(SV *val, int_str *is, unsigned short *flags, unsigned short strflag) { char *s; STRLEN len; if (!SvOK(val)) { LM_ERR("AVP:sv2int_str: Invalid value " "(not a scalar).\n"); return 0; } if (SvIOK(val)) { /* numerical name */ is->n = SvIV(val); *flags = 0; return 1; } else if (SvPOK(val)) { s = SvPV(val, len); is->s.len = len; is->s.s = s; (*flags) |= strflag; return 1; } else { LM_ERR("AVP:sv2int_str: Invalid value " "(neither string nor integer).\n"); return 0; } }
static GnmFuncHelp * make_gnm_help (const char *name, int count, SV **SP) { GnmFuncHelp *help = NULL; /* We assume that the description is a Perl array of the form (key, text, key, text, ...). */ int n = count / 2, m = 0, k, type = GNM_FUNC_HELP_END; GnmFuncHelp *helptmp = g_new0 (GnmFuncHelp, n + 1); if (count % 2) POPs, count--; for (k = n; k-- > 0; ) { SV *sv = POPs; if (SvPOK(sv)) { STRLEN size; gchar *tmp; tmp = SvPV(sv, size); helptmp[k].text = g_strndup (tmp, size); } else { helptmp[k].text = NULL; } sv = POPs; if (SvIOK(sv)) type = SvIV(sv); if (helptmp[k].text && type >= GNM_FUNC_HELP_NAME && GNM_FUNC_HELP_ODF) { helptmp[k].type = type; m++; } else { helptmp[k].type = GNM_FUNC_HELP_END; if (helptmp[k].text) g_free ((char*)helptmp[k].text); helptmp[k].text = NULL; } } if (m == 0) { /* No valid entries. */ g_free (helptmp); } else { /* Collect all valid entries in a new array. */ if (n == m) { help = helptmp; } else { int i; help = g_new (GnmFuncHelp, m+1); for (i = 0, k = 0; k < n; k++) if (helptmp[k].type != GNM_FUNC_HELP_END && helptmp[k].text) help[i++] = helptmp[k]; g_free(helptmp); } help[m].type = GNM_FUNC_HELP_END; help[m].text = NULL; } if (!help) /* Provide a reasonable default. */ help = default_gnm_help (name); gnm_perl_loader_free_later (help); for (n = 0; help[n].type != GNM_FUNC_HELP_END; n++) gnm_perl_loader_free_later (help[n].text); return help; }
/* Returns perl value as a scheme one */ VCSI_OBJECT perl_return(VCSI_CONTEXT vc, SV* val) { if(SvIOK(val)) return make_long(vc,SvIV(val)); else if(SvNOK(val)) return make_float(vc,SvNV(val)); else return make_string(vc,SvPV_nolen(val)); }
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); }
char sv2idctype(const SV *sv) { if (SvIOK(sv)) return VT_LONG; else if (SvNOK(sv)) return VT_FLOAT; else if (SvPOK(sv)) return VT_STR; else { // otherwise, probably an object -> stringify return VT_STR; } }
bool PerlSortCondition::operator() (const RowHandle *r1, const RowHandle *r2) const { dSP; if (cbCompare_.isNull()) return false; // should never happen but just in case // the rows are passed to Perl as Rows, not RowHandles, because // wrapping the RowHandle requires a table pointer which is not available WrapRow *wr1 = new WrapRow(rt_, const_cast<Row *>(r1->getRow())); SV *svr1 = newSV(0); sv_setref_pv(svr1, "Triceps::Row", (void *)wr1); WrapRow *wr2 = new WrapRow(rt_, const_cast<Row *>(r2->getRow())); SV *svr2 = newSV(0); sv_setref_pv(svr2, "Triceps::Row", (void *)wr2); PerlCallbackStartCall(cbCompare_); XPUSHs(svr1); XPUSHs(svr2); SV *svrcode = NULL; PerlCallbackDoCallScalar(cbCompare_, svrcode); SvREFCNT_dec(svr1); SvREFCNT_dec(svr2); bool result = false; // the safe default, collapses all keys into one if (SvTRUE(ERRSV)) { Erref err; err.f("Error in PerlSortedIndex(%s) comparator: %s", name_.c_str(), SvPV_nolen(ERRSV)); // XXX print the source code of comparator is available table_->setStickyError(err); } else if (svrcode == NULL) { Erref err; err.f("Error in PerlSortedIndex(%s) comparator: comparator returned no value", name_.c_str()); // XXX print the source code of comparator is available table_->setStickyError(err); } else if (!SvIOK(svrcode)) { Erref err; err.f("Error in PerlSortedIndex(%s) comparator: comparator returned a non-integer value '%s'", name_.c_str(), SvPV_nolen(svrcode)); // XXX print the source code of comparator is available table_->setStickyError(err); } else { result = (SvIV(svrcode) < 0); // the Less } if (svrcode != NULL) SvREFCNT_dec(svrcode); return result; }
inline long IV2int(SV *in) { int ret = -1; if (SvOK(in)) { if (SvIOK(in)) { ret = SvIV(in); } SvREFCNT_dec(in); } return ret; }
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); }
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); }
const struct mro_alg * Perl_mro_get_from_name(pTHX_ SV *name) { SV **data; PERL_ARGS_ASSERT_MRO_GET_FROM_NAME; data = (SV **)Perl_hv_common(aTHX_ PL_registered_mros, name, NULL, 0, 0, HV_FETCH_JUST_SV, NULL, 0); if (!data) return NULL; assert(SvTYPE(*data) == SVt_IV); assert(SvIOK(*data)); return INT2PTR(const struct mro_alg *, SvUVX(*data)); }
static int scalar2constant(SV * svconstant, const char * context, int * val) { int rc = 0; if (!svconstant || !SvOK(svconstant)) { warn("Use of an undefined value"); return 0; } else if (SvIOK(svconstant)) { *val = SvIV(svconstant); rc = 1; } else if (SvPOK(svconstant)) { rc = rpmconstantFindName((char *)context, (void *) SvPV_nolen(svconstant), val, 0); } else { } return rc; }
int Tcl_GetIntFromObj (Tcl_Interp *interp, Tcl_Obj *obj, int *intPtr) { dTHX; SV *sv = ForceScalar(aTHX_ obj); if (SvIOK(sv) || looks_like_number(sv)) *intPtr = SvIV(sv); else { *intPtr = 0; return EXPIRE((interp, "'%s' isn't numeric", SvPVX(sv))); } return TCL_OK; }
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; }
PyObject* PerlPyObject_pyo_or_null(SV* sv) { MAGIC *mg; dCTXP; ASSERT_LOCK_PERL; if (SvROK(sv) && sv_derived_from(sv, "Python::Object")) { sv = SvRV(sv); mg = mg_find(sv, '~'); if (SvIOK(sv) && mg && mg->mg_virtual == &vtbl_free_pyo) { IV ival = SvIV(sv); return INT2PTR(PyObject *, ival); }
/* * Return the integer catalog value from the passed Catalog or IV. * Calls croak() if the SV is not of the correct type. */ ea_catalog_t catalog_value(SV *catalog) { SV *sv; /* If a reference, dereference and check it is a Catalog. */ if (SvROK(catalog)) { sv = SvRV(catalog); if (SvIOK(sv) && SvSTASH(sv) == Sun_Solaris_Exacct_Catalog_stash) { return (SvIV(sv)); } else { croak("Parameter is not a Catalog or integer"); } /* For a plain IV, just return the value. */ } else if (SvIOK(catalog)) { return (SvIV(catalog)); /* Anything else is an error */ } else { croak("Parameter is not a Catalog or integer"); } }
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; }
void PLCB__viewhandle_stop(SV *pp) { AV *req = (AV *)SvRV(pp); PLCB_t *parent = parent_from_req(req); SV **tmp, *vhsv; tmp = av_fetch(req, PLCB_VHIDX_VHANDLE, 0); if (!tmp) { return; } vhsv = *tmp; if (SvIOK(vhsv)) { lcb_VIEWHANDLE vh = NUM2PTR(lcb_VIEWHANDLE, SvUV(vhsv)); lcb_view_cancel(parent->instance, vh); av_store(req, PLCB_VHIDX_VHANDLE, SvREFCNT_inc(&PL_sv_undef)); av_store(req, PLCB_VHIDX_ISDONE, SvREFCNT_inc(&PL_sv_yes)); SvREFCNT_dec((SV *)req); } }
int sv2constant(SV * svconstant, const char * context) { AV * avparam; int val = 0; SV **tmpsv; int i; if (svconstant == NULL) { return 0; } else if (!SvOK(svconstant)) { return 0; } else if (SvPOK(svconstant) || SvIOK(svconstant)) { if (!scalar2constant(svconstant, context, &val)) warn("Unknow value '%s' in '%s'", SvPV_nolen(svconstant), context); } else if (SvTYPE(SvRV(svconstant)) == SVt_PVAV) { avparam = (AV*) SvRV(svconstant); for (i = 0; i <= av_len(avparam); i++) { tmpsv = av_fetch(avparam, i, 0); if (!scalar2constant(*tmpsv, context, &val)) warn("Unknow value '%s' in '%s' from array", SvPV_nolen(*tmpsv), context); } } else { } return val; }
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; }
int perlresult2dbres(SV *perlres, db1_res_t **r) { SV *colarrayref = NULL; AV *colarray = NULL; SV *acol = NULL; int colcount = 0; SV *rowarrayref = NULL; AV *rowarray = NULL; int rowcount = 0; SV *arowref = NULL; AV *arow = NULL; int arowlen = 0; SV *aelement = NULL; SV *atypesv = 0; int atype = 0; SV *aval = NULL; char *charbuf; char *currentstring; int i, j; int retval = 0; STRLEN len; SV *d1; /* helper variables */ /*db_val_t cur_val;*/ /* Abbreviation in "switch" below. The currently modified db result value. */ if (!(SvROK(perlres) && (sv_derived_from(perlres, "Kamailio::VDB::Result")))) { goto error; } /* Memory allocation for C side result structure */ *r = (db1_res_t *)pkg_malloc(sizeof(db1_res_t)); if (!(*r)) { LM_ERR("no pkg memory left\n"); return -1; } memset(*r, 0, sizeof(db1_res_t)); /* Fetch column definitions */ colarrayref = perlvdb_perlmethod(perlres, PERL_VDB_COLDEFSMETHOD, NULL, NULL, NULL, NULL); if (!(SvROK(colarrayref))) goto error; colarray = (AV *)SvRV(colarrayref); if (!(SvTYPE(colarray) == SVt_PVAV)) goto error; colcount = av_len(colarray) + 1; /* Allocate col def memory */ (*r)->col.n = colcount; (*r)->col.types = (db_type_t*)pkg_malloc(colcount*sizeof(db_type_t)); (*r)->col.names = (db_key_t*)pkg_malloc(colcount*sizeof(db_key_t)); /* reverse direction, as elements are removed by "SvREFCNT_dec" */ for (i = colcount-1; i >= 0; i--) { acol = *av_fetch(colarray, i, 0); d1 = perlvdb_perlmethod(acol, PERL_VDB_TYPEMETHOD, NULL, NULL, NULL, NULL); if (!SvIOK(d1)) goto error; (*r)->col.types[i] = SvIV(d1); SvREFCNT_dec(d1); d1 = perlvdb_perlmethod(acol, PERL_VDB_NAMEMETHOD, NULL, NULL, NULL, NULL); if (!SvPOK(d1)) goto error; currentstring = SvPV(d1, len); charbuf = pkg_malloc(len+1); strncpy(charbuf, currentstring, len+1); (*r)->col.names[i]->s = charbuf; (*r)->col.names[i]->len = strlen(charbuf); SvREFCNT_dec(d1); } rowarrayref = perlvdb_perlmethod(perlres, PERL_VDB_ROWSMETHOD, NULL, NULL, NULL, NULL); if (!(SvROK(rowarrayref))) { /* Empty result set */ (*r)->n = 0; (*r)->res_rows = 0; (*r)->last_row = 0; goto end; } rowarray = (AV *)SvRV(rowarrayref); if (!(SvTYPE(rowarray) == SVt_PVAV)) goto error; rowcount = av_len(rowarray) + 1; (*r)->n = rowcount; (*r)->res_rows = rowcount; (*r)->last_row = rowcount; (*r)->rows = (db_row_t *)pkg_malloc(rowcount*sizeof(db_row_t)); for (i = 0; i < rowcount; i++) { arowref = *av_fetch(rowarray, 0, 0); if (!SvROK(arowref)) goto error; arow = (AV *)SvRV(arowref); if (!(SvTYPE(colarray) == SVt_PVAV)) goto error; arowlen = av_len(arow) + 1; (*r)->rows[i].n = arowlen; (*r)->rows[i].values = (db_val_t *)pkg_malloc(arowlen*sizeof(db_val_t)); for (j = 0; j < arowlen; j++) { aelement = *av_fetch(arow, j, 0); #define cur_val (((*r)->rows)[i].values)[j] /*cur_val = (((*r)->rows)[i].values)[j];*/ /* cur_val is just an "abbreviation" */ if (!(sv_isobject(aelement) && sv_derived_from(aelement, PERL_CLASS_VALUE))) { cur_val.nul = 1; continue; } atype = SvIV(atypesv = perlvdb_perlmethod(aelement, PERL_VDB_TYPEMETHOD, NULL, NULL, NULL, NULL)); aval = perlvdb_perlmethod(aelement, PERL_VDB_DATAMETHOD, NULL, NULL, NULL, NULL); (*r)->rows[i].values[j].type = atype; if (!SvOK(aval)) { cur_val.nul = 1; } else { switch (atype) { case DB1_INT: cur_val.val.int_val = SvIV(aval); cur_val.nul = 0; break; case DB1_DOUBLE: cur_val.val.double_val = SvNV(aval); cur_val.nul = 0; break; case DB1_STRING: case DB1_STR: /* We dont support DB1_STR for now. * Set DB1_STRING instead */ cur_val.type = DB1_STRING; currentstring = SvPV(aval, len); charbuf = pkg_malloc(len+1); strncpy(charbuf, currentstring, len+1); cur_val.val.string_val = charbuf; cur_val.nul = 0; break; case DB1_DATETIME: cur_val.val.time_val = (time_t)SvIV(aval); cur_val.nul = 0; break; case DB1_BLOB: currentstring = SvPV(aval, len); charbuf = pkg_malloc(len+1); strncpy(charbuf, currentstring, len+1); cur_val.val.blob_val.s = charbuf; cur_val.val.blob_val.len = len; cur_val.nul = 0; break; case DB1_BITMAP: cur_val.val.bitmap_val = SvIV(aval); cur_val.nul = 0; break; default: LM_CRIT("cannot handle this data type.\n"); return -1; break; } } SvREFCNT_dec(atypesv); SvREFCNT_dec(aval); } } end: av_undef(colarray); av_undef(rowarray); return retval; error: LM_CRIT("broken result set. Exiting, leaving Kamailio in unknown state.\n"); return -1; }