#import "NSStringAdditions.h" @implementation NSString (NSStringAdditions) + (NSString *) mimeCharsetTagFromStringEncoding:(NSStringEncoding) encoding { switch( encoding ) { default: case NSASCIIStringEncoding: case NSNonLossyASCIIStringEncoding: return @"us-ascii"; break; case NSUTF8StringEncoding: return @"utf-8"; break; case NSISOLatin1StringEncoding: return @"iso-8859-1"; break; case 0x80000203: return @"iso-8859-3"; break; case 0x80000208: return @"iso-8859-8"; break; case 0x80000005: return @"x-mac-hebrew"; break; case 0x80000505: return @"windows-1255"; break; case 0x8000020F: return @"iso-8859-9"; break; case NSWindowsCP1252StringEncoding: return @"windows-1252"; break; case NSISOLatin2StringEncoding: return @"iso-8859-2"; break; case 0x80000204: return @"iso-8859-4"; break; case NSWindowsCP1250StringEncoding: return @"windows-1250"; break; case 0x80000A02: return @"KOI8-R"; break; case 0x80000205: return @"iso-8859-5"; break; case NSWindowsCP1251StringEncoding: return @"windows-1251"; break; case 0x80000A01: return @"Shift_JIS"; break; case NSISO2022JPStringEncoding: return @"iso-2022-jp"; break; case NSJapaneseEUCStringEncoding: return @"EUC-JP"; break; } } #pragma mark - - (unsigned long) UTF8StringByteLength { const char *str = [self UTF8String]; return ( str ? strlen( str ) : 0 ); } #pragma mark - - (id) initWithBytes:(const void *) bytes encoding:(NSStringEncoding) encoding { if( bytes && strlen( bytes ) ) { id ret = [self initWithBytes:bytes length:strlen( bytes ) encoding:encoding]; if( ! ret ) ret = [self initWithCString:bytes]; if( ! ret ) [self release]; return ( self = ret ); } [self release]; return nil; } + (id) stringWithBytes:(const void *) bytes encoding:(NSStringEncoding) encoding { if( bytes && strlen( bytes ) ) return [[[self alloc] initWithBytes:bytes encoding:encoding] autorelease]; return nil; } #pragma mark - - (const char *) bytesUsingEncoding:(NSStringEncoding) encoding allowLossyConversion:(BOOL) lossy { NSMutableData *ret = [[[self dataUsingEncoding:encoding allowLossyConversion:lossy] mutableCopy] autorelease]; [ret appendBytes:"\0" length:1]; return [ret bytes]; } - (const char *) bytesUsingEncoding:(NSStringEncoding) encoding { return [self bytesUsingEncoding:encoding allowLossyConversion:NO]; } #pragma mark - - (NSString *) stringByEncodingXMLSpecialCharactersAsEntities { NSMutableString *result = [self mutableCopy]; [result encodeXMLSpecialCharactersAsEntities]; NSString *immutableResult = [NSString stringWithString:result]; [result release]; return immutableResult; } - (NSString *) stringByDecodingXMLSpecialCharacterEntities { NSMutableString *result = [self mutableCopy]; [result decodeXMLSpecialCharacterEntities]; NSString *immutableResult = [NSString stringWithString:result]; [result release]; return immutableResult; } #pragma mark - - (NSString *) stringByEscapingCharactersInSet:(NSCharacterSet *) set { NSMutableString *result = [self mutableCopy]; [result escapeCharactersInSet:set]; NSString *immutableResult = [NSString stringWithString:result]; [result release]; return immutableResult; } #pragma mark - - (NSString *) stringByEncodingIllegalURLCharacters { return [(NSString *)CFURLCreateStringByAddingPercentEscapes( NULL, (CFStringRef)self, NULL, CFSTR( ",;:/?@&$=|^~`\{}[]" ), kCFStringEncodingUTF8 ) autorelease]; } - (NSString *) stringByDecodingIllegalURLCharacters { return [(NSString *)CFURLCreateStringByReplacingPercentEscapes( NULL, (CFStringRef)self, CFSTR( "" ) ) autorelease]; } #pragma mark - - (NSString *) stringByStrippingIllegalXMLCharacters { NSMutableString *result = [self mutableCopy]; [result stripIllegalXMLCharacters]; NSString *immutableResult = [NSString stringWithString:result]; [result release]; return immutableResult; } @end #pragma mark - @implementation NSMutableString (NSMutableStringAdditions) - (void) encodeXMLSpecialCharactersAsEntities { [self replaceOccurrencesOfString:@"&" withString:@"&" options:NSLiteralSearch range:NSMakeRange( 0, [self length] )]; [self replaceOccurrencesOfString:@"<" withString:@"<" options:NSLiteralSearch range:NSMakeRange( 0, [self length] )]; [self replaceOccurrencesOfString:@">" withString:@">" options:NSLiteralSearch range:NSMakeRange( 0, [self length] )]; [self replaceOccurrencesOfString:@"\"" withString:@""" options:NSLiteralSearch range:NSMakeRange( 0, [self length] )]; [self replaceOccurrencesOfString:@"'" withString:@"'" options:NSLiteralSearch range:NSMakeRange( 0, [self length] )]; } - (void) decodeXMLSpecialCharacterEntities { [self replaceOccurrencesOfString:@"&" withString:@"&" options:NSLiteralSearch range:NSMakeRange( 0, [self length] )]; [self replaceOccurrencesOfString:@"<" withString:@"<" options:NSLiteralSearch range:NSMakeRange( 0, [self length] )]; [self replaceOccurrencesOfString:@">" withString:@">" options:NSLiteralSearch range:NSMakeRange( 0, [self length] )]; [self replaceOccurrencesOfString:@""" withString:@"\"" options:NSLiteralSearch range:NSMakeRange( 0, [self length] )]; [self replaceOccurrencesOfString:@"'" withString:@"'" options:NSLiteralSearch range:NSMakeRange( 0, [self length] )]; } #pragma mark - - (void) escapeCharactersInSet:(NSCharacterSet *) set { NSScanner *scanner = [[NSScanner alloc] initWithString:self]; int offset = 0; while( ! [scanner isAtEnd] ) { [scanner scanUpToCharactersFromSet:set intoString:nil]; if( ! [scanner isAtEnd] ) { [self insertString:@"\\" atIndex:[scanner scanLocation] + offset++]; [scanner setScanLocation:[scanner scanLocation] + 1]; } } [scanner release]; } #pragma mark - - (void) encodeIllegalURLCharacters { [self setString:[self stringByEncodingIllegalURLCharacters]]; } - (void) decodeIllegalURLCharacters { [self setString:[self stringByDecodingIllegalURLCharacters]]; } #pragma mark - - (void) stripIllegalXMLCharacters { NSMutableCharacterSet *illegalSet = [[[NSCharacterSet characterSetWithRange:NSMakeRange( 0, 0x1f )] mutableCopy] autorelease]; [illegalSet addCharactersInRange:NSMakeRange( 0x7f, 1 )]; [illegalSet addCharactersInRange:NSMakeRange( 0xfffe, 1 )]; [illegalSet addCharactersInRange:NSMakeRange( 0xffff, 1 )]; NSRange range = [self rangeOfCharacterFromSet:illegalSet]; while( range.location != NSNotFound ) { [self deleteCharactersInRange:range]; range = [self rangeOfCharacterFromSet:illegalSet]; } } @end