RUBY-302 RUBY-303 fix buffer namespace conflict by renaming to bson_buffer.
This commit is contained in:
parent
b32f895ed6
commit
ace1313b99
@ -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;
|
||||||
}
|
}
|
@ -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
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user