KWStringUtilities.m 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. //
  2. // Licensed under the terms in License.txt
  3. //
  4. // Copyright 2010 Allen Ding. All rights reserved.
  5. //
  6. #import "KWStringUtilities.h"
  7. #pragma mark - Checking for Case Separated Words
  8. BOOL KWStringHasWordPrefix(NSString *string, NSString *prefix) {
  9. return [string isEqualToString:prefix] || KWStringHasStrictWordPrefix(string, prefix);
  10. }
  11. BOOL KWStringHasStrictWordPrefix(NSString *string, NSString *prefix) {
  12. if (![string hasPrefix:prefix] || [string length] == [prefix length])
  13. return NO;
  14. unichar firstCharacterAfterPrefix = [string characterAtIndex:[prefix length]];
  15. NSCharacterSet *uppercaseCharacterSet = [NSCharacterSet uppercaseLetterCharacterSet];
  16. return [uppercaseCharacterSet characterIsMember:firstCharacterAfterPrefix];
  17. }
  18. BOOL KWStringHasWord(NSString *string, NSString *word) {
  19. if (KWStringHasWordPrefix(string, word))
  20. return YES;
  21. NSCharacterSet *lowercaseCharacterSet = [NSCharacterSet lowercaseLetterCharacterSet];
  22. NSCharacterSet *uppercaseCharacterSet = [NSCharacterSet uppercaseLetterCharacterSet];
  23. NSRange searchRange = NSMakeRange(0, [string length]);
  24. // Never match if word begins with a lowercase letter and was not a prefix.
  25. if ([lowercaseCharacterSet characterIsMember:[word characterAtIndex:0]])
  26. return NO;
  27. while (1) {
  28. if (searchRange.location >= [string length])
  29. return NO;
  30. NSRange range = [string rangeOfString:word options:0 range:searchRange];
  31. searchRange.location = range.location + range.length;
  32. searchRange.length = [string length] - searchRange.location;
  33. if (range.location == NSNotFound)
  34. return NO;
  35. if (range.location > 0) {
  36. unichar charBeforeRange = [string characterAtIndex:range.location - 1];
  37. if (![lowercaseCharacterSet characterIsMember:charBeforeRange])
  38. continue;
  39. }
  40. if (range.location + range.length < [string length]) {
  41. unichar charAfterRange = [string characterAtIndex:range.location + range.length];
  42. if (![uppercaseCharacterSet characterIsMember:charAfterRange])
  43. continue;
  44. }
  45. return YES;
  46. }
  47. }
  48. #pragma mark - Getting Type Encodings
  49. NSString *KWEncodingWithObjCTypes(const char *firstType, ...) {
  50. if (firstType == nil)
  51. return nil;
  52. NSMutableString *encoding = [NSMutableString stringWithCapacity:8];
  53. va_list argumentList;
  54. va_start(argumentList, firstType);
  55. const char *type = firstType;
  56. do {
  57. [encoding appendFormat:@"%s", type];
  58. type = va_arg(argumentList, const char *);
  59. } while (type != nil);
  60. va_end(argumentList);
  61. return encoding;
  62. }
  63. NSString *KWEncodingForDefaultMethod(void) {
  64. return KWEncodingWithObjCTypes(@encode(id), @encode(id), @encode(SEL), nil);
  65. }