-
-
Save krackers/41156714eb3e19c128bfd81c8c67965c to your computer and use it in GitHub Desktop.
Reverse-engineered implementation of -[NSString isEqual:] and -[NSString isEqualToString:]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Most NSString instances will actually be __NSCFString instances, so here are both NSString and __NSCFString implementations. | |
* If you know how to create an NSString instance whose class is actually NSString please let me know. | |
* Other possible concrete subclasses of NSString are: NSConstantString, __NSCFConstantString, NSPathStore2, NSSimpleCString and __NSLocalizedString. | |
*/ | |
// CoreFoundation.framework 635.19.0 (Mac OS X 10.7.3) | |
@implementation NSObject | |
- (BOOL) isNSString__ | |
{ | |
return NO; | |
} | |
@end | |
@implementation __NSCFString | |
static CFStringEncoding enc = 0; | |
- (BOOL) isNSString__ | |
{ | |
return YES; | |
} | |
- (BOOL) isEqual:(id)string | |
{ | |
if (self == string) | |
{ | |
return YES; | |
} | |
else if (string == nil) | |
{ | |
return NO | |
} | |
else | |
{ | |
Class stringClass = [string class]; | |
Class nscfStringClass = objc_lookUpClass("__NSCFString"); | |
if (stringClass == nscfStringClass || class_getSuperclass(stringClass) == nscfStringClass) | |
{ | |
if (enc == kCFStringEncodingInvalidId) | |
enc = CFStringGetSystemEncoding(); | |
const char *selfCString = CFStringGetCStringPtr(self, enc); | |
if (enc == kCFStringEncodingInvalidId) | |
enc = CFStringGetSystemEncoding(); | |
const char *argCString = CFStringGetCStringPtr(string, enc); | |
if (selfCString != NULL && argCString != NULL) | |
{ | |
CFIndex length = _CFStringGetLength2(self); | |
if (length == _CFStringGetLength2(string)) | |
{ | |
return memcmp(selfCString, argCString, length) == 0; | |
} | |
else | |
{ | |
return NO; | |
} | |
} | |
} | |
} | |
if (![string isNSString__]) | |
return NO; | |
// Eventually calls __CFStringEqual whose implementation is available at http://opensource.apple.com/source/CF/CF-635.19/CFString.c | |
return CFEqual(self, string); | |
} | |
- (BOOL) isEqualToString:(NSString *)string | |
{ | |
if (self == string) | |
{ | |
return YES; | |
} | |
else if (string == nil) | |
{ | |
return NO | |
} | |
else | |
{ | |
Class stringClass = [string class]; | |
Class nscfStringClass = objc_lookUpClass("__NSCFString"); | |
if (stringClass == nscfStringClass || class_getSuperclass(stringClass) == nscfStringClass) | |
{ | |
if (enc == kCFStringEncodingInvalidId) | |
enc = CFStringGetSystemEncoding(); | |
const char *selfCString = CFStringGetCStringPtr(self, enc); | |
if (enc == kCFStringEncodingInvalidId) | |
enc = CFStringGetSystemEncoding(); | |
const char *argCString = CFStringGetCStringPtr(string, enc); | |
if (selfCString != NULL && argCString != NULL) | |
{ | |
CFIndex length = _CFStringGetLength2(self); | |
if (length == _CFStringGetLength2(string)) | |
{ | |
return memcmp(selfCString, argCString, length) == 0; | |
} | |
else | |
{ | |
return NO; | |
} | |
} | |
} | |
} | |
// Eventually calls __CFStringEqual whose implementation is available at http://opensource.apple.com/source/CF/CF-635.19/CFString.c | |
return CFEqual(self, string); | |
} | |
@end | |
// Foundation.framework 833.24.0 (Mac OS X 10.7.3) | |
@implementation NSString | |
- (BOOL) isNSString__ | |
{ | |
return YES; | |
} | |
- (BOOL) isEqual:(id)string | |
{ | |
if ([string isNSString__]) | |
return [self isEqualToString:string]; | |
else | |
return NO; | |
} | |
- (BOOL) isEqualToString:(NSString *)string | |
{ | |
if (self == string) | |
return YES; | |
else | |
return [self compare:string options:NSLiteralSearch range:NSMakeRange(0, [self length])] == NSOrderedSame; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment