#import "XMPP.h" #import "NSXMLElement+XEP_0203.h" #import "XMPPRosterMemoryStoragePrivate.h" #if ! __has_feature(objc_arc) #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). #endif @implementation XMPPResourceMemoryStorageObject - (id)initWithPresence:(XMPPPresence *)aPresence { if((self = [super init])) { jid = [aPresence from]; presence = aPresence; presenceDate = [presence delayedDeliveryDate]; if (presenceDate == nil) { presenceDate = [[NSDate alloc] init]; } } return self; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark Copying //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (id)copyWithZone:(NSZone *)zone { // We use [self class] to support subclassing XMPPResourceMemoryStorageObject *deepCopy = (XMPPResourceMemoryStorageObject *)[[[self class] alloc] init]; deepCopy->jid = [jid copy]; deepCopy->presence = presence; // No need to bother with a copy sicne we don't alter presence deepCopy->presenceDate = [presenceDate copy]; return deepCopy; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark Encoding, Decoding //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #if ! TARGET_OS_IPHONE - (id)replacementObjectForPortCoder:(NSPortCoder *)encoder { if([encoder isBycopy]) return self; else return [super replacementObjectForPortCoder:encoder]; // return [NSDistantObject proxyWithLocal:self connection:[encoder connection]]; } #endif - (id)initWithCoder:(NSCoder *)coder { if ((self = [super init])) { if([coder allowsKeyedCoding]) { if([coder respondsToSelector:@selector(requiresSecureCoding)] && [coder requiresSecureCoding]) { jid = [coder decodeObjectOfClass:[XMPPJID class] forKey:@"jid"]; presence = [coder decodeObjectOfClass:[XMPPPresence class] forKey:@"presence"]; presenceDate = [coder decodeObjectOfClass:[NSDate class] forKey:@"presenceDate"]; } else { jid = [coder decodeObjectForKey:@"jid"]; presence = [coder decodeObjectForKey:@"presence"]; presenceDate = [coder decodeObjectForKey:@"presenceDate"]; } } else { jid = [coder decodeObject]; presence = [coder decodeObject]; presenceDate = [coder decodeObject]; } } return self; } - (void)encodeWithCoder:(NSCoder *)coder { if ([coder allowsKeyedCoding]) { [coder encodeObject:jid forKey:@"jid"]; [coder encodeObject:presence forKey:@"presence"]; [coder encodeObject:presenceDate forKey:@"presenceDate"]; } else { [coder encodeObject:jid]; [coder encodeObject:presence]; [coder encodeObject:presenceDate]; } } + (BOOL) supportsSecureCoding { return YES; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark Standard Methods //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (XMPPJID *)jid { return jid; } - (XMPPPresence *)presence { return presence; } - (NSDate *)presenceDate { return presenceDate; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark Update Methods //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (void)updateWithPresence:(XMPPPresence *)aPresence { presence = aPresence; presenceDate = [presence delayedDeliveryDate]; if (presenceDate == nil) { presenceDate = [[NSDate alloc] init]; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark Comparison Methods //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (NSComparisonResult)compare:(id )another { XMPPPresence *mp = [self presence]; XMPPPresence *ap = [another presence]; int mpp = [mp priority]; int app = [ap priority]; if(mpp < app) return NSOrderedDescending; if(mpp > app) return NSOrderedAscending; // Priority is the same. // Determine who is more available based on their show. int mps = [mp intShow]; int aps = [ap intShow]; if(mps < aps) return NSOrderedDescending; if(mps > aps) return NSOrderedAscending; // Priority and Show are the same. // Determine based on who was the last to receive a presence element. NSDate *mpd = [self presenceDate]; NSDate *apd = [another presenceDate]; return [mpd compare:apd]; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark NSObject Methods //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (NSUInteger)hash { return [jid hash]; } - (BOOL)isEqual:(id)anObject { if([anObject isMemberOfClass:[self class]]) { XMPPResourceMemoryStorageObject *another = (XMPPResourceMemoryStorageObject *)anObject; return [jid isEqualToJID:[another jid]]; } return NO; } - (NSString *)description { return [NSString stringWithFormat:@"", self, [jid full]]; } @end