faststep 0.0.8.1 → 0.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
data/ext/faststep/bson.c CHANGED
@@ -15,12 +15,14 @@
15
15
  * limitations under the License.
16
16
  */
17
17
 
18
- #include "bson.h"
19
18
  #include <stdlib.h>
20
19
  #include <string.h>
21
20
  #include <stdio.h>
22
21
  #include <time.h>
23
22
 
23
+ #include "bson.h"
24
+ #include "encoding.h"
25
+
24
26
  const int initialBufferSize = 128;
25
27
 
26
28
  /* only need one of these */
@@ -32,7 +34,8 @@ static const int zero = 0;
32
34
 
33
35
  bson * bson_empty(bson * obj){
34
36
  static char * data = "\005\0\0\0\0";
35
- return bson_init(obj, data, 0);
37
+ bson_init(obj, data, 0);
38
+ return obj;
36
39
  }
37
40
 
38
41
  void bson_copy(bson* out, const bson* in){
@@ -42,15 +45,18 @@ void bson_copy(bson* out, const bson* in){
42
45
  memcpy(out->data, in->data, bson_size(in));
43
46
  }
44
47
 
45
- bson * bson_from_buffer(bson * b, bson_buffer * buf){
46
- return bson_init(b, bson_buffer_finish(buf), 1);
48
+ int bson_from_buffer(bson * b, bson_buffer * buf){
49
+ b->err = buf->err;
50
+ bson_buffer_finish(buf);
51
+ return bson_init(b, buf->buf, 1);
47
52
  }
48
53
 
49
- bson * bson_init( bson * b , char * data , bson_bool_t mine ){
54
+ int bson_init( bson * b, char * data, bson_bool_t mine ){
50
55
  b->data = data;
51
56
  b->owned = mine;
52
- return b;
57
+ return BSON_OK;
53
58
  }
59
+
54
60
  int bson_size(const bson * b ){
55
61
  int i;
56
62
  if ( ! b || ! b->data )
@@ -58,6 +64,7 @@ int bson_size(const bson * b ){
58
64
  bson_little_endian32(&i, b->data);
59
65
  return i;
60
66
  }
67
+
61
68
  void bson_destroy( bson * b ){
62
69
  if ( b->owned && b->data )
63
70
  free( b->data );
@@ -204,7 +211,7 @@ bson_type bson_iterator_next( bson_iterator * i ){
204
211
  i->first = 0;
205
212
  return (bson_type)(*i->cur);
206
213
  }
207
-
214
+
208
215
  switch ( bson_iterator_type(i) ){
209
216
  case bson_eoo: return bson_eoo; /* don't advance */
210
217
  case bson_undefined:
@@ -399,42 +406,49 @@ void bson_iterator_subiterator(const bson_iterator * i, bson_iterator * sub){
399
406
  BUILDING
400
407
  ------------------------------ */
401
408
 
402
- bson_buffer * bson_buffer_init( bson_buffer * b ){
409
+ int bson_buffer_init( bson_buffer * b ){
403
410
  b->buf = (char*)bson_malloc( initialBufferSize );
404
411
  b->bufSize = initialBufferSize;
405
412
  b->cur = b->buf + 4;
406
413
  b->finished = 0;
407
414
  b->stackPos = 0;
408
- return b;
415
+ b->err = 0;
416
+ b->errstr = NULL;
417
+ return 0;
409
418
  }
410
419
 
411
- void bson_append_byte( bson_buffer * b , char c ){
420
+ void bson_append_byte( bson_buffer * b, char c ){
412
421
  b->cur[0] = c;
413
422
  b->cur++;
414
423
  }
415
- void bson_append( bson_buffer * b , const void * data , int len ){
424
+
425
+ void bson_append( bson_buffer * b, const void * data, int len ){
416
426
  memcpy( b->cur , data , len );
417
427
  b->cur += len;
418
428
  }
429
+
419
430
  void bson_append32(bson_buffer * b, const void * data){
420
431
  bson_little_endian32(b->cur, data);
421
432
  b->cur += 4;
422
433
  }
434
+
423
435
  void bson_append64(bson_buffer * b, const void * data){
424
436
  bson_little_endian64(b->cur, data);
425
437
  b->cur += 8;
426
438
  }
427
439
 
428
- bson_buffer * bson_ensure_space( bson_buffer * b , const int bytesNeeded ){
440
+ int bson_ensure_space( bson_buffer * b, const int bytesNeeded ){
429
441
  int pos = b->cur - b->buf;
430
442
  char * orig = b->buf;
431
443
  int new_size;
432
444
 
433
- if (b->finished)
434
- bson_fatal_msg(!!b->buf, "trying to append to finished buffer");
445
+ if (b->finished) {
446
+ b->err = BSON_OBJECT_FINISHED;
447
+ return BSON_ERROR;
448
+ }
435
449
 
436
450
  if (pos + bytesNeeded <= b->bufSize)
437
- return b;
451
+ return BSON_OK;
438
452
 
439
453
  new_size = 1.5 * (b->bufSize + bytesNeeded);
440
454
  b->buf = realloc(b->buf, new_size);
@@ -444,140 +458,206 @@ bson_buffer * bson_ensure_space( bson_buffer * b , const int bytesNeeded ){
444
458
  b->bufSize = new_size;
445
459
  b->cur += b->buf - orig;
446
460
 
447
- return b;
461
+ return BSON_OK;
448
462
  }
449
463
 
450
- char * bson_buffer_finish( bson_buffer * b ){
464
+ /**
465
+ * Add null byte, mark as finished, and return buffer.
466
+ * Note that the buffer will now be owned by the bson
467
+ * object created from a call to bson_from_buffer.
468
+ * This buffer is then deallocated by calling
469
+ * bson_destroy().
470
+ */
471
+ int bson_buffer_finish( bson_buffer * b ){
451
472
  int i;
452
473
  if ( ! b->finished ){
453
- if ( ! bson_ensure_space( b , 1 ) ) return 0;
454
- bson_append_byte( b , 0 );
474
+ if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR;
475
+ bson_append_byte( b, 0 );
455
476
  i = b->cur - b->buf;
456
477
  bson_little_endian32(b->buf, &i);
457
478
  b->finished = 1;
458
479
  }
459
- return b->buf;
480
+
481
+ return BSON_OK;
460
482
  }
461
483
 
462
484
  void bson_buffer_destroy( bson_buffer * b ){
463
485
  free( b->buf );
486
+ b->err = 0;
464
487
  b->buf = 0;
465
488
  b->cur = 0;
466
489
  b->finished = 1;
467
490
  }
468
491
 
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;
492
+ static int bson_append_estart( bson_buffer * b, int type, const char * name, const int dataSize ){
493
+ const int len = strlen(name) + 1;
494
+ if ( bson_ensure_space( b, 1 + len + dataSize ) == BSON_ERROR ) {
495
+ return BSON_ERROR;
496
+ }
497
+
498
+ if( bson_check_field_name( b, (unsigned char* )name, len - 1 ) == BSON_ERROR ) {
499
+ bson_builder_error( b );
500
+ return BSON_ERROR;
501
+ }
502
+
503
+ bson_append_byte( b, (char)type );
504
+ bson_append( b, name, len );
505
+ return BSON_OK;
476
506
  }
477
507
 
478
508
  /* ----------------------------
479
509
  BUILDING TYPES
480
510
  ------------------------------ */
481
511
 
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;
512
+ int bson_append_int( bson_buffer * b, const char * name, const int i ) {
513
+ if ( bson_append_estart( b, bson_int, name, 4 ) == BSON_ERROR )
514
+ return BSON_ERROR;
484
515
  bson_append32( b , &i );
485
- return b;
516
+ return BSON_OK;
486
517
  }
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;
518
+
519
+ int bson_append_long( bson_buffer * b, const char * name, const int64_t i ) {
520
+ if ( bson_append_estart( b , bson_long, name, 8 ) == BSON_ERROR )
521
+ return BSON_ERROR;
489
522
  bson_append64( b , &i );
490
- return b;
523
+ return BSON_OK;
491
524
  }
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;
525
+
526
+ int bson_append_double( bson_buffer * b, const char * name, const double d ) {
527
+ if ( bson_append_estart( b, bson_double, name, 8 ) == BSON_ERROR )
528
+ return BSON_ERROR;
494
529
  bson_append64( b , &d );
495
- return b;
530
+ return BSON_OK;
496
531
  }
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;
532
+
533
+ int bson_append_bool( bson_buffer * b, const char * name, const bson_bool_t i ) {
534
+ if ( bson_append_estart( b, bson_bool, name, 1 ) == BSON_ERROR )
535
+ return BSON_ERROR;
499
536
  bson_append_byte( b , i != 0 );
500
- return b;
537
+ return BSON_OK;
501
538
  }
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;
539
+
540
+ int bson_append_null( bson_buffer * b, const char * name ) {
541
+ if ( bson_append_estart( b , bson_null, name, 0 ) == BSON_ERROR )
542
+ return BSON_ERROR;
543
+ return BSON_OK;
505
544
  }
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;
545
+
546
+ int bson_append_undefined( bson_buffer * b, const char * name ) {
547
+ if ( bson_append_estart( b, bson_undefined, name, 0 ) == BSON_ERROR )
548
+ return BSON_ERROR;
549
+ return BSON_OK;
509
550
  }
510
- bson_buffer * bson_append_string_base( bson_buffer * b , const char * name , const char * value , bson_type type){
511
- int sl = strlen( value ) + 1;
512
- if ( ! bson_append_estart( b , type , name , 4 + sl ) ) return 0;
551
+
552
+ int bson_append_string_base( bson_buffer * b, const char * name,
553
+ const char * value, int len, bson_type type) {
554
+
555
+ int sl = len + 1;
556
+ if ( bson_append_estart( b, type, name, 4 + sl ) == BSON_ERROR ) {
557
+ return BSON_ERROR;
558
+ }
559
+ if ( bson_check_string( b, value, sl - 1 ) == BSON_ERROR )
560
+ return BSON_ERROR;
513
561
  bson_append32( b , &sl);
514
- bson_append( b , value , sl );
515
- return b;
562
+ bson_append( b , value , sl - 1 );
563
+ bson_append( b , "\0" , 1 );
564
+ return BSON_OK;
565
+ }
566
+
567
+ int bson_append_string( bson_buffer * b, const char * name, const char * value ) {
568
+ return bson_append_string_base(b, name, value, strlen ( value ), bson_string);
516
569
  }
517
- bson_buffer * bson_append_string( bson_buffer * b , const char * name , const char * value ){
518
- return bson_append_string_base(b, name, value, bson_string);
570
+
571
+ int bson_append_symbol( bson_buffer * b, const char * name, const char * value ) {
572
+ return bson_append_string_base(b, name, value, strlen ( value ), bson_symbol);
573
+ }
574
+
575
+ int bson_append_code( bson_buffer * b, const char * name, const char * value ) {
576
+ return bson_append_string_base(b, name, value, strlen ( value ), bson_code);
577
+ }
578
+
579
+ int bson_append_string_n( bson_buffer * b, const char * name, const char * value, int len ) {
580
+ return bson_append_string_base(b, name, value, len, bson_string);
519
581
  }
520
- bson_buffer * bson_append_symbol( bson_buffer * b , const char * name , const char * value ){
521
- return bson_append_string_base(b, name, value, bson_symbol);
582
+
583
+ int bson_append_symbol_n( bson_buffer * b, const char * name, const char * value, int len ) {
584
+ return bson_append_string_base(b, name, value, len, bson_symbol);
522
585
  }
523
- bson_buffer * bson_append_code( bson_buffer * b , const char * name , const char * value ){
524
- return bson_append_string_base(b, name, value, bson_code);
586
+
587
+ int bson_append_code_n( bson_buffer * b, const char * name, const char * value, int len ) {
588
+ return bson_append_string_base(b, name, value, len, bson_code);
525
589
  }
526
590
 
527
- bson_buffer * bson_append_code_w_scope( bson_buffer * b , const char * name , const char * code , const bson * scope){
528
- int sl = strlen(code) + 1;
591
+ int bson_append_code_w_scope_n( bson_buffer * b, const char * name,
592
+ const char * code, int len, const bson * scope) {
593
+
594
+ int sl = len + 1;
529
595
  int size = 4 + 4 + sl + bson_size(scope);
530
- if (!bson_append_estart(b, bson_codewscope, name, size)) return 0;
596
+ if ( bson_append_estart(b, bson_codewscope, name, size) == BSON_ERROR )
597
+ return BSON_ERROR;
531
598
  bson_append32(b, &size);
532
599
  bson_append32(b, &sl);
533
600
  bson_append(b, code, sl);
534
601
  bson_append(b, scope->data, bson_size(scope));
535
- return b;
602
+ return BSON_OK;
536
603
  }
537
604
 
538
- bson_buffer * bson_append_binary( bson_buffer * b, const char * name, char type, const char * str, int len ){
605
+ int bson_append_code_w_scope( bson_buffer * b, const char * name, const char * code, const bson * scope){
606
+ return bson_append_code_w_scope_n( b, name, code, strlen ( code ), scope );
607
+ }
608
+
609
+ int bson_append_binary( bson_buffer * b, const char * name, char type, const char * str, int len ){
539
610
  if ( type == 2 ){
540
611
  int subtwolen = len + 4;
541
- if ( ! bson_append_estart( b , bson_bindata , name , 4+1+4+len ) ) return 0;
542
- bson_append32(b, &subtwolen);
543
- bson_append_byte(b, type);
544
- bson_append32(b, &len);
545
- bson_append(b, str, len);
546
- }else{
547
- if ( ! bson_append_estart( b , bson_bindata , name , 4+1+len ) ) return 0;
548
- bson_append32(b, &len);
549
- bson_append_byte(b, type);
550
- bson_append(b, str, len);
612
+ if ( bson_append_estart( b, bson_bindata, name, 4+1+4+len ) == BSON_ERROR )
613
+ return BSON_ERROR;
614
+ bson_append32(b, &subtwolen);
615
+ bson_append_byte(b, type);
616
+ bson_append32(b, &len);
617
+ bson_append(b, str, len);
618
+ } else {
619
+ if ( bson_append_estart( b, bson_bindata, name, 4+1+len ) == BSON_ERROR )
620
+ return BSON_ERROR;
621
+ bson_append32(b, &len);
622
+ bson_append_byte(b, type);
623
+ bson_append(b, str, len);
551
624
  }
552
- return b;
625
+ return BSON_OK;
553
626
  }
554
- bson_buffer * bson_append_oid( bson_buffer * b , const char * name , const bson_oid_t * oid ){
555
- if ( ! bson_append_estart( b , bson_oid , name , 12 ) ) return 0;
627
+
628
+ int bson_append_oid( bson_buffer * b, const char * name, const bson_oid_t * oid ){
629
+ if ( bson_append_estart( b, bson_oid, name, 12 ) == BSON_ERROR )
630
+ return BSON_ERROR;
556
631
  bson_append( b , oid , 12 );
557
- return b;
632
+ return BSON_OK;
558
633
  }
559
- bson_buffer * bson_append_new_oid( bson_buffer * b , const char * name ){
634
+
635
+ int bson_append_new_oid( bson_buffer * b, const char * name ){
560
636
  bson_oid_t oid;
561
637
  bson_oid_gen(&oid);
562
638
  return bson_append_oid(b, name, &oid);
563
639
  }
564
640
 
565
- bson_buffer * bson_append_regex( bson_buffer * b , const char * name , const char * pattern, const char * opts ){
641
+ int bson_append_regex( bson_buffer * b, const char * name, const char * pattern, const char * opts ){
566
642
  const int plen = strlen(pattern)+1;
567
643
  const int olen = strlen(opts)+1;
568
- if ( ! bson_append_estart( b , bson_regex , name , plen + olen ) ) return 0;
644
+ if ( bson_append_estart( b, bson_regex, name, plen + olen ) == BSON_ERROR )
645
+ return BSON_ERROR;
646
+ if ( bson_check_string( b, pattern, plen - 1 ) == BSON_ERROR )
647
+ return BSON_ERROR;
569
648
  bson_append( b , pattern , plen );
570
649
  bson_append( b , opts , olen );
571
- return b;
650
+ return BSON_OK;
572
651
  }
573
652
 
574
- bson_buffer * bson_append_bson( bson_buffer * b , const char * name , const bson* bson){
575
- if ( ! bson_append_estart( b , bson_object , name , bson_size(bson) ) ) return 0;
653
+ int bson_append_bson( bson_buffer * b, const char * name, const bson* bson){
654
+ if ( bson_append_estart( b, bson_object, name, bson_size(bson) ) == BSON_ERROR )
655
+ return BSON_ERROR;
576
656
  bson_append( b , bson->data , bson_size(bson) );
577
- return b;
657
+ return BSON_OK;
578
658
  }
579
659
 
580
- bson_buffer * bson_append_element( bson_buffer * b, const char * name_or_null, const bson_iterator* elem){
660
+ int bson_append_element( bson_buffer * b, const char * name_or_null, const bson_iterator* elem){
581
661
  bson_iterator next = *elem;
582
662
  int size;
583
663
 
@@ -585,7 +665,8 @@ bson_buffer * bson_append_element( bson_buffer * b, const char * name_or_null, c
585
665
  size = next.cur - elem->cur;
586
666
 
587
667
  if (name_or_null == NULL){
588
- bson_ensure_space(b, size);
668
+ if( bson_ensure_space(b, size) == BSON_ERROR )
669
+ return BSON_ERROR;
589
670
  bson_append(b, elem->cur, size);
590
671
  }else{
591
672
  int data_size = size - 2 - strlen(bson_iterator_key(elem));
@@ -593,53 +674,53 @@ bson_buffer * bson_append_element( bson_buffer * b, const char * name_or_null, c
593
674
  bson_append(b, bson_iterator_value(elem), data_size);
594
675
  }
595
676
 
596
- return b;
677
+ return BSON_OK;
597
678
  }
598
679
 
599
- bson_buffer * bson_append_timestamp( bson_buffer * b, const char * name, bson_timestamp_t * ts ){
600
- if ( ! bson_append_estart( b , bson_timestamp , name , 8 ) ) return 0;
680
+ int bson_append_timestamp( bson_buffer * b, const char * name, bson_timestamp_t * ts ){
681
+ if ( bson_append_estart( b, bson_timestamp, name, 8 ) == BSON_ERROR ) return BSON_ERROR;
601
682
 
602
683
  bson_append32( b , &(ts->i) );
603
684
  bson_append32( b , &(ts->t) );
604
685
 
605
- return b;
686
+ return BSON_OK;
606
687
  }
607
688
 
608
- bson_buffer * bson_append_date( bson_buffer * b , const char * name , bson_date_t millis ){
609
- if ( ! bson_append_estart( b , bson_date , name , 8 ) ) return 0;
689
+ int bson_append_date( bson_buffer * b, const char * name, bson_date_t millis ) {
690
+ if ( bson_append_estart( b, bson_date, name, 8 ) == BSON_ERROR ) return BSON_ERROR;
610
691
  bson_append64( b , &millis );
611
- return b;
692
+ return BSON_OK;
612
693
  }
613
694
 
614
- bson_buffer * bson_append_time_t( bson_buffer * b , const char * name , time_t secs){
695
+ int bson_append_time_t( bson_buffer * b, const char * name, time_t secs) {
615
696
  return bson_append_date(b, name, (bson_date_t)secs * 1000);
616
697
  }
617
698
 
618
- bson_buffer * bson_append_start_object( bson_buffer * b , const char * name ){
619
- if ( ! bson_append_estart( b , bson_object , name , 5 ) ) return 0;
699
+ int bson_append_start_object( bson_buffer * b, const char * name ) {
700
+ if ( bson_append_estart( b, bson_object, name, 5 ) == BSON_ERROR ) return BSON_ERROR;
620
701
  b->stack[ b->stackPos++ ] = b->cur - b->buf;
621
702
  bson_append32( b , &zero );
622
- return b;
703
+ return BSON_OK;
623
704
  }
624
705
 
625
- bson_buffer * bson_append_start_array( bson_buffer * b , const char * name ){
626
- if ( ! bson_append_estart( b , bson_array , name , 5 ) ) return 0;
706
+ int bson_append_start_array( bson_buffer * b, const char * name ) {
707
+ if ( bson_append_estart( b, bson_array, name, 5 ) == BSON_ERROR ) return BSON_ERROR;
627
708
  b->stack[ b->stackPos++ ] = b->cur - b->buf;
628
709
  bson_append32( b , &zero );
629
- return b;
710
+ return BSON_OK;
630
711
  }
631
712
 
632
- bson_buffer * bson_append_finish_object( bson_buffer * b ){
713
+ int bson_append_finish_object( bson_buffer * b ){
633
714
  char * start;
634
715
  int i;
635
- if ( ! bson_ensure_space( b , 1 ) ) return 0;
716
+ if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR;
636
717
  bson_append_byte( b , 0 );
637
718
 
638
719
  start = b->buf + b->stack[ --b->stackPos ];
639
720
  i = b->cur - start;
640
721
  bson_little_endian32(start, &i);
641
722
 
642
- return b;
723
+ return BSON_OK;
643
724
  }
644
725
 
645
726
  void* bson_malloc(int size){
@@ -662,6 +743,17 @@ bson_err_handler set_bson_err_handler(bson_err_handler func){
662
743
  return old;
663
744
  }
664
745
 
746
+ /**
747
+ * This method is invoked when a non-fatal bson error is encountered.
748
+ * Calls the error handler if available.
749
+ *
750
+ * @param
751
+ */
752
+ void bson_builder_error( bson_buffer* b ) {
753
+ if( err_handler )
754
+ err_handler( "BSON error." );
755
+ }
756
+
665
757
  void bson_fatal( int ok ){
666
758
  bson_fatal_msg(ok, "");
667
759
  }