Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Branch: master
Fetching contributors…

Cannot retrieve contributors at this time

280 lines (213 sloc) 8.516 kB
//
// NSString+SSToolkitAdditions.m
// SSToolkit
//
// Created by Sam Soffes on 6/22/09.
// Copyright 2009-2011 Sam Soffes. All rights reserved.
//
#import "NSString+SSToolkitAdditions.h"
#import "NSData+SSToolkitAdditions.h"
#import <CommonCrypto/CommonDigest.h>
@implementation NSString (SSToolkitAdditions)
- (BOOL)containsString:(NSString *)string {
return !NSEqualRanges([self rangeOfString:string], NSMakeRange(NSNotFound, 0));
}
- (NSString *)MD5Sum {
const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:self.length];
return [data MD5Sum];
}
- (NSString *)SHA1Sum {
const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:self.length];
return [data SHA1Sum];
}
// Adapted from http://snipplr.com/view/2771/compare-two-version-strings
- (NSComparisonResult)compareToVersionString:(NSString *)version {
// Break version into fields (separated by '.')
NSMutableArray *leftFields = [[NSMutableArray alloc] initWithArray:[self componentsSeparatedByString:@"."]];
NSMutableArray *rightFields = [[NSMutableArray alloc] initWithArray:[version componentsSeparatedByString:@"."]];
// Implict ".0" in case version doesn't have the same number of '.'
if ([leftFields count] < [rightFields count]) {
while ([leftFields count] != [rightFields count]) {
[leftFields addObject:@"0"];
}
} else if ([leftFields count] > [rightFields count]) {
while ([leftFields count] != [rightFields count]) {
[rightFields addObject:@"0"];
}
}
// Do a numeric comparison on each field
for (NSUInteger i = 0; i < [leftFields count]; i++) {
NSComparisonResult result = [[leftFields objectAtIndex:i] compare:[rightFields objectAtIndex:i] options:NSNumericSearch];
if (result != NSOrderedSame) {
return result;
}
}
return NSOrderedSame;
}
#pragma mark - HTML Methods
- (NSString *)escapeHTML {
NSMutableString *s = [NSMutableString string];
NSUInteger start = 0;
NSUInteger len = [self length];
NSCharacterSet *chs = [NSCharacterSet characterSetWithCharactersInString:@"<>&\""];
while (start < len) {
NSRange r = [self rangeOfCharacterFromSet:chs options:0 range:NSMakeRange(start, len-start)];
if (r.location == NSNotFound) {
[s appendString:[self substringFromIndex:start]];
break;
}
if (start < r.location) {
[s appendString:[self substringWithRange:NSMakeRange(start, r.location-start)]];
}
switch ([self characterAtIndex:r.location]) {
case '<':
[s appendString:@"&lt;"];
break;
case '>':
[s appendString:@"&gt;"];
break;
case '"':
[s appendString:@"&quot;"];
break;
// case '…':
// [s appendString:@"&hellip;"];
// break;
case '&':
[s appendString:@"&amp;"];
break;
}
start = r.location + 1;
}
return s;
}
- (NSString *)unescapeHTML {
NSMutableString *s = [NSMutableString string];
NSMutableString *target = [self mutableCopy];
NSCharacterSet *chs = [NSCharacterSet characterSetWithCharactersInString:@"&"];
while ([target length] > 0) {
NSRange r = [target rangeOfCharacterFromSet:chs];
if (r.location == NSNotFound) {
[s appendString:target];
break;
}
if (r.location > 0) {
[s appendString:[target substringToIndex:r.location]];
[target deleteCharactersInRange:NSMakeRange(0, r.location)];
}
if ([target hasPrefix:@"&lt;"]) {
[s appendString:@"<"];
[target deleteCharactersInRange:NSMakeRange(0, 4)];
} else if ([target hasPrefix:@"&gt;"]) {
[s appendString:@">"];
[target deleteCharactersInRange:NSMakeRange(0, 4)];
} else if ([target hasPrefix:@"&quot;"]) {
[s appendString:@"\""];
[target deleteCharactersInRange:NSMakeRange(0, 6)];
} else if ([target hasPrefix:@"&#39;"]) {
[s appendString:@"'"];
[target deleteCharactersInRange:NSMakeRange(0, 5)];
} else if ([target hasPrefix:@"&amp;"]) {
[s appendString:@"&"];
[target deleteCharactersInRange:NSMakeRange(0, 5)];
} else if ([target hasPrefix:@"&hellip;"]) {
[s appendString:@""];
[target deleteCharactersInRange:NSMakeRange(0, 8)];
} else {
[s appendString:@"&"];
[target deleteCharactersInRange:NSMakeRange(0, 1)];
}
}
return s;
}
#pragma mark - URL Escaping and Unescaping
- (NSString *)stringByEscapingForURLQuery {
NSString *result = self;
static CFStringRef leaveAlone = CFSTR(" ");
static CFStringRef toEscape = CFSTR("\n\r:/=,!$&'()*+;[]@#?%");
CFStringRef escapedStr = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)self, leaveAlone,
toEscape, kCFStringEncodingUTF8);
if (escapedStr) {
NSMutableString *mutable = [NSMutableString stringWithString:(__bridge NSString *)escapedStr];
CFRelease(escapedStr);
[mutable replaceOccurrencesOfString:@" " withString:@"+" options:0 range:NSMakeRange(0, [mutable length])];
result = mutable;
}
return result;
}
- (NSString *)stringByUnescapingFromURLQuery {
NSString *deplussed = [self stringByReplacingOccurrencesOfString:@"+" withString:@" "];
return [deplussed stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}
#pragma mark - URL Encoding and Unencoding (Deprecated)
- (NSString *)URLEncodedString {
static CFStringRef toEscape = CFSTR(":/=,!$&'()*+;[]@#?%");
return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(__bridge CFStringRef)self,
NULL,
toEscape,
kCFStringEncodingUTF8);
}
- (NSString *)URLEncodedParameterString {
static CFStringRef toEscape = CFSTR(":/=,!$&'()*+;[]@#?");
return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(__bridge CFStringRef)self,
NULL,
toEscape,
kCFStringEncodingUTF8);
}
- (NSString *)URLDecodedString {
return (__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault,
(__bridge CFStringRef)self,
CFSTR(""),
kCFStringEncodingUTF8);
}
#pragma mark - Base64 Encoding
- (NSString *)base64EncodedString {
if ([self length] == 0) {
return nil;
}
return [[self dataUsingEncoding:NSUTF8StringEncoding] base64EncodedString];
}
+ (NSString *)stringWithBase64String:(NSString *)base64String {
return [[NSString alloc] initWithData:[NSData dataWithBase64String:base64String] encoding:NSUTF8StringEncoding];
}
#pragma mark - Generating a UUID
+ (NSString *)stringWithUUID {
CFUUIDRef uuid = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, uuid);
CFRelease(uuid);
return (__bridge_transfer NSString *)string;
}
#pragma mark - Trimming
- (NSString *)stringByTrimmingLeadingAndTrailingCharactersInSet:(NSCharacterSet *)characterSet {
return [[self stringByTrimmingLeadingCharactersInSet:characterSet]
stringByTrimmingTrailingCharactersInSet:characterSet];
}
- (NSString *)stringByTrimmingLeadingAndTrailingWhitespaceAndNewlineCharacters {
return [[self stringByTrimmingLeadingWhitespaceAndNewlineCharacters]
stringByTrimmingTrailingWhitespaceAndNewlineCharacters];
}
- (NSString *)stringByTrimmingLeadingCharactersInSet:(NSCharacterSet *)characterSet {
NSRange rangeOfFirstWantedCharacter = [self rangeOfCharacterFromSet:[characterSet invertedSet]];
if (rangeOfFirstWantedCharacter.location == NSNotFound) {
return @"";
}
return [self substringFromIndex:rangeOfFirstWantedCharacter.location];
}
- (NSString *)stringByTrimmingLeadingWhitespaceAndNewlineCharacters {
return [self stringByTrimmingLeadingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (NSString *)stringByTrimmingTrailingCharactersInSet:(NSCharacterSet *)characterSet {
NSRange rangeOfLastWantedCharacter = [self rangeOfCharacterFromSet:[characterSet invertedSet]
options:NSBackwardsSearch];
if (rangeOfLastWantedCharacter.location == NSNotFound) {
return @"";
}
return [self substringToIndex:rangeOfLastWantedCharacter.location + 1]; // Non-inclusive
}
- (NSString *)stringByTrimmingTrailingWhitespaceAndNewlineCharacters {
return [self stringByTrimmingTrailingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
@end
Jump to Line
Something went wrong with that request. Please try again.