/ src / Cookies / CFHTTPCookieStorage.c
CFHTTPCookieStorage.c
  1  //
  2  //  CFHTTPCookieStorage.c
  3  //  CFNetwork
  4  //
  5  //  Copyright (c) 2014 Apportable. All rights reserved.
  6  //
  7  
  8  #include "CFBase.h"
  9  #include "CFRuntime.h"
 10  #include "CFHTTPCookieStorage.h"
 11  #include "CFHTTPCookie.h"
 12  #include "CFArray.h"
 13  #include <dispatch/dispatch.h>
 14  
 15  struct __CFHTTPCookieStorage {
 16      CFRuntimeBase _base;
 17      CFMutableArrayRef _cookies;
 18  };
 19  
 20  static void __CFHTTPCookieStorageDeallocate(CFTypeRef cf) {
 21      struct __CFHTTPCookieStorage *item = (struct __CFHTTPCookieStorage *)cf;
 22      CFRelease(item->_cookies);
 23  }
 24  
 25  static CFTypeID __kCFHTTPCookieStorageTypeID = _kCFRuntimeNotATypeID;
 26  
 27  static const CFRuntimeClass __CFHTTPCookieStorageClass = {
 28      _kCFRuntimeScannedObject,
 29      "CFHTTPCookieStorage",
 30      NULL,   // init
 31      NULL,   // copy
 32      __CFHTTPCookieStorageDeallocate,
 33      NULL,
 34      NULL,
 35      NULL,
 36      NULL
 37  };
 38  
 39  static void __CFHTTPCookieStorageInitialize(void) {
 40      __kCFHTTPCookieStorageTypeID = _CFRuntimeRegisterClass(&__CFHTTPCookieStorageClass);
 41  }
 42  
 43  CFTypeID CFHTTPCookieStorageGetTypeID(void) {
 44      if (__kCFHTTPCookieStorageTypeID == _kCFRuntimeNotATypeID) {
 45          __CFHTTPCookieStorageInitialize();
 46      }
 47      return __kCFHTTPCookieStorageTypeID;
 48  }
 49  
 50  static struct __CFHTTPCookieStorage *_CFHTTPCookieStorageCreate(CFAllocatorRef allocator) {
 51      CFIndex size = sizeof(struct __CFHTTPCookieStorage) - sizeof(CFRuntimeBase);
 52      struct __CFHTTPCookieStorage *cookieStorage = (struct __CFHTTPCookieStorage *)_CFRuntimeCreateInstance(allocator, CFHTTPCookieStorageGetTypeID(), size, NULL);
 53      
 54      cookieStorage->_cookies = (CFMutableArrayRef)CFRetain(CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks));
 55      
 56      
 57      return cookieStorage;
 58  }
 59  
 60  
 61  
 62  CFHTTPCookieStorageRef CFHTTPCookieStorageGetDefault() {
 63      static struct __CFHTTPCookieStorage *sharedStorage = NULL;
 64      static dispatch_once_t once = 0L;
 65      dispatch_once(&once, ^{
 66          sharedStorage = _CFHTTPCookieStorageCreate(kCFAllocatorDefault);
 67      });
 68      return (CFHTTPCookieStorageRef)sharedStorage;
 69  
 70  }
 71  
 72  void CFHTTPCookieStorageDeleteCookie(CFHTTPCookieStorageRef storage, CFHTTPCookieRef cookie) {
 73      CFMutableArrayRef cookies = storage->_cookies;
 74      CFIndex i = CFArrayGetFirstIndexOfValue(cookies,
 75                                              CFRangeMake(0, CFArrayGetCount(cookies)),
 76                                              cookie);
 77      if (i != kCFNotFound)
 78          CFArrayRemoveValueAtIndex(cookies, i);
 79  }
 80  
 81  void CFHTTPCookieStorageSetCookie(CFHTTPCookieStorageRef storage, CFHTTPCookieRef cookie) {
 82      CFIndex existingCookieIndex = kCFNotFound;
 83      for (int j=0; j<CFArrayGetCount(storage->_cookies); j++) {
 84          CFHTTPCookieRef existingCookie = (CFHTTPCookieRef)CFArrayGetValueAtIndex(storage->_cookies, j);
 85          if (CFStringCompare(CFHTTPCookieGetName(existingCookie), CFHTTPCookieGetName(cookie), kCFCompareCaseInsensitive)==kCFCompareEqualTo) {
 86              existingCookieIndex = j;
 87              break;
 88          }
 89      }
 90      if (existingCookieIndex == kCFNotFound) {
 91          CFArrayAppendValue(storage->_cookies, cookie);
 92      } else {
 93          CFArrayReplaceValues(storage->_cookies, CFRangeMake(existingCookieIndex, 1), (CFTypeRef*)&cookie, 1);
 94      }
 95  }
 96  
 97  CFArrayRef CFHTTPCookieStorageCopyCookies(CFHTTPCookieStorageRef storage) {
 98      return CFArrayCreateCopy(kCFAllocatorDefault, storage->_cookies);
 99  }
100  
101  CFArrayRef CFHTTPCookieStorageCopyCookiesForURL(CFHTTPCookieStorageRef storage, CFURLRef url) {
102      //fixme respect the url
103      return CFHTTPCookieStorageCopyCookies(storage);
104  }
105  
106  
107  void CFHTTPCookieStorageSetCookies(CFHTTPCookieStorageRef storage, CFArrayRef cookies) {
108      //fixme bad big O.
109      for (int i=0; i<CFArrayGetCount(cookies); i++) {
110          CFHTTPCookieRef cookie = (CFHTTPCookieRef)CFArrayGetValueAtIndex(cookies, i);
111          CFHTTPCookieStorageSetCookie(storage, cookie);        
112      }
113  }
114  
115  
116  void CFHTTPCookieStorageSetCookiesWithResponseHeaderFields(CFHTTPCookieStorageRef storage, CFDictionaryRef headerFields, CFURLRef url) {
117      CFArrayRef cookies = CFHTTPCookieCreateWithResponseHeaderFields(headerFields, url);
118      if (cookies != NULL) {
119          CFHTTPCookieStorageSetCookies(storage, cookies);
120          CFRelease(cookies);
121      }
122  }
123  CFDictionaryRef CFHTTPCookieStorageCopyRequestHeaderFieldsForURL(CFHTTPCookieStorageRef storage, CFURLRef url) {
124      return CFHTTPCookieCopyRequestHeaderFields(storage->_cookies);
125  }
126  
127  
128