BSON-XS
view release on metacpan or search on metacpan
key = sv_2mortal( newSVpvn(name, strlen(name)) );
SvUTF8_on(key);
value = bson_elem_to_sv(iter, name, opts, depth);
call_method_va(ixhash, "STORE", 2, key, value);
}
/* tie the ixhash to the return hash */
sv_magic((SV*) hv, ixhash, PERL_MAGIC_tied, NULL, 0);
ret = newRV_noinc((SV*) hv);
/* XXX shouldn't need to limit to size 3 */
if ( !top && key_num >= 2 && is_dbref == 1
&& (wrap = _hv_fetchs_sv(opts, "wrap_dbrefs")) && SvTRUE(wrap)
) {
SV *class = sv_2mortal(newSVpvs("BSON::DBRef"));
SV *dbref = call_method_va(class, "new", 1, ret );
return dbref;
}
depth--;
return ret;
}
static SV *
bson_array_to_arrayref(bson_iter_t * iter, HV *opts, int depth) {
AV *ret = newAV ();
depth++;
if ( depth > MAX_DEPTH ) {
croak("Exceeded max object depth of %d", MAX_DEPTH);
}
while (bson_iter_next(iter)) {
SV *sv;
const char *name = bson_iter_key(iter);
/* get value */
if ((sv = bson_elem_to_sv(iter, name, opts, depth))) {
av_push (ret, sv);
}
}
depth--;
return newRV_noinc ((SV *)ret);
}
static SV *
bson_elem_to_sv (const bson_iter_t * iter, const char *key, HV *opts, int depth) {
SV **svp;
SV *value = 0;
switch(bson_iter_type(iter)) {
case BSON_TYPE_OID: {
value = bson_oid_to_sv(iter);
break;
}
case BSON_TYPE_DOUBLE: {
SV *tempsv;
SV *d = newSVnv(bson_iter_double(iter));
/* Check for Inf and NaN */
if (Perl_isinf(SvNV(d)) || Perl_isnan(SvNV(d)) ) {
SvPV_nolen(d); /* force to PVNV for compatibility */
}
if ( (tempsv = _hv_fetchs_sv(opts, "wrap_numbers")) && SvTRUE(tempsv) ) {
value = new_object_from_pairs("BSON::Double", "value", sv_2mortal(d), NULL);
}
else {
value = d;
}
break;
}
case BSON_TYPE_SYMBOL:
case BSON_TYPE_UTF8: {
SV *wrap;
SV *s;
const char * str;
uint32_t len;
if (bson_iter_type(iter) == BSON_TYPE_SYMBOL) {
str = bson_iter_symbol(iter, &len);
} else {
str = bson_iter_utf8(iter, &len);
}
if ( ! is_utf8_string((const U8*)str,len)) {
croak( "Invalid UTF-8 detected while decoding BSON" );
}
/* this makes a copy of the buffer */
/* len includes \0 */
s = newSVpvn(str, len);
SvUTF8_on(s);
if ( (wrap = _hv_fetchs_sv(opts, "wrap_strings")) && SvTRUE(wrap) ) {
value = new_object_from_pairs("BSON::String", "value", sv_2mortal(s), NULL);
}
else {
value = s;
}
break;
}
case BSON_TYPE_DOCUMENT: {
bson_iter_t child;
bson_iter_recurse(iter, &child);
value = bson_doc_to_hashref(&child, opts, depth, FALSE);
break;
}
case BSON_TYPE_ARRAY: {
bson_iter_t child;
bson_iter_recurse(iter, &child);
value = bson_array_to_arrayref(&child, opts, depth);
break;
}
case BSON_TYPE_BINARY: {
( run in 2.773 seconds using v1.01-cache-2.11-cpan-364913b4093 )