bson_ext 1.3.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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);