bson_ext 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -22,12 +22,11 @@ namespace :build do
22
22
  jar_dir = File.join(java_dir, 'jar')
23
23
 
24
24
  jruby_jar = File.join(jar_dir, 'jruby.jar')
25
- mongo_jar = File.join(jar_dir, 'mongo-2.4.jar')
26
- bson_jar = File.join(jar_dir, 'bson-2.2.jar')
25
+ mongo_jar = File.join(jar_dir, 'mongo-2.6.5.jar')
27
26
 
28
27
  src_base = File.join(java_dir, 'src')
29
28
 
30
- system("javac -Xlint:unchecked -classpath #{jruby_jar}:#{mongo_jar}:#{bson_jar} #{File.join(src_base, 'org', 'jbson', '*.java')}")
29
+ system("javac -Xlint:deprecation -Xlint:unchecked -classpath #{jruby_jar}:#{mongo_jar} #{File.join(src_base, 'org', 'jbson', '*.java')}")
31
30
  system("cd #{src_base} && jar cf #{File.join(jar_dir, 'jbson.jar')} #{File.join('.', 'org', 'jbson', '*.class')}")
32
31
  end
33
32
  end
@@ -142,7 +141,7 @@ task :ydoc do
142
141
  require File.join(File.dirname(__FILE__), 'lib', 'mongo')
143
142
  out = File.join('ydoc', Mongo::VERSION)
144
143
  FileUtils.rm_rf('ydoc')
145
- system "yardoc lib/**/*.rb lib/mongo/**/*.rb lib/bson/**/*.rb -e yard/yard_ext.rb -p yard/templates -o #{out} --title MongoRuby-#{Mongo::VERSION} --files docs/TUTORIAL.md,docs/GridFS.md,docs/FAQ.md,docs/REPLICA_SETS.md,docs/WRITE_CONCERN.md,docs/HISTORY.md,docs/CREDITS.md,docs/RELEASES.md"
144
+ system "yardoc lib/**/*.rb lib/mongo/**/*.rb lib/bson/**/*.rb -e ./yard/yard_ext.rb -p yard/templates -o #{out} --title MongoRuby-#{Mongo::VERSION} --files docs/TUTORIAL.md,docs/GridFS.md,docs/FAQ.md,docs/REPLICA_SETS.md,docs/WRITE_CONCERN.md,docs/READ_PREFERENCE.md,docs/HISTORY.md,docs/CREDITS.md,docs/RELEASES.md,docs/CREDITS.md,docs/TAILABLE_CURSORS.md"
146
145
  end
147
146
 
148
147
  namespace :bamboo do
@@ -17,21 +17,23 @@
17
17
  #include <stdlib.h>
18
18
  #include <string.h>
19
19
 
20
- #include "buffer.h"
20
+ #include "bson_buffer.h"
21
21
 
22
22
  #define INITIAL_BUFFER_SIZE 256
23
+ #define DEFAULT_MAX_SIZE 4 * 1024 * 1024
23
24
 
