1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-03 09:57:46 +01:00
Telegram/thirdparty/GDFileManager/GDAPIToken.m
2015-10-01 19:19:52 +03:00

147 lines
3.9 KiB
Objective-C
Executable File

//
// GDAPIToken.m
// GDFileManagerExample
//
// Created by Graham Dennis on 11/01/13.
// Copyright (c) 2013 Graham Dennis. All rights reserved.
//
#import "GDAPIToken.h"
static NSDictionary *tokenMap = nil;
static dispatch_queue_t token_map_queue = nil;
NSString *const GDAPITokenRegisteredNotification;
NSString *const GDAPITokenUnregisteredNotification;
@implementation GDAPIToken
#pragma mark - Class Support methods
+ (void)initialize
{
if (self == [GDAPIToken class]) {
tokenMap = [NSDictionary new];
token_map_queue = dispatch_queue_create("me.grahamdennis.token_map_queue", DISPATCH_QUEUE_SERIAL);
}
}
+ (NSArray *)tokensForClass
{
return [tokenMap objectForKey:NSStringFromClass([self class])];
}
+ (instancetype)sharedToken
{
NSArray *tokens = [self tokensForClass];
if ([tokens count] == 0) return nil;
return [tokens objectAtIndex:0];
}
+ (instancetype)tokenForKey:(NSString *)key
{
NSArray *tokens = [self tokensForClass];
for (GDAPIToken *token in tokens) {
if ([token.key isEqualToString:key])
return token;
}
return nil;
}
+ (void)registerToken:(GDAPIToken *)token
{
NSParameterAssert(token);
[self _mutateTokenMapForToken:token mutationBlock:^(NSMutableArray *tokens) {
[tokens removeObject:token];
[tokens insertObject:token atIndex:0];
}];
[[NSNotificationCenter defaultCenter] postNotificationName:GDAPITokenRegisteredNotification object:token];
}
+ (void)unregisterToken:(GDAPIToken *)token
{
NSParameterAssert(token);
[self _mutateTokenMapForToken:token mutationBlock:^(NSMutableArray *tokens) {
[tokens removeObject:token];
}];
[[NSNotificationCenter defaultCenter] postNotificationName:GDAPITokenUnregisteredNotification object:token];
}
+ (void)_mutateTokenMapForToken:(GDAPIToken *)token mutationBlock:(void (^)(NSMutableArray *tokens))mutationBlock
{
dispatch_sync(token_map_queue, ^{
NSMutableArray *tokens = [NSMutableArray arrayWithArray:[[token class] tokensForClass]];
mutationBlock(tokens);
NSMutableDictionary *mutableTokenMap = [tokenMap mutableCopy];
[mutableTokenMap setObject:[tokens copy] forKey:NSStringFromClass([token class])];
tokenMap = [mutableTokenMap copy];
});
}
+ (instancetype)registerTokenWithKey:(NSString *)key secret:(NSString *)secret
{
GDAPIToken *apiToken = [[[self class] alloc] initWithKey:key secret:secret];
[[self class] registerToken:apiToken];
return apiToken;
}
#pragma mark - Instance methods
- (id)initWithKey:(NSString *)key secret:(NSString *)secret
{
if ((self = [super init]))
{
_key = key;
_secret = secret;
}
GDAPIToken *apiToken = [[self class] tokenForKey:key];
if (apiToken && [apiToken isEqual:self]) {
return apiToken;
}
return self;
}
- (BOOL)isEqual:(id)object
{
if ([object isKindOfClass:[GDAPIToken class]]
&& [self.key isEqualToString:[(GDAPIToken *)object key]]
&& [self.secret isEqualToString:[(GDAPIToken *)object secret]])
return YES;
return NO;
}
- (NSUInteger)hash
{
return NSUINTROTATE([self.key hash], NSUINT_BIT/4) ^ [self.secret hash];
}
#pragma mark - NSCoding
static NSString *const kAPITokenClassCoderKey = @"apiTokenClass";
static NSString *const kAPITokenKeyCoderKey = @"apiTokenKey";
- (id)initWithCoder:(NSCoder *)aDecoder
{
NSString *apiTokenClassName = [aDecoder decodeObjectForKey:kAPITokenClassCoderKey];
Class apiTokenClass = NSClassFromString(apiTokenClassName);
NSString *apiTokenKey = [aDecoder decodeObjectForKey:kAPITokenKeyCoderKey];
return [apiTokenClass tokenForKey:apiTokenKey];
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:NSStringFromClass([self class]) forKey:kAPITokenClassCoderKey];
[aCoder encodeObject:self.key forKey:kAPITokenKeyCoderKey];
}
@end