PNXMPPFramework/Extensions/Roster/MemoryStorage/XMPPResourceMemoryStorageObject.m
2016-02-24 16:56:39 +01:00

207 lines
5.6 KiB
Objective-C

#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 <XMPPResource>)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:@"<XMPPResource[%p]: %@>", self, [jid full]];
}
@end