RUBY-302 RUBY-303 fix buffer namespace conflict by renaming to bson_buffer.

This commit is contained in:
Kyle Banker 2011-08-08 15:06:39 -04:00
parent b32f895ed6
commit ace1313b99
3 changed files with 71 additions and 71 deletions

View File

@ -17,11 +17,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "buffer.h" #include "bson_buffer.h"
#define INITIAL_BUFFER_SIZE 256 #define INITIAL_BUFFER_SIZE 256
struct buffer { struct bson_buffer {
char* buffer; char* buffer;
int size; int size;
int position; int position;
@ -29,9 +29,9 @@ struct buffer {
/* Allocate and return a new buffer. /* Allocate and return a new buffer.
* Return NULL on allocation failure. */ * Return NULL on allocation failure. */
buffer_t buffer_new(void) { bson_buffer_t bson_buffer_new(void) {
buffer_t buffer; bson_buffer_t buffer;
buffer = (buffer_t)malloc(sizeof(struct buffer)); buffer = (bson_buffer_t)malloc(sizeof(struct bson_buffer));
if (buffer == NULL) { if (buffer == NULL) {
return NULL; return NULL;
} }
@ -49,7 +49,7 @@ buffer_t buffer_new(void) {
/* Free the memory allocated for `buffer`. /* Free the memory allocated for `buffer`.
* Return non-zero on failure. */ * Return non-zero on failure. */
int buffer_free(buffer_t buffer) { int bson_buffer_free(bson_buffer_t buffer) {
if (buffer == NULL) { if (buffer == NULL) {
return 1; return 1;
} }
@ -60,7 +60,7 @@ int buffer_free(buffer_t buffer) {
/* Grow `buffer` to at least `min_length`. /* Grow `buffer` to at least `min_length`.
* Return non-zero on allocation failure. */ * Return non-zero on allocation failure. */
static int buffer_grow(buffer_t buffer, int min_length) { static int buffer_grow(bson_buffer_t buffer, int min_length) {
int size = buffer->size; int size = buffer->size;
char* old_buffer = buffer->buffer; char* old_buffer = buffer->buffer;
if (size >= min_length) { if (size >= min_length) {
@ -81,7 +81,7 @@ static int buffer_grow(buffer_t buffer, int min_length) {
/* Assure that `buffer` has at least `size` free bytes (and grow if needed). /* Assure that `buffer` has at least `size` free bytes (and grow if needed).
* Return non-zero on allocation failure. */ * Return non-zero on allocation failure. */
static int buffer_assure_space(buffer_t buffer, int size) { static int buffer_assure_space(bson_buffer_t buffer, int size) {
if (buffer->position + size <= buffer->size) { if (buffer->position + size <= buffer->size) {
return 0; return 0;
} }
@ -90,7 +90,7 @@ static int buffer_assure_space(buffer_t buffer, int size) {
/* Save `size` bytes from the current position in `buffer` (and grow if needed). /* Save `size` bytes from the current position in `buffer` (and grow if needed).
* Return offset for writing, or -1 on allocation failure. */ * Return offset for writing, or -1 on allocation failure. */
buffer_position buffer_save_space(buffer_t buffer, int size) { bson_buffer_position bson_buffer_save_space(bson_buffer_t buffer, int size) {
int position = buffer->position; int position = buffer->position;
if (buffer_assure_space(buffer, size) != 0) { if (buffer_assure_space(buffer, size) != 0) {
return -1; return -1;
@ -101,7 +101,7 @@ buffer_position buffer_save_space(buffer_t buffer, int size) {
/* Write `size` bytes from `data` to `buffer` (and grow if needed). /* Write `size` bytes from `data` to `buffer` (and grow if needed).
* Return non-zero on allocation failure. */ * Return non-zero on allocation failure. */
int buffer_write(buffer_t buffer, const char* data, int size) { int bson_buffer_write(bson_buffer_t buffer, const char* data, int size) {
if (buffer_assure_space(buffer, size) != 0) { if (buffer_assure_space(buffer, size) != 0) {
return 1; return 1;
} }
@ -114,7 +114,7 @@ int buffer_write(buffer_t buffer, const char* data, int size) {
/* Write `size` bytes from `data` to `buffer` at position `position`. /* Write `size` bytes from `data` to `buffer` at position `position`.
* Does not change the internal position of `buffer`. * Does not change the internal position of `buffer`.
* Return non-zero if buffer isn't large enough for write. */ * Return non-zero if buffer isn't large enough for write. */
int buffer_write_at_position(buffer_t buffer, buffer_position position, int bson_buffer_write_at_position(bson_buffer_t buffer, bson_buffer_position position,
const char* data, int size) { const char* data, int size) {
if (position + size > buffer->size) { if (position + size > buffer->size) {
buffer_free(buffer); buffer_free(buffer);
@ -126,10 +126,10 @@ int buffer_write_at_position(buffer_t buffer, buffer_position position,
} }
int buffer_get_position(buffer_t buffer) { int bson_buffer_get_position(bson_buffer_t buffer) {
return buffer->position; return buffer->position;
} }
char* buffer_get_buffer(buffer_t buffer) { char* bson_buffer_get_buffer(bson_buffer_t buffer) {
return buffer->buffer; return buffer->buffer;
} }

View File

@ -14,42 +14,42 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef BUFFER_H #ifndef _BSON_BUFFER_H
#define BUFFER_H #define _BSON_BUFFER_H
/* Note: if any of these functions return a failure condition then the buffer /* Note: if any of these functions return a failure condition then the buffer
* has already been freed. */ * has already been freed. */
/* A buffer */ /* A buffer */
typedef struct buffer* buffer_t; typedef struct bson_buffer* bson_buffer_t;
/* A position in the buffer */ /* A position in the buffer */
typedef int buffer_position; typedef int bson_buffer_position;
/* Allocate and return a new buffer. /* Allocate and return a new buffer.
* Return NULL on allocation failure. */ * Return NULL on allocation failure. */
buffer_t buffer_new(void); bson_buffer_t bson_buffer_new(void);
/* Free the memory allocated for `buffer`. /* Free the memory allocated for `buffer`.
* Return non-zero on failure. */ * Return non-zero on failure. */
int buffer_free(buffer_t buffer); int bson_buffer_free(bson_buffer_t buffer);
/* Save `size` bytes from the current position in `buffer` (and grow if needed). /* Save `size` bytes from the current position in `buffer` (and grow if needed).
* Return offset for writing, or -1 on allocation failure. */ * Return offset for writing, or -1 on allocation failure. */
buffer_position buffer_save_space(buffer_t buffer, int size); bson_buffer_position bson_buffer_save_space(bson_buffer_t buffer, int size);
/* Write `size` bytes from `data` to `buffer` (and grow if needed). /* Write `size` bytes from `data` to `buffer` (and grow if needed).
* Return non-zero on allocation failure. */ * Return non-zero on allocation failure. */
int buffer_write(buffer_t buffer, const char* data, int size); int bson_buffer_write(bson_buffer_t buffer, const char* data, int size);
/* Write `size` bytes from `data` to `buffer` at position `position`. /* Write `size` bytes from `data` to `buffer` at position `position`.
* Does not change the internal position of `buffer`. * Does not change the internal position of `buffer`.
* Return non-zero if buffer isn't large enough for write. */ * Return non-zero if buffer isn't large enough for write. */
int buffer_write_at_position(buffer_t buffer, buffer_position position, const char* data, int size); int bson_buffer_write_at_position(bson_buffer_t buffer, bson_buffer_position position, const char* data, int size);
/* Getters for the internals of a buffer_t. /* Getters for the internals of a bson_buffer_t.
* Should try to avoid using these as much as possible * Should try to avoid using these as much as possible
* since they break the abstraction. */ * since they break the abstraction. */
buffer_position buffer_get_position(buffer_t buffer); bson_buffer_position bson_buffer_get_position(bson_buffer_t buffer);
char* buffer_get_buffer(buffer_t buffer); char* bson_buffer_get_buffer(bson_buffer_t buffer);
#endif #endif

View File

@ -61,16 +61,16 @@
#include <time.h> #include <time.h>
#include "version.h" #include "version.h"
#include "buffer.h" #include "bson_buffer.h"
#include "encoding_helpers.h" #include "encoding_helpers.h"
#define SAFE_WRITE(buffer, data, size) \ #define SAFE_WRITE(buffer, data, size) \
if (buffer_write((buffer), (data), (size)) != 0) \ if (bson_buffer_write((buffer), (data), (size)) != 0) \
rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c") rb_raise(rb_eNoMemError, "failed to allocate memory in bson_buffer.c")
#define SAFE_WRITE_AT_POS(buffer, position, data, size) \ #define SAFE_WRITE_AT_POS(buffer, position, data, size) \
if (buffer_write_at_position((buffer), (position), (data), (size)) != 0) \ if (bson_buffer_write_at_position((buffer), (position), (data), (size)) != 0) \
rb_raise(rb_eRuntimeError, "invalid write at position in buffer.c") rb_raise(rb_eRuntimeError, "invalid write at position in bson_buffer.c")
#define MAX_HOSTNAME_LENGTH 256 #define MAX_HOSTNAME_LENGTH 256
@ -114,14 +114,14 @@ static int max_bson_size;
#define TO_UTF8(string) (string) #define TO_UTF8(string) (string)
#endif #endif
static void write_utf8(buffer_t buffer, VALUE string, char check_null) { static void write_utf8(bson_buffer_t buffer, VALUE string, char check_null) {
result_t status = check_string(RSTRING_PTR(string), RSTRING_LEN(string), result_t status = check_string(RSTRING_PTR(string), RSTRING_LEN(string),
1, check_null); 1, check_null);
if (status == HAS_NULL) { if (status == HAS_NULL) {
buffer_free(buffer); bson_buffer_free(buffer);
rb_raise(InvalidDocument, "Key names / regex patterns must not contain the NULL byte"); rb_raise(InvalidDocument, "Key names / regex patterns must not contain the NULL byte");
} else if (status == NOT_UTF_8) { } else if (status == NOT_UTF_8) {
buffer_free(buffer); bson_buffer_free(buffer);
rb_raise(InvalidStringEncoding, "String not valid UTF-8"); rb_raise(InvalidStringEncoding, "String not valid UTF-8");
} }
string = TO_UTF8(string); string = TO_UTF8(string);
@ -192,23 +192,23 @@ static int cmp_char(const void* a, const void* b) {
return *(char*)a - *(char*)b; return *(char*)a - *(char*)b;
} }
static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_id); static void write_doc(bson_buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_id);
static int write_element_with_id(VALUE key, VALUE value, VALUE extra); static int write_element_with_id(VALUE key, VALUE value, VALUE extra);
static int write_element_without_id(VALUE key, VALUE value, VALUE extra); static int write_element_without_id(VALUE key, VALUE value, VALUE extra);
static VALUE elements_to_hash(const char* buffer, int max); static VALUE elements_to_hash(const char* buffer, int max);
static VALUE pack_extra(buffer_t buffer, VALUE check_keys) { static VALUE pack_extra(bson_buffer_t buffer, VALUE check_keys) {
return rb_ary_new3(2, LL2NUM((long long)buffer), check_keys); return rb_ary_new3(2, LL2NUM((long long)buffer), check_keys);
} }
static void write_name_and_type(buffer_t buffer, VALUE name, char type) { static void write_name_and_type(bson_buffer_t buffer, VALUE name, char type) {
SAFE_WRITE(buffer, &type, 1); SAFE_WRITE(buffer, &type, 1);
write_utf8(buffer, name, 1); write_utf8(buffer, name, 1);
SAFE_WRITE(buffer, &zero, 1); SAFE_WRITE(buffer, &zero, 1);
} }
static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) { static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
buffer_t buffer = (buffer_t)NUM2LL(rb_ary_entry(extra, 0)); bson_buffer_t buffer = (bson_buffer_t)NUM2LL(rb_ary_entry(extra, 0));
VALUE check_keys = rb_ary_entry(extra, 1); VALUE check_keys = rb_ary_entry(extra, 1);
if (TYPE(key) == T_SYMBOL) { if (TYPE(key) == T_SYMBOL) {
@ -217,7 +217,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
} }
if (TYPE(key) != T_STRING) { if (TYPE(key) != T_STRING) {
buffer_free(buffer); bson_buffer_free(buffer);
rb_raise(rb_eTypeError, "keys must be strings or symbols"); rb_raise(rb_eTypeError, "keys must be strings or symbols");
} }
@ -228,12 +228,12 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
if (check_keys == Qtrue) { if (check_keys == Qtrue) {
int i; int i;
if (RSTRING_LEN(key) > 0 && RSTRING_PTR(key)[0] == '$') { if (RSTRING_LEN(key) > 0 && RSTRING_PTR(key)[0] == '$') {
buffer_free(buffer); bson_buffer_free(buffer);
rb_raise(InvalidKeyName, "%s - key must not start with '$'", RSTRING_PTR(key)); rb_raise(InvalidKeyName, "%s - key must not start with '$'", RSTRING_PTR(key));
} }
for (i = 0; i < RSTRING_LEN(key); i++) { for (i = 0; i < RSTRING_LEN(key); i++) {
if (RSTRING_PTR(key)[i] == '.') { if (RSTRING_PTR(key)[i] == '.') {
buffer_free(buffer); bson_buffer_free(buffer);
rb_raise(InvalidKeyName, "%s - key must not contain '.'", RSTRING_PTR(key)); rb_raise(InvalidKeyName, "%s - key must not contain '.'", RSTRING_PTR(key));
} }
} }
@ -244,7 +244,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
{ {
if (rb_funcall(value, gt_operator, 1, LL2NUM(9223372036854775807LL)) == Qtrue || if (rb_funcall(value, gt_operator, 1, LL2NUM(9223372036854775807LL)) == Qtrue ||
rb_funcall(value, lt_operator, 1, LL2NUM(-9223372036854775808ULL)) == Qtrue) { rb_funcall(value, lt_operator, 1, LL2NUM(-9223372036854775808ULL)) == Qtrue) {
buffer_free(buffer); bson_buffer_free(buffer);
rb_raise(rb_eRangeError, "MongoDB can only handle 8-byte ints"); rb_raise(rb_eRangeError, "MongoDB can only handle 8-byte ints");
} }
} }
@ -298,15 +298,15 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
} }
case T_ARRAY: case T_ARRAY:
{ {
buffer_position length_location, start_position, obj_length; bson_buffer_position length_location, start_position, obj_length;
int items, i; int items, i;
VALUE* values; VALUE* values;
write_name_and_type(buffer, key, 0x04); write_name_and_type(buffer, key, 0x04);
start_position = buffer_get_position(buffer); start_position = bson_buffer_get_position(buffer);
// save space for length // save space for length
length_location = buffer_save_space(buffer, 4); length_location = bson_buffer_save_space(buffer, 4);
if (length_location == -1) { if (length_location == -1) {
rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c"); rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
} }
@ -323,7 +323,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
// write null byte and fill in length // write null byte and fill in length
SAFE_WRITE(buffer, &zero, 1); SAFE_WRITE(buffer, &zero, 1);
obj_length = buffer_get_position(buffer) - start_position; obj_length = bson_buffer_get_position(buffer) - start_position;
SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4); SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4);
break; break;
} }
@ -380,14 +380,14 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
break; break;
} }
if (strcmp(cls, "BSON::DBRef") == 0) { if (strcmp(cls, "BSON::DBRef") == 0) {
buffer_position length_location, start_position, obj_length; bson_buffer_position length_location, start_position, obj_length;
VALUE ns, oid; VALUE ns, oid;
write_name_and_type(buffer, key, 0x03); write_name_and_type(buffer, key, 0x03);
start_position = buffer_get_position(buffer); start_position = bson_buffer_get_position(buffer);
// save space for length // save space for length
length_location = buffer_save_space(buffer, 4); length_location = bson_buffer_save_space(buffer, 4);
if (length_location == -1) { if (length_location == -1) {
rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c"); rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
} }
@ -399,18 +399,18 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
// write null byte and fill in length // write null byte and fill in length
SAFE_WRITE(buffer, &zero, 1); SAFE_WRITE(buffer, &zero, 1);
obj_length = buffer_get_position(buffer) - start_position; obj_length = bson_buffer_get_position(buffer) - start_position;
SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4); SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4);
break; break;
} }
if (strcmp(cls, "BSON::Code") == 0) { if (strcmp(cls, "BSON::Code") == 0) {
buffer_position length_location, start_position, total_length; bson_buffer_position length_location, start_position, total_length;
int length; int length;
VALUE code_str; VALUE code_str;
write_name_and_type(buffer, key, 0x0F); write_name_and_type(buffer, key, 0x0F);
start_position = buffer_get_position(buffer); start_position = bson_buffer_get_position(buffer);
length_location = buffer_save_space(buffer, 4); length_location = bson_buffer_save_space(buffer, 4);
if (length_location == -1) { if (length_location == -1) {
rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c"); rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
} }
@ -422,7 +422,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
SAFE_WRITE(buffer, &zero, 1); SAFE_WRITE(buffer, &zero, 1);
write_doc(buffer, rb_funcall(value, rb_intern("scope"), 0), Qfalse, Qfalse); write_doc(buffer, rb_funcall(value, rb_intern("scope"), 0), Qfalse, Qfalse);
total_length = buffer_get_position(buffer) - start_position; total_length = bson_buffer_get_position(buffer) - start_position;
SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&total_length, 4); SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&total_length, 4);
break; break;
} }
@ -446,16 +446,16 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
break; break;
} }
if (strcmp(cls, "DateTime") == 0 || strcmp(cls, "Date") == 0 || strcmp(cls, "ActiveSupport::TimeWithZone") == 0) { if (strcmp(cls, "DateTime") == 0 || strcmp(cls, "Date") == 0 || strcmp(cls, "ActiveSupport::TimeWithZone") == 0) {
buffer_free(buffer); bson_buffer_free(buffer);
rb_raise(InvalidDocument, "%s is not currently supported; use a UTC Time instance instead.", cls); rb_raise(InvalidDocument, "%s is not currently supported; use a UTC Time instance instead.", cls);
break; break;
} }
if(strcmp(cls, "Complex") == 0 || strcmp(cls, "Rational") == 0 || strcmp(cls, "BigDecimal") == 0) { if(strcmp(cls, "Complex") == 0 || strcmp(cls, "Rational") == 0 || strcmp(cls, "BigDecimal") == 0) {
buffer_free(buffer); bson_buffer_free(buffer);
rb_raise(InvalidDocument, "Cannot serialize the Numeric type %s as BSON; only Bignum, Fixnum, and Float are supported.", cls); rb_raise(InvalidDocument, "Cannot serialize the Numeric type %s as BSON; only Bignum, Fixnum, and Float are supported.", cls);
break; break;
} }
buffer_free(buffer); bson_buffer_free(buffer);
rb_raise(InvalidDocument, "Cannot serialize an object of class %s into BSON.", cls); rb_raise(InvalidDocument, "Cannot serialize an object of class %s into BSON.", cls);
break; break;
} }
@ -470,11 +470,11 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
break; break;
} }
if(strcmp(cls, "BigDecimal") == 0) { if(strcmp(cls, "BigDecimal") == 0) {
buffer_free(buffer); bson_buffer_free(buffer);
rb_raise(InvalidDocument, "Cannot serialize the Numeric type %s as BSON; only Bignum, Fixnum, and Float are supported.", cls); rb_raise(InvalidDocument, "Cannot serialize the Numeric type %s as BSON; only Bignum, Fixnum, and Float are supported.", cls);
break; break;
} }
buffer_free(buffer); bson_buffer_free(buffer);
rb_raise(InvalidDocument, "Cannot serialize an object of class %s into BSON.", cls); rb_raise(InvalidDocument, "Cannot serialize an object of class %s into BSON.", cls);
break; break;
} }
@ -507,9 +507,9 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
has_extra = rb_funcall(value, rb_intern("respond_to?"), 1, rb_str_new2("extra_options_str")); has_extra = rb_funcall(value, rb_intern("respond_to?"), 1, rb_str_new2("extra_options_str"));
if (TYPE(has_extra) == T_TRUE) { if (TYPE(has_extra) == T_TRUE) {
VALUE extra = rb_funcall(value, rb_intern("extra_options_str"), 0); VALUE extra = rb_funcall(value, rb_intern("extra_options_str"), 0);
buffer_position old_position = buffer_get_position(buffer); bson_buffer_position old_position = bson_buffer_get_position(buffer);
SAFE_WRITE(buffer, RSTRING_PTR(extra), RSTRING_LENINT(extra)); SAFE_WRITE(buffer, RSTRING_PTR(extra), RSTRING_LENINT(extra));
qsort(buffer_get_buffer(buffer) + old_position, RSTRING_LEN(extra), sizeof(char), cmp_char); qsort(bson_buffer_get_buffer(buffer) + old_position, RSTRING_LEN(extra), sizeof(char), cmp_char);
} }
SAFE_WRITE(buffer, &zero, 1); SAFE_WRITE(buffer, &zero, 1);
@ -518,7 +518,7 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
default: default:
{ {
const char* cls = rb_obj_classname(value); const char* cls = rb_obj_classname(value);
buffer_free(buffer); bson_buffer_free(buffer);
rb_raise(InvalidDocument, "Cannot serialize an object of class %s (type %d) into BSON.", cls, TYPE(value)); rb_raise(InvalidDocument, "Cannot serialize an object of class %s (type %d) into BSON.", cls, TYPE(value));
break; break;
} }
@ -534,10 +534,10 @@ static int write_element_with_id(VALUE key, VALUE value, VALUE extra) {
return write_element(key, value, extra, 1); return write_element(key, value, extra, 1);
} }
static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_id) { static void write_doc(bson_buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_id) {
buffer_position start_position = buffer_get_position(buffer); bson_buffer_position start_position = bson_buffer_get_position(buffer);
buffer_position length_location = buffer_save_space(buffer, 4); bson_buffer_position length_location = bson_buffer_save_space(buffer, 4);
buffer_position length; bson_buffer_position length;
int allow_id; int allow_id;
int (*write_function)(VALUE, VALUE, VALUE) = NULL; int (*write_function)(VALUE, VALUE, VALUE) = NULL;
VALUE id_str = rb_str_new2("_id"); VALUE id_str = rb_str_new2("_id");
@ -590,17 +590,17 @@ static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_
} else if (rb_obj_is_kind_of(hash, RB_HASH) == Qtrue) { } else if (rb_obj_is_kind_of(hash, RB_HASH) == Qtrue) {
rb_hash_foreach(hash, write_function, pack_extra(buffer, check_keys)); rb_hash_foreach(hash, write_function, pack_extra(buffer, check_keys));
} else { } else {
buffer_free(buffer); bson_buffer_free(buffer);
rb_raise(InvalidDocument, "BSON.serialize takes a Hash but got a %s", rb_obj_classname(hash)); rb_raise(InvalidDocument, "BSON.serialize takes a Hash but got a %s", rb_obj_classname(hash));
} }
// write null byte and fill in length // write null byte and fill in length
SAFE_WRITE(buffer, &zero, 1); SAFE_WRITE(buffer, &zero, 1);
length = buffer_get_position(buffer) - start_position; length = bson_buffer_get_position(buffer) - start_position;
// make sure that length doesn't exceed 4MB // make sure that length doesn't exceed 4MB
if (length > max_bson_size) { if (length > max_bson_size) {
buffer_free(buffer); bson_buffer_free(buffer);
rb_raise(InvalidDocument, "Document too large: BSON documents are limited to %d bytes.", max_bson_size); rb_raise(InvalidDocument, "Document too large: BSON documents are limited to %d bytes.", max_bson_size);
return; return;
} }
@ -609,15 +609,15 @@ static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys, VALUE move_
static VALUE method_serialize(VALUE self, VALUE doc, VALUE check_keys, VALUE move_id) { static VALUE method_serialize(VALUE self, VALUE doc, VALUE check_keys, VALUE move_id) {
VALUE result; VALUE result;
buffer_t buffer = buffer_new(); bson_buffer_t buffer = bson_buffer_new();
if (buffer == NULL) { if (buffer == NULL) {
rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c"); rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
} }
write_doc(buffer, doc, check_keys, move_id); write_doc(buffer, doc, check_keys, move_id);
result = rb_str_new(buffer_get_buffer(buffer), buffer_get_position(buffer)); result = rb_str_new(bson_buffer_get_buffer(buffer), bson_buffer_get_position(buffer));
if (buffer_free(buffer) != 0) { if (bson_buffer_free(buffer) != 0) {
rb_raise(rb_eRuntimeError, "failed to free buffer"); rb_raise(rb_eRuntimeError, "failed to free buffer");
} }
return result; return result;