123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- #import "SKVersionNumber.h"
- #define VERSION_LONG @"version"
- #define VERSION_SHORT @"v"
- #define ALPHA_LONG @"alpha"
- #define ALPHA_SHORT @"a"
- #define BETA_LONG @"beta"
- #define BETA_SHORT @"b"
- #define DEVELOPMENT_LONG @"development"
- #define DEVELOPMENT_SHORT @"d"
- #define FINAL_LONG @"final"
- #define FINAL_SHORT @"f"
- #define RELEASE_CANDIDATE_LONG @"release candidate"
- #define RELEASE_CANDIDATE_SHORT @"rc"
- #define SEPARATOR @"."
- #define DASH @"-"
- #define EMPTY @""
- @implementation SKVersionNumber
- @synthesize originalVersionString, cleanVersionString, componentCount, releaseType;
- + (NSComparisonResult)compareVersionString:(NSString *)versionString toVersionString:(NSString *)otherVersionString;
- {
- SKVersionNumber *versionNumber = [[self alloc] initWithVersionString:versionString];
- SKVersionNumber *otherVersionNumber = [[self alloc] initWithVersionString:otherVersionString];
- NSComparisonResult result = [versionNumber compare:otherVersionNumber];
- return result;
- }
- - (id)initWithVersionString:(NSString *)versionString;
- {
-
- self = [super init];
- if (self) {
-
- if (versionString == nil || [versionString isKindOfClass:[NSString class]] == NO) {
- return nil;
- }
-
- originalVersionString = [versionString copy];
- releaseType = SKReleaseVersionType;
-
- NSMutableString *mutableVersionString = [[NSMutableString alloc] init];
- NSScanner *scanner = [[NSScanner alloc] initWithString:versionString];
- NSString *sep = EMPTY;
-
- [scanner setCharactersToBeSkipped:[NSCharacterSet whitespaceCharacterSet]];
-
-
- if ([scanner scanString:VERSION_LONG intoString:NULL] || [scanner scanString:VERSION_SHORT intoString:NULL])
- [scanner scanString:DASH intoString:NULL];
-
- while ([scanner isAtEnd] == NO && sep != nil) {
- NSInteger component;
-
- if ([scanner scanInteger:&component] && component >= 0) {
-
- [mutableVersionString appendFormat:@"%@%ld", sep, (long)component];
-
- componentCount++;
- components = (NSInteger *)NSZoneRealloc(NSDefaultMallocZone(), components, sizeof(NSInteger) * componentCount);
- components[componentCount - 1] = component;
-
- if ([scanner isAtEnd] == NO) {
- sep = nil;
- if ([scanner scanString:SEPARATOR intoString:NULL] || [scanner scanString:DASH intoString:NULL] || [scanner scanString:VERSION_LONG intoString:NULL] || [scanner scanString:VERSION_SHORT intoString:NULL]) {
- sep = SEPARATOR;
- }
- if (releaseType == SKReleaseVersionType) {
- if ([scanner scanString:ALPHA_LONG intoString:NULL] || [scanner scanString:ALPHA_SHORT intoString:NULL]) {
- releaseType = SKAlphaVersionType;
- [mutableVersionString appendString:ALPHA_SHORT];
- } else if ([scanner scanString:BETA_LONG intoString:NULL] || [scanner scanString:BETA_SHORT intoString:NULL]) {
- releaseType = SKBetaVersionType;
- [mutableVersionString appendString:BETA_SHORT];
- } else if ([scanner scanString:DEVELOPMENT_LONG intoString:NULL] || [scanner scanString:DEVELOPMENT_SHORT intoString:NULL]) {
- releaseType = SKDevelopmentVersionType;
- [mutableVersionString appendString:DEVELOPMENT_SHORT];
- } else if ([scanner scanString:FINAL_LONG intoString:NULL] || [scanner scanString:FINAL_SHORT intoString:NULL]) {
- releaseType = SKReleaseCandidateVersionType;
- [mutableVersionString appendString:FINAL_SHORT];
- } else if ([scanner scanString:RELEASE_CANDIDATE_LONG intoString:NULL] || [scanner scanString:RELEASE_CANDIDATE_SHORT intoString:NULL]) {
- releaseType = SKReleaseCandidateVersionType;
- [mutableVersionString appendString:RELEASE_CANDIDATE_SHORT];
- }
-
- if (releaseType != SKReleaseVersionType) {
-
- componentCount++;
- components = (NSInteger *)NSZoneRealloc(NSDefaultMallocZone(), components, sizeof(NSInteger) * componentCount);
- components[componentCount - 1] = releaseType;
-
- sep = EMPTY;
-
-
- if ([scanner scanString:SEPARATOR intoString:NULL] == NO)
- [scanner scanString:DASH intoString:NULL];
- }
- }
- }
- } else
- sep = nil;
- }
-
- if ([mutableVersionString isEqualToString:originalVersionString])
- cleanVersionString = originalVersionString;
- else
- cleanVersionString = [mutableVersionString copy];
-
-
- if (componentCount == 0) {
-
- return nil;
- }
- }
- return self;
- }
- - (void)dealloc;
- {
- }
- - (NSString *)description {
- return [NSString stringWithFormat:@"<%@: %@>", [self class], [self originalVersionString]];
- }
- #pragma mark API
- - (NSInteger)componentAtIndex:(NSUInteger)componentIndex;
- {
-
- if (componentIndex < componentCount)
- return components[componentIndex];
- return 0;
- }
- #pragma mark NSCopying
- #pragma mark Comparison
- - (NSUInteger)hash;
- {
- return [cleanVersionString hash];
- }
- - (BOOL)isEqual:(id)otherObject;
- {
- if ([otherObject isMemberOfClass:[self class]] == NO)
- return NO;
- return [self compare:(SKVersionNumber *)otherObject] == NSOrderedSame;
- }
- - (NSComparisonResult)compare:(SKVersionNumber *)otherVersion;
- {
- if (otherVersion == nil)
- return NSOrderedAscending;
-
- NSUInteger idx = 0, otherIdx = 0, otherCount = [otherVersion componentCount];
- while (idx < componentCount || otherIdx < otherCount) {
- NSInteger component = [self componentAtIndex:idx];
- NSInteger otherComponent = [otherVersion componentAtIndex:otherIdx];
-
-
- if (component < 0 && otherComponent >= 0 && otherIdx < otherCount) {
- component = 0;
- otherIdx++;
- } else if (component >= 0 && otherComponent < 0 && idx < componentCount) {
- otherComponent = 0;
- idx++;
- } else {
- idx++;
- otherIdx++;
- }
-
- if (component < otherComponent)
- return NSOrderedAscending;
- else if (component > otherComponent)
- return NSOrderedDescending;
- }
-
- return NSOrderedSame;
- }
- @end
|