BSON-XS
view release on metacpan or search on metacpan
static SV * call_method_with_pairs_va(SV *self, const char *method, ...);
static SV * new_object_from_pairs(const char *klass, ...);
static SV * call_method_with_arglist (SV *self, const char *method, va_list args);
static SV * call_sv_va (SV *func, int num, ...);
static SV * call_pv_va (char *func, int num, ...);
static bool call_key_value_iter (SV *func, SV **ret );
#define call_perl_reader(s,m) call_method_va(s,m,0)
/* BSON encoding
*
* Public function perl_mongo_sv_to_bsonis the entry point. It calls one
* of the container encoding functions, hv_doc_to_bson, or
* ixhash_doc_to_bson. Those iterate their contents, encoding them with
* sv_to_bson_elem. sv_to_bson_elem delegates to various append_*
* functions for particular types.
*
* Other functions are utility functions used during encoding.
*/
static void perl_mongo_sv_to_bson (bson_t * bson, SV *sv, HV *opts);
static void hv_to_bson(bson_t * bson, SV *sv, HV *opts, stackette *stack, int depth, bool subdoc);
static void ixhash_to_bson(bson_t * bson, SV *sv, HV *opts, stackette *stack, int depth, bool subdoc);
static void iter_src_to_bson(bson_t * bson, SV *sv, HV *opts, stackette *stack, int depth, bool subdoc);
#define hv_doc_to_bson(b,d,o,s,u) hv_to_bson((b),(d),(o),(s),(u),0)
#define hv_elem_to_bson(b,d,o,s,u) hv_to_bson((b),(d),(o),(s),(u),1)
#define ixhash_doc_to_bson(b,d,o,s,u) ixhash_to_bson((b),(d),(o),(s),(u),0)
#define ixhash_elem_to_bson(b,d,o,s,u) ixhash_to_bson((b),(d),(o),(s),(u),1)
#define iter_doc_to_bson(b,d,o,s,u) iter_src_to_bson((b),(d),(o),(s),(u),0)
#define iter_elem_to_bson(b,d,o,s,u) iter_src_to_bson((b),(d),(o),(s),(u),1)
static void sv_to_bson_elem (bson_t * bson, const char *key, SV *sv, HV *opts, stackette *stack, int depth);
const char * maybe_append_first_key(bson_t *bson, HV *opts, stackette *stack, int depth);
static void append_binary(bson_t * bson, const char * key, bson_subtype_t subtype, SV * sv);
static void append_regex(bson_t * bson, const char *key, REGEXP *re, SV * sv);
static void append_decomposed_regex(bson_t *bson, const char *key, const char *pattern, const char *flags);
static void append_fit_int(bson_t * bson, const char *key, SV * sv);
static void append_utf8(bson_t * bson, const char *key, SV * sv);
static void assert_valid_key(const char* str, STRLEN len);
static const char * bson_key(const char * str, HV *opts);
static void get_regex_flags(char * flags, SV *sv);
static int64_t math_bigint_to_int64(SV *sv, const char *key);
static SV* int64_as_SV(int64_t value);
static stackette * check_circular_ref(void *ptr, stackette *stack);
static SV* bson_parent_type(SV *sv);
/* BSON decoding
*
* Public function _decode_bson is the entry point. It calls
* bson_doc_to_hashref, which construct a container and fills it using
* bson_elem_to_sv. That may call bson_doc_to_hashref or
* bson_doc_to_arrayref to decode sub-containers.
*
* The bson_oid_to_sv function manually constructs a BSON::OID object to
* avoid the overhead of calling its constructor. This optimization is
* fragile and might need to be reconsidered.
*
*/
static SV * bson_doc_to_hashref(bson_iter_t * iter, HV *opts, int depth, bool top);
static SV * bson_doc_to_tiedhash(bson_iter_t * iter, HV *opts, int depth, bool top);
static SV * bson_array_to_arrayref(bson_iter_t * iter, HV *opts, int depth);
static SV * bson_elem_to_sv(const bson_iter_t * iter, const char *key, HV *opts, int depth);
static SV * bson_oid_to_sv(const bson_iter_t * iter);
/********************************************************************
* Some C libraries (e.g. MSVCRT) do not have a "timegm" function.
* Here is a surrogate implementation.
********************************************************************/
#if defined(WIN32) || defined(sun)
static int
is_leap_year(unsigned year) {
year += 1900;
return (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0);
}
static time_t
timegm(struct tm *tm) {
static const unsigned month_start[2][12] = {
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 },
};
time_t ret = 0;
int i;
for (i = 70; i < tm->tm_year; ++i)
ret += is_leap_year(i) ? 366 : 365;
ret += month_start[is_leap_year(tm->tm_year)][tm->tm_mon];
ret += tm->tm_mday - 1;
ret *= 24;
ret += tm->tm_hour;
ret *= 60;
ret += tm->tm_min;
ret *= 60;
ret += tm->tm_sec;
return ret;
}
#endif /* WIN32 */
/********************************************************************
* perl call helpers
********************************************************************/
/* call_method_va -- calls a method with a variable number
* of SV * arguments. The SV* arguments are NOT mortalized.
* Must give the number of arguments before the variable list */
static SV *
call_method_va (SV *self, const char *method, int num, ...) {
dSP;
SV *ret;
I32 count;
( run in 2.867 seconds using v1.01-cache-2.11-cpan-364913b4093 )