From 1b98394e7e96e4d36587697a2a86dc8c66962ed5 Mon Sep 17 00:00:00 2001 From: fredkiefer Date: Mon, 29 Nov 2010 22:54:28 +0000 Subject: [PATCH] Add a few OSX 10.6 methods for NSPropertyList. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31692 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 5 + Headers/Foundation/NSPropertyList.h | 28 ++- Source/NSPropertyList.m | 312 ++++++++++++++++++---------- 3 files changed, 232 insertions(+), 113 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0c195920..5683b7ba6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-29 Fred Kiefer + + * Headers/Foundation/NSPropertyList.h, + * Source/NSPropertyList.m: Add a few OSX 10.6 methods. + 2010-11-28 Richard Frith-Macdonald * Source/Additions/Unicode.m: Remove unnecessary include of Foundation.h diff --git a/Headers/Foundation/NSPropertyList.h b/Headers/Foundation/NSPropertyList.h index 27f166322..27b150fa7 100644 --- a/Headers/Foundation/NSPropertyList.h +++ b/Headers/Foundation/NSPropertyList.h @@ -37,7 +37,7 @@ extern "C" { #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) -@class NSData, NSString; +@class NSData, NSString, NSInputStream, NSOutputStream; enum { NSPropertyListImmutable = 0, @@ -64,6 +64,12 @@ enum { NSPropertyListGNUstepFormat = 1000, NSPropertyListGNUstepBinaryFormat, }; + +#if OS_API_VERSION(100600,GS_API_LATEST) +typedef NSUInteger NSPropertyListWriteOptions; +typedef NSUInteger NSPropertyListReadOptions; +#endif + /** * Specifies the serialisation format for a serialised property list. * @@ -254,6 +260,26 @@ typedef NSUInteger NSPropertyListFormat; format: (NSPropertyListFormat*)aFormat errorDescription: (NSString**)anErrorString; +#if OS_API_VERSION(100600,GS_API_LATEST) ++ (NSData *) dataWithPropertyList: (id)aPropertyList + format: (NSPropertyListFormat)aFormat + options: (NSPropertyListWriteOptions)anOption + error: (NSError**)error; ++ (id) propertyListWithData: (NSData*)data + options: (NSPropertyListReadOptions)anOption + format: (NSPropertyListFormat*)aFormat + error: (NSError**)error; ++ (id) propertyListWithStream: (NSInputStream*)stream + options: (NSPropertyListReadOptions)anOption + format: (NSPropertyListFormat*)aFormat + error: (NSError**)error; ++ (NSInteger) writePropertyList: (id)plist + toStream: (NSOutputStream*)stream + format: (NSPropertyListFormat)aFormat + options: (NSPropertyListWriteOptions)anOption + error: (NSError**)error; +#endif + @end #endif /* GS_API_MACOSX */ diff --git a/Source/NSPropertyList.m b/Source/NSPropertyList.m index 8232d9c86..8b1bbb38d 100644 --- a/Source/NSPropertyList.m +++ b/Source/NSPropertyList.m @@ -35,9 +35,11 @@ #import "Foundation/NSData.h" #import "Foundation/NSDictionary.h" #import "Foundation/NSEnumerator.h" +#import "Foundation/NSError.h" #import "Foundation/NSException.h" #import "Foundation/NSPropertyList.h" #import "Foundation/NSSerialization.h" +#import "Foundation/NSStream.h" #import "Foundation/NSTimeZone.h" #import "Foundation/NSUserDefaults.h" #import "Foundation/NSValue.h" @@ -440,7 +442,7 @@ foundIgnorableWhitespace: (NSString *)string @end -@interface BinaryPLGenerator : NSObject +@interface GSBinaryPLGenerator : NSObject { NSMutableData *dest; NSMapTable *objectList; @@ -2287,6 +2289,16 @@ OAppend(id obj, NSDictionary *loc, unsigned lev, unsigned step, +static inline NSError* +create_error(int code, NSString* desc) +{ + return [NSError errorWithDomain: @"NSPropertyListSerialization" + code: code + userInfo: [NSDictionary + dictionaryWithObjectsAndKeys: desc, + NSLocalizedDescriptionKey, nil]]; +} + @implementation NSPropertyListSerialization @@ -2323,6 +2335,25 @@ static BOOL classInitialized = NO; + (NSData*) dataFromPropertyList: (id)aPropertyList format: (NSPropertyListFormat)aFormat errorDescription: (NSString**)anErrorString +{ + NSError *error = nil; + NSData *data = [self dataWithPropertyList: aPropertyList + format: aFormat + options: 0 + error: &error]; + + if ((error != nil) && (anErrorString != NULL)) + { + *anErrorString = [error description]; + } + + return data; +} + ++ (NSData *) dataWithPropertyList: (id)aPropertyList + format: (NSPropertyListFormat)aFormat + options: (NSPropertyListWriteOptions)anOption + error: (NSError**)error { NSMutableData *dest; NSDictionary *loc; @@ -2333,7 +2364,7 @@ static BOOL classInitialized = NO; if (aFormat == NSPropertyListXMLFormat_v1_0) { - const char *prefix = + const char *prefix = "\n\n" @@ -2349,7 +2380,7 @@ static BOOL classInitialized = NO; } else if (aFormat == NSPropertyListBinaryFormat_v1_0) { - [BinaryPLGenerator serializePropertyList: aPropertyList intoData: dest]; + [GSBinaryPLGenerator serializePropertyList: aPropertyList intoData: dest]; } else { @@ -2454,146 +2485,165 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, mutabilityOption: (NSPropertyListMutabilityOptions)anOption format: (NSPropertyListFormat*)aFormat errorDescription: (NSString**)anErrorString +{ + NSError *error = nil; + id prop = [self propertyListWithData: data + options: anOption + format: aFormat + error: &error]; + + if ((error != nil) && (anErrorString != NULL)) + { + *anErrorString = [error description]; + } + + return prop; +} + ++ (id) propertyListWithData: (NSData*)data + options: (NSPropertyListReadOptions)anOption + format: (NSPropertyListFormat*)aFormat + error: (NSError**)error { NSPropertyListFormat format = 0; - NSString *error = nil; + NSString *errorStr = nil; id result = nil; const unsigned char *bytes = 0; unsigned int length = 0; if (data == nil) { - error = @"nil data argument passed to method"; + errorStr = @"nil data argument passed to method"; } else if ([data isKindOfClass: NSDataClass] == NO) { - error = @"non-NSData data argument passed to method"; + errorStr = @"non-NSData data argument passed to method"; } else if ([data length] == 0) { - error = @"empty data argument passed to method"; + errorStr = @"empty data argument passed to method"; } else { bytes = [data bytes]; length = [data length]; if (length >= 8 && memcmp(bytes, "bplist00", 8) == 0) - { - format = NSPropertyListBinaryFormat_v1_0; - } + { + format = NSPropertyListBinaryFormat_v1_0; + } else if (bytes[0] == 0 || bytes[0] == 1) - { - format = NSPropertyListGNUstepBinaryFormat; - } + { + format = NSPropertyListGNUstepBinaryFormat; + } else - { - unsigned int index = 0; + { + unsigned int index = 0; - // Skip any leading white space. - while (index < length && GS_IS_WHITESPACE(bytes[index]) == YES) - { - index++; - } - - if (length - index > 2 - && bytes[index] == '<' && bytes[index+1] == '?') - { - // It begins with ' 2 + && bytes[index] == '<' && bytes[index+1] == '?') + { + // It begins with '= 0; i--) + { + buffer[i] = num & 0xFF; + num >>= 8; + } + [dest appendBytes: buffer length: index_size]; + } else if (index_size == 4) { unsigned int oid;