checkpoint - beginnings of c encoder
This commit is contained in:
parent
f907edcde5
commit
c69fbb7f67
|
@ -4,3 +4,6 @@ pkg
|
|||
doc
|
||||
mongo-ruby-driver-*.gem
|
||||
nbproject
|
||||
*.bundle
|
||||
*.o
|
||||
ext/cbson/Makefile
|
||||
|
|
13
Rakefile
13
Rakefile
|
@ -4,7 +4,10 @@ require 'fileutils'
|
|||
require 'rake'
|
||||
require 'rake/testtask'
|
||||
require 'rake/gempackagetask'
|
||||
require 'rake/contrib/rubyforgepublisher'
|
||||
begin
|
||||
require 'rake/contrib/rubyforgepublisher'
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
# NOTE: some of the tests assume Mongo is running
|
||||
Rake::TestTask.new do |t|
|
||||
|
@ -23,6 +26,14 @@ task :publish => [:rdoc] do
|
|||
Rake::RubyForgePublisher.new(GEM, RUBYFORGE_USER).upload
|
||||
end
|
||||
|
||||
desc "Compile the extension"
|
||||
task :compile do
|
||||
cd 'ext/cbson'
|
||||
ruby 'extconf.rb'
|
||||
sh 'make'
|
||||
cp 'cbson.bundle', '../../lib/mongo/ext/cbson.bundle'
|
||||
end
|
||||
|
||||
namespace :gem do
|
||||
|
||||
desc "Install the gem locally"
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
#include "ruby.h"
|
||||
#include <assert.h>
|
||||
|
||||
#define INITIAL_BUFFER_SIZE 256
|
||||
|
||||
typedef struct {
|
||||
char* buffer;
|
||||
int size;
|
||||
int position;
|
||||
} bson_buffer;
|
||||
|
||||
static bson_buffer* buffer_new(void) {
|
||||
bson_buffer* buffer;
|
||||
buffer = (bson_buffer*)malloc(sizeof(bson_buffer));
|
||||
assert(buffer);
|
||||
|
||||
buffer->size = INITIAL_BUFFER_SIZE;
|
||||
buffer->position = 0;
|
||||
buffer->buffer = (char*)malloc(INITIAL_BUFFER_SIZE);
|
||||
assert(buffer->buffer);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void buffer_free(bson_buffer* buffer) {
|
||||
assert(buffer);
|
||||
assert(buffer->buffer);
|
||||
|
||||
free(buffer->buffer);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
static void buffer_resize(bson_buffer* buffer, int min_length) {
|
||||
int size = buffer->size;
|
||||
if (size >= min_length) {
|
||||
return;
|
||||
}
|
||||
while (size < min_length) {
|
||||
size *= 2;
|
||||
}
|
||||
buffer->buffer = (char*)realloc(buffer->buffer, size);
|
||||
assert(buffer->buffer);
|
||||
buffer->size = size;
|
||||
}
|
||||
|
||||
static void buffer_assure_space(bson_buffer* buffer, int size) {
|
||||
if (buffer->position + size <= buffer->size) {
|
||||
return;
|
||||
}
|
||||
buffer_resize(buffer, buffer->position + size);
|
||||
}
|
||||
|
||||
/* returns offset for writing */
|
||||
static int buffer_save_bytes(bson_buffer* buffer, int size) {
|
||||
buffer_assure_space(buffer, size);
|
||||
int position = buffer->position;
|
||||
buffer->position += size;
|
||||
return position;
|
||||
}
|
||||
|
||||
static void buffer_write_bytes(bson_buffer* buffer, const char* bytes, int size) {
|
||||
buffer_assure_space(buffer, size);
|
||||
|
||||
memcpy(buffer->buffer + buffer->position, bytes, size);
|
||||
buffer->position += size;
|
||||
}
|
||||
|
||||
static VALUE method_serialize(VALUE self, VALUE doc) {
|
||||
char data[5] = {0x05, 0x00, 0x00, 0x00, 0x00};
|
||||
return rb_str_new(data, 5);
|
||||
}
|
||||
|
||||
void Init_cbson() {
|
||||
VALUE CBson = rb_define_module("CBson");
|
||||
rb_define_module_function(CBson, "serialize", method_serialize, 1);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
require 'mkmf'
|
||||
|
||||
extension_name = 'cbson'
|
||||
|
||||
dir_config(extension_name)
|
||||
|
||||
create_makefile(extension_name)
|
|
@ -72,21 +72,28 @@ class BSON
|
|||
@buf.to_a
|
||||
end
|
||||
|
||||
def serialize(obj)
|
||||
raise "Document is null" unless obj
|
||||
begin
|
||||
require 'mongo/ext/cbson'
|
||||
def serialize(obj)
|
||||
@buf = ByteBuffer.new(CBson.serialize(obj))
|
||||
end
|
||||
rescue LoadError
|
||||
def serialize(obj)
|
||||
raise "Document is null" unless obj
|
||||
|
||||
@buf.rewind
|
||||
# put in a placeholder for the total size
|
||||
@buf.put_int(0)
|
||||
@buf.rewind
|
||||
# put in a placeholder for the total size
|
||||
@buf.put_int(0)
|
||||
|
||||
# Write key/value pairs. Always write _id first if it exists.
|
||||
oid = obj['_id'] || obj[:_id]
|
||||
serialize_key_value('_id', oid) if oid
|
||||
obj.each {|k, v| serialize_key_value(k, v) unless k == '_id' || k == :_id }
|
||||
# Write key/value pairs. Always write _id first if it exists.
|
||||
oid = obj['_id'] || obj[:_id]
|
||||
serialize_key_value('_id', oid) if oid
|
||||
obj.each {|k, v| serialize_key_value(k, v) unless k == '_id' || k == :_id }
|
||||
|
||||
serialize_eoo_element(@buf)
|
||||
@buf.put_int(@buf.size, 0)
|
||||
self
|
||||
serialize_eoo_element(@buf)
|
||||
@buf.put_int(@buf.size, 0)
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
def serialize_key_value(k, v)
|
||||
|
|
Loading…
Reference in New Issue