bson_ext 1.5.0 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
data/ext/cbson/version.h CHANGED
@@ -14,4 +14,4 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- #define VERSION "1.5.0"
17
+ #define VERSION "1.5.1"
@@ -0,0 +1,699 @@
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 "bson.h"
19
+ #include <stdlib.h>
20
+ #include <string.h>
21
+ #include <stdio.h>
22
+ #include <time.h>
23
+
24
+ const int initialBufferSize = 128;
25
+
26
+ /* only need one of these */
27
+ static const int zero = 0;
28
+
29
+ /* ----------------------------
30
+ READING
31
+ ------------------------------ */
32
+
33
+ bson * bson_empty(bson * obj){
34
+ static char * data = "\005\0\0\0\0";
35
+ return bson_init(obj, data, 0);
36
+ }
37
+
38
+ void bson_copy(bson* out, const bson* in){
39
+ if (!out) return;
40
+ out->data = bson_malloc(bson_size(in));
41
+ out->owned = 1;
42
+ memcpy(out->data, in->data, bson_size(in));
43
+ }
44
+
45
+ bson * bson_from_buffer(bson * b, bson_buffer * buf){
46
+ return bson_init(b, bson_buffer_finish(buf), 1);
47
+ }
48
+
49
+ bson * bson_init( bson * b , char * data , bson_bool_t mine ){
50
+ b->data = data;
51
+ b->owned = mine;
52
+ return b;
53
+ }
54
+ int bson_size(const bson * b ){
55
+ int i;
56
+ if ( ! b || ! b->data )
57
+ return 0;
58
+ bson_little_endian32(&i, b->data);
59
+ return i;
60
+ }
61
+ void bson_destroy( bson * b ){
62
+ if ( b->owned && b->data )
63
+ free( b->data );
64
+ b->data = 0;
65
+ b->owned = 0;
66
+ }
67
+
68
+ static char hexbyte(char hex){
69
+ switch (hex){
70
+ case '0': return 0x0;
71
+ case '1': return 0x1;
72
+ case '2': return 0x2;
73
+ case '3': return 0x3;
74
+ case '4': return 0x4;
75
+ case '5': return 0x5;
76
+ case '6': return 0x6;
77
+ case '7': return 0x7;
78
+ case '8': return 0x8;
79
+ case '9': return 0x9;
80
+ case 'a':
81
+ case 'A': return 0xa;
82
+ case 'b':
83
+ case 'B': return 0xb;
84
+ case 'c':
85
+ case 'C': return 0xc;
86
+ case 'd':
87
+ case 'D': return 0xd;
88
+ case 'e':
89
+ case 'E': return 0xe;
90
+ case 'f':
91
+ case 'F': return 0xf;
92
+ default: return 0x0; /* something smarter? */
93
+ }
94
+ }
95
+
96
+ void bson_oid_from_string(bson_oid_t* oid, const char* str){
97
+ int i;
98
+ for (i=0; i<12; i++){
99
+ oid->bytes[i] = (hexbyte(str[2*i]) << 4) | hexbyte(str[2*i + 1]);
100
+ }
101
+ }
102
+ void bson_oid_to_string(const bson_oid_t* oid, char* str){
103
+ static const char hex[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
104
+ int i;
105
+ for (i=0; i<12; i++){
106
+ str[2*i] = hex[(oid->bytes[i] & 0xf0) >> 4];
107
+ str[2*i + 1] = hex[ oid->bytes[i] & 0x0f ];
108
+ }
109
+ str[24] = '\0';
110
+ }
111
+ void bson_oid_gen(bson_oid_t* oid){
112
+ static int incr = 0;
113
+ static int fuzz = 0;
114
+ int i = incr++; /*TODO make atomic*/
115
+ int t = time(NULL);
116
+
117
+ /* TODO rand sucks. find something better */
118
+ if (!fuzz){
119
+ srand(t);
120
+ fuzz = rand();
121
+ }
122
+
123
+ bson_big_endian32(&oid->ints[0], &t);
124
+ oid->ints[1] = fuzz;
125
+ bson_big_endian32(&oid->ints[2], &i);
126
+ }
127
+
128
+ time_t bson_oid_generated_time(bson_oid_t* oid){
129
+ time_t out;
130
+ bson_big_endian32(&out, &oid->ints[0]);
131
+ return out;
132
+
133
+ }
134
+ void bson_print( bson * b ){
135
+ bson_print_raw( b->data , 0 );
136
+ }
137
+
138
+ void bson_print_raw( const char * data , int depth ){
139
+ bson_iterator i;
140
+ const char * key;
141
+ int temp;
142
+ bson_timestamp_t ts;
143
+ char oidhex[25];
144
+ bson_iterator_init( &i , data );
145
+
146
+ while ( bson_iterator_next( &i ) ){
147
+ bson_type t = bson_iterator_type( &i );
148
+ if ( t == 0 )
149
+ break;
150
+ key = bson_iterator_key( &i );
151
+
152
+ for ( temp=0; temp<=depth; temp++ )
153
+ printf( "\t" );
154
+ printf( "%s : %d \t " , key , t );
155
+ switch ( t ){
156
+ case bson_int: printf( "%d" , bson_iterator_int( &i ) ); break;
157
+ case bson_double: printf( "%f" , bson_iterator_double( &i ) ); break;
158
+ case bson_bool: printf( "%s" , bson_iterator_bool( &i ) ? "true" : "false" ); break;
159
+ case bson_string: printf( "%s" , bson_iterator_string( &i ) ); break;
160
+ case bson_null: printf( "null" ); break;
161
+ case bson_oid: bson_oid_to_string(bson_iterator_oid(&i), oidhex); printf( "%s" , oidhex ); break;
162
+ case bson_timestamp:
163
+ ts = bson_iterator_timestamp( &i );
164
+ printf("i: %d, t: %d", ts.i, ts.t);
165
+ break;
166
+ case bson_object:
167
+ case bson_array:
168
+ printf( "\n" );
169
+ bson_print_raw( bson_iterator_value( &i ) , depth + 1 );
170
+ break;
171
+ default:
172
+ fprintf( stderr , "can't print type : %d\n" , t );
173
+ }
174
+ printf( "\n" );
175
+ }
176
+ }
177
+
178
+ /* ----------------------------
179
+ ITERATOR
180
+ ------------------------------ */
181
+
182
+ void bson_iterator_init( bson_iterator * i , const char * bson ){
183
+ i->cur = bson + 4;
184
+ i->first = 1;
185
+ }
186
+
187
+ bson_type bson_find(bson_iterator* it, const bson* obj, const char* name){
188
+ bson_iterator_init(it, obj->data);
189
+ while(bson_iterator_next(it)){
190
+ if (strcmp(name, bson_iterator_key(it)) == 0)
191
+ break;
192
+ }
193
+ return bson_iterator_type(it);
194
+ }
195
+
196
+ bson_bool_t bson_iterator_more( const bson_iterator * i ){
197
+ return *(i->cur);
198
+ }
199
+
200
+ bson_type bson_iterator_next( bson_iterator * i ){
201
+ int ds;
202
+
203
+ if ( i->first ){
204
+ i->first = 0;
205
+ return (bson_type)(*i->cur);
206
+ }
207
+
208
+ switch ( bson_iterator_type(i) ){
209
+ case bson_eoo: return bson_eoo; /* don't advance */
210
+ case bson_undefined:
211
+ case bson_null: ds = 0; break;
212
+ case bson_bool: ds = 1; break;
213
+ case bson_int: ds = 4; break;
214
+ case bson_long:
215
+ case bson_double:
216
+ case bson_timestamp:
217
+ case bson_date: ds = 8; break;
218
+ case bson_oid: ds = 12; break;
219
+ case bson_string:
220
+ case bson_symbol:
221
+ case bson_code: ds = 4 + bson_iterator_int_raw(i); break;
222
+ case bson_bindata: ds = 5 + bson_iterator_int_raw(i); break;
223
+ case bson_object:
224
+ case bson_array:
225
+ case bson_codewscope: ds = bson_iterator_int_raw(i); break;
226
+ case bson_dbref: ds = 4+12 + bson_iterator_int_raw(i); break;
227
+ case bson_regex:
228
+ {
229
+ const char * s = bson_iterator_value(i);
230
+ const char * p = s;
231
+ p += strlen(p)+1;
232
+ p += strlen(p)+1;
233
+ ds = p-s;
234
+ break;
235
+ }
236
+
237
+ default:
238
+ {
239
+ char msg[] = "unknown type: 000000000000";
240
+ bson_numstr(msg+14, (unsigned)(i->cur[0]));
241
+ bson_fatal_msg(0, msg);
242
+ return 0;
243
+ }
244
+ }
245
+
246
+ i->cur += 1 + strlen( i->cur + 1 ) + 1 + ds;
247
+
248
+ return (bson_type)(*i->cur);
249
+ }
250
+
251
+ bson_type bson_iterator_type( const bson_iterator * i ){
252
+ return (bson_type)i->cur[0];
253
+ }
254
+ const char * bson_iterator_key( const bson_iterator * i ){
255
+ return i->cur + 1;
256
+ }
257
+ const char * bson_iterator_value( const bson_iterator * i ){
258
+ const char * t = i->cur + 1;
259
+ t += strlen( t ) + 1;
260
+ return t;
261
+ }
262
+
263
+ /* types */
264
+
265
+ int bson_iterator_int_raw( const bson_iterator * i ){
266
+ int out;
267
+ bson_little_endian32(&out, bson_iterator_value( i ));
268
+ return out;
269
+ }
270
+ double bson_iterator_double_raw( const bson_iterator * i ){
271
+ double out;
272
+ bson_little_endian64(&out, bson_iterator_value( i ));
273
+ return out;
274
+ }
275
+ int64_t bson_iterator_long_raw( const bson_iterator * i ){
276
+ int64_t out;
277
+ bson_little_endian64(&out, bson_iterator_value( i ));
278
+ return out;
279
+ }
280
+
281
+ bson_bool_t bson_iterator_bool_raw( const bson_iterator * i ){
282
+ return bson_iterator_value( i )[0];
283
+ }
284
+
285
+ bson_oid_t * bson_iterator_oid( const bson_iterator * i ){
286
+ return (bson_oid_t*)bson_iterator_value(i);
287
+ }
288
+
289
+ int bson_iterator_int( const bson_iterator * i ){
290
+ switch (bson_iterator_type(i)){
291
+ case bson_int: return bson_iterator_int_raw(i);
292
+ case bson_long: return bson_iterator_long_raw(i);
293
+ case bson_double: return bson_iterator_double_raw(i);
294
+ default: return 0;
295
+ }
296
+ }
297
+ double bson_iterator_double( const bson_iterator * i ){
298
+ switch (bson_iterator_type(i)){
299
+ case bson_int: return bson_iterator_int_raw(i);
300
+ case bson_long: return bson_iterator_long_raw(i);
301
+ case bson_double: return bson_iterator_double_raw(i);
302
+ default: return 0;
303
+ }
304
+ }
305
+ int64_t bson_iterator_long( const bson_iterator * i ){
306
+ switch (bson_iterator_type(i)){
307
+ case bson_int: return bson_iterator_int_raw(i);
308
+ case bson_long: return bson_iterator_long_raw(i);
309
+ case bson_double: return bson_iterator_double_raw(i);
310
+ default: return 0;
311
+ }
312
+ }
313
+
314
+ bson_timestamp_t bson_iterator_timestamp( const bson_iterator * i){
315
+ bson_timestamp_t ts;
316
+ bson_little_endian32(&(ts.i), bson_iterator_value(i));
317
+ bson_little_endian32(&(ts.t), bson_iterator_value(i) + 4);
318
+ return ts;
319
+ }
320
+
321
+ bson_bool_t bson_iterator_bool( const bson_iterator * i ){
322
+ switch (bson_iterator_type(i)){
323
+ case bson_bool: return bson_iterator_bool_raw(i);
324
+ case bson_int: return bson_iterator_int_raw(i) != 0;
325
+ case bson_long: return bson_iterator_long_raw(i) != 0;
326
+ case bson_double: return bson_iterator_double_raw(i) != 0;
327
+ case bson_eoo:
328
+ case bson_null: return 0;
329
+ default: return 1;
330
+ }
331
+ }
332
+
333
+ const char * bson_iterator_string( const bson_iterator * i ){
334
+ return bson_iterator_value( i ) + 4;
335
+ }
336
+ int bson_iterator_string_len( const bson_iterator * i ){
337
+ return bson_iterator_int_raw( i );
338
+ }
339
+
340
+ const char * bson_iterator_code( const bson_iterator * i ){
341
+ switch (bson_iterator_type(i)){
342
+ case bson_string:
343
+ case bson_code: return bson_iterator_value(i) + 4;
344
+ case bson_codewscope: return bson_iterator_value(i) + 8;
345
+ default: return NULL;
346
+ }
347
+ }
348
+
349
+ void bson_iterator_code_scope(const bson_iterator * i, bson * scope){
350
+ if (bson_iterator_type(i) == bson_codewscope){
351
+ int code_len;
352
+ bson_little_endian32(&code_len, bson_iterator_value(i)+4);
353
+ bson_init(scope, (void*)(bson_iterator_value(i)+8+code_len), 0);
354
+ }else{
355
+ bson_empty(scope);
356
+ }
357
+ }
358
+
359
+ bson_date_t bson_iterator_date(const bson_iterator * i){
360
+ return bson_iterator_long_raw(i);
361
+ }
362
+
363
+ time_t bson_iterator_time_t(const bson_iterator * i){
364
+ return bson_iterator_date(i) / 1000;
365
+ }
366
+
367
+ int bson_iterator_bin_len( const bson_iterator * i ){
368
+ return (bson_iterator_bin_type(i) == 2)
369
+ ? bson_iterator_int_raw( i ) - 4
370
+ : bson_iterator_int_raw( i );
371
+ }
372
+
373
+ char bson_iterator_bin_type( const bson_iterator * i ){
374
+ return bson_iterator_value(i)[4];
375
+ }
376
+ const char * bson_iterator_bin_data( const bson_iterator * i ){
377
+ return (bson_iterator_bin_type( i ) == 2)
378
+ ? bson_iterator_value( i ) + 9
379
+ : bson_iterator_value( i ) + 5;
380
+ }
381
+
382
+ const char * bson_iterator_regex( const bson_iterator * i ){
383
+ return bson_iterator_value( i );
384
+ }
385
+ const char * bson_iterator_regex_opts( const bson_iterator * i ){
386
+ const char* p = bson_iterator_value( i );
387
+ return p + strlen(p) + 1;
388
+
389
+ }
390
+
391
+ void bson_iterator_subobject(const bson_iterator * i, bson * sub){
392
+ bson_init(sub, (char*)bson_iterator_value(i), 0);
393
+ }
394
+ void bson_iterator_subiterator(const bson_iterator * i, bson_iterator * sub){
395
+ bson_iterator_init(sub, bson_iterator_value(i));
396
+ }
397
+
398
+ /* ----------------------------
399
+ BUILDING
400
+ ------------------------------ */
401
+
402
+ bson_buffer * bson_buffer_init( bson_buffer * b ){
403
+ b->buf = (char*)bson_malloc( initialBufferSize );
404
+ b->bufSize = initialBufferSize;
405
+ b->cur = b->buf + 4;
406
+ b->finished = 0;
407
+ b->stackPos = 0;
408
+ return b;
409
+ }
410
+
411
+ void bson_append_byte( bson_buffer * b , char c ){
412
+ b->cur[0] = c;
413
+ b->cur++;
414
+ }
415
+ void bson_append( bson_buffer * b , const void * data , int len ){
416
+ memcpy( b->cur , data , len );
417
+ b->cur += len;
418
+ }
419
+ void bson_append32(bson_buffer * b, const void * data){
420
+ bson_little_endian32(b->cur, data);
421
+ b->cur += 4;
422
+ }
423
+ void bson_append64(bson_buffer * b, const void * data){
424
+ bson_little_endian64(b->cur, data);
425
+ b->cur += 8;
426
+ }
427
+
428
+ bson_buffer * bson_ensure_space( bson_buffer * b , const int bytesNeeded ){
429
+ int pos = b->cur - b->buf;
430
+ char * orig = b->buf;
431
+ int new_size;
432
+
433
+ if (b->finished)
434
+ bson_fatal_msg(!!b->buf, "trying to append to finished buffer");
435
+
436
+ if (pos + bytesNeeded <= b->bufSize)
437
+ return b;
438
+
439
+ new_size = 1.5 * (b->bufSize + bytesNeeded);
440
+ b->buf = realloc(b->buf, new_size);
441
+ if (!b->buf)
442
+ bson_fatal_msg(!!b->buf, "realloc() failed");
443
+
444
+ b->bufSize = new_size;
445
+ b->cur += b->buf - orig;
446
+
447
+ return b;
448
+ }
449
+
450
+ char * bson_buffer_finish( bson_buffer * b ){
451
+ int i;
452
+ if ( ! b->finished ){
453
+ if ( ! bson_ensure_space( b , 1 ) ) return 0;
454
+ bson_append_byte( b , 0 );
455
+ i = b->cur - b->buf;
456
+ bson_little_endian32(b->buf, &i);
457
+ b->finished = 1;
458
+ }
459
+ return b->buf;
460
+ }
461
+
462
+ void bson_buffer_destroy( bson_buffer * b ){
463
+ free( b->buf );
464
+ b->buf = 0;
465
+ b->cur = 0;
466
+ b->finished = 1;
467
+ }
468
+
469
+ static bson_buffer * bson_append_estart( bson_buffer * b , int type , const char * name , const int dataSize ){
470
+ const int sl = strlen(name) + 1;
471
+ if ( ! bson_ensure_space( b , 1 + sl + dataSize ) )
472
+ return 0;
473
+ bson_append_byte( b , (char)type );
474
+ bson_append( b , name , sl );
475
+ return b;
476
+ }
477
+
478
+ /* ----------------------------
479
+ BUILDING TYPES
480
+ ------------------------------ */
481
+
482
+ bson_buffer * bson_append_int( bson_buffer * b , const char * name , const int i ){
483
+ if ( ! bson_append_estart( b , bson_int , name , 4 ) ) return 0;
484
+ bson_append32( b , &i );
485
+ return b;
486
+ }
487
+ bson_buffer * bson_append_long( bson_buffer * b , const char * name , const int64_t i ){
488
+ if ( ! bson_append_estart( b , bson_long , name , 8 ) ) return 0;
489
+ bson_append64( b , &i );
490
+ return b;
491
+ }
492
+ bson_buffer * bson_append_double( bson_buffer * b , const char * name , const double d ){
493
+ if ( ! bson_append_estart( b , bson_double , name , 8 ) ) return 0;
494
+ bson_append64( b , &d );
495
+ return b;
496
+ }
497
+ bson_buffer * bson_append_bool( bson_buffer * b , const char * name , const bson_bool_t i ){
498
+ if ( ! bson_append_estart( b , bson_bool , name , 1 ) ) return 0;
499
+ bson_append_byte( b , i != 0 );
500
+ return b;
501
+ }
502
+ bson_buffer * bson_append_null( bson_buffer * b , const char * name ){
503
+ if ( ! bson_append_estart( b , bson_null , name , 0 ) ) return 0;
504
+ return b;
505
+ }
506
+ bson_buffer * bson_append_undefined( bson_buffer * b , const char * name ){
507
+ if ( ! bson_append_estart( b , bson_undefined , name , 0 ) ) return 0;
508
+ return b;
509
+ }
510
+ bson_buffer * bson_append_string_base( bson_buffer * b , const char * name , const char * value , int len , bson_type type){
511
+ int sl = len + 1;
512
+ if ( ! bson_append_estart( b , type , name , 4 + sl ) ) return 0;
513
+ bson_append32( b , &sl);
514
+ bson_append( b , value , sl - 1 );
515
+ bson_append( b , "\0" , 1 );
516
+ return b;
517
+ }
518
+ bson_buffer * bson_append_string( bson_buffer * b , const char * name , const char * value ){
519
+ return bson_append_string_base(b, name, value, strlen ( value ), bson_string);
520
+ }
521
+ bson_buffer * bson_append_symbol( bson_buffer * b , const char * name , const char * value ){
522
+ return bson_append_string_base(b, name, value, strlen ( value ), bson_symbol);
523
+ }
524
+ bson_buffer * bson_append_code( bson_buffer * b , const char * name , const char * value ){
525
+ return bson_append_string_base(b, name, value, strlen ( value ), bson_code);
526
+ }
527
+ bson_buffer * bson_append_string_n( bson_buffer * b , const char * name , const char * value , int len ){
528
+ return bson_append_string_base(b, name, value, len, bson_string);
529
+ }
530
+ bson_buffer * bson_append_symbol_n( bson_buffer * b , const char * name , const char * value , int len ){
531
+ return bson_append_string_base(b, name, value, len, bson_symbol);
532
+ }
533
+ bson_buffer * bson_append_code_n( bson_buffer * b , const char * name , const char * value , int len ){
534
+ return bson_append_string_base(b, name, value, len, bson_code);
535
+ }
536
+ bson_buffer * bson_append_code_w_scope_n( bson_buffer * b , const char * name , const char * code , int len , const bson * scope){
537
+ int sl = len + 1;
538
+ int size = 4 + 4 + sl + bson_size(scope);
539
+ if (!bson_append_estart(b, bson_codewscope, name, size)) return 0;
540
+ bson_append32(b, &size);
541
+ bson_append32(b, &sl);
542
+ bson_append(b, code, sl);
543
+ bson_append(b, scope->data, bson_size(scope));
544
+ return b;
545
+ }
546
+ bson_buffer * bson_append_code_w_scope( bson_buffer * b , const char * name , const char * code , const bson * scope){
547
+ return bson_append_code_w_scope_n( b, name, code, strlen ( code ), scope );
548
+ }
549
+
550
+ bson_buffer * bson_append_binary( bson_buffer * b, const char * name, char type, const char * str, int len ){
551
+ if ( type == 2 ){
552
+ int subtwolen = len + 4;
553
+ if ( ! bson_append_estart( b , bson_bindata , name , 4+1+4+len ) ) return 0;
554
+ bson_append32(b, &subtwolen);
555
+ bson_append_byte(b, type);
556
+ bson_append32(b, &len);
557
+ bson_append(b, str, len);
558
+ }else{
559
+ if ( ! bson_append_estart( b , bson_bindata , name , 4+1+len ) ) return 0;
560
+ bson_append32(b, &len);
561
+ bson_append_byte(b, type);
562
+ bson_append(b, str, len);
563
+ }
564
+ return b;
565
+ }
566
+ bson_buffer * bson_append_oid( bson_buffer * b , const char * name , const bson_oid_t * oid ){
567
+ if ( ! bson_append_estart( b , bson_oid , name , 12 ) ) return 0;
568
+ bson_append( b , oid , 12 );
569
+ return b;
570
+ }
571
+ bson_buffer * bson_append_new_oid( bson_buffer * b , const char * name ){
572
+ bson_oid_t oid;
573
+ bson_oid_gen(&oid);
574
+ return bson_append_oid(b, name, &oid);
575
+ }
576
+
577
+ bson_buffer * bson_append_regex( bson_buffer * b , const char * name , const char * pattern, const char * opts ){
578
+ const int plen = strlen(pattern)+1;
579
+ const int olen = strlen(opts)+1;
580
+ if ( ! bson_append_estart( b , bson_regex , name , plen + olen ) ) return 0;
581
+ bson_append( b , pattern , plen );
582
+ bson_append( b , opts , olen );
583
+ return b;
584
+ }
585
+
586
+ bson_buffer * bson_append_bson( bson_buffer * b , const char * name , const bson* bson){
587
+ if ( ! bson_append_estart( b , bson_object , name , bson_size(bson) ) ) return 0;
588
+ bson_append( b , bson->data , bson_size(bson) );
589
+ return b;
590
+ }
591
+
592
+ bson_buffer * bson_append_element( bson_buffer * b, const char * name_or_null, const bson_iterator* elem){
593
+ bson_iterator next = *elem;
594
+ int size;
595
+
596
+ bson_iterator_next(&next);
597
+ size = next.cur - elem->cur;
598
+
599
+ if (name_or_null == NULL){
600
+ bson_ensure_space(b, size);
601
+ bson_append(b, elem->cur, size);
602
+ }else{
603
+ int data_size = size - 2 - strlen(bson_iterator_key(elem));
604
+ bson_append_estart(b, elem->cur[0], name_or_null, data_size);
605
+ bson_append(b, bson_iterator_value(elem), data_size);
606
+ }
607
+
608
+ return b;
609
+ }
610
+
611
+ bson_buffer * bson_append_timestamp( bson_buffer * b, const char * name, bson_timestamp_t * ts ){
612
+ if ( ! bson_append_estart( b , bson_timestamp , name , 8 ) ) return 0;
613
+
614
+ bson_append32( b , &(ts->i) );
615
+ bson_append32( b , &(ts->t) );
616
+
617
+ return b;
618
+ }
619
+
620
+ bson_buffer * bson_append_date( bson_buffer * b , const char * name , bson_date_t millis ){
621
+ if ( ! bson_append_estart( b , bson_date , name , 8 ) ) return 0;
622
+ bson_append64( b , &millis );
623
+ return b;
624
+ }
625
+
626
+ bson_buffer * bson_append_time_t( bson_buffer * b , const char * name , time_t secs){
627
+ return bson_append_date(b, name, (bson_date_t)secs * 1000);
628
+ }
629
+
630
+ bson_buffer * bson_append_start_object( bson_buffer * b , const char * name ){
631
+ if ( ! bson_append_estart( b , bson_object , name , 5 ) ) return 0;
632
+ b->stack[ b->stackPos++ ] = b->cur - b->buf;
633
+ bson_append32( b , &zero );
634
+ return b;
635
+ }
636
+
637
+ bson_buffer * bson_append_start_array( bson_buffer * b , const char * name ){
638
+ if ( ! bson_append_estart( b , bson_array , name , 5 ) ) return 0;
639
+ b->stack[ b->stackPos++ ] = b->cur - b->buf;
640
+ bson_append32( b , &zero );
641
+ return b;
642
+ }
643
+
644
+ bson_buffer * bson_append_finish_object( bson_buffer * b ){
645
+ char * start;
646
+ int i;
647
+ if ( ! bson_ensure_space( b , 1 ) ) return 0;
648
+ bson_append_byte( b , 0 );
649
+
650
+ start = b->buf + b->stack[ --b->stackPos ];
651
+ i = b->cur - start;
652
+ bson_little_endian32(start, &i);
653
+
654
+ return b;
655
+ }
656
+
657
+ void* bson_malloc(int size){
658
+ void* p = malloc(size);
659
+ bson_fatal_msg(!!p, "malloc() failed");
660
+ return p;
661
+ }
662
+
663
+ void* bson_realloc(void* ptr, int size){
664
+ void* p = realloc(ptr, size);
665
+ bson_fatal_msg(!!p, "realloc() failed");
666
+ return p;
667
+ }
668
+
669
+ static bson_err_handler err_handler = NULL;
670
+
671
+ bson_err_handler set_bson_err_handler(bson_err_handler func){
672
+ bson_err_handler old = err_handler;
673
+ err_handler = func;
674
+ return old;
675
+ }
676
+
677
+ void bson_fatal( int ok ){
678
+ bson_fatal_msg(ok, "");
679
+ }
680
+
681
+ void bson_fatal_msg( int ok , const char* msg){
682
+ if (ok)
683
+ return;
684
+
685
+ if (err_handler){
686
+ err_handler(msg);
687
+ }
688
+
689
+ fprintf( stderr , "error: %s\n" , msg );
690
+ exit(-5);
691
+ }
692
+
693
+ extern const char bson_numstrs[1000][4];
694
+ void bson_numstr(char* str, int i){
695
+ if(i < 1000)
696
+ memcpy(str, bson_numstrs[i], 4);
697
+ else
698
+ sprintf(str,"%d", i);
699
+ }