/ 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