/ Examples / plconvert.c
plconvert.c
  1  // Mac OS X: clang -F<path-to-CFLite-framework> -framework CoreFoundation Examples/plconvert.c -o plconvert
  2  //  note: When running this sample, be sure to set the environment variable DYLD_FRAMEWORK_PATH to point to the directory containing your new version of CoreFoundation.
  3  //   e.g.
  4  //  DYLD_FRAMEWORK_PATH=/tmp/CF-Root ./plconvert <input> <output>
  5  // 
  6  // Linux: clang -I/usr/local/include -L/usr/local/lib -lCoreFoundation plconvert.c -o plconvert
  7  
  8  /*
  9   This example shows usage of CFString, CFData, and other CFPropertyList types. It takes two arguments:
 10      1. A property list file to read, in either binary or XML property list format.
 11      2. A file name to write a converted property list file to.
 12   If the first input is binary, the output is XML and vice-versa.
 13  */
 14  
 15  #include <sys/types.h>
 16  #include <sys/stat.h>
 17  #include <fcntl.h>
 18  #include <string.h>
 19  #include <stdio.h>
 20  #include <unistd.h>
 21  
 22  #include <CoreFoundation/CoreFoundation.h>
 23  
 24  static void logIt(CFStringRef format, ...) {
 25      va_list args;
 26      va_start(args, format); 
 27      CFStringRef str = CFStringCreateWithFormatAndArguments(kCFAllocatorSystemDefault, NULL, format, args);
 28      if (!str) return;
 29      
 30      CFIndex blen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
 31      char *buf = str ? (char *)malloc(blen + 1) : 0;
 32      if (buf) {
 33          Boolean converted = CFStringGetCString(str, buf, blen, kCFStringEncodingUTF8);
 34          if (converted) {
 35              // null-terminate
 36              buf[blen] = 0;
 37              printf("%s\n", buf);
 38          }
 39      }
 40      if (buf) free(buf);
 41      if (str) CFRelease(str);      va_end(args);
 42  }
 43  
 44  static CFMutableDataRef createDataFromFile(const char *fname) {
 45      int fd = open(fname, O_RDONLY);
 46      CFMutableDataRef res = CFDataCreateMutable(kCFAllocatorSystemDefault, 0);
 47      char buf[4096];
 48      
 49      ssize_t amountRead;
 50      while ((amountRead = read(fd, buf, 4096)) > 0) {
 51          CFDataAppendBytes(res, (const UInt8 *)buf, amountRead);
 52      }
 53      
 54      close(fd);
 55      return res;
 56  }
 57  
 58  static bool writeDataToFile(CFDataRef data, const char *fname) {
 59      int fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
 60      if (fd < 0) {
 61          printf("There was an error creating the file: %d", errno);
 62          return false;
 63      }
 64      int dataLen = CFDataGetLength(data);
 65      int w = write(fd, CFDataGetBytePtr(data), dataLen);
 66      fsync(fd);
 67      close(fd);
 68      if (w != dataLen) return false;
 69      return true;
 70  }
 71  
 72  int main(int argc, char **argv) {
 73      
 74      if (argc != 3) {
 75          printf("Usage: plconvert <in file> <out file>\nIf the in file is an XML property list, convert to binary property list in out file. If the in file is a binary property list, convert to XML property list in out file.\n");
 76      } else {
 77          CFMutableDataRef plistData = createDataFromFile(argv[1]);
 78          if (!plistData) {
 79              printf("Unable to create data from file name: %s", argv[1]);
 80          } else {
 81              CFPropertyListFormat fmt;
 82              CFErrorRef err;
 83              CFPropertyListRef plist = CFPropertyListCreateWithData(kCFAllocatorSystemDefault, (CFDataRef)plistData, 0, &fmt, &err);
 84              if (!plist) {
 85                  logIt(CFSTR("Unable to create property list from data: %@"), err);
 86              } else {
 87                  logIt(CFSTR("Property list contents:\n%@"), plist);
 88                  if (fmt == kCFPropertyListBinaryFormat_v1_0) {
 89                      logIt(CFSTR("Converting to XML property list at: %s"), argv[2]);
 90                      fmt = kCFPropertyListXMLFormat_v1_0;
 91                  } else if (fmt == kCFPropertyListXMLFormat_v1_0) {
 92                      logIt(CFSTR("Converting to binary property list at: %s"), argv[2]);
 93                      fmt = kCFPropertyListBinaryFormat_v1_0;
 94                  } else {
 95                      logIt(CFSTR("Unknown property list format! Not converting output format."));
 96                  }
 97                  
 98                  CFDataRef outputData = CFPropertyListCreateData(kCFAllocatorSystemDefault, plist, fmt, 0, &err);
 99                  if (!outputData) {
100                      logIt(CFSTR("Unable to write property list to data: %@"), err);
101                  } else {
102                      bool success = writeDataToFile(outputData, argv[2]);
103                      if (!success) {
104                          logIt(CFSTR("Unable to write data to file"));
105                      }
106                      CFRelease(outputData);
107                  }
108                  CFRelease(plist);
109              }
110              CFRelease(plistData);
111          }
112      }
113  }