-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathKeyValue+MiscMerge.m
executable file
·120 lines (92 loc) · 2.86 KB
/
KeyValue+MiscMerge.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//
// KeyValue+MiscMerge.m
//
// Written by Don Yacktman and Carl Lindberg
//
// Copyright 2001-2004 by Don Yacktman and Carl Lindberg.
// All rights reserved.
//
// This notice may not be removed from this source code.
//
// This header is included in the MiscKit by permission from the author
// and its use is governed by the MiscKit license, found in the file
// "License.rtf" in the MiscKit distribution. Please refer to that file
// for a list of all applicable permissions and restrictions.
//
#import "KeyValue+MiscMerge.h"
#import <Foundation/NSObjCRuntime.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <Foundation/NSCharacterSet.h>
#import <stdlib.h> // for NULL os OSX
#if GNU_RUNTIME
#import <objc/objc-api.h>
static Ivar_t class_getInstanceVariable(Class aClass, const char *name);
#else
#import <objc/objc-runtime.h>
#endif
@interface NSObject (WarningAvoidance)
+ (BOOL)accessInstanceVariablesDirectly;
@end
@implementation NSObject (MiscMergeHasKey)
- (BOOL)hasMiscMergeKeyPath:(NSString *)keyPath
{
static NSCharacterSet *dotSet;
NSString *key = keyPath;
NSRange dotRange;
if ( dotSet == nil ) {
dotSet = [[NSCharacterSet characterSetWithRange:NSMakeRange((unsigned int)'.', 1)] retain];
}
dotRange = [keyPath rangeOfCharacterFromSet:dotSet];
if (dotRange.length > 0)
{
key = [keyPath substringToIndex:dotRange.location];
}
return [self hasMiscMergeKey:key];
}
- (BOOL)hasMiscMergeKey:(NSString *)key
{
SEL keySelector;
if ([key length] == 0) return NO;
keySelector = NSSelectorFromString(key);
return (keySelector != NULL && [self respondsToSelector:keySelector]) ||
([[self class] accessInstanceVariablesDirectly] &&
class_getInstanceVariable([self class], [key cStringUsingEncoding:NSUTF8StringEncoding]));
}
@end
@implementation NSDictionary (MiscMergeHasKey)
- (BOOL)hasMiscMergeKey:(NSString *)key
{
return ([self objectForKey:key] != nil)? YES : NO;
}
@end
@implementation NSArray (MiscMergeHasKey)
- (BOOL)hasMiscMergeKey:(NSString *)key
{
if ([key isEqualToString:@"count"]) return YES;
if ([key hasPrefix:@"@"]) return YES;
if ([self count] == 0) return YES; //Hmm
return [[self objectAtIndex:0] hasMiscMergeKey:key];
}
@end
#if GNU_RUNTIME
static Ivar_t class_getInstanceVariable(Class aClass, const char *name)
{
Class currClass;
if (name == NULL) return NULL;
for (currClass = aClass; currClass != Nil; currClass = currClass->super_class)
{
struct objc_ivar_list *ivars = aClass->ivars;
int pos;
for (pos = 0; pos < ivars->ivar_count; pos++)
{
Ivar_t currIvar = &(ivars->ivar_list[pos]);
if (strcmp(currIvar->ivar_name, name) == 0) {
return currIvar;
}
}
}
return NULL;
}
#endif