PageRenderTime 59ms CodeModel.GetById 10ms app.highlight 46ms RepoModel.GetById 1ms app.codeStats 0ms

/core/externals/update-engine/externals/google-toolbox-for-mac/Foundation/GTMNSDictionary+CaseInsensitive.m

http://macfuse.googlecode.com/
Objective C | 116 lines | 77 code | 21 blank | 18 comment | 11 complexity | effa865e633fd191fbfd6bf18cb07b9d MD5 | raw file
  1//
  2//  GTMNSDictionary+CaseInsensitive.m
  3//
  4//  Copyright 2009 Google Inc.
  5//
  6//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7//  use this file except in compliance with the License.  You may obtain a copy
  8//  of the License at
  9//
 10//  http://www.apache.org/licenses/LICENSE-2.0
 11//
 12//  Unless required by applicable law or agreed to in writing, software
 13//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 14//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 15//  License for the specific language governing permissions and limitations under
 16//  the License.
 17//
 18
 19#import "GTMNSDictionary+CaseInsensitive.h"
 20#import "GTMDefines.h"
 21#import <CoreFoundation/CoreFoundation.h>
 22
 23@interface NSMutableDictionary (GTMNSMutableDictionaryCaseInsensitiveAdditions)
 24
 25// Returns a mutable equivalent to GTMNSDictionaryCaseInsensitiveAdditions.
 26- (id)gtm_initWithDictionaryCaseInsensitive:(NSDictionary *)dictionary;
 27
 28@end
 29
 30static Boolean CaseInsensitiveEqualCallback(const void *a, const void *b) {
 31  id idA = (id)a;
 32  id idB = (id)b;
 33  Boolean ret = FALSE;
 34  if ([idA isKindOfClass:[NSString class]] &&
 35      [idB isKindOfClass:[NSString class]]) {
 36    ret = ([idA compare:idB options:NSCaseInsensitiveSearch|NSLiteralSearch]
 37           == NSOrderedSame);
 38  } else {
 39    ret = [idA isEqual:idB];
 40  }
 41  return ret;
 42}
 43
 44static CFHashCode CaseInsensitiveHashCallback(const void *value) {
 45  id idValue = (id)value;
 46  CFHashCode ret = 0;
 47  if ([idValue isKindOfClass:[NSString class]]) {
 48    ret = [[idValue lowercaseString] hash];
 49  } else {
 50    ret = [idValue hash];
 51  }
 52  return ret;
 53}
 54
 55@implementation NSDictionary (GTMNSDictionaryCaseInsensitiveAdditions)
 56
 57- (id)gtm_initWithDictionaryCaseInsensitive:(NSDictionary *)dictionary {
 58  [self release];
 59  self = nil;
 60
 61  CFIndex count = 0;
 62  void *keys = NULL;
 63  void *values = NULL;
 64
 65  if (dictionary) {
 66    count = CFDictionaryGetCount((CFDictionaryRef)dictionary);
 67
 68    if (count) {
 69      keys = malloc(count * sizeof(void *));
 70      values = malloc(count * sizeof(void *));
 71      if (!keys || !values) {
 72        free(keys);
 73        free(values);
 74        return self;
 75      }
 76
 77      CFDictionaryGetKeysAndValues((CFDictionaryRef)dictionary, keys, values);
 78    }
 79  }
 80
 81  CFDictionaryKeyCallBacks keyCallbacks = kCFCopyStringDictionaryKeyCallBacks;
 82  _GTMDevAssert(keyCallbacks.version == 0,
 83                @"CFDictionaryKeyCallBacks structure updated");
 84  keyCallbacks.equal = CaseInsensitiveEqualCallback;
 85  keyCallbacks.hash = CaseInsensitiveHashCallback;
 86
 87  self = (id)CFDictionaryCreate(kCFAllocatorDefault,
 88                                keys, values, count, &keyCallbacks,
 89                                &kCFTypeDictionaryValueCallBacks);
 90
 91  free(keys);
 92  free(values);
 93
 94  return self;
 95}
 96
 97+ (id)gtm_dictionaryWithDictionaryCaseInsensitive:(NSDictionary *)dictionary {
 98  return [[[self alloc]
 99           gtm_initWithDictionaryCaseInsensitive:dictionary] autorelease];
100}
101
102@end
103
104@implementation NSMutableDictionary (GTMNSMutableDictionaryCaseInsensitiveAdditions)
105
106- (id)gtm_initWithDictionaryCaseInsensitive:(NSDictionary *)dictionary {
107  if ((self = [super gtm_initWithDictionaryCaseInsensitive:dictionary])) {
108    id copy = (id)CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0,
109                                                (CFDictionaryRef)self);
110    [self release];
111    self = copy;
112  }
113  return self;
114}
115
116@end