Adding loads of neato registration stuff!
[MenuTunes.git] / MTeSerialNumber.m
diff --git a/MTeSerialNumber.m b/MTeSerialNumber.m
new file mode 100755 (executable)
index 0000000..9d8da42
--- /dev/null
@@ -0,0 +1,239 @@
+#import "MTeSerialNumber.h"
+#import "validate.h"
+
+
+@interface MTeSerialNumber (Private)
+- (short)validate;
+- (eSellerate_String)eSellerateStringForString:(NSString *)string;
+@end
+
+@implementation MTeSerialNumber
+
+/*************************************************************************/
+#pragma mark -
+#pragma mark INITIALIZATION METHODS
+/*************************************************************************/
+
+- (id)initWithSerialNumber:(NSString *)serial
+                      name:(NSString *)name
+                     extra:(NSString *)extra
+                 publisher:(NSString *)publisher
+{
+    if ( self = [super init] ) {
+        _serialNumber = serial;
+        _nameBasedKey = name;
+        _extraDataKey = nil;       //extra data is currently unused.
+        _publisherKey = publisher;
+        _deadSerials  = nil;
+    }
+    return self;
+}
+
+- (id)initWithDictionary:(NSDictionary *)dict
+{
+    return [self initWithSerialNumber:[dict objectForKey:@"Key"]
+                                 name:[dict objectForKey:@"Owner"]
+                                extra:[dict objectForKey:@"Extra"]
+                            publisher:[dict objectForKey:@"Publisher"]];
+}
+
+- (id)initWithContentsOfFile:(NSString *)path
+                       extra:(NSString *)extra
+                   publisher:(NSString *)publisher
+{
+    NSDictionary *fileDict = [[[NSDictionary alloc] initWithContentsOfFile:path] autorelease];
+    
+    if ( fileDict ) {
+        NSMutableDictionary *dict = [[[NSMutableDictionary alloc] initWithCapacity:4] autorelease];
+
+        [dict setObject:[fileDict objectForKey:@"Key"] forKey:@"Key"];
+        [dict setObject:[fileDict objectForKey:@"Owner"] forKey:@"Owner"];
+        [dict setObject:extra forKey:@"Extra"];
+        [dict setObject:publisher forKey:@"Publisher"];
+
+        return [self initWithDictionary:dict];
+    } else {
+        return nil;
+    }
+}
+
+
+/*************************************************************************/
+#pragma mark -
+#pragma mark ACCESSOR METHODS
+/*************************************************************************/
+
+- (NSString *)serialNumber
+{
+    return _serialNumber;
+}
+
+- (void)setSerialNumber:(NSString *)newSerial
+{
+    [_serialNumber autorelease];
+    _serialNumber = [newSerial copy];
+}
+
+- (NSString *)nameBasedKey
+{
+    return _nameBasedKey;
+}
+
+- (void)setNameBasedKey:(NSString *)newName
+{
+    [_nameBasedKey autorelease];
+    _nameBasedKey = [newName copy];
+}
+
+- (NSString *)extraDataKey
+{
+    return _extraDataKey;
+}
+
+- (void)setExtraDataKey:(NSString *)newData
+{
+    [_extraDataKey autorelease];
+    _extraDataKey = [newData copy];
+}
+
+- (NSString *)publisherKey
+{
+    return _publisherKey;
+}
+
+- (void)setPublisherKey:(NSString *)newPublisher
+{
+    [_publisherKey autorelease];
+    _publisherKey = [newPublisher copy];
+}
+
+- (NSArray *)deadSerials
+{
+    return _deadSerials;
+}
+
+- (void)setDeadSerials:(NSArray *)newList
+{
+    [_deadSerials autorelease];
+    _deadSerials = [newList copy];
+}
+
+
+/*************************************************************************/
+#pragma mark -
+#pragma mark INSTANCE METHODS
+/*************************************************************************/
+
+- (MTeSerialNumberValidationResult)isValid
+{
+    if ( _serialNumber ) {
+
+        BOOL dead = NO;
+        
+        if ( [_deadSerials count] )  {
+            NSEnumerator *deadEnum = [_deadSerials objectEnumerator];
+            id            aDeadSerial;
+            
+            while ( aDeadSerial = [deadEnum nextObject] ) {
+                if ( [aDeadSerial isEqualToString:_serialNumber] ) {
+                    dead = YES;
+               }
+            }
+        }
+
+        if ( dead ) {
+            return ITeSerialNumberIsDead;
+        } else {
+            return ( ( [self validate] > 0 ) ? ITeSerialNumberIsValid : ITeSerialNumberIsInvalid );
+        }
+    } else {
+        return nil;
+    }
+}
+
+- (MTeSerialNumberExpirationResult)isExpired;
+{
+    return ( ! [self secondsRemaining] > 0 );
+}
+
+- (NSDate *)storedDate
+{
+    NSCalendarDate *refDate = [NSCalendarDate dateWithYear:2000 month:1 day:1
+                                                      hour:0 minute:0 second:0
+                                                  timeZone:[NSTimeZone systemTimeZone]];
+
+    NSTimeInterval secondsFromRefToExp = ([self validate] * 86400);
+
+    return [[[NSDate alloc] initWithTimeInterval:secondsFromRefToExp
+                                       sinceDate:refDate] autorelease];
+}
+
+- (NSTimeInterval)secondsRemaining
+{
+    return [[self storedDate] timeIntervalSinceDate:[NSDate date]];
+}
+
+- (NSDictionary *)infoDictionary
+{
+    NSString *prefix        = [[_serialNumber componentsSeparatedByString:@"-"] objectAtIndex:0];
+    NSString *appIdentifier = nil;
+    NSString *version       = nil;
+    NSString *typeCode      = nil;
+    NSString *quantity      = nil;
+    
+    if ( ( [prefix length] == 10 ) || ( [prefix length] == 7 ) ) {
+        appIdentifier = [_serialNumber substringWithRange:NSMakeRange(0,2)];
+        version       = [_serialNumber substringWithRange:NSMakeRange(2,3)];
+        typeCode      = [_serialNumber substringWithRange:NSMakeRange(5,2)];
+    } else {
+        return nil;
+    }
+
+    if ( [prefix length] == 10 ) {
+        quantity = [_serialNumber substringWithRange:NSMakeRange(7,3)];
+    }
+
+    return [NSDictionary dictionaryWithObjectsAndKeys:
+        appIdentifier, @"appIdentifier",
+        version,       @"version",
+        typeCode,      @"typeCode",
+        quantity,      @"quantity",   nil];
+}
+
+
+/*************************************************************************/
+#pragma mark -
+#pragma mark PRIVATE IMPLEMENTATIONS
+/*************************************************************************/
+
+- (short)validate
+{
+    eSellerate_String pSerial    = [self eSellerateStringForString:_serialNumber];
+    eSellerate_String pName      = [self eSellerateStringForString:_nameBasedKey];
+    eSellerate_String pExtraData = [self eSellerateStringForString:_extraDataKey];
+    eSellerate_String pPublisher = [self eSellerateStringForString:_publisherKey];
+    
+    return eSellerate_ValidateSerialNumber(pSerial,
+                                           pName,
+                                           pExtraData,
+                                           pPublisher);
+}
+
+- (eSellerate_String)eSellerateStringForString:(NSString *)string
+{
+    if ( string ) {
+        NSMutableData *buffer = [[[NSMutableData alloc] initWithCapacity:256] autorelease];
+        
+        CFStringGetPascalString( (CFStringRef)string,
+                                 [buffer mutableBytes],
+                                 256,
+                                 CFStringGetSystemEncoding());
+                                 
+        return (eSellerate_String)[buffer bytes];
+    } else {
+        return nil;
+    }
+}
+
+
+@end