1 /* bson.c */
2 
3 /*    Copyright 2009, 2010 10gen Inc.
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *    http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17 
18 #include <stdlib.h>
19 #include <string.h>
20 #include <stdio.h>
21 #include <time.h>
22 #include <limits.h>
23 
24 #include "bson.h"
25 #include "encoding.h"
26 
27 const int initialBufferSize = 128;
28 
29 /* only need one of these */
30 static const int zero = 0;
31 
32 /* Custom standard function pointers. */
33 void *( *bson_malloc_func )( size_t ) = malloc;
34 void *( *bson_realloc_func )( void *, size_t ) = realloc;
35 void  ( *bson_free )( void * ) = free;
36 #ifdef R_SAFETY_NET
37 bson_printf_func bson_printf;
38 #else
39 bson_printf_func bson_printf = printf;
40 #endif
41 bson_fprintf_func bson_fprintf = fprintf;
42 bson_sprintf_func bson_sprintf = sprintf;
43 
44 static int _bson_errprintf( const char *, ... );
45 bson_printf_func bson_errprintf = _bson_errprintf;
46 
47 /* ObjectId fuzz functions. */
48 static int ( *oid_fuzz_func )( void ) = NULL;
49 static int ( *oid_inc_func )( void )  = NULL;
50 
51 /* ----------------------------
52    READING
53    ------------------------------ */
54 
bson_create()55 MONGO_EXPORT bson* bson_create() {
56 	return (bson*)bson_malloc(sizeof(bson));
57 }
58 
bson_dispose(bson * b)59 MONGO_EXPORT void bson_dispose(bson* b) {
60 	bson_free(b);
61 }
62 
bson_empty(bson * obj)63 bson *bson_empty( bson *obj ) {
64     static char *data = "\005\0\0\0\0";
65     bson_init_data( obj, data );
66     obj->finished = 1;
67     obj->err = 0;
68     obj->stackPos = 0;
69     return obj;
70 }
71 
bson_copy(bson * out,const bson * in)72 MONGO_EXPORT int bson_copy( bson *out, const bson *in ) {
73     if ( !out ) return BSON_ERROR;
74     if ( !in->finished ) return BSON_ERROR;
75     bson_init_size( out, bson_size( in ) );
76     memcpy( out->data, in->data, bson_size( in ) );
77     out->finished = 1;
78 
79     return BSON_OK;
80 }
81 
bson_init_data(bson * b,char * data)82 int bson_init_data( bson *b, char *data ) {
83     b->data = data;
84     return BSON_OK;
85 }
86 
bson_init_finished_data(bson * b,char * data)87 int bson_init_finished_data( bson *b, char *data ) {
88     bson_init_data( b, data );
89     b->finished = 1;
90     return BSON_OK;
91 }
92 
_bson_reset(bson * b)93 static void _bson_reset( bson *b ) {
94     b->finished = 0;
95     b->stackPos = 0;
96     b->err = 0;
97     b->errstr = NULL;
98 }
99 
bson_size(const bson * b)100 MONGO_EXPORT int bson_size( const bson *b ) {
101     int i;
102     if ( ! b || ! b->data )
103         return 0;
104     bson_little_endian32( &i, b->data );
105     return i;
106 }
107 
bson_buffer_size(const bson * b)108 MONGO_EXPORT int bson_buffer_size( const bson *b ) {
109     return (b->cur - b->data + 1);
110 }
111 
112 
bson_data(bson * b)113 const char *bson_data( bson *b ) {
114     return (const char *)b->data;
115 }
116 
hexbyte(char hex)117 static char hexbyte( char hex ) {
118     switch ( hex ) {
119     case '0':
120         return 0x0;
121     case '1':
122         return 0x1;
123     case '2':
124         return 0x2;
125     case '3':
126         return 0x3;
127     case '4':
128         return 0x4;
129     case '5':
130         return 0x5;
131     case '6':
132         return 0x6;
133     case '7':
134         return 0x7;
135     case '8':
136         return 0x8;
137     case '9':
138         return 0x9;
139     case 'a':
140     case 'A':
141         return 0xa;
142     case 'b':
143     case 'B':
144         return 0xb;
145     case 'c':
146     case 'C':
147         return 0xc;
148     case 'd':
149     case 'D':
150         return 0xd;
151     case 'e':
152     case 'E':
153         return 0xe;
154     case 'f':
155     case 'F':
156         return 0xf;
157     default:
158         return 0x0; /* something smarter? */
159     }
160 }
161 
bson_oid_from_string(bson_oid_t * oid,const char * str)162 MONGO_EXPORT void bson_oid_from_string( bson_oid_t *oid, const char *str ) {
163     int i;
164     for ( i=0; i<12; i++ ) {
165         oid->bytes[i] = ( hexbyte( str[2*i] ) << 4 ) | hexbyte( str[2*i + 1] );
166     }
167 }
168 
bson_oid_to_string(const bson_oid_t * oid,char * str)169 MONGO_EXPORT void bson_oid_to_string( const bson_oid_t *oid, char *str ) {
170     static const char hex[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
171     int i;
172     for ( i=0; i<12; i++ ) {
173         str[2*i]     = hex[( oid->bytes[i] & 0xf0 ) >> 4];
174         str[2*i + 1] = hex[ oid->bytes[i] & 0x0f      ];
175     }
176     str[24] = '\0';
177 }
178 
bson_set_oid_fuzz(int (* func)(void))179 void bson_set_oid_fuzz( int ( *func )( void ) ) {
180     oid_fuzz_func = func;
181 }
182 
bson_set_oid_inc(int (* func)(void))183 void bson_set_oid_inc( int ( *func )( void ) ) {
184     oid_inc_func = func;
185 }
186 
bson_oid_gen(bson_oid_t * oid)187 MONGO_EXPORT void bson_oid_gen( bson_oid_t *oid ) {
188     static int incr = 0;
189     static int fuzz = 0;
190     int i;
191     int t = time( NULL );
192 
193     if( oid_inc_func )
194         i = oid_inc_func();
195     else
196         i = incr++;
197 
198     if ( !fuzz ) {
199         if ( oid_fuzz_func )
200             fuzz = oid_fuzz_func();
201         else {
202             srand( t );
203             fuzz = rand();
204         }
205     }
206 
207     bson_big_endian32( &oid->ints[0], &t );
208     oid->ints[1] = fuzz;
209     bson_big_endian32( &oid->ints[2], &i );
210 }
211 
bson_oid_generated_time(bson_oid_t * oid)212 time_t bson_oid_generated_time( bson_oid_t *oid ) {
213     time_t out;
214     bson_big_endian32( &out, &oid->ints[0] );
215 
216     return out;
217 }
218 
bson_print(bson * b)219 void bson_print( bson *b ) {
220     bson_print_raw( b->data , 0 );
221 }
222 
bson_print_raw(const char * data,int depth)223 void bson_print_raw( const char *data , int depth ) {
224     bson_iterator i;
225     const char *key;
226     int temp;
227     bson_timestamp_t ts;
228     char oidhex[25];
229     bson scope;
230     bson_iterator_from_buffer( &i, data );
231 
232     while ( bson_iterator_next( &i ) ) {
233         bson_type t = bson_iterator_type( &i );
234         if ( t == 0 )
235             break;
236         key = bson_iterator_key( &i );
237 
238         for ( temp=0; temp<=depth; temp++ )
239             bson_printf( "\t" );
240         bson_printf( "%s : %d \t " , key , t );
241         switch ( t ) {
242         case BSON_DOUBLE:
243             bson_printf( "%f" , bson_iterator_double( &i ) );
244             break;
245         case BSON_STRING:
246             bson_printf( "%s" , bson_iterator_string( &i ) );
247             break;
248         case BSON_SYMBOL:
249             bson_printf( "SYMBOL: %s" , bson_iterator_string( &i ) );
250             break;
251         case BSON_OID:
252             bson_oid_to_string( bson_iterator_oid( &i ), oidhex );
253             bson_printf( "%s" , oidhex );
254             break;
255         case BSON_BOOL:
256             bson_printf( "%s" , bson_iterator_bool( &i ) ? "true" : "false" );
257             break;
258         case BSON_DATE:
259             bson_printf( "%ld" , ( long int )bson_iterator_date( &i ) );
260             break;
261         case BSON_BINDATA:
262             bson_printf( "BSON_BINDATA" );
263             break;
264         case BSON_UNDEFINED:
265             bson_printf( "BSON_UNDEFINED" );
266             break;
267         case BSON_NULL:
268             bson_printf( "BSON_NULL" );
269             break;
270         case BSON_REGEX:
271             bson_printf( "BSON_REGEX: %s", bson_iterator_regex( &i ) );
272             break;
273         case BSON_CODE:
274             bson_printf( "BSON_CODE: %s", bson_iterator_code( &i ) );
275             break;
276         case BSON_CODEWSCOPE:
277             bson_printf( "BSON_CODE_W_SCOPE: %s", bson_iterator_code( &i ) );
278             bson_init( &scope );
279             bson_iterator_code_scope( &i, &scope );
280             bson_printf( "\n\t SCOPE: " );
281             bson_print( &scope );
282             break;
283         case BSON_INT:
284             bson_printf( "%d" , bson_iterator_int( &i ) );
285             break;
286         case BSON_LONG:
287             bson_printf( "%lld" , ( uint64_t )bson_iterator_long( &i ) );
288             break;
289         case BSON_TIMESTAMP:
290             ts = bson_iterator_timestamp( &i );
291             bson_printf( "i: %d, t: %d", ts.i, ts.t );
292             break;
293         case BSON_OBJECT:
294         case BSON_ARRAY:
295             bson_printf( "\n" );
296             bson_print_raw( bson_iterator_value( &i ) , depth + 1 );
297             break;
298         default:
299             bson_errprintf( "can't print type : %d\n" , t );
300         }
301         bson_printf( "\n" );
302     }
303 }
304 
305 /* ----------------------------
306    ITERATOR
307    ------------------------------ */
308 
bson_iterator_create()309 MONGO_EXPORT bson_iterator* bson_iterator_create() {
310     return (bson_iterator*)malloc(sizeof(bson_iterator*));
311 }
312 
bson_iterator_dispose(bson_iterator * i)313 MONGO_EXPORT void bson_iterator_dispose(bson_iterator* i) {
314     free(i);
315 }
316 
bson_iterator_init(bson_iterator * i,const bson * b)317 MONGO_EXPORT void bson_iterator_init( bson_iterator *i, const bson *b ) {
318     i->cur = b->data + 4;
319     i->first = 1;
320 }
321 
bson_iterator_from_buffer(bson_iterator * i,const char * buffer)322 void bson_iterator_from_buffer( bson_iterator *i, const char *buffer ) {
323     i->cur = buffer + 4;
324     i->first = 1;
325 }
326 
bson_find(bson_iterator * it,const bson * obj,const char * name)327 MONGO_EXPORT bson_type bson_find( bson_iterator *it, const bson *obj, const char *name ) {
328     bson_iterator_init( it, (bson *)obj );
329     while( bson_iterator_next( it ) ) {
330         if ( strcmp( name, bson_iterator_key( it ) ) == 0 )
331             break;
332     }
333     return bson_iterator_type( it );
334 }
335 
bson_iterator_more(const bson_iterator * i)336 bson_bool_t bson_iterator_more( const bson_iterator *i ) {
337     return *( i->cur );
338 }
339 
bson_iterator_next(bson_iterator * i)340 MONGO_EXPORT bson_type bson_iterator_next( bson_iterator *i ) {
341     int ds;
342 
343     if ( i->first ) {
344         i->first = 0;
345         return ( bson_type )( *i->cur );
346     }
347 
348     switch ( bson_iterator_type( i ) ) {
349     case BSON_EOO:
350         return BSON_EOO; /* don't advance */
351     case BSON_UNDEFINED:
352     case BSON_NULL:
353         ds = 0;
354         break;
355     case BSON_BOOL:
356         ds = 1;
357         break;
358     case BSON_INT:
359         ds = 4;
360         break;
361     case BSON_LONG:
362     case BSON_DOUBLE:
363     case BSON_TIMESTAMP:
364     case BSON_DATE:
365         ds = 8;
366         break;
367     case BSON_OID:
368         ds = 12;
369         break;
370     case BSON_STRING:
371     case BSON_SYMBOL:
372     case BSON_CODE:
373         ds = 4 + bson_iterator_int_raw( i );
374         break;
375     case BSON_BINDATA:
376         ds = 5 + bson_iterator_int_raw( i );
377         break;
378     case BSON_OBJECT:
379     case BSON_ARRAY:
380     case BSON_CODEWSCOPE:
381         ds = bson_iterator_int_raw( i );
382         break;
383     case BSON_DBREF:
384         ds = 4+12 + bson_iterator_int_raw( i );
385         break;
386     case BSON_REGEX: {
387         const char *s = bson_iterator_value( i );
388         const char *p = s;
389         p += strlen( p )+1;
390         p += strlen( p )+1;
391         ds = p-s;
392         break;
393     }
394 
395     default: {
396         char msg[] = "unknown type: 000000000000";
397         bson_numstr( msg+14, ( unsigned )( i->cur[0] ) );
398         bson_fatal_msg( 0, msg );
399         return 0;
400     }
401     }
402 
403     i->cur += 1 + strlen( i->cur + 1 ) + 1 + ds;
404 
405     return ( bson_type )( *i->cur );
406 }
407 
bson_iterator_type(const bson_iterator * i)408 MONGO_EXPORT bson_type bson_iterator_type( const bson_iterator *i ) {
409     return ( bson_type )i->cur[0];
410 }
411 
bson_iterator_key(const bson_iterator * i)412 MONGO_EXPORT const char *bson_iterator_key( const bson_iterator *i ) {
413     return i->cur + 1;
414 }
415 
bson_iterator_value(const bson_iterator * i)416 const char *bson_iterator_value( const bson_iterator *i ) {
417     const char *t = i->cur + 1;
418     t += strlen( t ) + 1;
419     return t;
420 }
421 
422 /* types */
423 
bson_iterator_int_raw(const bson_iterator * i)424 int bson_iterator_int_raw( const bson_iterator *i ) {
425     int out;
426     bson_little_endian32( &out, bson_iterator_value( i ) );
427     return out;
428 }
429 
bson_iterator_double_raw(const bson_iterator * i)430 double bson_iterator_double_raw( const bson_iterator *i ) {
431     double out;
432     bson_little_endian64( &out, bson_iterator_value( i ) );
433     return out;
434 }
435 
bson_iterator_long_raw(const bson_iterator * i)436 int64_t bson_iterator_long_raw( const bson_iterator *i ) {
437     int64_t out;
438     bson_little_endian64( &out, bson_iterator_value( i ) );
439     return out;
440 }
441 
bson_iterator_bool_raw(const bson_iterator * i)442 bson_bool_t bson_iterator_bool_raw( const bson_iterator *i ) {
443     return bson_iterator_value( i )[0];
444 }
445 
bson_iterator_oid(const bson_iterator * i)446 MONGO_EXPORT bson_oid_t *bson_iterator_oid( const bson_iterator *i ) {
447     return ( bson_oid_t * )bson_iterator_value( i );
448 }
449 
bson_iterator_int(const bson_iterator * i)450 MONGO_EXPORT int bson_iterator_int( const bson_iterator *i ) {
451     switch ( bson_iterator_type( i ) ) {
452     case BSON_INT:
453         return bson_iterator_int_raw( i );
454     case BSON_LONG:
455         return bson_iterator_long_raw( i );
456     case BSON_DOUBLE:
457         return bson_iterator_double_raw( i );
458     default:
459         return 0;
460     }
461 }
462 
bson_iterator_double(const bson_iterator * i)463 MONGO_EXPORT double bson_iterator_double( const bson_iterator *i ) {
464     switch ( bson_iterator_type( i ) ) {
465     case BSON_INT:
466         return bson_iterator_int_raw( i );
467     case BSON_LONG:
468         return bson_iterator_long_raw( i );
469     case BSON_DOUBLE:
470         return bson_iterator_double_raw( i );
471     default:
472         return 0;
473     }
474 }
475 
bson_iterator_long(const bson_iterator * i)476 MONGO_EXPORT int64_t bson_iterator_long( const bson_iterator *i ) {
477     switch ( bson_iterator_type( i ) ) {
478     case BSON_INT:
479         return bson_iterator_int_raw( i );
480     case BSON_LONG:
481         return bson_iterator_long_raw( i );
482     case BSON_DOUBLE:
483         return bson_iterator_double_raw( i );
484     default:
485         return 0;
486     }
487 }
488 
bson_iterator_timestamp(const bson_iterator * i)489 bson_timestamp_t bson_iterator_timestamp( const bson_iterator *i ) {
490     bson_timestamp_t ts;
491     bson_little_endian32( &( ts.i ), bson_iterator_value( i ) );
492     bson_little_endian32( &( ts.t ), bson_iterator_value( i ) + 4 );
493     return ts;
494 }
495 
496 
bson_iterator_timestamp_time(const bson_iterator * i)497 MONGO_EXPORT int bson_iterator_timestamp_time( const bson_iterator *i ) {
498     int time;
499     bson_little_endian32( &time, bson_iterator_value( i ) + 4 );
500     return time;
501 }
502 
503 
bson_iterator_timestamp_increment(const bson_iterator * i)504 MONGO_EXPORT int bson_iterator_timestamp_increment( const bson_iterator *i ) {
505     int increment;
506     bson_little_endian32( &increment, bson_iterator_value( i ) );
507     return increment;
508 }
509 
510 
bson_iterator_bool(const bson_iterator * i)511 MONGO_EXPORT bson_bool_t bson_iterator_bool( const bson_iterator *i ) {
512     switch ( bson_iterator_type( i ) ) {
513     case BSON_BOOL:
514         return bson_iterator_bool_raw( i );
515     case BSON_INT:
516         return bson_iterator_int_raw( i ) != 0;
517     case BSON_LONG:
518         return bson_iterator_long_raw( i ) != 0;
519     case BSON_DOUBLE:
520         return bson_iterator_double_raw( i ) != 0;
521     case BSON_EOO:
522     case BSON_NULL:
523         return 0;
524     default:
525         return 1;
526     }
527 }
528 
bson_iterator_string(const bson_iterator * i)529 MONGO_EXPORT const char *bson_iterator_string( const bson_iterator *i ) {
530     return bson_iterator_value( i ) + 4;
531 }
532 
bson_iterator_string_len(const bson_iterator * i)533 int bson_iterator_string_len( const bson_iterator *i ) {
534     return bson_iterator_int_raw( i );
535 }
536 
bson_iterator_code(const bson_iterator * i)537 MONGO_EXPORT const char *bson_iterator_code( const bson_iterator *i ) {
538     switch ( bson_iterator_type( i ) ) {
539     case BSON_STRING:
540     case BSON_CODE:
541         return bson_iterator_value( i ) + 4;
542     case BSON_CODEWSCOPE:
543         return bson_iterator_value( i ) + 8;
544     default:
545         return NULL;
546     }
547 }
548 
bson_iterator_code_scope(const bson_iterator * i,bson * scope)549 MONGO_EXPORT void bson_iterator_code_scope( const bson_iterator *i, bson *scope ) {
550     if ( bson_iterator_type( i ) == BSON_CODEWSCOPE ) {
551         int code_len;
552         bson_little_endian32( &code_len, bson_iterator_value( i )+4 );
553         bson_init_data( scope, ( void * )( bson_iterator_value( i )+8+code_len ) );
554         _bson_reset( scope );
555         scope->finished = 1;
556     } else {
557         bson_empty( scope );
558     }
559 }
560 
bson_iterator_date(const bson_iterator * i)561 MONGO_EXPORT bson_date_t bson_iterator_date( const bson_iterator *i ) {
562     return bson_iterator_long_raw( i );
563 }
564 
bson_iterator_time_t(const bson_iterator * i)565 time_t bson_iterator_time_t( const bson_iterator *i ) {
566     return bson_iterator_date( i ) / 1000;
567 }
568 
bson_iterator_bin_len(const bson_iterator * i)569 MONGO_EXPORT int bson_iterator_bin_len( const bson_iterator *i ) {
570     return ( bson_iterator_bin_type( i ) == BSON_BIN_BINARY_OLD )
571            ? bson_iterator_int_raw( i ) - 4
572            : bson_iterator_int_raw( i );
573 }
574 
bson_iterator_bin_type(const bson_iterator * i)575 MONGO_EXPORT char bson_iterator_bin_type( const bson_iterator *i ) {
576     return bson_iterator_value( i )[4];
577 }
578 
bson_iterator_bin_data(const bson_iterator * i)579 MONGO_EXPORT const char *bson_iterator_bin_data( const bson_iterator *i ) {
580     return ( bson_iterator_bin_type( i ) == BSON_BIN_BINARY_OLD )
581            ? bson_iterator_value( i ) + 9
582            : bson_iterator_value( i ) + 5;
583 }
584 
bson_iterator_regex(const bson_iterator * i)585 MONGO_EXPORT const char *bson_iterator_regex( const bson_iterator *i ) {
586     return bson_iterator_value( i );
587 }
588 
bson_iterator_regex_opts(const bson_iterator * i)589 MONGO_EXPORT const char *bson_iterator_regex_opts( const bson_iterator *i ) {
590     const char *p = bson_iterator_value( i );
591     return p + strlen( p ) + 1;
592 
593 }
594 
bson_iterator_subobject(const bson_iterator * i,bson * sub)595 void bson_iterator_subobject( const bson_iterator *i, bson *sub ) {
596     bson_init_data( sub, ( char * )bson_iterator_value( i ) );
597     _bson_reset( sub );
598     sub->finished = 1;
599 }
600 
bson_iterator_subiterator(const bson_iterator * i,bson_iterator * sub)601 MONGO_EXPORT void bson_iterator_subiterator( const bson_iterator *i, bson_iterator *sub ) {
602     bson_iterator_from_buffer( sub, bson_iterator_value( i ) );
603 }
604 
605 /* ----------------------------
606    BUILDING
607    ------------------------------ */
608 
_bson_init_size(bson * b,int size)609 static void _bson_init_size( bson *b, int size ) {
610     if( size == 0 )
611         b->data = NULL;
612     else
613         b->data = ( char * )bson_malloc( size );
614     b->dataSize = size;
615     b->cur = b->data + 4;
616     _bson_reset( b );
617 }
618 
bson_init(bson * b)619 MONGO_EXPORT void bson_init( bson *b ) {
620     _bson_init_size( b, initialBufferSize );
621 }
622 
bson_init_size(bson * b,int size)623 void bson_init_size( bson *b, int size ) {
624     _bson_init_size( b, size );
625 }
626 
bson_append_byte(bson * b,char c)627 void bson_append_byte( bson *b, char c ) {
628     b->cur[0] = c;
629     b->cur++;
630 }
631 
bson_append(bson * b,const void * data,int len)632 void bson_append( bson *b, const void *data, int len ) {
633     memcpy( b->cur , data , len );
634     b->cur += len;
635 }
636 
bson_append32(bson * b,const void * data)637 void bson_append32( bson *b, const void *data ) {
638     bson_little_endian32( b->cur, data );
639     b->cur += 4;
640 }
641 
bson_append64(bson * b,const void * data)642 void bson_append64( bson *b, const void *data ) {
643     bson_little_endian64( b->cur, data );
644     b->cur += 8;
645 }
646 
bson_ensure_space(bson * b,const int bytesNeeded)647 int bson_ensure_space( bson *b, const int bytesNeeded ) {
648     int pos = b->cur - b->data;
649     char *orig = b->data;
650     int new_size;
651 
652     if ( pos + bytesNeeded <= b->dataSize )
653         return BSON_OK;
654 
655     new_size = 1.5 * ( b->dataSize + bytesNeeded );
656 
657     if( new_size < b->dataSize ) {
658         if( ( b->dataSize + bytesNeeded ) < INT_MAX )
659             new_size = INT_MAX;
660         else {
661             b->err = BSON_SIZE_OVERFLOW;
662             return BSON_ERROR;
663         }
664     }
665 
666     b->data = bson_realloc( b->data, new_size );
667     if ( !b->data )
668         bson_fatal_msg( !!b->data, "realloc() failed" );
669 
670     b->dataSize = new_size;
671     b->cur += b->data - orig;
672 
673     return BSON_OK;
674 }
675 
bson_finish(bson * b)676 MONGO_EXPORT int bson_finish( bson *b ) {
677     int i;
678 
679     if( b->err & BSON_NOT_UTF8 )
680         return BSON_ERROR;
681 
682     if ( ! b->finished ) {
683         if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR;
684         bson_append_byte( b, 0 );
685         i = b->cur - b->data;
686         bson_little_endian32( b->data, &i );
687         b->finished = 1;
688     }
689 
690     return BSON_OK;
691 }
692 
bson_destroy(bson * b)693 MONGO_EXPORT void bson_destroy( bson *b ) {
694     if (b) {
695         bson_free( b->data );
696         b->err = 0;
697         b->data = 0;
698         b->cur = 0;
699         b->finished = 1;
700     }
701 }
702 
bson_append_estart(bson * b,int type,const char * name,const int dataSize)703 static int bson_append_estart( bson *b, int type, const char *name, const int dataSize ) {
704     const int len = strlen( name ) + 1;
705 
706     if ( b->finished ) {
707         b->err |= BSON_ALREADY_FINISHED;
708         return BSON_ERROR;
709     }
710 
711     if ( bson_ensure_space( b, 1 + len + dataSize ) == BSON_ERROR ) {
712         return BSON_ERROR;
713     }
714 
715     if( bson_check_field_name( b, ( const char * )name, len - 1 ) == BSON_ERROR ) {
716         bson_builder_error( b );
717         return BSON_ERROR;
718     }
719 
720     bson_append_byte( b, ( char )type );
721     bson_append( b, name, len );
722     return BSON_OK;
723 }
724 
725 /* ----------------------------
726    BUILDING TYPES
727    ------------------------------ */
728 
bson_append_int(bson * b,const char * name,const int i)729 MONGO_EXPORT int bson_append_int( bson *b, const char *name, const int i ) {
730     if ( bson_append_estart( b, BSON_INT, name, 4 ) == BSON_ERROR )
731         return BSON_ERROR;
732     bson_append32( b , &i );
733     return BSON_OK;
734 }
735 
bson_append_long(bson * b,const char * name,const int64_t i)736 MONGO_EXPORT int bson_append_long( bson *b, const char *name, const int64_t i ) {
737     if ( bson_append_estart( b , BSON_LONG, name, 8 ) == BSON_ERROR )
738         return BSON_ERROR;
739     bson_append64( b , &i );
740     return BSON_OK;
741 }
742 
bson_append_double(bson * b,const char * name,const double d)743 MONGO_EXPORT int bson_append_double( bson *b, const char *name, const double d ) {
744     if ( bson_append_estart( b, BSON_DOUBLE, name, 8 ) == BSON_ERROR )
745         return BSON_ERROR;
746     bson_append64( b , &d );
747     return BSON_OK;
748 }
749 
bson_append_bool(bson * b,const char * name,const bson_bool_t i)750 MONGO_EXPORT int bson_append_bool( bson *b, const char *name, const bson_bool_t i ) {
751     if ( bson_append_estart( b, BSON_BOOL, name, 1 ) == BSON_ERROR )
752         return BSON_ERROR;
753     bson_append_byte( b , i != 0 );
754     return BSON_OK;
755 }
756 
bson_append_null(bson * b,const char * name)757 MONGO_EXPORT int bson_append_null( bson *b, const char *name ) {
758     if ( bson_append_estart( b , BSON_NULL, name, 0 ) == BSON_ERROR )
759         return BSON_ERROR;
760     return BSON_OK;
761 }
762 
bson_append_undefined(bson * b,const char * name)763 MONGO_EXPORT int bson_append_undefined( bson *b, const char *name ) {
764     if ( bson_append_estart( b, BSON_UNDEFINED, name, 0 ) == BSON_ERROR )
765         return BSON_ERROR;
766     return BSON_OK;
767 }
768 
bson_append_string_base(bson * b,const char * name,const char * value,int len,bson_type type)769 int bson_append_string_base( bson *b, const char *name,
770                              const char *value, int len, bson_type type ) {
771 
772     int sl = len + 1;
773     if ( bson_check_string( b, ( const char * )value, sl - 1 ) == BSON_ERROR )
774         return BSON_ERROR;
775     if ( bson_append_estart( b, type, name, 4 + sl ) == BSON_ERROR ) {
776         return BSON_ERROR;
777     }
778     bson_append32( b , &sl );
779     bson_append( b , value , sl - 1 );
780     bson_append( b , "\0" , 1 );
781     return BSON_OK;
782 }
783 
bson_append_string(bson * b,const char * name,const char * value)784 MONGO_EXPORT int bson_append_string( bson *b, const char *name, const char *value ) {
785     return bson_append_string_base( b, name, value, strlen ( value ), BSON_STRING );
786 }
787 
bson_append_symbol(bson * b,const char * name,const char * value)788 MONGO_EXPORT int bson_append_symbol( bson *b, const char *name, const char *value ) {
789     return bson_append_string_base( b, name, value, strlen ( value ), BSON_SYMBOL );
790 }
791 
bson_append_code(bson * b,const char * name,const char * value)792 MONGO_EXPORT int bson_append_code( bson *b, const char *name, const char *value ) {
793     return bson_append_string_base( b, name, value, strlen ( value ), BSON_CODE );
794 }
795 
bson_append_string_n(bson * b,const char * name,const char * value,int len)796 int bson_append_string_n( bson *b, const char *name, const char *value, int len ) {
797     return bson_append_string_base( b, name, value, len, BSON_STRING );
798 }
799 
bson_append_symbol_n(bson * b,const char * name,const char * value,int len)800 int bson_append_symbol_n( bson *b, const char *name, const char *value, int len ) {
801     return bson_append_string_base( b, name, value, len, BSON_SYMBOL );
802 }
803 
bson_append_code_n(bson * b,const char * name,const char * value,int len)804 int bson_append_code_n( bson *b, const char *name, const char *value, int len ) {
805     return bson_append_string_base( b, name, value, len, BSON_CODE );
806 }
807 
bson_append_code_w_scope_n(bson * b,const char * name,const char * code,int len,const bson * scope)808 int bson_append_code_w_scope_n( bson *b, const char *name,
809                                 const char *code, int len, const bson *scope ) {
810 
811     int sl = len + 1;
812     int size = 4 + 4 + sl + bson_size( scope );
813     if ( bson_append_estart( b, BSON_CODEWSCOPE, name, size ) == BSON_ERROR )
814         return BSON_ERROR;
815     bson_append32( b, &size );
816     bson_append32( b, &sl );
817     bson_append( b, code, sl );
818     bson_append( b, scope->data, bson_size( scope ) );
819     return BSON_OK;
820 }
821 
bson_append_code_w_scope(bson * b,const char * name,const char * code,const bson * scope)822 MONGO_EXPORT int bson_append_code_w_scope( bson *b, const char *name, const char *code, const bson *scope ) {
823     return bson_append_code_w_scope_n( b, name, code, strlen ( code ), scope );
824 }
825 
bson_append_binary(bson * b,const char * name,char type,const char * str,int len)826 MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, int len ) {
827     if ( type == BSON_BIN_BINARY_OLD ) {
828         int subtwolen = len + 4;
829         if ( bson_append_estart( b, BSON_BINDATA, name, 4+1+4+len ) == BSON_ERROR )
830             return BSON_ERROR;
831         bson_append32( b, &subtwolen );
832         bson_append_byte( b, type );
833         bson_append32( b, &len );
834         bson_append( b, str, len );
835     } else {
836         if ( bson_append_estart( b, BSON_BINDATA, name, 4+1+len ) == BSON_ERROR )
837             return BSON_ERROR;
838         bson_append32( b, &len );
839         bson_append_byte( b, type );
840         bson_append( b, str, len );
841     }
842     return BSON_OK;
843 }
844 
bson_append_oid(bson * b,const char * name,const bson_oid_t * oid)845 MONGO_EXPORT int bson_append_oid( bson *b, const char *name, const bson_oid_t *oid ) {
846     if ( bson_append_estart( b, BSON_OID, name, 12 ) == BSON_ERROR )
847         return BSON_ERROR;
848     bson_append( b , oid , 12 );
849     return BSON_OK;
850 }
851 
bson_append_new_oid(bson * b,const char * name)852 int bson_append_new_oid( bson *b, const char *name ) {
853     bson_oid_t oid;
854     bson_oid_gen( &oid );
855     return bson_append_oid( b, name, &oid );
856 }
857 
bson_append_regex(bson * b,const char * name,const char * pattern,const char * opts)858 MONGO_EXPORT int bson_append_regex( bson *b, const char *name, const char *pattern, const char *opts ) {
859     const int plen = strlen( pattern )+1;
860     const int olen = strlen( opts )+1;
861     if ( bson_append_estart( b, BSON_REGEX, name, plen + olen ) == BSON_ERROR )
862         return BSON_ERROR;
863     if ( bson_check_string( b, pattern, plen - 1 ) == BSON_ERROR )
864         return BSON_ERROR;
865     bson_append( b , pattern , plen );
866     bson_append( b , opts , olen );
867     return BSON_OK;
868 }
869 
bson_append_bson(bson * b,const char * name,const bson * bson)870 MONGO_EXPORT int bson_append_bson( bson *b, const char *name, const bson *bson ) {
871     if ( bson_append_estart( b, BSON_OBJECT, name, bson_size( bson ) ) == BSON_ERROR )
872         return BSON_ERROR;
873     bson_append( b , bson->data , bson_size( bson ) );
874     return BSON_OK;
875 }
876 
bson_append_element(bson * b,const char * name_or_null,const bson_iterator * elem)877 int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem ) {
878     bson_iterator next = *elem;
879     int size;
880 
881     bson_iterator_next( &next );
882     size = next.cur - elem->cur;
883 
884     if ( name_or_null == NULL ) {
885         if( bson_ensure_space( b, size ) == BSON_ERROR )
886             return BSON_ERROR;
887         bson_append( b, elem->cur, size );
888     } else {
889         int data_size = size - 2 - strlen( bson_iterator_key( elem ) );
890         bson_append_estart( b, elem->cur[0], name_or_null, data_size );
891         bson_append( b, bson_iterator_value( elem ), data_size );
892     }
893 
894     return BSON_OK;
895 }
896 
bson_append_timestamp(bson * b,const char * name,bson_timestamp_t * ts)897 int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts ) {
898     if ( bson_append_estart( b, BSON_TIMESTAMP, name, 8 ) == BSON_ERROR ) return BSON_ERROR;
899 
900     bson_append32( b , &( ts->i ) );
901     bson_append32( b , &( ts->t ) );
902 
903     return BSON_OK;
904 }
905 
bson_append_timestamp2(bson * b,const char * name,int time,int increment)906 MONGO_EXPORT int bson_append_timestamp2( bson *b, const char *name, int time, int increment ) {
907     if ( bson_append_estart( b, BSON_TIMESTAMP, name, 8 ) == BSON_ERROR ) return BSON_ERROR;
908 
909     bson_append32( b , &increment );
910     bson_append32( b , &time );
911     return BSON_OK;
912 }
913 
bson_append_date(bson * b,const char * name,bson_date_t millis)914 MONGO_EXPORT int bson_append_date( bson *b, const char *name, bson_date_t millis ) {
915     if ( bson_append_estart( b, BSON_DATE, name, 8 ) == BSON_ERROR ) return BSON_ERROR;
916     bson_append64( b , &millis );
917     return BSON_OK;
918 }
919 
bson_append_time_t(bson * b,const char * name,time_t secs)920 int bson_append_time_t( bson *b, const char *name, time_t secs ) {
921     return bson_append_date( b, name, ( bson_date_t )secs * 1000 );
922 }
923 
bson_append_start_object(bson * b,const char * name)924 MONGO_EXPORT int bson_append_start_object( bson *b, const char *name ) {
925     if ( bson_append_estart( b, BSON_OBJECT, name, 5 ) == BSON_ERROR ) return BSON_ERROR;
926     b->stack[ b->stackPos++ ] = b->cur - b->data;
927     bson_append32( b , &zero );
928     return BSON_OK;
929 }
930 
bson_append_start_array(bson * b,const char * name)931 MONGO_EXPORT int bson_append_start_array( bson *b, const char *name ) {
932     if ( bson_append_estart( b, BSON_ARRAY, name, 5 ) == BSON_ERROR ) return BSON_ERROR;
933     b->stack[ b->stackPos++ ] = b->cur - b->data;
934     bson_append32( b , &zero );
935     return BSON_OK;
936 }
937 
bson_append_finish_object(bson * b)938 MONGO_EXPORT int bson_append_finish_object( bson *b ) {
939     char *start;
940     int i;
941     if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR;
942     bson_append_byte( b , 0 );
943 
944     start = b->data + b->stack[ --b->stackPos ];
945     i = b->cur - start;
946     bson_little_endian32( start, &i );
947 
948     return BSON_OK;
949 }
950 
bson_int64_to_double(int64_t i64)951 MONGO_EXPORT double bson_int64_to_double( int64_t i64 ) {
952   return (double)i64;
953 }
954 
bson_append_finish_array(bson * b)955 int bson_append_finish_array( bson *b ) {
956     return bson_append_finish_object( b );
957 }
958 
959 /* Error handling and allocators. */
960 
961 static bson_err_handler err_handler = NULL;
962 
set_bson_err_handler(bson_err_handler func)963 MONGO_EXPORT bson_err_handler set_bson_err_handler( bson_err_handler func ) {
964     bson_err_handler old = err_handler;
965     err_handler = func;
966     return old;
967 }
968 
bson_malloc(int size)969 void *bson_malloc( int size ) {
970     void *p;
971     p = bson_malloc_func( size );
972     bson_fatal_msg( !!p, "malloc() failed" );
973     return p;
974 }
975 
bson_realloc(void * ptr,int size)976 void *bson_realloc( void *ptr, int size ) {
977     void *p;
978     p = bson_realloc_func( ptr, size );
979     bson_fatal_msg( !!p, "realloc() failed" );
980     return p;
981 }
982 
_bson_errprintf(const char * format,...)983 int _bson_errprintf( const char *format, ... ) {
984     va_list ap;
985     int ret;
986     va_start( ap, format );
987 #ifndef R_SAFETY_NET
988     ret = vfprintf( stderr, format, ap );
989 #endif
990     va_end( ap );
991 
992     return ret;
993 }
994 
995 /**
996  * This method is invoked when a non-fatal bson error is encountered.
997  * Calls the error handler if available.
998  *
999  *  @param
1000  */
bson_builder_error(bson * b)1001 void bson_builder_error( bson *b ) {
1002     if( err_handler )
1003         err_handler( "BSON error." );
1004 }
1005 
bson_fatal(int ok)1006 void bson_fatal( int ok ) {
1007     bson_fatal_msg( ok, "" );
1008 }
1009 
bson_fatal_msg(int ok,const char * msg)1010 void bson_fatal_msg( int ok , const char *msg ) {
1011     if ( ok )
1012         return;
1013 
1014     if ( err_handler ) {
1015         err_handler( msg );
1016     }
1017 #ifndef R_SAFETY_NET
1018     bson_errprintf( "error: %s\n" , msg );
1019     exit( -5 );
1020 #endif
1021 }
1022 
1023 
1024 /* Efficiently copy an integer to a string. */
1025 extern const char bson_numstrs[1000][4];
1026 
bson_numstr(char * str,int i)1027 void bson_numstr( char *str, int i ) {
1028     if( i < 1000 )
1029         memcpy( str, bson_numstrs[i], 4 );
1030     else
1031         bson_sprintf( str,"%d", i );
1032 }
1033