3c99b42015-10-14Martin Nilsson /* -*- c -*- || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
7e80f82015-02-12Martin Nilsson 
d4e4662013-07-07Bill Welliver #define _GNU_SOURCE
3796d62013-11-03Bill Welliver #include "bson_config.h" #if HAVE_ARPA_INET_H
cfea502013-08-05Martin Nilsson #include <arpa/inet.h>
3796d62013-11-03Bill Welliver #endif /* HAVE_ARPA_INET_H */ #if HAVE_WINSOCK2_H #include <Winsock2.h> #endif /* HAVE_WINSOCK2_H */
cfea502013-08-05Martin Nilsson 
d4e4662013-07-07Bill Welliver /* Standard Pike include files. */ #include "bignum.h" #include "array.h" #include "builtin_functions.h" #include "constants.h" #include "interpret.h" #include "mapping.h" #include "module_support.h"
8079a42014-01-11Tobias S. Josefowitz #include "bitvector.h"
d4e4662013-07-07Bill Welliver #include "object.h" #include "pike_macros.h" #include "pike_types.h" #include "program.h" #include "stralloc.h" #include "svalue.h" #include "version.h" #include "operators.h" #include "sscanf.h"
b3bac32017-05-09Martin Nilsson #include "modules/_Stdio/buffer.h"
498d752013-08-14Marcus Comstedt #define DEFAULT_CMOD_STORAGE static
30b1992017-07-15Henrik Grubbström (Grubba) /*! @module Standards */ /*! @module _BSON */
3dce002017-07-16Martin Nilsson #define TYPE_BSON_DOUBLE 0x01 #define TYPE_BSON_STRING 0x02 #define TYPE_BSON_DOCUMENT 0x03 #define TYPE_BSON_ARRAY 0x04 #define TYPE_BSON_BINARY 0x05 #define TYPE_BSON_UNDEFINED 0x06 /* deprecated */ #define TYPE_BSON_OBJECTID 0x07 #define TYPE_BSON_BOOLEAN 0x08 #define TYPE_BSON_SECOND 0x09 #define TYPE_BSON_NULL 0x0a #define TYPE_BSON_REGEX 0x0b #define TYPE_BSON_DBPTR 0x0c /* deprecated */ #define TYPE_BSON_JS 0x0d #define TYPE_BSON_SYMBOL 0x0e /* deprecated */ #define TYPE_BSON_JS_W_C 0x0f
f297fd2016-09-11Martin Nilsson #define TYPE_BSON_INTEGER 0x10
d4e4662013-07-07Bill Welliver #define TYPE_BSON_TIMESTAMP 0x11
f297fd2016-09-11Martin Nilsson #define TYPE_BSON_INTEGER64 0x12
3dce002017-07-16Martin Nilsson #define TYPE_BSON_DECIMAL128 0x13 /* not supported */
f297fd2016-09-11Martin Nilsson 
d4e4662013-07-07Bill Welliver #define TYPE_BSON_MINKEY 0xff #define TYPE_BSON_MAXKEY 0x7f struct object * True; struct object * False; struct object * Null; struct object * MinKey; struct object * MaxKey; struct program * Javascript; struct svalue * Second; struct program * ObjectId;
8576532017-06-16Marcus Agehall struct program * Binary;
d4e4662013-07-07Bill Welliver struct program * Symbol; struct program * Regex; struct program * Timestamp; struct svalue low_Second;
5d84ca2017-05-08Martin Nilsson char *decode_next_value(char *, size_t, struct mapping *);
d4e4662013-07-07Bill Welliver  struct object * lookup_object(const char * obj) { struct object * p; push_text(obj); SAFE_APPLY_MASTER("resolv", 1 );
05ba522014-04-16Arne Goedeke  if(TYPEOF(Pike_sp[-1]) != T_OBJECT)
d4e4662013-07-07Bill Welliver  { Pike_error("Unable to load object.\n"); } p = Pike_sp[-1].u.object; add_ref(p); pop_stack(); return p; } struct program * lookup_program(const char * prog) { struct program * p; push_text(prog); SAFE_APPLY_MASTER("resolv", 1 );
05ba522014-04-16Arne Goedeke  if(TYPEOF(Pike_sp[-1]) != T_PROGRAM)
d4e4662013-07-07Bill Welliver  { Pike_error("Unable to load class %s.\n", prog); } p = Pike_sp[-1].u.program; add_ref(p); pop_stack(); return p; } struct svalue * lookup_svalue(const char * prog) { struct svalue * p; push_text(prog); SAFE_APPLY_MASTER("resolv", 1 );
05ba522014-04-16Arne Goedeke  if(TYPEOF(Pike_sp[-1]) == PIKE_T_INT)
d4e4662013-07-07Bill Welliver  { Pike_error("Unable to load class %s.\n", prog); }
6fdf992015-03-19Henrik Grubbström (Grubba)  assign_svalue(&low_Second, Pike_sp-1);
d4e4662013-07-07Bill Welliver  pop_stack();
6fdf992015-03-19Henrik Grubbström (Grubba)  return &low_Second;
d4e4662013-07-07Bill Welliver } DECLARATIONS
b3bac32017-05-09Martin Nilsson size_t decode_document(char *slist, INT32 slist_len)
d4e4662013-07-07Bill Welliver {
563bd62015-03-19Henrik Grubbström (Grubba)  INT32 len;
d4e4662013-07-07Bill Welliver  char * n; char * end; struct mapping * list;
e44c1b2017-05-08Martin Nilsson  check_c_stack (8);
1fb4612014-04-16Arne Goedeke 
d4e4662013-07-07Bill Welliver  n = slist;
13670c2015-05-25Martin Nilsson 
70043f2017-05-08Martin Nilsson  if(slist_len < 4)
d4e4662013-07-07Bill Welliver  Pike_error("invalid BSON. not enough data.\n");
13670c2015-05-25Martin Nilsson 
8079a42014-01-11Tobias S. Josefowitz  len = get_unaligned_le32(n);
3cab612017-05-08Martin Nilsson  end = n + (len -1);
70043f2017-05-08Martin Nilsson  n += 4;
13670c2015-05-25Martin Nilsson 
70043f2017-05-08Martin Nilsson  if(slist_len < len)
d4e4662013-07-07Bill Welliver  {
70043f2017-05-08Martin Nilsson  Pike_error("invalid BSON. not enough data left to form document: expected %d bytes, have %d.\n", len, slist_len);
d4e4662013-07-07Bill Welliver  }
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  if((char)*end != 0x0) Pike_error("invalid BSON, last byte of document must be NULL.\n");
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  list = allocate_mapping(2);
f331f92014-04-16Arne Goedeke  push_mapping(list);
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  while(n < end)
5d84ca2017-05-08Martin Nilsson  n = decode_next_value(n, end-n, list);
b3bac32017-05-09Martin Nilsson 
d584ff2017-05-09Martin Nilsson  return len;
d4e4662013-07-07Bill Welliver }
5d84ca2017-05-08Martin Nilsson char * decode_next_value(char * n, size_t n_len, struct mapping * list)
d4e4662013-07-07Bill Welliver {
5d84ca2017-05-08Martin Nilsson  char *slist = n;
b2ac032015-03-19Henrik Grubbström (Grubba)  unsigned INT8 type;
d4e4662013-07-07Bill Welliver  char * cname;
563bd62015-03-19Henrik Grubbström (Grubba)  INT32 name_len;
d4e4662013-07-07Bill Welliver  type = n[0]; n++;
7e80f82015-02-12Martin Nilsson  /* guaranteed by spec to be a null terminated string. */
d4e4662013-07-07Bill Welliver  cname = n;
7e80f82015-02-12Martin Nilsson  name_len = strlen(cname); n += name_len + 1;
d4e4662013-07-07Bill Welliver  switch(type) { case TYPE_BSON_DOUBLE:
13670c2015-05-25Martin Nilsson  {
d4e4662013-07-07Bill Welliver  struct pike_string * fstr; struct array * a;
5d84ca2017-05-08Martin Nilsson  INT32 left = n_len - (n - slist);
d4e4662013-07-07Bill Welliver  if(8 > left)
5275752015-02-12Martin Nilsson  Pike_error("Invalid BSON. Not enough data.\n");
4f71d92014-04-17Arne Goedeke  fstr = make_shared_binary_string(n, 8);
d4e4662013-07-07Bill Welliver  push_string(fstr);
5e9fc02015-08-18Per Hedbor  push_static_text("%-8F");
d4e4662013-07-07Bill Welliver  f_sscanf(2);
05ba522014-04-16Arne Goedeke  if(TYPEOF(Pike_sp[-1]) != PIKE_T_ARRAY)
5275752015-02-12Martin Nilsson  Pike_error("Unable to parse float.\n");
d4e4662013-07-07Bill Welliver  a = Pike_sp[-1].u.array; push_svalue(ITEM(a)); stack_swap(); pop_stack(); n+=8; break; } case TYPE_BSON_STRING: {
563bd62015-03-19Henrik Grubbström (Grubba)  INT32 bump; INT32 left;
8079a42014-01-11Tobias S. Josefowitz  bump = get_unaligned_le32(n);
5d84ca2017-05-08Martin Nilsson  left = n_len - (n - slist);
d4e4662013-07-07Bill Welliver 
e44ecb2014-03-12Arne Goedeke  if(bump <= 0 || bump > left)
d4e4662013-07-07Bill Welliver  {
5275752015-02-12Martin Nilsson  Pike_error("Invalid BSON. Not enough data.\n");
d4e4662013-07-07Bill Welliver  } n+=4;
5275752015-02-12Martin Nilsson  push_string( make_shared_binary_string(n, bump-1) ); /* length includes null. */
d4e4662013-07-07Bill Welliver  n += (bump); f_utf8_to_string(1); break; } case TYPE_BSON_BINARY: {
563bd62015-03-19Henrik Grubbström (Grubba)  INT32 bump = get_unaligned_le32(n); INT32 left;
faad1b2017-07-16Martin Nilsson  unsigned INT8 subtype;
d4e4662013-07-07Bill Welliver  n+=4;
faad1b2017-07-16Martin Nilsson  subtype = *(unsigned INT8*)n;
8576532017-06-16Marcus Agehall  n++;
5d84ca2017-05-08Martin Nilsson  left = n_len - (n - slist);
d4e4662013-07-07Bill Welliver 
faad1b2017-07-16Martin Nilsson  if(bump < 0 || bump > left)
d4e4662013-07-07Bill Welliver  {
5275752015-02-12Martin Nilsson  Pike_error("Invalid BSON. Not enough data.\n");
d4e4662013-07-07Bill Welliver  }
8576532017-06-16Marcus Agehall  if (!Binary) Binary = lookup_program("Standards.BSON.Binary"); ref_push_program(Binary); push_string( make_shared_binary_string(n, bump) ); push_int(subtype); apply_svalue(Pike_sp - 3, 2); stack_swap(); pop_stack();
d4e4662013-07-07Bill Welliver  n += (bump);
5275752015-02-12Martin Nilsson 
d4e4662013-07-07Bill Welliver  break; }
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  case TYPE_BSON_INTEGER:
13670c2015-05-25Martin Nilsson  {
5d84ca2017-05-08Martin Nilsson  INT32 left = n_len - (n - slist);
d4e4662013-07-07Bill Welliver  if(left < 4) {
5275752015-02-12Martin Nilsson  Pike_error("Invalid BSON. Not enough data.\n");
d4e4662013-07-07Bill Welliver  }
2f18272017-02-09Martin Nilsson  push_int( (INT32)get_unaligned_le32(n) );
d4e4662013-07-07Bill Welliver  n+=4; break; } case TYPE_BSON_INTEGER64:
dce9932015-03-19Henrik Grubbström (Grubba)  {
5d84ca2017-05-08Martin Nilsson  INT32 left = n_len - (n - slist);
d4e4662013-07-07Bill Welliver  if(left < 8) {
5275752015-02-12Martin Nilsson  Pike_error("Invalid BSON. Not enough data.\n");
d4e4662013-07-07Bill Welliver  }
2f18272017-02-09Martin Nilsson  push_int64( (INT64)get_unaligned_le64(n) );
d4e4662013-07-07Bill Welliver  n+=8; break; }
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  case TYPE_BSON_BOOLEAN: {
b2ac032015-03-19Henrik Grubbström (Grubba)  INT8 t = n[0];
d4e4662013-07-07Bill Welliver  n++;
d430842014-04-15Arne Goedeke  if(t == 1) /* true */
d4e4662013-07-07Bill Welliver  { if(!True)
d7cd102014-04-15Arne Goedeke  True = lookup_object("Val.true"); ref_push_object(True);
d4e4662013-07-07Bill Welliver  }
d430842014-04-15Arne Goedeke  else if(t ==0) /* false */
d4e4662013-07-07Bill Welliver  { if(!False)
d7cd102014-04-15Arne Goedeke  False = lookup_object("Val.false"); ref_push_object(False);
d4e4662013-07-07Bill Welliver  } else { Pike_error("Invalid value of boolean field.\n"); }
13670c2015-05-25Martin Nilsson  break;
d4e4662013-07-07Bill Welliver  }
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  case TYPE_BSON_MINKEY: { if(!MinKey) MinKey = lookup_object("Standards.BSON.MinKey");
d7cd102014-04-15Arne Goedeke  ref_push_object(MinKey);
13670c2015-05-25Martin Nilsson  break;
d4e4662013-07-07Bill Welliver  }
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  case TYPE_BSON_MAXKEY: { if(!MaxKey) MaxKey = lookup_object("Standards.BSON.MaxKey");
d7cd102014-04-15Arne Goedeke  ref_push_object(MaxKey);
13670c2015-05-25Martin Nilsson  break;
d4e4662013-07-07Bill Welliver  }
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  case TYPE_BSON_NULL: { if(!Null)
d7cd102014-04-15Arne Goedeke  Null = lookup_object("Val.null"); ref_push_object(Null);
13670c2015-05-25Martin Nilsson  break;
d4e4662013-07-07Bill Welliver  }
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  case TYPE_BSON_OBJECTID: { struct pike_string * str;
13670c2015-05-25Martin Nilsson 
5d84ca2017-05-08Martin Nilsson  INT32 left = n_len - (n - slist);
d4e4662013-07-07Bill Welliver  if(left < 12) {
5275752015-02-12Martin Nilsson  Pike_error("Invalid BSON. Not enough data.\n");
d4e4662013-07-07Bill Welliver  } str = make_shared_binary_string(n, 12); n+=12; if(!ObjectId) ObjectId = lookup_program("Standards.BSON.ObjectId"); ref_push_program(ObjectId); push_string(str); apply_svalue( Pike_sp-2, 1 );
13670c2015-05-25Martin Nilsson  stack_swap();
d4e4662013-07-07Bill Welliver  pop_stack();
13670c2015-05-25Martin Nilsson  break;
d4e4662013-07-07Bill Welliver  }
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  case TYPE_BSON_TIMESTAMP: {
5d84ca2017-05-08Martin Nilsson  INT32 left = n_len - (n - slist);
d4e4662013-07-07Bill Welliver  if(left < 8) {
5275752015-02-12Martin Nilsson  Pike_error("Invalid BSON. Not enough data.\n");
d4e4662013-07-07Bill Welliver  }
dce9932015-03-19Henrik Grubbström (Grubba)  if(!Timestamp) Timestamp = lookup_program("Standards.BSON.Timestamp"); ref_push_program(Timestamp);
04fe052017-07-27Martin Nilsson  /* counter */
c0c7a22017-07-20Henrik Grubbström (Grubba)  push_int64( get_unaligned_le32(n) );
3c2faa2017-07-16Martin Nilsson  n+=4;
04fe052017-07-27Martin Nilsson  /* timestamp */ push_int64( get_unaligned_le32(n) );
3c2faa2017-07-16Martin Nilsson  n+=4;
13670c2015-05-25Martin Nilsson 
3c2faa2017-07-16Martin Nilsson  apply_svalue( Pike_sp-3, 2);
13670c2015-05-25Martin Nilsson  stack_swap();
d4e4662013-07-07Bill Welliver  pop_stack();
13670c2015-05-25Martin Nilsson  break;
d4e4662013-07-07Bill Welliver  }
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  case TYPE_BSON_SECOND: {
467d5a2017-07-16Martin Nilsson  INT64 sec;
5d84ca2017-05-08Martin Nilsson  INT32 left = n_len - (n - slist);
d4e4662013-07-07Bill Welliver  if(left < 8) {
5275752015-02-12Martin Nilsson  Pike_error("Invalid BSON. Not enough data.\n");
d4e4662013-07-07Bill Welliver  } if(!Second) Second = lookup_svalue("Calendar.Second");
5e9fc02015-08-18Per Hedbor  push_static_text("unix");
dce9932015-03-19Henrik Grubbström (Grubba)  sec = get_unaligned_le64(n);
d4e4662013-07-07Bill Welliver  push_int64(sec/1000);
dce9932015-03-19Henrik Grubbström (Grubba)  n+=8;
d4e4662013-07-07Bill Welliver  apply_svalue(Second, 2);
13670c2015-05-25Martin Nilsson  break;
d4e4662013-07-07Bill Welliver  }
d584ff2017-05-09Martin Nilsson 
13670c2015-05-25Martin Nilsson  case TYPE_BSON_ARRAY:
d4e4662013-07-07Bill Welliver  { struct array * arr;
a94d7c2013-07-07Bill Welliver  INT_TYPE asize; /* used by NEW_MAPPING_LOOP */ const struct keypair *k=0; const struct mapping_data *md; INT32 e;
5d84ca2017-05-08Martin Nilsson  INT32 left = n_len - (n - slist);
d584ff2017-05-09Martin Nilsson  n += decode_document(n, left);
a94d7c2013-07-07Bill Welliver 
d430842014-04-15Arne Goedeke  /* * arrays are encoded as mappings with indices containing * string representations of the index number. */
a94d7c2013-07-07Bill Welliver 
1be1842017-05-08Martin Nilsson  asize = m_sizeof(Pike_sp[-1].u.mapping);
a94d7c2013-07-07Bill Welliver  arr = allocate_array(asize);
1be1842017-05-08Martin Nilsson  md = Pike_sp[-1].u.mapping->data;
a94d7c2013-07-07Bill Welliver 
f331f92014-04-16Arne Goedeke  push_array(arr);
1be1842017-05-08Martin Nilsson  stack_swap();
f331f92014-04-16Arne Goedeke 
a94d7c2013-07-07Bill Welliver  NEW_MAPPING_LOOP(md) { INT_TYPE i; push_svalue(&k->ind); o_cast_to_int(); i = Pike_sp[-1].u.integer;
84c1332014-04-10Arne Goedeke  if (i < 0 || i >= asize)
5275752015-02-12Martin Nilsson  Pike_error("Invalid BSON. Array index out of bounds.\n");
a94d7c2013-07-07Bill Welliver  pop_stack();
9adc7a2013-08-01Arne Goedeke  assign_svalue(ITEM(arr) + i, &k->val);
a94d7c2013-07-07Bill Welliver  }
f331f92014-04-16Arne Goedeke  /* pop the document off the stack */ pop_stack();
d4e4662013-07-07Bill Welliver  break; } case TYPE_BSON_DOCUMENT: {
5d84ca2017-05-08Martin Nilsson  INT32 left = n_len - (n - slist);
d584ff2017-05-09Martin Nilsson  n += decode_document(n, left);
d4e4662013-07-07Bill Welliver  break; }
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  case TYPE_BSON_REGEX: { char * reg; char * opt;
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  reg = (n); n += strlen(reg) + 1;
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  opt = (n); n += strlen(opt) + 1;
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  if(!Regex) Regex = lookup_program("Standards.BSON.Regex");
13670c2015-05-25Martin Nilsson 
d7cd102014-04-15Arne Goedeke  ref_push_program(Regex);
d4e4662013-07-07Bill Welliver  push_text(reg); push_text(opt);
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  apply_svalue( Pike_sp-3, 2);
13670c2015-05-25Martin Nilsson  stack_swap();
d4e4662013-07-07Bill Welliver  pop_stack();
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  break; }
13670c2015-05-25Martin Nilsson 
3dce002017-07-16Martin Nilsson  case TYPE_BSON_JS:
d4e4662013-07-07Bill Welliver  { struct pike_string * val;
563bd62015-03-19Henrik Grubbström (Grubba)  INT32 bump = get_unaligned_le32(n); INT32 left;
d4e4662013-07-07Bill Welliver  n+=4;
5d84ca2017-05-08Martin Nilsson  left = n_len - (n - slist);
e44ecb2014-03-12Arne Goedeke  if(bump <= 0 || bump > left)
5275752015-02-12Martin Nilsson  Pike_error("Invalid BSON. Not enough data.\n");
d430842014-04-15Arne Goedeke  val = make_shared_binary_string(n, bump-1); /* length includes null. */
d4e4662013-07-07Bill Welliver  n += (bump);
13670c2015-05-25Martin Nilsson 
d4e4662013-07-07Bill Welliver  if(!Javascript) Javascript = lookup_program("Standards.BSON.Javascript");
d7cd102014-04-15Arne Goedeke  ref_push_program(Javascript);
d4e4662013-07-07Bill Welliver  push_string(val); f_utf8_to_string(1); apply_svalue( Pike_sp-2, 1);
13670c2015-05-25Martin Nilsson  stack_swap();
d4e4662013-07-07Bill Welliver  pop_stack(); break; }
13670c2015-05-25Martin Nilsson 
3dce002017-07-16Martin Nilsson  case TYPE_BSON_JS_W_C: { struct pike_string * val; INT32 len, jslen, left; len = get_unaligned_le32(n); left = n_len - (n - slist); n += 4; if( len<0 || len > left ) Pike_error("Invalid BSON. Not enough data %d %d.\n", len, left); jslen = get_unaligned_le32(n); n += 4; if( jslen<0 || jslen > len-4 ) Pike_error("Invalid BSON. Not enough data 2.\n"); val = make_shared_binary_string(n, jslen-1); /* length includes null. */ n += jslen; if(!Javascript) Javascript = lookup_program("Standards.BSON.Javascript"); ref_push_program(Javascript); push_string(val); f_utf8_to_string(1); left = n_len - (n - slist); n += decode_document(n, left); apply_svalue( Pike_sp-3, 2); stack_swap(); pop_stack(); break; }
d4e4662013-07-07Bill Welliver  default:
3c2faa2017-07-16Martin Nilsson  Pike_error("Unknown field type 0x%02x.\n", type);
d4e4662013-07-07Bill Welliver  }
7e80f82015-02-12Martin Nilsson  push_string( make_shared_binary_string(cname, name_len) );
f0d10f2015-02-12Marcus Agehall  f_utf8_to_string(1);
7e80f82015-02-12Martin Nilsson  mapping_insert(list, Pike_sp-1, Pike_sp-2);
f0d10f2015-02-12Marcus Agehall  pop_stack();
d4e4662013-07-07Bill Welliver  pop_stack(); return n; }
30b1992017-07-15Henrik Grubbström (Grubba) /*! @decl mapping decode(string(8bit) document) */
6b52762017-05-08Martin Nilsson PIKEFUN mapping decode(string(8bit) document)
d4e4662013-07-07Bill Welliver {
6b52762017-05-08Martin Nilsson  if(document->size_shift) Pike_error("wide strings are not allowed.\n");
13670c2015-05-25Martin Nilsson 
1be1842017-05-08Martin Nilsson  decode_document(document->str, document->len);
d4e4662013-07-07Bill Welliver }
30b1992017-07-15Henrik Grubbström (Grubba) /*! @decl mapping decode(Stdio.Buffer document) */
b3bac32017-05-09Martin Nilsson PIKEFUN mapping decode(Stdio.Buffer document) rawtype tFunc(tObjIs_STDIO_BUFFER, tMapping); { Buffer *io = io_buffer_from_object(document); if (!io) SIMPLE_ARG_TYPE_ERROR("decode_from", 1, "object(Stdio.Buffer)"); io_consume(io, decode_document((char*)io_read_pointer(io), io_len(io))); }
d4e4662013-07-07Bill Welliver PIKE_MODULE_INIT { INIT;
cfea502013-08-05Martin Nilsson  // We could initialize these to their real values for some minimal // runtime performance gain. True = NULL; False = NULL; Null = NULL; MinKey = NULL; MaxKey = NULL; Javascript = NULL; Second = NULL; ObjectId = NULL;
3ddc1d2017-07-19Henrik Grubbström (Grubba)  Binary = NULL;
cfea502013-08-05Martin Nilsson  Symbol = NULL; Regex = NULL; Timestamp = NULL;
d4e4662013-07-07Bill Welliver }
13670c2015-05-25Martin Nilsson PIKE_MODULE_EXIT
d4e4662013-07-07Bill Welliver {
cfea502013-08-05Martin Nilsson  if( True ) free_object(True); if( False ) free_object(False); if( Null ) free_object(Null); if( MinKey ) free_object(MinKey); if( MaxKey ) free_object(MaxKey); if( Javascript ) free_program(Javascript); if( Second ) free_svalue(Second); if( ObjectId ) free_program(ObjectId);
3ddc1d2017-07-19Henrik Grubbström (Grubba)  if( Binary ) free_program(Binary);
cfea502013-08-05Martin Nilsson  if( Symbol ) free_program(Symbol); if( Regex ) free_program(Regex); if( Timestamp ) free_program(Timestamp);
d4e4662013-07-07Bill Welliver  EXIT; }
30b1992017-07-15Henrik Grubbström (Grubba)  /*! @endmodule _BSON */ /*! @endmodule Standards */