Skip to content

Commit

Permalink
split NuBSON into separate files, renamed NuMongoDBObjectID->NuBSONOb…
Browse files Browse the repository at this point in the history
…jectID
  • Loading branch information
Tim Burks committed Sep 3, 2010
1 parent 53d6e17 commit b7eac84
Show file tree
Hide file tree
Showing 5 changed files with 371 additions and 335 deletions.
52 changes: 52 additions & 0 deletions objc/NuBSON.h
@@ -0,0 +1,52 @@
/*!
@header NuBSON.h
@discussion Declarations for the NuBSON component.
@copyright Copyright (c) 2010 Neon Design Technology, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "bson.h"

#import <Foundation/Foundation.h>

/*!
@class NuBSON
@abstract A BSON serializer and deserializer.
@discussion BSON is the wire format used to communicate with MongoDB.
*/
@interface NuBSON : NSObject
{
@public
bson bsonValue;
}

/*! Create a BSON representation of a dictionary object. */
- (NuBSON *) initWithDictionary:(NSDictionary *) dict;
/*! Return a dictionary equivalent of a BSON object. */
- (NSMutableDictionary *) dictionaryValue;
@end

@interface NuBSONObjectID : NSObject
{
@public
bson_oid_t oid;
}

@end

bson *bson_for_object(id object);

316 changes: 316 additions & 0 deletions objc/NuBSON.m
@@ -0,0 +1,316 @@
#import "NuMongoDB.h"

@interface NuBSON (Private)
- (NuBSON *) initWithBSON:(bson) b;
@end

@implementation NuBSONObjectID
- (id) initWithString:(NSString *) s
{
if (self = [super init]) {
bson_oid_from_string(&oid, [s cStringUsingEncoding:NSUTF8StringEncoding]);
}
return self;
}

- (id) initWithObjectIDPointer:(const bson_oid_t *) objectIDPointer
{
if (self = [super init]) {
oid = *objectIDPointer;
}
return self;
}

- (const bson_oid_t *) objectIDPointer {return &oid;}

- (NSString *) description
{
char buffer[25]; /* str must be at least 24 hex chars + null byte */
bson_oid_to_string(&oid, buffer);
return [NSString stringWithFormat:@"(oid \"%s\")", buffer];
}

- (NSString *) stringValue
{
char buffer[25]; /* str must be at least 24 hex chars + null byte */
bson_oid_to_string(&oid, buffer);
return [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];
}

- (NSComparisonResult)compare:(NuBSONObjectID *) other
{
for (int i = 0; i < 3; i++) {
int diff = oid.ints[i] - other->oid.ints[i];
if (diff < 0)
return NSOrderedAscending;
else if (diff > 0)
return NSOrderedDescending;
}
return NSOrderedSame;
}

- (BOOL)isEqual:(id)other
{
return ([self compare:other] == 0);
}

@end

@implementation NuBSON

- (NuBSON *) initWithBSON:(bson) b
{
if (self = [super init]) {
bsonValue = b;
}
return self;
}

void add_object_to_bson_buffer(bson_buffer *bb, id key, id object)
{
const char *name = [key cStringUsingEncoding:NSUTF8StringEncoding];

if ([object isKindOfClass:[NSNumber class]]) {
const char *objCType = [object objCType];
switch (*objCType) {
case 'd':
case 'f':
bson_append_double(bb, name, [object doubleValue]);
break;
case 'l':
case 'L':
bson_append_long(bb, name, [object longValue]);
break;
case 'B':
bson_append_bool(bb, name, [object boolValue]);
break;
case 'c':
case 'C':
case 's':
case 'S':
case 'i':
case 'I':
default:
bson_append_int(bb, name, [object intValue]);
break;
}
}
else if ([object respondsToSelector:@selector(cStringUsingEncoding:)]) {
bson_append_string(bb, name,[object cStringUsingEncoding:NSUTF8StringEncoding]);
}
else if ([object isKindOfClass:[NSDictionary class]]) {
bson_buffer *sub = bson_append_start_object(bb, name);
id keys = [object allKeys];
for (int i = 0; i < [keys count]; i++) {
id key = [keys objectAtIndex:i];
add_object_to_bson_buffer(sub, key, [object objectForKey:key]);
}
bson_append_finish_object(sub);
}
else if ([object isKindOfClass:[NSArray class]]) {
bson_buffer *arr = bson_append_start_array(bb, name);
for (int i = 0; i < [object count]; i++) {
add_object_to_bson_buffer(arr, [[NSNumber numberWithInt:i] stringValue], [object objectAtIndex:i]);
}
bson_append_finish_object(arr);
}
else if ([object isKindOfClass:[NSNull class]]) {
bson_append_null(bb, name);
}
else if ([object isKindOfClass:[NSDate class]]) {
bson_date_t millis = (bson_date_t) ([object timeIntervalSince1970] * 1000.0);
bson_append_date(bb, name, millis);
}
else if ([object isKindOfClass:[NSData class]]) {
bson_append_binary(bb, name, 0, [object bytes], [object length]);
}
else if ([object isKindOfClass:[NuBSONObjectID class]]) {
bson_append_oid(bb, name, [((NuBSONObjectID *) object) objectIDPointer]);
}
else {
NSLog(@"We have a problem. %@ cannot be serialized to bson", object);
}
}

- (NuBSON *) initWithDictionary:(NSDictionary *) dict
{
bson b;
bson_buffer bb;
bson_buffer_init(& bb );
id keys = [dict allKeys];
for (int i = 0; i < [keys count]; i++) {
id key = [keys objectAtIndex:i];
add_object_to_bson_buffer(&bb, key, [dict objectForKey:key]);
}
bson_from_buffer(&b, &bb);
return [self initWithBSON:b];
}

