BSON-XS
view release on metacpan or search on metacpan
/* normalize from little endian back to native byte order */
Copy(bid_bytes, &dec.low, 1, uint64_t);
Copy(bid_bytes + 8, &dec.high, 1, uint64_t);
dec.low = BSON_UINT64_FROM_LE(dec.low);
dec.high = BSON_UINT64_FROM_LE(dec.high);
bson_append_decimal128(bson, key, -1, &dec);
}
else {
croak ("For key '%s', can't encode value of type '%s'", key, HvNAME(SvSTASH(SvRV(sv))));
}
} else {
SV *deref = SvRV(sv);
switch (SvTYPE (deref)) {
case SVt_PVHV: {
/* hash */
bson_t child;
bson_append_document_begin(bson, key, -1, &child);
/* don't add a _id to inner objs */
hv_elem_to_bson (&child, sv, opts, stack, depth);
bson_append_document_end(bson, &child);
break;
}
case SVt_PVAV: {
/* array */
bson_t child;
bson_append_array_begin(bson, key, -1, &child);
av_to_bson (&child, (AV *)SvRV (sv), opts, stack, depth);
bson_append_array_end(bson, &child);
break;
}
default: {
if ( SvPOK(deref) ) {
/* binary */
append_binary(bson, key, BSON_SUBTYPE_BINARY, deref);
}
else {
croak ("For key '%s', can't encode value '%s'", key, SvPV_nolen(sv));
}
}
}
}
} else {
/* Value is a defined, non-reference scalar */
SV *tempsv;
bool prefer_numeric;
tempsv = _hv_fetchs_sv(opts, "prefer_numeric");
prefer_numeric = SvTRUE(tempsv);
#if PERL_REVISION==5 && PERL_VERSION<=18
/* Before 5.18, get magic would clear public flags. This restores them
* from private flags but ONLY if there is no public flag already, as
* we have nothing else to go on for serialization.
*/
if (!(SvFLAGS(sv) & (SVf_IOK|SVf_NOK|SVf_POK))) {
SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
}
#endif
I32 is_number = looks_like_number(sv);
if ( SvNOK(sv) ) {
bson_append_double(bson, key, -1, (double)SvNV(sv));
} else if ( SvIOK(sv) ) {
append_fit_int(bson, key, sv);
} else if ( prefer_numeric && is_number ) {
/* copy to avoid modifying flags of the original */
tempsv = sv_2mortal(newSVsv(sv));
if (is_number & IS_NUMBER_NOT_INT) { /* double */
bson_append_double(bson, key, -1, (double)SvNV(tempsv));
} else {
append_fit_int(bson, key, tempsv);
}
} else {
append_utf8(bson, key, sv);
}
}
}
const char *
maybe_append_first_key(bson_t *bson, HV *opts, stackette *stack, int depth) {
SV *tempsv;
SV **svp;
const char *first_key = NULL;
if ( (tempsv = _hv_fetchs_sv(opts, "first_key")) && SvOK (tempsv) ) {
STRLEN len;
first_key = SvPVutf8(tempsv, len);
assert_valid_key(first_key, len);
if ( (tempsv = _hv_fetchs_sv(opts, "first_value")) ) {
sv_to_bson_elem(bson, first_key, tempsv, opts, stack, depth);
}
else {
bson_append_null(bson, first_key, -1);
}
}
return first_key;
}
static void
append_decomposed_regex(bson_t *bson, const char *key, const char *pattern, const char *flags ) {
size_t pattern_length = strlen( pattern );
char *buf;
Newx(buf, pattern_length + 1, char );
Copy(pattern, buf, pattern_length, char );
buf[ pattern_length ] = '\0';
bson_append_regex(bson, key, -1, buf, flags);
Safefree(buf);
}
static void
append_regex(bson_t * bson, const char *key, REGEXP *re, SV * sv) {
char flags[] = {0,0,0,0,0,0,0}; /* space for imxslu + \0 */
char *buf;
int i, j;
get_regex_flags(flags, sv);
( run in 1.438 second using v1.01-cache-2.11-cpan-8dfa8b56332 )