mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-25 17:51:01 +00:00
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
This commit is contained in:
parent
a9face8dc8
commit
850c2fb314
3 changed files with 232 additions and 113 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2010-11-29 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
|
* Headers/Foundation/NSPropertyList.h,
|
||||||
|
* Source/NSPropertyList.m: Add a few OSX 10.6 methods.
|
||||||
|
|
||||||
2010-11-28 Richard Frith-Macdonald <rfm@gnu.org>
|
2010-11-28 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/Additions/Unicode.m: Remove unnecessary include of Foundation.h
|
* Source/Additions/Unicode.m: Remove unnecessary include of Foundation.h
|
||||||
|
|
|
@ -37,7 +37,7 @@ extern "C" {
|
||||||
|
|
||||||
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
|
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
|
||||||
|
|
||||||
@class NSData, NSString;
|
@class NSData, NSString, NSInputStream, NSOutputStream;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NSPropertyListImmutable = 0,
|
NSPropertyListImmutable = 0,
|
||||||
|
@ -64,6 +64,12 @@ enum {
|
||||||
NSPropertyListGNUstepFormat = 1000,
|
NSPropertyListGNUstepFormat = 1000,
|
||||||
NSPropertyListGNUstepBinaryFormat,
|
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.
|
* Specifies the serialisation format for a serialised property list.
|
||||||
* <list>
|
* <list>
|
||||||
|
@ -254,6 +260,26 @@ typedef NSUInteger NSPropertyListFormat;
|
||||||
format: (NSPropertyListFormat*)aFormat
|
format: (NSPropertyListFormat*)aFormat
|
||||||
errorDescription: (NSString**)anErrorString;
|
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
|
@end
|
||||||
|
|
||||||
#endif /* GS_API_MACOSX */
|
#endif /* GS_API_MACOSX */
|
||||||
|
|
|
@ -35,9 +35,11 @@
|
||||||
#import "Foundation/NSData.h"
|
#import "Foundation/NSData.h"
|
||||||
#import "Foundation/NSDictionary.h"
|
#import "Foundation/NSDictionary.h"
|
||||||
#import "Foundation/NSEnumerator.h"
|
#import "Foundation/NSEnumerator.h"
|
||||||
|
#import "Foundation/NSError.h"
|
||||||
#import "Foundation/NSException.h"
|
#import "Foundation/NSException.h"
|
||||||
#import "Foundation/NSPropertyList.h"
|
#import "Foundation/NSPropertyList.h"
|
||||||
#import "Foundation/NSSerialization.h"
|
#import "Foundation/NSSerialization.h"
|
||||||
|
#import "Foundation/NSStream.h"
|
||||||
#import "Foundation/NSTimeZone.h"
|
#import "Foundation/NSTimeZone.h"
|
||||||
#import "Foundation/NSUserDefaults.h"
|
#import "Foundation/NSUserDefaults.h"
|
||||||
#import "Foundation/NSValue.h"
|
#import "Foundation/NSValue.h"
|
||||||
|
@ -440,7 +442,7 @@ foundIgnorableWhitespace: (NSString *)string
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface BinaryPLGenerator : NSObject
|
@interface GSBinaryPLGenerator : NSObject
|
||||||
{
|
{
|
||||||
NSMutableData *dest;
|
NSMutableData *dest;
|
||||||
NSMapTable *objectList;
|
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
|
@implementation NSPropertyListSerialization
|
||||||
|
|
||||||
|
@ -2323,6 +2335,25 @@ static BOOL classInitialized = NO;
|
||||||
+ (NSData*) dataFromPropertyList: (id)aPropertyList
|
+ (NSData*) dataFromPropertyList: (id)aPropertyList
|
||||||
format: (NSPropertyListFormat)aFormat
|
format: (NSPropertyListFormat)aFormat
|
||||||
errorDescription: (NSString**)anErrorString
|
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;
|
NSMutableData *dest;
|
||||||
NSDictionary *loc;
|
NSDictionary *loc;
|
||||||
|
@ -2333,7 +2364,7 @@ static BOOL classInitialized = NO;
|
||||||
|
|
||||||
if (aFormat == NSPropertyListXMLFormat_v1_0)
|
if (aFormat == NSPropertyListXMLFormat_v1_0)
|
||||||
{
|
{
|
||||||
const char *prefix =
|
const char *prefix =
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist "
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist "
|
||||||
"PUBLIC \"-//GNUstep//DTD plist 0.9//EN\" "
|
"PUBLIC \"-//GNUstep//DTD plist 0.9//EN\" "
|
||||||
"\"http://www.gnustep.org/plist-0_9.xml\">\n"
|
"\"http://www.gnustep.org/plist-0_9.xml\">\n"
|
||||||
|
@ -2349,7 +2380,7 @@ static BOOL classInitialized = NO;
|
||||||
}
|
}
|
||||||
else if (aFormat == NSPropertyListBinaryFormat_v1_0)
|
else if (aFormat == NSPropertyListBinaryFormat_v1_0)
|
||||||
{
|
{
|
||||||
[BinaryPLGenerator serializePropertyList: aPropertyList intoData: dest];
|
[GSBinaryPLGenerator serializePropertyList: aPropertyList intoData: dest];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2454,146 +2485,165 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml,
|
||||||
mutabilityOption: (NSPropertyListMutabilityOptions)anOption
|
mutabilityOption: (NSPropertyListMutabilityOptions)anOption
|
||||||
format: (NSPropertyListFormat*)aFormat
|
format: (NSPropertyListFormat*)aFormat
|
||||||
errorDescription: (NSString**)anErrorString
|
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;
|
NSPropertyListFormat format = 0;
|
||||||
NSString *error = nil;
|
NSString *errorStr = nil;
|
||||||
id result = nil;
|
id result = nil;
|
||||||
const unsigned char *bytes = 0;
|
const unsigned char *bytes = 0;
|
||||||
unsigned int length = 0;
|
unsigned int length = 0;
|
||||||
|
|
||||||
if (data == nil)
|
if (data == nil)
|
||||||
{
|
{
|
||||||
error = @"nil data argument passed to method";
|
errorStr = @"nil data argument passed to method";
|
||||||
}
|
}
|
||||||
else if ([data isKindOfClass: NSDataClass] == NO)
|
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)
|
else if ([data length] == 0)
|
||||||
{
|
{
|
||||||
error = @"empty data argument passed to method";
|
errorStr = @"empty data argument passed to method";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bytes = [data bytes];
|
bytes = [data bytes];
|
||||||
length = [data length];
|
length = [data length];
|
||||||
if (length >= 8 && memcmp(bytes, "bplist00", 8) == 0)
|
if (length >= 8 && memcmp(bytes, "bplist00", 8) == 0)
|
||||||
{
|
{
|
||||||
format = NSPropertyListBinaryFormat_v1_0;
|
format = NSPropertyListBinaryFormat_v1_0;
|
||||||
}
|
}
|
||||||
else if (bytes[0] == 0 || bytes[0] == 1)
|
else if (bytes[0] == 0 || bytes[0] == 1)
|
||||||
{
|
{
|
||||||
format = NSPropertyListGNUstepBinaryFormat;
|
format = NSPropertyListGNUstepBinaryFormat;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int index = 0;
|
unsigned int index = 0;
|
||||||
|
|
||||||
// Skip any leading white space.
|
// Skip any leading white space.
|
||||||
while (index < length && GS_IS_WHITESPACE(bytes[index]) == YES)
|
while (index < length && GS_IS_WHITESPACE(bytes[index]) == YES)
|
||||||
{
|
{
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length - index > 2
|
if (length - index > 2
|
||||||
&& bytes[index] == '<' && bytes[index+1] == '?')
|
&& bytes[index] == '<' && bytes[index+1] == '?')
|
||||||
{
|
{
|
||||||
// It begins with '<?' so it is xml
|
// It begins with '<?' so it is xml
|
||||||
format = NSPropertyListXMLFormat_v1_0;
|
format = NSPropertyListXMLFormat_v1_0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Assume openstep format unless we find otherwise.
|
// Assume openstep format unless we find otherwise.
|
||||||
format = NSPropertyListOpenStepFormat;
|
format = NSPropertyListOpenStepFormat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error == nil)
|
if (errorStr == nil)
|
||||||
{
|
{
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case NSPropertyListXMLFormat_v1_0:
|
case NSPropertyListXMLFormat_v1_0:
|
||||||
{
|
{
|
||||||
GSXMLPListParser *parser;
|
GSXMLPListParser *parser;
|
||||||
|
|
||||||
|
parser = [GSXMLPListParser alloc];
|
||||||
|
parser = AUTORELEASE([parser initWithData: data
|
||||||
|
mutability: anOption]);
|
||||||
|
if ([parser parse] == YES)
|
||||||
|
{
|
||||||
|
result = AUTORELEASE(RETAIN([parser result]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errorStr = @"failed to parse as XML property list";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NSPropertyListOpenStepFormat:
|
||||||
|
{
|
||||||
|
pldata _pld;
|
||||||
|
|
||||||
|
_pld.ptr = bytes;
|
||||||
|
_pld.pos = 0;
|
||||||
|
_pld.end = length;
|
||||||
|
_pld.err = nil;
|
||||||
|
_pld.lin = 0;
|
||||||
|
_pld.opt = anOption;
|
||||||
|
_pld.key = NO;
|
||||||
|
_pld.old = YES; // OpenStep style
|
||||||
|
|
||||||
|
result = AUTORELEASE(parsePlItem(&_pld));
|
||||||
|
if (_pld.old == NO)
|
||||||
|
{
|
||||||
|
// Found some modern GNUstep extension in data.
|
||||||
|
format = NSPropertyListGNUstepFormat;
|
||||||
|
}
|
||||||
|
if (_pld.err != nil)
|
||||||
|
{
|
||||||
|
errorStr = [NSString stringWithFormat:
|
||||||
|
@"Parse failed at line %d (char %d) - %@",
|
||||||
|
_pld.lin + 1, _pld.pos + 1, _pld.err];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
parser = [GSXMLPListParser alloc];
|
case NSPropertyListGNUstepBinaryFormat:
|
||||||
parser = AUTORELEASE([parser initWithData: data
|
if (anOption == NSPropertyListImmutable)
|
||||||
mutability: anOption]);
|
{
|
||||||
if ([parser parse] == YES)
|
result = [NSDeserializer deserializePropertyListFromData: data
|
||||||
{
|
mutableContainers: NO];
|
||||||
result = AUTORELEASE(RETAIN([parser result]));
|
}
|
||||||
}
|
else
|
||||||
else if (error == nil)
|
{
|
||||||
{
|
result = [NSDeserializer deserializePropertyListFromData: data
|
||||||
error = @"failed to parse as XML property list";
|
mutableContainers: YES];
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
|
case NSPropertyListBinaryFormat_v1_0:
|
||||||
case NSPropertyListOpenStepFormat:
|
{
|
||||||
{
|
GSBinaryPLParser *p = [GSBinaryPLParser alloc];
|
||||||
pldata _pld;
|
|
||||||
|
p = [p initWithData: data mutability: anOption];
|
||||||
_pld.ptr = bytes;
|
result = [p rootObject];
|
||||||
_pld.pos = 0;
|
RELEASE(p);
|
||||||
_pld.end = length;
|
}
|
||||||
_pld.err = nil;
|
break;
|
||||||
_pld.lin = 0;
|
|
||||||
_pld.opt = anOption;
|
default:
|
||||||
_pld.key = NO;
|
errorStr = @"format not supported";
|
||||||
_pld.old = YES; // OpenStep style
|
break;
|
||||||
|
}
|
||||||
result = AUTORELEASE(parsePlItem(&_pld));
|
|
||||||
if (_pld.old == NO)
|
|
||||||
{
|
|
||||||
// Found some modern GNUstep extension in data.
|
|
||||||
format = NSPropertyListGNUstepFormat;
|
|
||||||
}
|
|
||||||
if (_pld.err != nil)
|
|
||||||
{
|
|
||||||
error = [NSString stringWithFormat:
|
|
||||||
@"Parse failed at line %d (char %d) - %@",
|
|
||||||
_pld.lin + 1, _pld.pos + 1, _pld.err];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NSPropertyListGNUstepBinaryFormat:
|
|
||||||
if (anOption == NSPropertyListImmutable)
|
|
||||||
{
|
|
||||||
result = [NSDeserializer deserializePropertyListFromData: data
|
|
||||||
mutableContainers: NO];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = [NSDeserializer deserializePropertyListFromData: data
|
|
||||||
mutableContainers: YES];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NSPropertyListBinaryFormat_v1_0:
|
|
||||||
{
|
|
||||||
GSBinaryPLParser *p = [GSBinaryPLParser alloc];
|
|
||||||
|
|
||||||
p = [p initWithData: data mutability: anOption];
|
|
||||||
result = [p rootObject];
|
|
||||||
RELEASE(p);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
error = @"format not supported";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Done ... return all values.
|
* Done ... return all values.
|
||||||
*/
|
*/
|
||||||
if (anErrorString != 0)
|
if ((errorStr != nil) && (error != NULL))
|
||||||
{
|
{
|
||||||
*anErrorString = error;
|
*error = create_error(0, errorStr);
|
||||||
}
|
}
|
||||||
if (aFormat != 0)
|
if (aFormat != 0)
|
||||||
{
|
{
|
||||||
|
@ -2602,6 +2652,31 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (id) propertyListWithStream: (NSInputStream*)stream
|
||||||
|
options: (NSPropertyListReadOptions)anOption
|
||||||
|
format: (NSPropertyListFormat*)aFormat
|
||||||
|
error: (NSError**)error
|
||||||
|
{
|
||||||
|
// FIXME
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSInteger) writePropertyList: (id)aPropertyList
|
||||||
|
toStream: (NSOutputStream*)stream
|
||||||
|
format: (NSPropertyListFormat)aFormat
|
||||||
|
options: (NSPropertyListWriteOptions)anOption
|
||||||
|
error: (NSError**)error
|
||||||
|
{
|
||||||
|
// FIXME: The NSData operations should be implemented on top of this method,
|
||||||
|
// not the other way round,
|
||||||
|
NSData *data = [self dataWithPropertyList: aPropertyList
|
||||||
|
format: aFormat
|
||||||
|
options: 0
|
||||||
|
error: error];
|
||||||
|
|
||||||
|
return [stream write: [data bytes] maxLength: [data length]];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@ -3254,14 +3329,14 @@ isEqualFunc(const void *item1, const void *item2,
|
||||||
return [o1 isEqual: o2];
|
return [o1 isEqual: o2];
|
||||||
}
|
}
|
||||||
|
|
||||||
@implementation BinaryPLGenerator
|
@implementation GSBinaryPLGenerator
|
||||||
|
|
||||||
+ (void) serializePropertyList: (id)aPropertyList
|
+ (void) serializePropertyList: (id)aPropertyList
|
||||||
intoData: (NSMutableData *)destination
|
intoData: (NSMutableData *)destination
|
||||||
{
|
{
|
||||||
BinaryPLGenerator *gen;
|
GSBinaryPLGenerator *gen;
|
||||||
|
|
||||||
gen = [[BinaryPLGenerator alloc]
|
gen = [[GSBinaryPLGenerator alloc]
|
||||||
initWithPropertyList: aPropertyList intoData: destination];
|
initWithPropertyList: aPropertyList intoData: destination];
|
||||||
[gen generate];
|
[gen generate];
|
||||||
RELEASE(gen);
|
RELEASE(gen);
|
||||||
|
@ -3525,6 +3600,19 @@ isEqualFunc(const void *item1, const void *item2,
|
||||||
oid = NSSwapHostShortToBig(index);
|
oid = NSSwapHostShortToBig(index);
|
||||||
[dest appendBytes: &oid length: 2];
|
[dest appendBytes: &oid length: 2];
|
||||||
}
|
}
|
||||||
|
else if (index_size == 3)
|
||||||
|
{
|
||||||
|
unsigned char buffer[index_size];
|
||||||
|
int i;
|
||||||
|
unsigned num = index;
|
||||||
|
|
||||||
|
for (i = index_size - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
buffer[i] = num & 0xFF;
|
||||||
|
num >>= 8;
|
||||||
|
}
|
||||||
|
[dest appendBytes: buffer length: index_size];
|
||||||
|
}
|
||||||
else if (index_size == 4)
|
else if (index_size == 4)
|
||||||
{
|
{
|
||||||
unsigned int oid;
|
unsigned int oid;
|
||||||
|
|
Loading…
Reference in a new issue