|
Wired Foundation
2.0
A foundation framework for the Wired implementation on Mac OS X
|
00001 /* $Id$ */ 00002 00003 /* 00004 * Copyright (c) 2003-2009 Axel Andersson 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 2. Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * 00016 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00017 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00018 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00019 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 00020 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00021 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00022 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00023 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 00024 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00025 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00026 * POSSIBILITY OF SUCH DAMAGE. 00027 */ 00028 00029 #import <WiredFoundation/NSScanner-WIFoundation.h> 00030 #import <WiredFoundation/NSString-WIFoundation.h> 00031 00032 @implementation NSString(WIFoundation) 00033 00034 + (id)stringWithFormat:(NSString *)format arguments:(va_list)arguments { 00035 return [[[self alloc] initWithFormat:format arguments:arguments] autorelease]; 00036 } 00037 00038 00039 00040 + (id)stringWithData:(NSData *)data encoding:(NSStringEncoding)encoding { 00041 return [[[self alloc] initWithData:data encoding:encoding] autorelease]; 00042 } 00043 00044 00045 00046 + (id)stringWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding { 00047 return [[[self alloc] initWithBytes:bytes length:length encoding:encoding] autorelease]; 00048 } 00049 00050 00051 00052 + (id)stringWithRandomCharactersFromString:(NSString *)characters length:(NSUInteger)length { 00053 NSMutableString *string; 00054 NSUInteger count; 00055 00056 string = [NSMutableString string]; 00057 count = [characters length]; 00058 00059 while(length > 0) { 00060 [string appendFormat:@"%C", [characters characterAtIndex:random() % count]]; 00061 00062 length--; 00063 } 00064 00065 return string; 00066 } 00067 00068 00069 00070 + (id)UUIDString { 00071 NSString *string; 00072 CFUUIDRef uuidRef; 00073 CFStringRef stringRef; 00074 00075 uuidRef = CFUUIDCreate(NULL); 00076 stringRef = CFUUIDCreateString(NULL, uuidRef); 00077 CFRelease(uuidRef); 00078 00079 string = [[self alloc] initWithString:(NSString *) stringRef]; 00080 00081 CFRelease(stringRef); 00082 00083 return [string autorelease]; 00084 } 00085 00086 00087 00088 #pragma mark - 00089 00090 - (NSUInteger)UTF8StringLength { 00091 return strlen([self UTF8String]); 00092 } 00093 00094 00095 00096 - (unsigned long long)unsignedLongLongValue { 00097 return (unsigned long long) [self longLongValue]; 00098 } 00099 00100 00101 00102 - (unsigned int)unsignedIntValue { 00103 return (unsigned int) [self intValue]; 00104 } 00105 00106 00107 00108 - (NSUInteger)unsignedIntegerValue { 00109 return (NSUInteger) [self integerValue]; 00110 } 00111 00112 00113 00114 #pragma mark - 00115 00116 - (BOOL)containsSubstring:(NSString *)string { 00117 return ([self rangeOfString:string].location != NSNotFound); 00118 } 00119 00120 00121 - (BOOL)containsSubstring:(NSString *)string options:(NSUInteger)options { 00122 return ([self rangeOfString:string options:options].location != NSNotFound); 00123 } 00124 00125 00126 - (BOOL)containsCharactersFromSet:(NSCharacterSet *)set { 00127 return ([self rangeOfCharacterFromSet:set].location != NSNotFound); 00128 } 00129 00130 00131 00132 - (BOOL)isComposedOfCharactersFromSet:(NSCharacterSet *)set { 00133 return ![self containsCharactersFromSet:[set invertedSet]]; 00134 } 00135 00136 00137 00138 #pragma mark - 00139 00140 - (NSArray *)componentsSeparatedByCharactersFromSet:(NSCharacterSet *)set { 00141 NSScanner *scanner; 00142 NSMutableArray *components; 00143 NSCharacterSet *invertedSet; 00144 NSString *string; 00145 00146 if([self length] == 0) 00147 return NULL; 00148 00149 if(![self containsCharactersFromSet:set]) 00150 return [NSArray arrayWithObject:self]; 00151 00152 scanner = [NSScanner scannerWithString:self]; 00153 components = [NSMutableArray array]; 00154 invertedSet = [set invertedSet]; 00155 00156 while(![scanner isAtEnd]) { 00157 [scanner scanUpToCharactersFromSet:set intoString:&string]; 00158 [scanner scanUpToCharactersFromSet:invertedSet intoString:NULL]; 00159 00160 if([string length] > 0) 00161 [components addObject:string]; 00162 } 00163 00164 return components; 00165 } 00166 00167 00168 00169 #pragma mark - 00170 00171 - (NSString *)stringByReplacingOccurencesOfString:(NSString *)target withString:(NSString *)replacement { 00172 NSMutableString *string; 00173 00174 string = [self mutableCopy]; 00175 00176 [string replaceOccurrencesOfString:target 00177 withString:replacement 00178 options:0 00179 range:NSMakeRange(0, [string length])]; 00180 00181 return [string autorelease]; 00182 } 00183 00184 00185 00186 - (NSString *)stringByReplacingOccurencesOfStrings:(NSArray *)targets withString:(NSString *)replacement { 00187 NSMutableString *string; 00188 NSEnumerator *enumerator; 00189 NSString *target; 00190 00191 string = [self mutableCopy]; 00192 enumerator = [targets objectEnumerator]; 00193 00194 while((target = [enumerator nextObject])) { 00195 [string replaceOccurrencesOfString:target 00196 withString:replacement 00197 options:0 00198 range:NSMakeRange(0, [string length])]; 00199 } 00200 00201 return [string autorelease]; 00202 } 00203 00204 00205 00206 #pragma mark - 00207 00208 - (NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)encoding charactersToLeaveUnescaped:(NSString *)charactersToLeaveUnescaped { 00209 return [(NSString *) CFURLCreateStringByAddingPercentEscapes(NULL, 00210 (CFStringRef) self, 00211 (CFStringRef) charactersToLeaveUnescaped, 00212 NULL, 00213 CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease]; 00214 } 00215 00216 00217 00218 - (NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)encoding legalURLCharactersToBeEscaped:(NSString *)legalURLCharactersToBeEscaped { 00219 return [(NSString *) CFURLCreateStringByAddingPercentEscapes(NULL, 00220 (CFStringRef) self, 00221 NULL, 00222 (CFStringRef) legalURLCharactersToBeEscaped, 00223 CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease]; 00224 } 00225 00226 00227 00228 #pragma mark - 00229 00230 - (NSString *)stringByReplacingPathExtensionWithExtension:(NSString *)extension { 00231 return [[self stringByDeletingPathExtension] stringByAppendingPathExtension:extension]; 00232 } 00233 00234 00235 00236 #pragma mark - 00237 00238 - (NSString *)stringByApplyingFilter:(WITextFilter *)filter { 00239 NSMutableString *string; 00240 00241 string = [self mutableCopy]; 00242 [string applyFilter:filter]; 00243 00244 return [string autorelease]; 00245 } 00246 00247 00248 00249 #pragma mark - 00250 00251 - (NSComparisonResult)caseInsensitiveAndNumericCompare:(NSString *)string { 00252 return [self compare:string 00253 options:NSCaseInsensitiveSearch | NSNumericSearch 00254 range:NSMakeRange(0, [self length]) 00255 locale:[NSLocale currentLocale]]; 00256 } 00257 00258 00259 00260 - (NSComparisonResult)finderCompare:(NSString *)string { 00261 return /* NSWidthInsensitiveSearch *//* NSForcedOrderingSearch */[self compare:string 00262 options:NSCaseInsensitiveSearch | NSNumericSearch | 256 | 512 00263 range:NSMakeRange(0, [self length]) 00264 locale:[NSLocale currentLocale]]; 00265 } 00266 00267 @end 00268 00269 00270 00271 @implementation NSString(WIStringChecksumming) 00272 00273 - (NSString *)SHA1 { 00274 CC_SHA1_CTX c; 00275 static unsigned char hex[] = "0123456789abcdef"; 00276 unsigned char sha[CC_SHA1_DIGEST_LENGTH]; 00277 char text[CC_SHA1_DIGEST_LENGTH * 2 + 1]; 00278 NSUInteger i; 00279 00280 CC_SHA1_Init(&c); 00281 CC_SHA1_Update(&c, [self UTF8String], (CC_LONG)[self UTF8StringLength]); 00282 CC_SHA1_Final(sha, &c); 00283 00284 for(i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) { 00285 text[i + i] = hex[sha[i] >> 4]; 00286 text[i + i + 1] = hex[sha[i] & 0x0F]; 00287 } 00288 00289 text[i + i] = '\0'; 00290 00291 return [NSString stringWithUTF8String:text]; 00292 } 00293 00294 @end 00295 00296 00297 00298 @implementation NSString(WIHumanReadableStringFormatting) 00299 00300 + (NSString *)humanReadableStringForTimeInterval:(NSTimeInterval)interval { 00301 NSString *string; 00302 NSUInteger days, hours, minutes, seconds; 00303 BOOL past = NO; 00304 00305 interval = rint(interval); 00306 00307 if(interval < 0) { 00308 past = YES; 00309 interval = -interval; 00310 } 00311 00312 days = interval / 86400; 00313 interval -= days * 86400; 00314 00315 hours = interval / 3600; 00316 interval -= hours * 3600; 00317 00318 minutes = interval / 60; 00319 interval -= minutes * 60; 00320 00321 seconds = interval; 00322 00323 if(days > 0) { 00324 string = [NSSWF: 00325 WILS(@"%lu:%0.2lu:%0.2lu:%0.2lu days", @"NSString-WIFoundation: time strings (days, hours, minutes, seconds)"), 00326 days, hours, minutes, seconds]; 00327 } 00328 else if(hours > 0) { 00329 string = [NSSWF: 00330 WILS(@"%0.2lu:%0.2lu:%0.2lu hours", @"NSString-WIFoundation: time strings (hours, minutes, seconds)"), 00331 hours, minutes, seconds]; 00332 } 00333 else if(minutes > 0) { 00334 string = [NSSWF: 00335 WILS(@"%0.2lu:%0.2lu minutes", @"NSString-WIFoundation: time strings (minutes, seconds)"), 00336 minutes, seconds]; 00337 } 00338 else { 00339 string = [NSSWF: 00340 WILS(@"00:%0.2lu seconds", @"NSString-WIFoundation: time string (minutes, seconds)"), 00341 seconds]; 00342 } 00343 00344 if(past) 00345 string = [NSSWF:WILS(@"%@ ago", @"NSString-WIFoundation: time string"), string]; 00346 00347 return string; 00348 } 00349 00350 00351 00352 + (NSString *)humanReadableStringForSizeInBytes:(unsigned long long)size { 00353 static NSNumberFormatter *formatter; 00354 double kb, mb, gb, tb, pb; 00355 00356 if(!formatter) { 00357 formatter = [[NSNumberFormatter alloc] init]; 00358 [formatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; 00359 [formatter setNumberStyle:NSNumberFormatterDecimalStyle]; 00360 [formatter setMaximumFractionDigits:1]; 00361 } 00362 00363 if(size < 1000) { 00364 return [NSSWF:WILS(@"%llu bytes", @"NSString-WIFoundation: byte size strings"), 00365 size]; 00366 } 00367 00368 kb = (double) size / 1024.0; 00369 00370 if(kb < 1000) { 00371 return [NSSWF:WILS(@"%@ KB", @"NSString-WIFoundation: byte size strings"), 00372 [formatter stringForObjectValue:[NSNumber numberWithDouble:kb]]]; 00373 } 00374 00375 mb = (double) kb / 1024.0; 00376 00377 if(mb < 1000) { 00378 return [NSSWF:WILS(@"%@ MB", @"NSString-WIFoundation: byte size strings"), 00379 [formatter stringForObjectValue:[NSNumber numberWithDouble:mb]]]; 00380 } 00381 00382 gb = (double) mb / 1024.0; 00383 00384 if(gb < 1000) { 00385 return [NSSWF:WILS(@"%@ GB", @"NSString-WIFoundation: byte size strings"), 00386 [formatter stringForObjectValue:[NSNumber numberWithDouble:gb]]]; 00387 } 00388 00389 tb = (double) gb / 1024.0; 00390 00391 if(tb < 1000) { 00392 return [NSSWF:WILS(@"%@ TB", @"NSString-WIFoundation: byte size strings"), 00393 [formatter stringForObjectValue:[NSNumber numberWithDouble:tb]]]; 00394 } 00395 00396 pb = (double) tb / 1024.0; 00397 00398 if(pb < 1000) { 00399 return [NSSWF:WILS(@"%@ PB", @"NSString-WIFoundation: byte size strings"), 00400 [formatter stringForObjectValue:[NSNumber numberWithDouble:pb]]]; 00401 } 00402 00403 return NULL; 00404 } 00405 00406 00407 00408 + (NSString *)humanReadableStringForSizeInBytes:(unsigned long long)size withBytes:(BOOL)bytes { 00409 static NSNumberFormatter *formatter; 00410 NSString *string; 00411 00412 string = [NSString humanReadableStringForSizeInBytes:size]; 00413 00414 if(size > 1024 && bytes) { 00415 if(!formatter) { 00416 formatter = [[NSNumberFormatter alloc] init]; 00417 [formatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; 00418 [formatter setNumberStyle:NSNumberFormatterDecimalStyle]; 00419 } 00420 00421 string = [NSSWF:@"%@ (%@ %@)", 00422 string, 00423 [formatter stringForObjectValue:[NSNumber numberWithUnsignedLongLong:size]], 00424 size == 1 00425 ? WILS(@"byte", @"NSString-WIFoundation: 'byte' singular") 00426 : WILS(@"bytes", @"NSString-WIFoundation: 'byte' plural")]; 00427 } 00428 00429 return string; 00430 } 00431 00432 00433 00434 + (NSString *)humanReadableStringForSizeInBits:(unsigned long long)size { 00435 static NSNumberFormatter *formatter; 00436 double kb, mb, gb, tb, pb; 00437 00438 if(!formatter) { 00439 formatter = [[NSNumberFormatter alloc] init]; 00440 [formatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; 00441 [formatter setNumberStyle:NSNumberFormatterDecimalStyle]; 00442 [formatter setMaximumFractionDigits:1]; 00443 } 00444 00445 if(size < 1000) { 00446 return [NSSWF:WILS(@"%llu bits", @"NSString-WIFoundation: bit size strings"), 00447 size]; 00448 } 00449 00450 kb = (double) size / 1024.0; 00451 00452 if(kb < 1000) { 00453 return [NSSWF:WILS(@"%@ kbit", @"NSString-WIFoundation: bit size strings"), 00454 [formatter stringForObjectValue:[NSNumber numberWithDouble:kb]]]; 00455 } 00456 00457 mb = (double) kb / 1024.0; 00458 00459 if(mb < 1000) { 00460 return [NSSWF:WILS(@"%@ Mbit", @"NSString-WIFoundation: bit size strings"), 00461 [formatter stringForObjectValue:[NSNumber numberWithDouble:mb]]]; 00462 } 00463 00464 gb = (double) mb / 1024.0; 00465 00466 if(gb < 1000) { 00467 return [NSSWF:WILS(@"%@ Gbit", @"NSString-WIFoundation: bit size strings"), 00468 [formatter stringForObjectValue:[NSNumber numberWithDouble:gb]]]; 00469 } 00470 00471 tb = (double) gb / 1024.0; 00472 00473 if(tb < 1000) { 00474 return [NSSWF:WILS(@"%@ Tbit", @"NSString-WIFoundation: bit size strings"), 00475 [formatter stringForObjectValue:[NSNumber numberWithDouble:tb]]]; 00476 } 00477 00478 pb = (double) tb / 1024.0; 00479 00480 if(pb < 1000) { 00481 return [NSSWF:WILS(@"%@ Pbit", @"NSString-WIFoundation: bit size strings"), 00482 [formatter stringForObjectValue:[NSNumber numberWithDouble:pb]]]; 00483 } 00484 00485 return NULL; 00486 } 00487 00488 00489 00490 + (NSString *)humanReadableStringForBandwidth:(NSUInteger)speed { 00491 if(speed > 0) { 00492 if(speed <= 3600) 00493 return WILS(@"28.8k Modem", @"NSString-WIFoundation: bandwidth strings"); 00494 else if(speed <= 4200) 00495 return WILS(@"33.6k Modem", @"NSString-WIFoundation: bandwidth strings"); 00496 else if(speed <= 7000) 00497 return WILS(@"56k Modem", @"NSString-WIFoundation: bandwidth strings"); 00498 else if(speed <= 8000) 00499 return WILS(@"64k ISDN", @"NSString-WIFoundation: bandwidth strings"); 00500 else if(speed <= 16000) 00501 return WILS(@"128k ISDN/DSL", @"NSString-WIFoundation: bandwidth strings"); 00502 else if(speed <= 32000) 00503 return WILS(@"256k DSL/Cable", @"NSString-WIFoundation: bandwidth strings"); 00504 else if(speed <= 48000) 00505 return WILS(@"384k DSL/Cable", @"NSString-WIFoundation: bandwidth strings"); 00506 else if(speed <= 64000) 00507 return WILS(@"512k DSL/Cable", @"NSString-WIFoundation: bandwidth strings"); 00508 else if(speed <= 96000) 00509 return WILS(@"768k DSL/Cable", @"NSString-WIFoundation: bandwidth strings"); 00510 else if(speed <= 128000) 00511 return WILS(@"1M DSL/Cable", @"NSString-WIFoundation: bandwidth strings"); 00512 else if(speed <= 256000) 00513 return WILS(@"2M DSL/Cable", @"NSString-WIFoundation: bandwidth strings"); 00514 else if(speed <= 1280000) 00515 return WILS(@"10M LAN", @"NSString-WIFoundation: bandwidth strings"); 00516 else if(speed <= 12800000) 00517 return WILS(@"100M LAN", @"NSString-WIFoundation: bandwidth strings"); 00518 } 00519 00520 return WILS(@"Unknown", @"NSString-WIFoundation: bandwidth strings"); 00521 } 00522 00523 @end 00524 00525 00526 00527 @implementation NSString(WIWiredVersionStringFormatting) 00528 00529 - (NSString *)wiredVersion { 00530 NSString *unknown, *client, *clientVersion, *os, *osVersion, *arch; 00531 NSScanner *scanner; 00532 const NXArchInfo *info; 00533 00534 // "Wired Client/1.0 (Darwin; 7.3.0; powerpc) (OpenSSL 0.9.6i Feb 19 2003; CoreFoundation 299.3; AppKit 743.20)" 00535 00536 unknown = WILS(@"Unknown", @"NSString-WIFoundation: unknown Wired client"); 00537 scanner = [NSScanner scannerWithString:self]; 00538 [scanner setCharactersToBeSkipped:NULL]; 00539 00540 if(![scanner scanUpToString:@"/" intoString:&client]) 00541 return unknown; 00542 00543 if(![scanner scanString:@"/" intoString:NULL]) 00544 return unknown; 00545 00546 if(![scanner scanUpToString:@" " intoString:&clientVersion]) 00547 return unknown; 00548 00549 if(![scanner scanString:@" (" intoString:NULL]) 00550 return unknown; 00551 00552 if(![scanner scanUpToString:@";" intoString:&os]) 00553 return unknown; 00554 00555 if(![scanner scanString:@"; " intoString:NULL]) 00556 return unknown; 00557 00558 if(![scanner scanUpToString:@";" intoString:&osVersion]) 00559 return unknown; 00560 00561 if(![scanner scanString:@"; " intoString:NULL]) 00562 return unknown; 00563 00564 if(![scanner scanUpToString:@")" intoString:&arch]) 00565 return unknown; 00566 00567 if([arch isEqualToString:@"powerpc"]) 00568 arch = @"ppc"; 00569 00570 info = NXGetArchInfoFromName([arch UTF8String]); 00571 00572 if(info) 00573 arch = [NSSWF:@"%s", info->description]; 00574 00575 return [NSSWF: 00576 WILS(@"%@ %@ on %@ %@ (%@)", @"NSString-WIFoundation: Wired client version (client, client version, os, os version, architecture)"), 00577 client, clientVersion, os, osVersion, arch]; 00578 } 00579 00580 @end 00581 00582 00583 00584 @implementation NSMutableString(WIFoundation) 00585 00586 - (void)deleteCharactersToIndex:(NSUInteger)index { 00587 [self deleteCharactersInRange:NSMakeRange(0, index)]; 00588 } 00589 00590 00591 00592 - (void)deleteCharactersFromIndex:(NSUInteger)index { 00593 [self deleteCharactersInRange:NSMakeRange(index, [self length] - index)]; 00594 } 00595 00596 00597 00598 - (NSUInteger)replaceOccurrencesOfString:(NSString *)target withString:(NSString *)replacement { 00599 return [self replaceOccurrencesOfString:target withString:replacement options:0 range:NSMakeRange(0, [self length])]; 00600 } 00601 00602 00603 00604 - (NSUInteger)replaceOccurrencesOfString:(NSString *)target withString:(NSString *)replacement options:(NSUInteger)options { 00605 return [self replaceOccurrencesOfString:target withString:replacement options:options range:NSMakeRange(0, [self length])]; 00606 } 00607 00608 00609 00610 - (void)trimCharactersInSet:(NSCharacterSet *)characterSet { 00611 [self setString:[self stringByTrimmingCharactersInSet:characterSet]]; 00612 } 00613 00614 00615 00616 - (void)applyFilter:(WITextFilter *)filter { 00617 [filter performSelector:@selector(filter:) withObject:self]; 00618 } 00619 00620 @end