/ NSPropertyList.m
NSPropertyList.m
1 // 2 // NSPropertyList.m 3 // CoreFoundation 4 // 5 // Copyright (c) 2014 Apportable. All rights reserved. 6 // 7 8 #import <Foundation/NSPropertyList.h> 9 #import <Foundation/NSData.h> 10 #import <Foundation/NSString.h> 11 12 @implementation NSPropertyListSerialization 13 14 + (BOOL)propertyList:(id)plist isValidForFormat:(NSPropertyListFormat)format 15 { 16 return CFPropertyListIsValid((CFPropertyListRef)plist, (CFPropertyListFormat)format); 17 } 18 19 + (NSData *)dataWithPropertyList:(id)plist format:(NSPropertyListFormat)format options:(NSPropertyListWriteOptions)opt error:(out NSError **)error 20 { 21 return [(NSData *)CFPropertyListCreateData(kCFAllocatorDefault, (CFPropertyListRef)plist, (CFPropertyListFormat)format, opt, (CFErrorRef *)error) autorelease]; 22 } 23 24 + (NSInteger)writePropertyList:(id)plist toStream:(NSOutputStream *)stream format:(NSPropertyListFormat)format options:(NSPropertyListWriteOptions)opt error:(out NSError **)error 25 { 26 return CFPropertyListWrite((CFPropertyListRef)plist, (CFWriteStreamRef)stream, (CFPropertyListFormat)format, opt, (CFErrorRef *)error); 27 } 28 29 + (id)propertyListWithData:(NSData *)data options:(NSPropertyListReadOptions)opt format:(NSPropertyListFormat *)format error:(out NSError **)error 30 { 31 return [(id)CFPropertyListCreateWithData(kCFAllocatorDefault, (CFDataRef)data, opt, (CFPropertyListFormat *)format, (CFErrorRef *)error) autorelease]; 32 } 33 34 + (id)propertyListWithStream:(NSInputStream *)stream options:(NSPropertyListReadOptions)opt format:(NSPropertyListFormat *)format error:(out NSError **)error 35 { 36 return [(id)CFPropertyListCreateWithStream(kCFAllocatorDefault, (CFReadStreamRef)stream, 0, opt, (CFPropertyListFormat *)format, (CFErrorRef *)error) autorelease]; 37 } 38 39 + (NSData *)dataFromPropertyList:(id)plist format:(NSPropertyListFormat)format errorDescription:(out __strong NSString **)errorString 40 { 41 CFWriteStreamRef stream = CFWriteStreamCreateWithAllocatedBuffers(kCFAllocatorDefault, kCFAllocatorDefault); 42 43 if (!CFWriteStreamOpen(stream)) 44 { 45 return nil; 46 } 47 48 CFPropertyListWriteToStream((CFPropertyListRef)plist, stream, (CFPropertyListFormat)format, (CFStringRef *)errorString); 49 NSData *data = (NSData *)CFWriteStreamCopyProperty(stream, kCFStreamPropertyDataWritten); 50 CFWriteStreamClose(stream); 51 CFRelease(stream); 52 53 return [data autorelease]; 54 } 55 56 + (id)propertyListFromData:(NSData *)data mutabilityOption:(NSPropertyListMutabilityOptions)opt format:(NSPropertyListFormat *)format errorDescription:(out __strong NSString **)errorString 57 { 58 CFErrorRef error = NULL; 59 // technically we could detect the plist format if it is that format, and then release the plist, and claim it was an error... but meh. 60 id plist = (id)CFPropertyListCreateWithData(kCFAllocatorDefault, (CFDataRef)data, opt, (CFPropertyListFormat *)format, &error); 61 62 if (plist == nil && errorString != NULL) 63 { 64 if (error == nil) 65 { 66 *errorString = @"Internal error, could not procure error to display"; 67 } 68 else 69 { 70 *errorString = [(NSString *)CFErrorCopyDescription(error) autorelease]; 71 } 72 } 73 74 return [plist autorelease]; 75 } 76 77 @end