Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added lower-level tools for building bson.

I discovered a problem related to using NSDictionary instances to
build bson queries. NSDictionary keys are unordered, so there is
no way to control the ordering of elements in a bson object
created from a dictionary. This is ordinarily not a problem,
but commands run with the runCommand:inDatabase: method must
have their elements specified in the correct order.
  • Loading branch information...
commit 5c00e6ccd3768b66c6e7117180e2fd76b7b11066 1 parent af6dfc4
Tim Burks authored
Showing with 86 additions and 2 deletions.
  1. +11 −0 objc/NuBSON.h
  2. +75 −2 objc/NuBSON.m
11 objc/NuBSON.h
View
@@ -62,3 +62,14 @@ bson *bson_for_object(id object);
@interface NSDictionary (NuBSON)
- (NSData *) BSONRepresentation;
@end
+
+@interface NuBSONBuffer : NSObject
+{
+ bson_buffer bb;
+}
+
+- (id) init;
+- (NuBSON *) bsonValue;
+- (void) addObject:(id) object withKey:(id) key;
+
+@end
77 objc/NuBSON.m
View
@@ -84,6 +84,9 @@ void add_object_to_bson_buffer(bson_buffer *bb, id key, id object)
{
const char *name = [key cStringUsingEncoding:NSUTF8StringEncoding];
+ Class NuCell = NSClassFromString(@"NuCell");
+ Class NuSymbol = NSClassFromString(@"NuSymbol");
+
if ([object isKindOfClass:[NSNumber class]]) {
const char *objCType = [object objCType];
switch (*objCType) {
@@ -145,6 +148,32 @@ void add_object_to_bson_buffer(bson_buffer *bb, id key, id object)
else if ([object isKindOfClass:[NuBSONObjectID class]]) {
bson_append_oid(bb, name, [((NuBSONObjectID *) object) objectIDPointer]);
}
+ else if (NuCell && [object isKindOfClass:[NuCell class]]) {
+ if ([[object car] isKindOfClass:[NuSymbol class]] && (([object length] % 2) == 0)) {
+ // assume we have an object
+ bson_buffer *sub = bson_append_start_object(bb, name);
+ id cursor = object;
+ while (cursor && (cursor != [NSNull null])) {
+ id key = [[cursor car] labelName];
+ id value = [[cursor cdr] car];
+ add_object_to_bson_buffer(sub, key, value);
+ cursor = [[cursor cdr] cdr];
+ }
+ bson_append_finish_object(sub);
+ }
+ else {
+ // assume we have an array
+ bson_buffer *arr = bson_append_start_array(bb, name);
+ id cursor = object;
+ int i = 0;
+ while (cursor && (cursor != [NSNull null])) {
+ add_object_to_bson_buffer(arr, [[NSNumber numberWithInt:i] stringValue], [cursor car]);
+ i++;
+ cursor = [cursor cdr];
+ }
+ bson_append_finish_object(arr);
+ }
+ }
else {
NSLog(@"We have a problem. %@ cannot be serialized to bson", object);
}
@@ -164,6 +193,22 @@ - (NuBSON *) initWithDictionary:(NSDictionary *) dict
return [self initWithBSON:b];
}
+- (NuBSON *) initWithList:(id) cell
+{
+ bson b;
+ bson_buffer bb;
+ bson_buffer_init(& bb );
+ id cursor = cell;
+ while (cursor && (cursor != [NSNull null])) {
+ id key = [[cursor car] labelName];
+ id value = [[cursor cdr] car];
+ add_object_to_bson_buffer(&bb, key, value);
+ cursor = [[cursor cdr] cdr];
+ }
+ bson_from_buffer(&b, &bb);
+ return [self initWithBSON:b];
+}
+
void dump_bson_iterator(bson_iterator it, const char *indent)
{
bson_iterator it2;
@@ -224,7 +269,9 @@ void add_bson_to_object(bson_iterator it, id object)
while(bson_iterator_next(&it)) {
- NSString *key = [[[NSString alloc] initWithCString:bson_iterator_key(&it) encoding:NSUTF8StringEncoding] autorelease];
+ NSString *key = [[[NSString alloc]
+ initWithCString:bson_iterator_key(&it) encoding:NSUTF8StringEncoding]
+ autorelease];
id value = nil;
char hex_oid[25];
@@ -235,7 +282,9 @@ void add_bson_to_object(bson_iterator it, id object)
value = [NSNumber numberWithDouble:bson_iterator_double(&it)];
break;
case bson_string:
- value = [[[NSString alloc] initWithCString:bson_iterator_string(&it) encoding:NSUTF8StringEncoding] autorelease];
+ value = [[[NSString alloc]
+ initWithCString:bson_iterator_string(&it) encoding:NSUTF8StringEncoding]
+ autorelease];
break;
case bson_object:
value = [NSMutableDictionary dictionary];
@@ -354,3 +403,27 @@ - (NSData *) BSONRepresentation
}
@end
+
+@implementation NuBSONBuffer
+
+- (id) init
+{
+ if (self = [super init]) {
+ bson_buffer_init(& bb );
+ }
+ return self;
+}
+
+- (NuBSON *) bsonValue
+{
+ bson b;
+ bson_from_buffer(&b, &bb);
+ return [[[NuBSON alloc] initWithBSON:b] autorelease];
+}
+
+- (void) addObject:(id) object withKey:(id) key
+{
+ add_object_to_bson_buffer(&bb, key, object);
+}
+
+@end
Please sign in to comment.
Something went wrong with that request. Please try again.