void dump_bson_iterator(bson_iterator it, const char *indent)
{
bson_iterator it2;
bson subobject;

char more_indent[2000];
sprintf(more_indent, " %s", indent);

while(bson_iterator_next(&it)) {
fprintf(stderr, "%s %s: ", indent, bson_iterator_key(&it));
char hex_oid[25];

switch(bson_iterator_type(&it)) {
case bson_double:
fprintf(stderr, "(double) %e\n", bson_iterator_double(&it));
break;
case bson_int:
fprintf(stderr, "(int) %d\n", bson_iterator_int(&it));
break;
case bson_string:
fprintf(stderr, "(string) \"%s\"\n", bson_iterator_string(&it));
break;
case bson_oid:
bson_oid_to_string(bson_iterator_oid(&it), hex_oid);
fprintf(stderr, "(oid) \"%s\"\n", hex_oid);
break;
case bson_object:
fprintf(stderr, "(subobject) {...}\n");
bson_iterator_subobject(&it, &subobject);
bson_iterator_init(&it2, subobject.data);
dump_bson_iterator(it2, more_indent);
break;
case bson_array:
fprintf(stderr, "(array) [...]\n");
bson_iterator_subobject(&it, &subobject);
bson_iterator_init(&it2, subobject.data);
dump_bson_iterator(it2, more_indent);
break;
default:
fprintf(stderr, "(type %d)\n", bson_iterator_type(&it));
break;
}
}
}

- (void) dump
{
bson_iterator it;
bson_iterator_init(&it, bsonValue.data);
dump_bson_iterator(it, "");
fprintf(stderr, "\n");
}

void add_bson_to_object(bson_iterator it, id object)
{
bson_iterator it2;
bson subobject;

while(bson_iterator_next(&it)) {

NSString *key = [[[NSString alloc] initWithCString:bson_iterator_key(&it) encoding:NSUTF8StringEncoding] autorelease];

id value = nil;
char hex_oid[25];
switch(bson_iterator_type(&it)) {
case bson_eoo:
break;
case bson_double:
value = [NSNumber numberWithDouble:bson_iterator_double(&it)];
break;
case bson_string:
value = [[[NSString alloc] initWithCString:bson_iterator_string(&it) encoding:NSUTF8StringEncoding] autorelease];
break;
case bson_object:
value = [NSMutableDictionary dictionary];
bson_iterator_subobject(&it, &subobject);
bson_iterator_init(&it2, subobject.data);
add_bson_to_object(it2, value);
break;
case bson_array:
value = [NSMutableArray array];
bson_iterator_subobject(&it, &subobject);
bson_iterator_init(&it2, subobject.data);
add_bson_to_object(it2, value);
break;
case bson_bindata:
value = [NSData
dataWithBytes:bson_iterator_bin_data(&it)
length:bson_iterator_bin_len(&it)];
break;
case bson_undefined:
break;
case bson_oid:
value = [[[NuBSONObjectID alloc] initWithObjectIDPointer:bson_iterator_oid(&it)] autorelease];
break;
case bson_bool:
value = [NSNumber numberWithBool:bson_iterator_bool(&it)];
break;
case bson_date:
value = [NSDate dateWithTimeIntervalSince1970:(0.001 * bson_iterator_date(&it))];
break;
case bson_null:
value = [NSNull null];
break;
case bson_regex:
break;
case bson_code:
break;
case bson_symbol:
break;
case bson_codewscope:
break;
case bson_int:
value = [NSNumber numberWithInt:bson_iterator_int(&it)];
break;
case bson_timestamp:
break;
case bson_long:
value = [NSNumber numberWithLong:bson_iterator_long(&it)];
break;
default:
break;
}
if (value) {
if ([object isKindOfClass:[NSDictionary class]]) {
[object setObject:value forKey:key];
}
else if ([object isKindOfClass:[NSArray class]]) {
[object addObject:value];
}
else {
fprintf(stderr, "(type %d)\n", bson_iterator_type(&it));
NSLog(@"we don't know how to add to %@", object);
}
}
}
}

- (NSMutableDictionary *) dictionaryValue
{
id object = [NSMutableDictionary dictionary];

bson_iterator it;
bson_iterator_init(&it, bsonValue.data);
add_bson_to_object(it, object);
return object;
}

@end

bson *bson_for_object(id object)
{
bson *b = 0;
if (!object) {
object = [NSDictionary dictionary];
}
if ([object isKindOfClass:[NuBSON class]]) {
b = &(((NuBSON *)object)->bsonValue);
}
else if ([object isKindOfClass:[NSDictionary class]]) {
NuBSON *bsonObject = [[[NuBSON alloc] initWithDictionary:object] autorelease];
b = &(bsonObject->bsonValue);
}
else {
NSLog(@"unable to convert objects of type %@ to BSON (%@).", [object className], object);
}
return b;
}
17 changes: 1 addition & 16 deletions objc/NuMongoDB.h
Expand Up @@ -24,22 +24,7 @@ limitations under the License.


#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>


/*! #import "NuBSON.h"
@class NuBSON
@abstract A BSON serializer and deserializer.
@discussion BSON is the wire format used to communicate with MongoDB.
*/
@interface NuBSON : NSObject
{
@public
bson bsonValue;
}

/*! Create a BSON representation of a dictionary object. */
- (NuBSON *) initWithDictionary:(NSDictionary *) dict;
/*! Return a dictionary equivalent of a BSON object. */
- (NSMutableDictionary *) dictionaryValue;
@end


/*! /*!
@class NuMongoDBCursor @class NuMongoDBCursor
Expand Down

0 comments on commit b7eac84

Please sign in to comment.