24
- struct buffer {
25
+ struct bson_buffer {
25
26
  char* buffer;
26
27
  int size;
27
28
  int position;
29
+ int max_size;
28
30
  };
29
31
 
30
32
  /* Allocate and return a new buffer.
31
33
  * Return NULL on allocation failure. */
32
- buffer_t buffer_new(void) {
33
- buffer_t buffer;
34
- buffer = (buffer_t)malloc(sizeof(struct buffer));
34
+ bson_buffer_t bson_buffer_new(void) {
35
+ bson_buffer_t buffer;
36
+ buffer = (bson_buffer_t)malloc(sizeof(struct bson_buffer));
35
37
  if (buffer == NULL) {
36
38
  return NULL;
37
39
  }
@@ -43,13 +45,22 @@ buffer_t buffer_new(void) {
43
45
  free(buffer);
44
46
  return NULL;
45
47
  }
48
+ buffer->max_size = DEFAULT_MAX_SIZE;
46
49
 
47
50
  return buffer;
48
51
  }
49
52
 
53
+ void bson_buffer_set_max_size(bson_buffer_t buffer, int max_size) {
54
+ buffer->max_size = max_size;
55
+ }
56
+
57
+ int bson_buffer_get_max_size(bson_buffer_t buffer) {
58
+ return buffer->max_size;
59
+ }
60
+
50
61
  /* Free the memory allocated for `buffer`.
51
62
  * Return non-zero on failure. */
52
- int buffer_free(buffer_t buffer) {
63
+ int bson_buffer_free(bson_buffer_t buffer) {
53
64
  if (buffer == NULL) {
54
65
  return 1;
55
66
  }
@@ -60,14 +71,19 @@ int buffer_free(buffer_t buffer) {
60
71
 
61
72
  /* Grow `buffer` to at least `min_length`.
62
73
  * Return non-zero on allocation failure. */
63
- static int buffer_grow(buffer_t buffer, int min_length) {
74
+ static int buffer_grow(bson_buffer_t buffer, int min_length) {
64
75
  int size = buffer->size;
76
+ int old_size;
65
77
  char* old_buffer = buffer->buffer;
66
78
  if (size >= min_length) {
67
79
  return 0;
68
80
  }
69
81
  while (size < min_length) {
82
+ old_size = size;
70
83
  size *= 2;
84
+ /* Prevent potential overflow. */
85
+ if( size < old_size )
86
+ size = min_length;
71
87
  }
72
88
  buffer->buffer = (char*)realloc(buffer->buffer, sizeof(char) * size);
73
89
  if (buffer->buffer == NULL) {
@@ -81,7 +97,7 @@ static int buffer_grow(buffer_t buffer, int min_length) {
81
97
 
82
98
  /* Assure that `buffer` has at least `size` free bytes (and grow if needed).
83
99
  * Return non-zero on allocation failure. */
84
- static int buffer_assure_space(buffer_t buffer, int size) {
100
+ static int buffer_assure_space(bson_buffer_t buffer, int size) {
85
101
  if (buffer->position + size <= buffer->size) {
86
102
  return 0;
87
103
  }
@@ -90,7 +106,7 @@ static int buffer_assure_space(buffer_t buffer, int size) {
90
106
 
91
107
  /* Save `size` bytes from the current position in `buffer` (and grow if needed).
92
108
  * Return offset for writing, or -1 on allocation failure. */
93
- buffer_position buffer_save_space(buffer_t buffer, int size) {
109
+ bson_buffer_position bson_buffer_save_space(bson_buffer_t buffer, int size) {
94
110
  int position = buffer->position;
95
111
  if (buffer_assure_space(buffer, size) != 0) {
96
112
  return -1;
@@ -101,7 +117,7 @@ buffer_position buffer_save_space(buffer_t buffer, int size) {
101
117
 
102
118
  /* Write `size` bytes from `data` to `buffer` (and grow if needed).
103
119
  * Return non-zero on allocation failure. */
104
- int buffer_write(buffer_t buffer, const char* data, int size) {
120
+ int bson_buffer_write(bson_buffer_t buffer, const char* data, int size) {
105
121
  if (buffer_assure_space(buffer, size) != 0) {
106
122
  return 1;
107
123
  }
@@ -114,10 +130,10 @@ int buffer_write(buffer_t buffer, const char* data, int size) {
114
130
  /* Write `size` bytes from `data` to `buffer` at position `position`.
115
131
  * Does not change the internal position of `buffer`.
116
132
  * Return non-zero if buffer isn't large enough for write. */
117
- int buffer_write_at_position(buffer_t buffer, buffer_position position,
133
+ int bson_buffer_write_at_position(bson_buffer_t buffer, bson_buffer_position position,
118
134
  const char* data, int size) {
119
135
  if (position + size > buffer->size) {
120
- buffer_free(buffer);
136
+ bson_buffer_free(buffer);
121
137
  return 1;
122
138
  }
123
139
 
@@ -126,10 +142,10 @@ int buffer_write_at_position(buffer_t buffer, buffer_position position,
126
142
  }
127
143
 
128
144
 
129
- int buffer_get_position(buffer_t buffer) {
145
+ int bson_buffer_get_position(bson_buffer_t buffer) {
130
146
  return buffer->position;
131
147
  }
132
148
 
133
- char* buffer_get_buffer(buffer_t buffer) {
149
+ char* bson_buffer_get_buffer(bson_buffer_t buffer) {
134
150
  return buffer->buffer;
135
151
  }
@@ -14,42 +14,46 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- #ifndef BUFFER_H
18
- #define BUFFER_H
17
+ #ifndef _BSON_BUFFER_H
18
+ #define _BSON_BUFFER_H
19
19
 
20
20
  /* Note: if any of these functions return a failure condition then the buffer
21
21
  * has already been freed. */
22
22
 
23
23
  /* A buffer */
24
- typedef struct buffer* buffer_t;
24
+ typedef struct bson_buffer* bson_buffer_t;
25
25
  /* A position in the buffer */
26
- typedef int buffer_position;
26
+ typedef int bson_buffer_position;
27
27
 
28
28
  /* Allocate and return a new buffer.
29
29
  * Return NULL on allocation failure. */
30
- buffer_t buffer_new(void);
30
+ bson_buffer_t bson_buffer_new(void);
31
+
32
+ /* Set the max size for this buffer.
33
+ * Note: this is not a hard limit. */
34
+ void bson_buffer_set_max_size(bson_buffer_t buffer, int max_size);
31
35
 
32
36
  /* Free the memory allocated for `buffer`.
33
37
  * Return non-zero on failure. */
34
- int buffer_free(buffer_t buffer);
38
+ int bson_buffer_free(bson_buffer_t buffer);
35
39
 
36
40
  /* Save `size` bytes from the current position in `buffer` (and grow if needed).
37
41
  * Return offset for writing, or -1 on allocation failure. */
38
- buffer_position buffer_save_space(buffer_t buffer, int size);
42
+ bson_buffer_position bson_buffer_save_space(bson_buffer_t buffer, int size);
39
43
 
40
44
  /* Write `size` bytes from `data` to `buffer` (and grow if needed).
41
45
  * Return non-zero on allocation failure. */
42
- int buffer_write(buffer_t buffer, const char* data, int size);
46
+ int bson_buffer_write(bson_buffer_t buffer, const char* data, int size);
43
47
 
44
48
  /* Write `size` bytes from `data` to `buffer` at position `position`.
45
49
  * Does not change the internal position of `buffer`.
46
50
  * Return non-zero if buffer isn't large enough for write. */
47
- int buffer_write_at_position(buffer_t buffer, buffer_position position, const char* data, int size);
51
+ int bson_buffer_write_at_position(bson_buffer_t buffer, bson_buffer_position position, const char* data, int size);
48
52
 
49
- /* Getters for the internals of a buffer_t.
53
+ /* Getters for the internals of a bson_buffer_t.
50
54
  * Should try to avoid using these as much as possible
51
55
  * since they break the abstraction. */
52
- buffer_position buffer_get_position(buffer_t buffer);
53
- char* buffer_get_buffer(buffer_t buffer);
56
+ bson_buffer_position bson_buffer_get_position(bson_buffer_t buffer);
57
+ char* bson_buffer_get_buffer(bson_buffer_t buffer);
54
58
 
55
59
  #endif
@@ -61,16 +61,16 @@
61
61
  #include <time.h>
62
62
 
63
63
  #include "version.h"
64
- #include "buffer.h"
64
+ #include "bson_buffer.h"
65
65
  #include "encoding_helpers.h"
66
66
 
67
67
  #define SAFE_WRITE(buffer, data, size) \
68
- if (buffer_write((buffer), (data), (size)) != 0) \
69
- rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c")
68
+ if (bson_buffer_write((buffer), (data), (size)) != 0) \
69
+ rb_raise(rb_eNoMemError, "failed to allocate memory in bson_buffer.c")
70
70
 
71
71
  #define SAFE_WRITE_AT_POS(buffer, position, data, size) \
72
- if (buffer_write_at_position((buffer), (position), (data), (size)) != 0) \
73
- rb_raise(rb_eRuntimeError, "invalid write at position in buffer.c")
72
+ if (bson_buffer_write_at_position((buffer), (position), (data), (size)) != 0) \
73
+ rb_raise(rb_eRuntimeError, "invalid write at position in bson_buffer.c")
74
74
 
75
75
  #define MAX_HOSTNAME_LENGTH 256
76
76
 
@@ -114,14 +114,14 @@ static int max_bson_size;
114
114
  #define TO_UTF8(string) (string)
115
115
  #endif
116
116
 
117
- static void write_utf8(buffer_t buffer, VALUE string, char check_null) {
117
+ static void write_utf8(bson_buffer_t buffer, VALUE string, char check_null) {
118
118
  result_t status = check_string(RSTRING_PTR(string), RSTRING_LEN(string),
119
119
  1, check_null);
120
120
  if (status == HAS_NULL) {
121
- buffer_free(buffer);
121
+ bson_buffer_free(buffer);
122
122
  rb_raise(InvalidDocument, "Key names / regex patterns must not contain the NULL byte");
123
123
  } else if (status == NOT_UTF_8) {
124
- buffer_free(buffer);
124
+ bson_buffer_free(buffer);
125
125
  rb_raise(InvalidStringEncoding, "String not valid UTF-8");
126
126
  }
127
127
  string = TO_UTF8(string);
@@ -192,23 +192,23 @@ static int cmp_char(const void* a, const void* b) {
192
192
  return *(char*)a - *(char*)b;
193
193
  }
194
194
 
195
- static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_id);
195
+ static void write_doc(bson_buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_id);
196
196
  static int write_element_with_id(VALUE key, VALUE value, VALUE extra);
197
197
  static int write_element_without_id(VALUE key, VALUE value, VALUE extra);
198
198
  static VALUE elements_to_hash(const char* buffer, int max);
199
199
 
200
- static VALUE pack_extra(buffer_t buffer, VALUE check_keys) {
200
+ static VALUE pack_extra(bson_buffer_t buffer, VALUE check_keys) {
201
201
  return rb_ary_new3(2, LL2NUM((long long)buffer), check_keys);
202
202
  }
203
203
 
204
- static void write_name_and_type(buffer_t buffer, VALUE name, char type) {
204
+ static void write_name_and_type(bson_buffer_t buffer, VALUE name, char type) {
205
205
  SAFE_WRITE(buffer, &type, 1);
206
206
  write_utf8(buffer, name, 1);
207
207
  SAFE_WRITE(buffer, &zero, 1);
208
208
  }
209
209
 
210
210
  static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
211
- buffer_t buffer = (buffer_t)NUM2LL(rb_ary_entry(extra, 0));
211
+ bson_buffer_t buffer = (bson_buffer_t)NUM2LL(rb_ary_entry(extra, 0));
212
212
  VALUE check_keys = rb_ary_entry(extra, 1);
213
213
 
214
214
  if (TYPE(key) == T_SYMBOL) {
@@ -217,7 +217,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
217
217
  }
218
218
 
219
219
  if (TYPE(key) != T_STRING) {
220
- buffer_free(buffer);
220
+ bson_buffer_free(buffer);
221
221
  rb_raise(rb_eTypeError, "keys must be strings or symbols");
222
222
  }
223
223
 
@@ -228,12 +228,12 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
228
228
  if (check_keys == Qtrue) {
229
229
  int i;
230
230
  if (RSTRING_LEN(key) > 0 && RSTRING_PTR(key)[0] == '$') {
231
- buffer_free(buffer);
231
+ bson_buffer_free(buffer);
232
232
  rb_raise(InvalidKeyName, "%s - key must not start with '$'", RSTRING_PTR(key));
233
233
  }
234
234
  for (i = 0; i < RSTRING_LEN(key); i++) {
235
235
  if (RSTRING_PTR(key)[i] == '.') {
236
- buffer_free(buffer);
236
+ bson_buffer_free(buffer);
237
237
  rb_raise(InvalidKeyName, "%s - key must not contain '.'", RSTRING_PTR(key));
238
238
  }
239
239
  }
@@ -244,7 +244,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
244
244
  {
245
245
  if (rb_funcall(value, gt_operator, 1, LL2NUM(9223372036854775807LL)) == Qtrue ||
246
246
  rb_funcall(value, lt_operator, 1, LL2NUM(-9223372036854775808ULL)) == Qtrue) {
247
- buffer_free(buffer);
247
+ bson_buffer_free(buffer);
248
248
  rb_raise(rb_eRangeError, "MongoDB can only handle 8-byte ints");
249
249
  }
250
250
  }
@@ -298,15 +298,15 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
298
298
  }
299
299
  case T_ARRAY:
300
300
  {
301
- buffer_position length_location, start_position, obj_length;
301
+ bson_buffer_position length_location, start_position, obj_length;
302
302
  int items, i;
303
303
  VALUE* values;
304
304
 
305
305
  write_name_and_type(buffer, key, 0x04);
306
- start_position = buffer_get_position(buffer);
306
+ start_position = bson_buffer_get_position(buffer);
307
307
 
308
308
  // save space for length
309
- length_location = buffer_save_space(buffer, 4);
309
+ length_location = bson_buffer_save_space(buffer, 4);
310
310
  if (length_location == -1) {
311
311
  rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
312
312
  }
@@ -323,7 +323,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
323
323
 
324
324
  // write null byte and fill in length
325
325
  SAFE_WRITE(buffer, &zero, 1);
326
- obj_length = buffer_get_position(buffer) - start_position;
326
+ obj_length = bson_buffer_get_position(buffer) - start_position;
327
327
  SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4);
328
328
  break;
329
329
  }
@@ -380,14 +380,14 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
380
380
  break;
381
381
  }
382
382
  if (strcmp(cls, "BSON::DBRef") == 0) {
383
- buffer_position length_location, start_position, obj_length;
383
+ bson_buffer_position length_location, start_position, obj_length;
384
384
  VALUE ns, oid;
385
385
  write_name_and_type(buffer, key, 0x03);
386
386
 
387
- start_position = buffer_get_position(buffer);
387
+ start_position = bson_buffer_get_position(buffer);
388
388
 
389
389
  // save space for length
390
- length_location = buffer_save_space(buffer, 4);
390
+ length_location = bson_buffer_save_space(buffer, 4);
391
391
  if (length_location == -1) {
392
392
  rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
393
393
  }
@@ -399,18 +399,18 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
399
399
 
400
400
  // write null byte and fill in length
401
401
  SAFE_WRITE(buffer, &zero, 1);
402
- obj_length = buffer_get_position(buffer) - start_position;
402
+ obj_length = bson_buffer_get_position(buffer) - start_position;
403
403
  SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4);
404
404
  break;
405
405
  }
406
406
  if (strcmp(cls, "BSON::Code") == 0) {
407
- buffer_position length_location, start_position, total_length;
407
+ bson_buffer_position length_location, start_position, total_length;
408
408
  int length;
409
409
  VALUE code_str;
410
410
  write_name_and_type(buffer, key, 0x0F);
411
411
 
412
- start_position = buffer_get_position(buffer);
413
- length_location = buffer_save_space(buffer, 4);
412
+ start_position = bson_buffer_get_position(buffer);
413
+ length_location = bson_buffer_save_space(buffer, 4);
414
414
  if (length_location == -1) {
415
415
  rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
416
416
  }
@@ -422,7 +422,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
422
422
  SAFE_WRITE(buffer, &zero, 1);
423
423
  write_doc(buffer, rb_funcall(value, rb_intern("scope"), 0), Qfalse, Qfalse);
424
424
 
425
- total_length = buffer_get_position(buffer) - start_position;
425
+ total_length = bson_buffer_get_position(buffer) - start_position;
426
426
  SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&total_length, 4);
427
427
  break;
428
428
  }
@@ -436,9 +436,9 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
436
436
  }
437
437
  if (strcmp(cls, "BSON::Timestamp") == 0) {
438
438
  write_name_and_type(buffer, key, 0x11);
439
- int seconds = FIX2INT(
439
+ unsigned int seconds = NUM2UINT(
440
440
  rb_funcall(value, rb_intern("seconds"), 0));
441
- int increment = FIX2INT(
441
+ unsigned int increment = NUM2UINT(
442
442
  rb_funcall(value, rb_intern("increment"), 0));
443
443
 
444
444
  SAFE_WRITE(buffer, (const char*)&increment, 4);
@@ -446,16 +446,16 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
446
446
  break;
447
447
  }
448
448
  if (strcmp(cls, "DateTime") == 0 || strcmp(cls, "Date") == 0 || strcmp(cls, "ActiveSupport::TimeWithZone") == 0) {
449
- buffer_free(buffer);
449
+ bson_buffer_free(buffer);
450
450
  rb_raise(InvalidDocument, "%s is not currently supported; use a UTC Time instance instead.", cls);
451
451
  break;
452
452
  }
453
453
  if(strcmp(cls, "Complex") == 0 || strcmp(cls, "Rational") == 0 || strcmp(cls, "BigDecimal") == 0) {
454
- buffer_free(buffer);
454
+ bson_buffer_free(buffer);
455
455
  rb_raise(InvalidDocument, "Cannot serialize the Numeric type %s as BSON; only Bignum, Fixnum, and Float are supported.", cls);
456
456
  break;
457
457
  }
458
- buffer_free(buffer);
458
+ bson_buffer_free(buffer);
459
459
  rb_raise(InvalidDocument, "Cannot serialize an object of class %s into BSON.", cls);
460
460
  break;
461
461
  }
@@ -470,11 +470,11 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
470
470
  break;
471
471
  }
472
472
  if(strcmp(cls, "BigDecimal") == 0) {
473
- buffer_free(buffer);
473
+ bson_buffer_free(buffer);
474
474
  rb_raise(InvalidDocument, "Cannot serialize the Numeric type %s as BSON; only Bignum, Fixnum, and Float are supported.", cls);
475
475
  break;
476
476
  }
477
- buffer_free(buffer);
477
+ bson_buffer_free(buffer);
478
478
  rb_raise(InvalidDocument, "Cannot serialize an object of class %s into BSON.", cls);
479
479
  break;
480
480
  }
@@ -507,9 +507,9 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
507
507
  has_extra = rb_funcall(value, rb_intern("respond_to?"), 1, rb_str_new2("extra_options_str"));
508
508
  if (TYPE(has_extra) == T_TRUE) {
509
509
  VALUE extra = rb_funcall(value, rb_intern("extra_options_str"), 0);
510
- buffer_position old_position = buffer_get_position(buffer);
510
+ bson_buffer_position old_position = bson_buffer_get_position(buffer);
511
511
  SAFE_WRITE(buffer, RSTRING_PTR(extra), RSTRING_LENINT(extra));
512
- qsort(buffer_get_buffer(buffer) + old_position, RSTRING_LEN(extra), sizeof(char), cmp_char);
512
+ qsort(bson_buffer_get_buffer(buffer) + old_position, RSTRING_LEN(extra), sizeof(char), cmp_char);
513
513
  }
514
514
  SAFE_WRITE(buffer, &zero, 1);
515
515
 
@@ -518,7 +518,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
518
518
  default:
519
519
  {
520
520
  const char* cls = rb_obj_classname(value);
521
- buffer_free(buffer);
521
+ bson_buffer_free(buffer);
522
522
  rb_raise(InvalidDocument, "Cannot serialize an object of class %s (type %d) into BSON.", cls, TYPE(value));
523
523
  break;
524
524
  }
@@ -534,10 +534,10 @@ static int write_element_with_id(VALUE key, VALUE value, VALUE extra) {
534
534
  return write_element(key, value, extra, 1);
535
535
  }
536
536
 
537
- static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_id) {
538
- buffer_position start_position = buffer_get_position(buffer);
539
- buffer_position length_location = buffer_save_space(buffer, 4);
540
- buffer_position length;
537
+ static void write_doc(bson_buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_id) {
538
+ bson_buffer_position start_position = bson_buffer_get_position(buffer);
539
+ bson_buffer_position length_location = bson_buffer_save_space(buffer, 4);
540
+ bson_buffer_position length;
541
541
  int allow_id;
542
542
  int (*write_function)(VALUE, VALUE, VALUE) = NULL;
543
543
  VALUE id_str = rb_str_new2("_id");
@@ -590,34 +590,39 @@ static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_
590
590
  } else if (rb_obj_is_kind_of(hash, RB_HASH) == Qtrue) {
591
591
  rb_hash_foreach(hash, write_function, pack_extra(buffer, check_keys));
592
592
  } else {
593
- buffer_free(buffer);
593
+ bson_buffer_free(buffer);
594
594
  rb_raise(InvalidDocument, "BSON.serialize takes a Hash but got a %s", rb_obj_classname(hash));
595
595
  }
596
596
 
597
597
  // write null byte and fill in length
598
598
  SAFE_WRITE(buffer, &zero, 1);
599
- length = buffer_get_position(buffer) - start_position;
599
+ length = bson_buffer_get_position(buffer) - start_position;
600
600
 
601
601
  // make sure that length doesn't exceed 4MB
602
- if (length > max_bson_size) {
603
- buffer_free(buffer);
604
- rb_raise(InvalidDocument, "Document too large: BSON documents are limited to %d bytes.", max_bson_size);
602
+ if (length > bson_buffer_get_max_size(buffer)) {
603
+ bson_buffer_free(buffer);
604
+ rb_raise(InvalidDocument,
605
+ "Document too large: This BSON documents is limited to %d bytes.",
606
+ bson_buffer_get_max_size(buffer));
605
607
  return;
606
608
  }
607
609
  SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&length, 4);
608
610
  }
609
611
 
610
- static VALUE method_serialize(VALUE self, VALUE doc, VALUE check_keys, VALUE move_id) {
612
+ static VALUE method_serialize(VALUE self, VALUE doc, VALUE check_keys,
613
+ VALUE move_id, VALUE max_size) {
614
+
611
615
  VALUE result;
612
- buffer_t buffer = buffer_new();
616
+ bson_buffer_t buffer = bson_buffer_new();
617
+ bson_buffer_set_max_size(buffer, FIX2INT(max_size));
613
618
  if (buffer == NULL) {
614
619
  rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
615
620
  }
616
621
 
617
622
  write_doc(buffer, doc, check_keys, move_id);
618
623
 
619
- result = rb_str_new(buffer_get_buffer(buffer), buffer_get_position(buffer));
620
- if (buffer_free(buffer) != 0) {
624
+ result = rb_str_new(bson_buffer_get_buffer(buffer), bson_buffer_get_position(buffer));
625
+ if (bson_buffer_free(buffer) != 0) {
621
626
  rb_raise(rb_eRuntimeError, "failed to free buffer");
622
627
  }
623
628
  return result;
@@ -830,12 +835,12 @@ static VALUE get_value(const char* buffer, int* position, int type) {
830
835
  }
831
836
  case 17:
832
837
  {
833
- int sec, inc;
838
+ unsigned int sec, inc;
834
839
  VALUE argv[2];
835
840
  memcpy(&inc, buffer + *position, 4);
836
841
  memcpy(&sec, buffer + *position + 4, 4);
837
- argv[0] = INT2FIX(sec);
838
- argv[1] = INT2FIX(inc);
842
+ argv[0] = UINT2NUM(sec);
843
+ argv[1] = UINT2NUM(inc);
839
844
  value = rb_class_new_instance(2, argv, Timestamp);
840
845
  *position += 8;
841
846
  break;
@@ -899,7 +904,7 @@ static VALUE objectid_generate(int argc, VALUE* args, VALUE self)
899
904
  if(argc == 0 || (argc == 1 && *args == Qnil)) {
900
905
  t = htonl((int)time(NULL));
901
906
  } else {
902
- t = htonl(FIX2INT(rb_funcall(*args, rb_intern("to_i"), 0)));
907
+ t = htonl(NUM2UINT(rb_funcall(*args, rb_intern("to_i"), 0)));
903
908
  }
904
909
  MEMCPY(&oid_bytes, &t, unsigned char, 4);
905
910
 
@@ -973,7 +978,7 @@ void Init_cbson() {
973
978
  CBson = rb_define_module("CBson");
974
979
  ext_version = rb_str_new2(VERSION);
975
980
  rb_define_const(CBson, "VERSION", ext_version);
976
- rb_define_module_function(CBson, "serialize", method_serialize, 3);
981
+ rb_define_module_function(CBson, "serialize", method_serialize, 4);
977
982
  rb_define_module_function(CBson, "deserialize", method_deserialize, 1);
978
983
  rb_define_module_function(CBson, "max_bson_size", method_max_bson_size, 0);
979
984
  rb_define_module_function(CBson, "update_max_bson_size", method_update_max_bson_size, 1);