Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Container With Pre-Encoded Strings #151

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions JSONKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@
#ifdef __cplusplus
extern "C" {
#endif


@interface PreSerialized : NSObject
- (NSString *)JSONString;
- (NSData *)JSONData;
@end

// For Mac OS X < 10.5.
#ifndef NSINTEGER_DEFINED
Expand Down Expand Up @@ -207,6 +211,8 @@ typedef struct JKParseState JKParseState; // Opaque internal, private type.
- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions includeQuotes:(BOOL)includeQuotes error:(NSError **)error;
- (NSString *)JSONString; // Invokes JSONStringWithOptions:JKSerializeOptionNone includeQuotes:YES
- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions includeQuotes:(BOOL)includeQuotes error:(NSError **)error;
- (PreSerialized *)JSONPreSerialized; // Invokes JSONPreSerializedWithOptions:JKSerializeOptionNone includeQuotes:YES
- (PreSerialized *)JSONPreSerializedWithOptions:(JKSerializeOptionFlags)serializeOptions includeQuotes:(BOOL)includeQuotes error:(NSError **)error;
@end

@interface NSArray (JSONKitSerializing)
Expand All @@ -216,6 +222,9 @@ typedef struct JKParseState JKParseState; // Opaque internal, private type.
- (NSString *)JSONString;
- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingDelegate:(id)delegate selector:(SEL)selector error:(NSError **)error;
- (PreSerialized *)JSONPreSerialized;
- (PreSerialized *)JSONPreSerializedWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
- (PreSerialized *)JSONPreSerializedWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingDelegate:(id)delegate selector:(SEL)selector error:(NSError **)error;
@end

@interface NSDictionary (JSONKitSerializing)
Expand All @@ -225,23 +234,26 @@ typedef struct JKParseState JKParseState; // Opaque internal, private type.
- (NSString *)JSONString;
- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingDelegate:(id)delegate selector:(SEL)selector error:(NSError **)error;
- (PreSerialized *)JSONPreSerialized;
- (PreSerialized *)JSONPreSerializedWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error;
- (PreSerialized *)JSONPreSerializedWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingDelegate:(id)delegate selector:(SEL)selector error:(NSError **)error;
@end

#ifdef __BLOCKS__

@interface NSArray (JSONKitSerializingBlockAdditions)
- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error;
- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error;
- (PreSerialized *)JSONPreSerializedWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error;
@end

@interface NSDictionary (JSONKitSerializingBlockAdditions)
- (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error;
- (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error;
@end

- (PreSerialized *)JSONPreSerializedWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error;
@end
#endif



#endif // __OBJC__

#endif // _JSONKIT_H_
Expand Down
142 changes: 130 additions & 12 deletions JSONKit.m
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ The code in isValidCodePoint() is derived from the ICU code in
JKClassArray = 3,
JKClassDictionary = 4,
JKClassNull = 5,
JKClassPreSerialized = 6,
};

enum {
Expand Down Expand Up @@ -457,6 +458,7 @@ The code in isValidCodePoint() is derived from the ICU code in
void *arrayClass;
void *dictionaryClass;
void *nullClass;
void *preSerializedClass;
};

struct JKEncodeCache {
Expand Down Expand Up @@ -872,6 +874,15 @@ - (id)nextObject

@end

@interface PreSerialized ()
{
NSData * _data;
JKSerializeOptionFlags _serializeOptionFlags;
}
+(instancetype)preSerializedWithData:(NSData *)data options:(JKSerializeOptionFlags)options;
@property (readonly, nonatomic) JKSerializeOptionFlags serializeOptionFlags;
@end

#pragma mark -
@interface JKDictionary : NSMutableDictionary <NSCopying, NSMutableCopying, NSFastEnumeration> {
NSUInteger count, capacity, mutations;
Expand Down Expand Up @@ -2092,7 +2103,7 @@ - (id)init
return([self initWithParseOptions:JKParseOptionStrict]);
}

- (id)initWithParseOptions:(JKParseOptionFlags)parseOptionFlags
- (id)initWithParseOptiOons:(JKParseOptionFlags)parseOptionFlags
{
if((self = [super init]) == NULL) { return(NULL); }

Expand Down Expand Up @@ -2599,18 +2610,20 @@ static int jk_encode_add_atom_to_buffer(JKEncodeState *encodeState, void *object
void *objectISA = (JK_EXPECT_F(workAroundMacOSXABIBreakingBug)) ? NULL : *((void **)objectPtr);
if(JK_EXPECT_F(workAroundMacOSXABIBreakingBug)) { goto slowClassLookup; }

if(JK_EXPECT_T(objectISA == encodeState->fastClassLookup.stringClass)) { isClass = JKClassString; }
else if(JK_EXPECT_T(objectISA == encodeState->fastClassLookup.numberClass)) { isClass = JKClassNumber; }
else if(JK_EXPECT_T(objectISA == encodeState->fastClassLookup.dictionaryClass)) { isClass = JKClassDictionary; }
else if(JK_EXPECT_T(objectISA == encodeState->fastClassLookup.arrayClass)) { isClass = JKClassArray; }
else if(JK_EXPECT_T(objectISA == encodeState->fastClassLookup.nullClass)) { isClass = JKClassNull; }
else {
if(JK_EXPECT_T(objectISA == encodeState->fastClassLookup.stringClass)) { isClass = JKClassString; }
else if(JK_EXPECT_T(objectISA == encodeState->fastClassLookup.numberClass)) { isClass = JKClassNumber; }
else if(JK_EXPECT_T(objectISA == encodeState->fastClassLookup.dictionaryClass)) { isClass = JKClassDictionary; }
else if(JK_EXPECT_T(objectISA == encodeState->fastClassLookup.arrayClass)) { isClass = JKClassArray; }
else if(JK_EXPECT_T(objectISA == encodeState->fastClassLookup.nullClass)) { isClass = JKClassNull; }
else if(JK_EXPECT_T(objectISA == encodeState->fastClassLookup.preSerializedClass)) { isClass = JKClassPreSerialized; }
else {
slowClassLookup:
if(JK_EXPECT_T([object isKindOfClass:[NSString class]])) { if(workAroundMacOSXABIBreakingBug == NO) { encodeState->fastClassLookup.stringClass = objectISA; } isClass = JKClassString; }
else if(JK_EXPECT_T([object isKindOfClass:[NSNumber class]])) { if(workAroundMacOSXABIBreakingBug == NO) { encodeState->fastClassLookup.numberClass = objectISA; } isClass = JKClassNumber; }
else if(JK_EXPECT_T([object isKindOfClass:[NSDictionary class]])) { if(workAroundMacOSXABIBreakingBug == NO) { encodeState->fastClassLookup.dictionaryClass = objectISA; } isClass = JKClassDictionary; }
else if(JK_EXPECT_T([object isKindOfClass:[NSArray class]])) { if(workAroundMacOSXABIBreakingBug == NO) { encodeState->fastClassLookup.arrayClass = objectISA; } isClass = JKClassArray; }
else if(JK_EXPECT_T([object isKindOfClass:[NSNull class]])) { if(workAroundMacOSXABIBreakingBug == NO) { encodeState->fastClassLookup.nullClass = objectISA; } isClass = JKClassNull; }
if(JK_EXPECT_T([object isKindOfClass:[NSString class]])) { if(workAroundMacOSXABIBreakingBug == NO) { encodeState->fastClassLookup.stringClass = objectISA; } isClass = JKClassString; }
else if(JK_EXPECT_T([object isKindOfClass:[NSNumber class]])) { if(workAroundMacOSXABIBreakingBug == NO) { encodeState->fastClassLookup.numberClass = objectISA; } isClass = JKClassNumber; }
else if(JK_EXPECT_T([object isKindOfClass:[NSDictionary class]])) { if(workAroundMacOSXABIBreakingBug == NO) { encodeState->fastClassLookup.dictionaryClass = objectISA; } isClass = JKClassDictionary; }
else if(JK_EXPECT_T([object isKindOfClass:[NSArray class]])) { if(workAroundMacOSXABIBreakingBug == NO) { encodeState->fastClassLookup.arrayClass = objectISA; } isClass = JKClassArray; }
else if(JK_EXPECT_T([object isKindOfClass:[NSNull class]])) { if(workAroundMacOSXABIBreakingBug == NO) { encodeState->fastClassLookup.nullClass = objectISA; } isClass = JKClassNull; }
else if(JK_EXPECT_T([object isKindOfClass:[PreSerialized class]])) { if(workAroundMacOSXABIBreakingBug == NO) { encodeState->fastClassLookup.preSerializedClass = objectISA; } isClass = JKClassPreSerialized; }
else {
if((rerunningAfterClassFormatter == NO) && (
#ifdef __BLOCKS__
Expand Down Expand Up @@ -2722,6 +2735,23 @@ static int jk_encode_add_atom_to_buffer(JKEncodeState *encodeState, void *object
}
break;

case JKClassPreSerialized:
{
if(JK_EXPECT_F([object serializeOptionFlags] != encodeState->serializeOptionFlags)) {
jk_encode_error(encodeState, @"PreSerialized objects were created with differente serialization options"); return (1); }
CFDataRef objBytes = (CFDataRef)[object JSONData];
CFIndex bytesLength = CFDataGetLength(objBytes);
if(bytesLength >= 0) {
if(JK_EXPECT_F(((encodeState->atIndex + (bytesLength * 2UL) + 256UL) > encodeState->stringBuffer.bytes.length)) && JK_EXPECT_F((jk_managedBuffer_resize(&encodeState->stringBuffer, encodeState->atIndex + (bytesLength * 2UL) + 1024UL) == NULL))) { jk_encode_error(encodeState, @"Unable to resize temporary buffer."); return(1); }
CFDataGetBytes((CFDataRef)objBytes, CFRangeMake(0, bytesLength), &encodeState->stringBuffer.bytes.ptr[encodeState->atIndex++]);
encodeState->atIndex += bytesLength - 1;
NSCParameterAssert((encodeState->atIndex + 1UL) < encodeState->stringBuffer.bytes.length);
jk_encode_updateCache(encodeState, cacheSlot, startingAtIndex, encodeCacheObject);
return(0);
}
}
break;

case JKClassNumber:
{
if(object == (id)kCFBooleanTrue) { return(jk_encode_writen(encodeState, cacheSlot, startingAtIndex, encodeCacheObject, "true", 4UL)); }
Expand Down Expand Up @@ -2952,6 +2982,17 @@ - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions inc
return([JKSerializer serializeObject:self options:serializeOptions encodeOption:(JKEncodeOptionAsString | ((includeQuotes == NO) ? JKEncodeOptionStringObjTrimQuotes : 0UL) | JKEncodeOptionStringObj) block:NULL delegate:NULL selector:NULL error:error]);
}

// PreSerialized returning methods...
- (PreSerialized *)JSONPreSerialized
{
return ([self JSONPreSerializedWithOptions:JKSerializeOptionNone includeQuotes:YES error:NULL]);
}

- (PreSerialized *)JSONPreSerializedWithOptions:(JKSerializeOptionFlags)serializeOptions includeQuotes:(BOOL)includeQuotes error:(NSError **)error
{
return [PreSerialized preSerializedWithData:[self JSONDataWithOptions:serializeOptions includeQuotes:includeQuotes error:error] options:serializeOptions];
}

@end

@implementation NSArray (JSONKitSerializing)
Expand Down Expand Up @@ -2990,6 +3031,22 @@ - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions ser
return([JKSerializer serializeObject:self options:serializeOptions encodeOption:(JKEncodeOptionAsString | JKEncodeOptionCollectionObj) block:NULL delegate:delegate selector:selector error:error]);
}

// PreSerialized returning methods...

- (PreSerialized *)JSONPreSerialized
{
return([PreSerialized preSerializedWithData:[JKSerializer serializeObject:self options:JKSerializeOptionNone encodeOption:(JKEncodeOptionAsData | JKEncodeOptionCollectionObj) block:NULL delegate:NULL selector:NULL error:NULL] options:JKSerializeOptionNone]);
}

- (PreSerialized *)JSONPreSerializedWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error
{
return([PreSerialized preSerializedWithData:[JKSerializer serializeObject:self options:serializeOptions encodeOption:(JKEncodeOptionAsData | JKEncodeOptionCollectionObj) block:NULL delegate:NULL selector:NULL error:error] options:serializeOptions]);
}

- (PreSerialized *)JSONPreSerializedWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingDelegate:(id)delegate selector:(SEL)selector error:(NSError **)error
{
return([PreSerialized preSerializedWithData:[JKSerializer serializeObject:self options:serializeOptions encodeOption:(JKEncodeOptionAsData | JKEncodeOptionCollectionObj) block:NULL delegate:delegate selector:selector error:error] options:serializeOptions]);
}
@end

@implementation NSDictionary (JSONKitSerializing)
Expand Down Expand Up @@ -3028,6 +3085,22 @@ - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions ser
return([JKSerializer serializeObject:self options:serializeOptions encodeOption:(JKEncodeOptionAsString | JKEncodeOptionCollectionObj) block:NULL delegate:delegate selector:selector error:error]);
}

// PreSerialized returning methods...

- (PreSerialized *)JSONPreSerialized
{
return([PreSerialized preSerializedWithData:[JKSerializer serializeObject:self options:JKSerializeOptionNone encodeOption:(JKEncodeOptionAsData | JKEncodeOptionCollectionObj) block:NULL delegate:NULL selector:NULL error:NULL] options:JKSerializeOptionNone]);
}

- (PreSerialized *)JSONPreSerializedWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error
{
return([PreSerialized preSerializedWithData:[JKSerializer serializeObject:self options:serializeOptions encodeOption:(JKEncodeOptionAsData | JKEncodeOptionCollectionObj) block:NULL delegate:NULL selector:NULL error:error] options:serializeOptions]);
}

- (PreSerialized *)JSONPreSerializedWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingDelegate:(id)delegate selector:(SEL)selector error:(NSError **)error
{
return([PreSerialized preSerializedWithData:[JKSerializer serializeObject:self options:serializeOptions encodeOption:(JKEncodeOptionAsData | JKEncodeOptionCollectionObj) block:NULL delegate:delegate selector:selector error:error] options:serializeOptions]);
}
@end


Expand All @@ -3045,6 +3118,10 @@ - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions ser
return([JKSerializer serializeObject:self options:serializeOptions encodeOption:(JKEncodeOptionAsString | JKEncodeOptionCollectionObj) block:block delegate:NULL selector:NULL error:error]);
}

- (PreSerialized *)JSONPreSerializedWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error
{
return([PreSerialized preSerializedWithData:[JKSerializer serializeObject:self options:serializeOptions encodeOption:(JKEncodeOptionAsData | JKEncodeOptionCollectionObj) block:block delegate:NULL selector:NULL error:error] options:serializeOptions]);
}
@end

@implementation NSDictionary (JSONKitSerializingBlockAdditions)
Expand All @@ -3059,7 +3136,48 @@ - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions ser
return([JKSerializer serializeObject:self options:serializeOptions encodeOption:(JKEncodeOptionAsString | JKEncodeOptionCollectionObj) block:block delegate:NULL selector:NULL error:error]);
}

- (PreSerialized *)JSONPreSerializedWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error
{
return([PreSerialized preSerializedWithData:[JKSerializer serializeObject:self options:serializeOptions encodeOption:(JKEncodeOptionAsData | JKEncodeOptionCollectionObj) block:block delegate:NULL selector:NULL error:error] options:serializeOptions]);
}
@end

#endif // __BLOCKS__

@implementation PreSerialized
-(instancetype)initWithData:(NSData *)data options:(JKSerializeOptionFlags)options
{
if (self = [super init]) {
_data = [data retain];
_serializeOptionFlags = options;
}
return self;
}

+(instancetype)preSerializedWithData:(NSData *)data options:(JKSerializeOptionFlags)options
{
return [[[self alloc] initWithData:data options:options] autorelease];
}

-(JKSerializeOptionFlags)serializeOptionFlags
{
return _serializeOptionFlags;
}

-(NSString *)JSONString
{
return [[[NSString alloc] initWithData:_data encoding:NSUTF8StringEncoding] autorelease];
}

-(NSData *)JSONData
{
return _data;
}

-(void)dealloc
{
[_data release];
[super dealloc];
}
@end