int memcached_tuple_set(struct memcached_connection *con, const char *kpos, uint32_t klen, uint64_t expire, const char *vpos, uint32_t vlen, uint64_t cas, uint32_t flags) { (void )con; uint64_t time = fiber_time64(); uint32_t len = mp_sizeof_array(6) + mp_sizeof_str (klen) + mp_sizeof_uint (expire) + mp_sizeof_uint (time) + mp_sizeof_str (vlen) + mp_sizeof_uint (cas) + mp_sizeof_uint (flags); char *begin = (char *)box_txn_alloc(len); if (begin == NULL) { memcached_error_ENOMEM(len, "tuple"); return -1; } char *end = mp_encode_array(begin, 6); end = mp_encode_str (end, kpos, klen); end = mp_encode_uint (end, expire); end = mp_encode_uint (end, time); end = mp_encode_str (end, vpos, vlen); end = mp_encode_uint (end, cas); end = mp_encode_uint (end, flags); assert(end <= begin + len); return box_replace(con->cfg->space_id, begin, end, NULL); }
static void test_next_on_array(uint32_t count) { note("next/check on array(%u)", count); char *d1 = data; d1 = mp_encode_array(d1, count); for (uint32_t i = 0; i < count; i++) { d1 = mp_encode_uint(d1, i % 0x7f); /* one byte */ } uint32_t len = count + mp_sizeof_array(count); const char *d2 = data; const char *d3 = data; ok(!mp_check(&d2, data + BUF_MAXLEN), "mp_check(array %u))", count); is((d1 - data), (ptrdiff_t)len, "len(array %u) == %u", count, len); is((d2 - data), (ptrdiff_t)len, "len(mp_check(array %u)) == %u", count, len); mp_next(&d3); is((d3 - data), (ptrdiff_t)len, "len(mp_next(array %u)) == %u", count, len); }
int memcached_tuple_get(struct memcached_connection *con, const char *key, uint32_t key_len, box_tuple_t **tuple) { /* Create key for getting previous tuple from space */ uint32_t len = mp_sizeof_array(1) + mp_sizeof_str (key_len); char *begin = (char *)box_txn_alloc(len); if (begin == NULL) { memcached_error_ENOMEM(len, "key"); return -1; } char *end = NULL; end = mp_encode_array(begin, 1); end = mp_encode_str (end, key, key_len); assert(end <= begin + len); /* Get tuple from space */ if (box_index_get(con->cfg->space_id, 0, begin, end, tuple) == -1) { return -1; } return 0; }
void _mpack_item(SV *res, SV *o) { size_t len, res_len, new_len; char *s, *res_s; res_s = SvPVbyte(res, res_len); unsigned i; if (!SvOK(o)) { new_len = res_len + mp_sizeof_nil(); res_s = SvGROW(res, new_len); SvCUR_set(res, new_len); mp_encode_nil(res_s + res_len); return; } if (SvROK(o)) { o = SvRV(o); if (SvOBJECT(o)) { SvGETMAGIC(o); HV *stash = SvSTASH(o); GV *mtd = gv_fetchmethod_autoload(stash, "msgpack", 0); if (!mtd) croak("Object has no method 'msgpack'"); dSP; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs (sv_bless (sv_2mortal (newRV_inc(o)), stash)); PUTBACK; call_sv((SV *)GvCV(mtd), G_SCALAR); SPAGAIN; SV *pkt = POPs; if (!SvOK(pkt)) croak("O->msgpack returned undef"); s = SvPV(pkt, len); new_len = res_len + len; res_s = SvGROW(res, new_len); SvCUR_set(res, new_len); memcpy(res_s + res_len, s, len); PUTBACK; FREETMPS; LEAVE; return; } switch(SvTYPE(o)) { case SVt_PVAV: { AV *a = (AV *)o; len = av_len(a) + 1; new_len = res_len + mp_sizeof_array(len); res_s = SvGROW(res, new_len); SvCUR_set(res, new_len); mp_encode_array(res_s + res_len, len); for (i = 0; i < len; i++) { SV **item = av_fetch(a, i, 0); if (!item) _mpack_item(res, 0); else _mpack_item(res, *item); } break; } case SVt_PVHV: { HV *h = (HV *)o; len = hv_iterinit(h); new_len = res_len + mp_sizeof_map(len); res_s = SvGROW(res, new_len); SvCUR_set(res, new_len); mp_encode_map(res_s + res_len, len); for (;;) { HE * iter = hv_iternext(h); if (!iter) break; SV *k = hv_iterkeysv(iter); SV *v = HeVAL(iter); _mpack_item(res, k); _mpack_item(res, v); } break; } default: croak("Can't serialize reference"); } return; } switch(SvTYPE(o)) { case SVt_PV: case SVt_PVIV: case SVt_PVNV: case SVt_PVMG: case SVt_REGEXP: if (!looks_like_number(o)) { s = SvPV(o, len); new_len = res_len + mp_sizeof_str(len); res_s = SvGROW(res, new_len); SvCUR_set(res, new_len); mp_encode_str(res_s + res_len, s, len); break; } case SVt_NV: { NV v = SvNV(o); IV iv = (IV)v; if (v != iv) { new_len = res_len + mp_sizeof_double(v); res_s = SvGROW(res, new_len); SvCUR_set(res, new_len); mp_encode_double(res_s + res_len, v); break; } } case SVt_IV: { IV v = SvIV(o); if (v >= 0) { new_len = res_len + mp_sizeof_uint(v); res_s = SvGROW(res, new_len); SvCUR_set(res, new_len); mp_encode_uint(res_s + res_len, v); } else { new_len = res_len + mp_sizeof_int(v); res_s = SvGROW(res, new_len); SvCUR_set(res, new_len); mp_encode_int(res_s + res_len, v); } break; } default: croak("Internal msgpack error %d", SvTYPE(o)); } }