- Update
This commit is contained in:
1 parent
d281d765ea
commit
5b074a5176
1261 files changed
+199158
-7303
No files matched your search
@@ -0,0 +1,707 @@
|
||||
#import "XMPPRoomMemoryStorage.h"
|
||||
#import "XMPPRoomPrivate.h"
|
||||
#import "XMPP.h"
|
||||
#import "NSXMLElement+XEP_0203.h"
|
||||
#import "XMPPLogging.h"
|
||||
|
||||
#if ! __has_feature(objc_arc)
|
||||
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
// Log levels: off, error, warn, info, verbose
|
||||
#if DEBUG
|
||||
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN; // | XMPP_LOG_FLAG_TRACE;
|
||||
#else
|
||||
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN;
|
||||
#endif
|
||||
|
||||
#define AssertPrivateQueue() \
|
||||
NSAssert(dispatch_get_specific(parentQueueTag), @"Private method: MUST run on parentQueue");
|
||||
|
||||
#define AssertParentQueue() \
|
||||
NSAssert(dispatch_get_specific(parentQueueTag), @"Private protocol method: MUST run on parentQueue");
|
||||
|
||||
@interface XMPPRoomMemoryStorage ()
|
||||
{
|
||||
#if __has_feature(objc_arc_weak)
|
||||
__weak XMPPRoom *parent;
|
||||
#else
|
||||
__unsafe_unretained XMPPRoom *parent;
|
||||
#endif
|
||||
dispatch_queue_t parentQueue;
|
||||
void *parentQueueTag;
|
||||
|
||||
NSMutableArray * messages;
|
||||
NSMutableArray * occupantsArray;
|
||||
NSMutableDictionary * occupantsDict;
|
||||
|
||||
Class messageClass;
|
||||
Class occupantClass;
|
||||
}
|
||||
|
||||
@property (readonly) dispatch_queue_t parentQueue;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@implementation XMPPRoomMemoryStorage
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
messages = [[NSMutableArray alloc] init];
|
||||
occupantsArray = [[NSMutableArray alloc] init];
|
||||
occupantsDict = [[NSMutableDictionary alloc] init];
|
||||
|
||||
messageClass = [XMPPRoomMessageMemoryStorageObject class];
|
||||
occupantClass = [XMPPRoomOccupantMemoryStorageObject class];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)configureWithParent:(XMPPRoom *)aParent queue:(dispatch_queue_t)queue
|
||||
{
|
||||
NSParameterAssert(aParent != nil);
|
||||
NSParameterAssert(queue != NULL);
|
||||
|
||||
BOOL result = NO;
|
||||
|
||||
@synchronized(self)
|
||||
{
|
||||
if ((parent == nil) && (parentQueue == NULL))
|
||||
{
|
||||
parent = aParent;
|
||||
parentQueue = queue;
|
||||
parentQueueTag = &parentQueueTag;
|
||||
dispatch_queue_set_specific(parentQueue, parentQueueTag, parentQueueTag, NULL);
|
||||
|
||||
#if !OS_OBJECT_USE_OBJC
|
||||
dispatch_retain(parentQueue);
|
||||
#endif
|
||||
|
||||
result = YES;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (GCDMulticastDelegate <XMPPRoomMemoryStorageDelegate> *)multicastDelegate
|
||||
{
|
||||
return (GCDMulticastDelegate <XMPPRoomMemoryStorageDelegate> *)[parent multicastDelegate];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
#if !OS_OBJECT_USE_OBJC
|
||||
if (parentQueue)
|
||||
dispatch_release(parentQueue);
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Properties
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@synthesize messageClass;
|
||||
@synthesize occupantClass;
|
||||
|
||||
- (XMPPRoom *)parent
|
||||
{
|
||||
XMPPRoom *result = nil;
|
||||
|
||||
@synchronized(self) // synchronized with configureWithParent:queue:
|
||||
{
|
||||
result = parent;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (dispatch_queue_t)parentQueue
|
||||
{
|
||||
dispatch_queue_t result = NULL;
|
||||
|
||||
@synchronized(self) // synchronized with configureWithParent:queue:
|
||||
{
|
||||
result = parentQueue;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Internal API
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (BOOL)existsMessage:(XMPPMessage *)message
|
||||
{
|
||||
NSDate *remoteTimestamp = [message delayedDeliveryDate];
|
||||
|
||||
if (remoteTimestamp == nil)
|
||||
{
|
||||
// When the xmpp server sends us a room message, it will always timestamp delayed messages.
|
||||
// For example, when retrieving the discussion history, all messages will include the original timestamp.
|
||||
// If a message doesn't include such timestamp, then we know we're getting it in "real time".
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
if ([messages count] == 0)
|
||||
{
|
||||
// Safety net for binary search algorithm used below
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
// Does this message already exist in the messages array?
|
||||
// How can we tell if two XMPPRoomMessages are the same?
|
||||
//
|
||||
// 1. Same jid
|
||||
// 2. Same text
|
||||
// 3. Same remoteTimestamp
|
||||
// 4. Approximately the same localTimestamps (if existing message doesn't have set remoteTimestamp)
|
||||
//
|
||||
// This is actually a rather difficult question.
|
||||
// What if the same user sends the exact same message multiple times?
|
||||
//
|
||||
// If we first received the message while already in the room, it won't contain a remoteTimestamp.
|
||||
// Returning to the room later and downloading the discussion history will return the same message,
|
||||
// this time with a remote timestamp.
|
||||
//
|
||||
// So if the message doesn't have a remoteTimestamp,
|
||||
// but it's localTimestamp is approximately the same as the remoteTimestamp,
|
||||
// then this is enough evidence to consider the messages the same.
|
||||
|
||||
// Algorithm overview:
|
||||
//
|
||||
// Since the clock of the client and server may be out of sync,
|
||||
// a localTimestamp and remoteTimestamp may be off by several seconds.
|
||||
// So we're going to search a range of messages, bounded by a min and max localTimestamp.
|
||||
//
|
||||
// We find the first message that has a localTimestamp >= minLocalTimestamp.
|
||||
// We then search from there to the first message that has a localTimestamp > maxLocalTimestamp.
|
||||
//
|
||||
// This represents our range of messages to search.
|
||||
// Then we can simply iterate over these messages to see if any have the same jid and text.
|
||||
|
||||
NSDate *minLocalTimestamp = [remoteTimestamp dateByAddingTimeInterval:-60];
|
||||
NSDate *maxLocalTimestamp = [remoteTimestamp dateByAddingTimeInterval: 60];
|
||||
|
||||
// Use binary search to locate first message with localTimestamp >= minLocalTimestamp.
|
||||
|
||||
NSInteger mid;
|
||||
NSInteger min = 0;
|
||||
NSInteger max = [messages count] - 1;
|
||||
|
||||
while (YES)
|
||||
{
|
||||
mid = (min + max) / 2;
|
||||
XMPPRoomMessageMemoryStorageObject *currentMessage = messages[mid];
|
||||
|
||||
NSComparisonResult cmp = [minLocalTimestamp compare:[currentMessage localTimestamp]];
|
||||
if (cmp == NSOrderedAscending)
|
||||
{
|
||||
// minLocalTimestamp < currentMessage.localTimestamp
|
||||
|
||||
if (mid == min)
|
||||
break;
|
||||
else
|
||||
max = mid - 1;
|
||||
}
|
||||
else // Descending || Same
|
||||
{
|
||||
// minLocalTimestamp >= currentMessage.localTimestamp
|
||||
|
||||
if (mid == max) {
|
||||
mid++;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
min = mid + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The 'mid' variable now points to the index of the first message in the sorted messages array
|
||||
// that has a localTimestamp >= minLocalTimestamp.
|
||||
//
|
||||
// We're going to start looking for matching messages here,
|
||||
// and break if we find a message with localTimestamp <= maxLocalTimestamp.
|
||||
|
||||
XMPPJID *messageJid = [message from];
|
||||
NSString *messageBody = [[message elementForName:@"body"] stringValue];
|
||||
|
||||
NSInteger index;
|
||||
for (index = mid; index < [messages count]; index++)
|
||||
{
|
||||
XMPPRoomMessageMemoryStorageObject *currentMessage = messages[index];
|
||||
|
||||
NSComparisonResult cmp = [maxLocalTimestamp compare:[currentMessage localTimestamp]];
|
||||
if (cmp != NSOrderedAscending)
|
||||
{
|
||||
// maxLocalTimestamp >= currentMessage.localTimestamp
|
||||
break;
|
||||
}
|
||||
|
||||
if ([currentMessage.jid isEqualToJID:messageJid])
|
||||
{
|
||||
if ([currentMessage.body isEqualToString:messageBody])
|
||||
{
|
||||
if (currentMessage.remoteTimestamp)
|
||||
{
|
||||
if ([currentMessage.remoteTimestamp isEqualToDate:remoteTimestamp])
|
||||
{
|
||||
// 1. jid matches
|
||||
// 2. body matches
|
||||
// 3. remoteTimestamp matches
|
||||
//
|
||||
// => Incoming message already exists in the array.
|
||||
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 1. jid matches
|
||||
// 2. body matches
|
||||
// 3. existing message in array doesn't have set remoteTimestamp
|
||||
// 4. existing message has approximately the same localTimestamp
|
||||
//
|
||||
// => Incoming message already exists in the array.
|
||||
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSUInteger)insertMessage:(XMPPRoomMessageMemoryStorageObject *)message
|
||||
{
|
||||
NSUInteger count = [messages count];
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
[messages addObject:message];
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Shortcut - Most (if not all) messages are inserted at the end
|
||||
|
||||
XMPPRoomMessageMemoryStorageObject *lastMessage = messages[count - 1];
|
||||
if ([message compare:lastMessage] != NSOrderedAscending)
|
||||
{
|
||||
[messages addObject:message];
|
||||
return count;
|
||||
}
|
||||
|
||||
// Shortcut didn't work.
|
||||
// Find location using binary search algorithm.
|
||||
|
||||
NSInteger mid;
|
||||
NSInteger min = 0;
|
||||
NSInteger max = count - 1;
|
||||
|
||||
while (YES)
|
||||
{
|
||||
mid = (min + max) / 2;
|
||||
XMPPRoomMessageMemoryStorageObject *currentMessage = messages[mid];
|
||||
|
||||
NSComparisonResult cmp = [message compare:currentMessage];
|
||||
if (cmp == NSOrderedAscending)
|
||||
{
|
||||
// message < currentMessage
|
||||
|
||||
if (mid == min)
|
||||
break;
|
||||
else
|
||||
max = mid - 1;
|
||||
}
|
||||
else // Descending || Same
|
||||
{
|
||||
// message >= currentMessage
|
||||
|
||||
if (mid == max) {
|
||||
mid++;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
min = mid + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Algorithm check:
|
||||
//
|
||||
// Insert in array[length] at index (index)
|
||||
// : min, mid, max (cmp_result)
|
||||
//
|
||||
//
|
||||
// Insert in array[3] at index (0)
|
||||
// : 0, 1, 2 (asc)
|
||||
// : 0, 0, 0 (asc) break
|
||||
//
|
||||
// Insert in array[3] at index (1)
|
||||
// : 0, 1, 2 (asc)
|
||||
// : 0, 0, 0 (dsc) mid++, break
|
||||
//
|
||||
// Insert in array[3] at index (2)
|
||||
// : 0, 1, 2 (dsc)
|
||||
// : 2, 2, 2 (asc) break
|
||||
//
|
||||
// Insert in array[3] at index (3)
|
||||
// : 0, 1, 2 (dsc)
|
||||
// : 2, 2, 2 (dsc) mid++, break
|
||||
|
||||
[messages insertObject:message atIndex:mid];
|
||||
return (NSUInteger)mid;
|
||||
}
|
||||
|
||||
- (void)addMessage:(XMPPRoomMessageMemoryStorageObject *)roomMsg
|
||||
{
|
||||
NSUInteger index = [self insertMessage:roomMsg];
|
||||
|
||||
XMPPRoomOccupantMemoryStorageObject *occupant = occupantsDict[[roomMsg jid]];
|
||||
|
||||
XMPPRoomMessageMemoryStorageObject *roomMsgCopy = [roomMsg copy];
|
||||
XMPPRoomOccupantMemoryStorageObject *occupantCopy = [occupant copy];
|
||||
NSArray *messagesCopy = [[NSArray alloc] initWithArray:messages copyItems:YES];
|
||||
|
||||
[[self multicastDelegate] xmppRoomMemoryStorage:self
|
||||
didReceiveMessage:roomMsgCopy
|
||||
fromOccupant:occupantCopy
|
||||
atIndex:index
|
||||
inArray:messagesCopy];
|
||||
}
|
||||
|
||||
- (NSUInteger)insertOccupant:(XMPPRoomOccupantMemoryStorageObject *)occupant
|
||||
{
|
||||
NSUInteger count = [occupantsArray count];
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
[occupantsArray addObject:occupant];
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Find location using binary search algorithm.
|
||||
|
||||
NSInteger mid;
|
||||
NSInteger min = 0;
|
||||
NSInteger max = count - 1;
|
||||
|
||||
while (YES)
|
||||
{
|
||||
mid = (min + max) / 2;
|
||||
XMPPRoomOccupantMemoryStorageObject *currentOccupant = occupantsArray[mid];
|
||||
|
||||
NSComparisonResult cmp = [occupant compare:currentOccupant];
|
||||
if (cmp == NSOrderedAscending)
|
||||
{
|
||||
// occupant < currentOccupant
|
||||
|
||||
if (mid == min)
|
||||
break;
|
||||
else
|
||||
max = mid - 1;
|
||||
}
|
||||
else // Descending || Same
|
||||
{
|
||||
// occupant >= currentOccupant
|
||||
|
||||
if (mid == max) {
|
||||
mid++;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
min = mid + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[occupantsArray insertObject:occupant atIndex:mid];
|
||||
return (NSUInteger)mid;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Public API
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (XMPPRoomOccupantMemoryStorageObject *)occupantForJID:(XMPPJID *)jid
|
||||
{
|
||||
XMPPLogTrace();
|
||||
|
||||
if (self.parentQueue == NULL)
|
||||
{
|
||||
// Haven't been attached to parent yet
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (dispatch_get_specific(parentQueueTag))
|
||||
{
|
||||
return occupantsDict[jid];
|
||||
}
|
||||
else
|
||||
{
|
||||
__block XMPPRoomOccupantMemoryStorageObject *occupant = nil;
|
||||
|
||||
dispatch_sync(parentQueue, ^{ @autoreleasepool {
|
||||
|
||||
occupant = [occupantsDict[jid] copy];
|
||||
}});
|
||||
|
||||
return occupant;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)messages
|
||||
{
|
||||
XMPPLogTrace();
|
||||
|
||||
if (self.parentQueue == NULL)
|
||||
{
|
||||
// Haven't been attached to parent yet
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (dispatch_get_specific(parentQueueTag))
|
||||
{
|
||||
return messages;
|
||||
}
|
||||
else
|
||||
{
|
||||
__block NSArray *result = nil;
|
||||
|
||||
dispatch_sync(parentQueue, ^{ @autoreleasepool {
|
||||
|
||||
result = [[NSArray alloc] initWithArray:messages copyItems:YES];
|
||||
}});
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)occupants
|
||||
{
|
||||
XMPPLogTrace();
|
||||
|
||||
if (self.parentQueue == NULL)
|
||||
{
|
||||
// Haven't been attached to parent yet
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (dispatch_get_specific(parentQueueTag))
|
||||
{
|
||||
return occupantsArray;
|
||||
}
|
||||
else
|
||||
{
|
||||
__block NSArray *result = nil;
|
||||
|
||||
dispatch_sync(parentQueue, ^{ @autoreleasepool {
|
||||
|
||||
result = [[NSArray alloc] initWithArray:occupantsArray copyItems:YES];
|
||||
}});
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)resortMessages
|
||||
{
|
||||
XMPPLogTrace();
|
||||
|
||||
if (self.parentQueue == NULL)
|
||||
{
|
||||
// Haven't been attached to parent yet
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (dispatch_get_specific(parentQueueTag))
|
||||
{
|
||||
[messages sortUsingSelector:@selector(compare:)];
|
||||
return messages;
|
||||
}
|
||||
else
|
||||
{
|
||||
__block NSArray *result = nil;
|
||||
|
||||
dispatch_sync(parentQueue, ^{ @autoreleasepool {
|
||||
|
||||
[messages sortUsingSelector:@selector(compare:)];
|
||||
result = [[NSArray alloc] initWithArray:messages copyItems:YES];
|
||||
}});
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)resortOccupants
|
||||
{
|
||||
XMPPLogTrace();
|
||||
|
||||
if (self.parentQueue == NULL)
|
||||
{
|
||||
// Haven't been attached to parent yet
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (dispatch_get_specific(parentQueueTag))
|
||||
{
|
||||
[occupantsArray sortUsingSelector:@selector(compare:)];
|
||||
return occupantsArray;
|
||||
}
|
||||
else
|
||||
{
|
||||
__block NSArray *result = nil;
|
||||
|
||||
dispatch_sync(parentQueue, ^{ @autoreleasepool {
|
||||
|
||||
[occupantsArray sortUsingSelector:@selector(compare:)];
|
||||
result = [[NSArray alloc] initWithArray:occupantsArray copyItems:YES];
|
||||
}});
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark XMPPRoomStorage Protocol
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (void)handlePresence:(XMPPPresence *)presence room:(XMPPRoom *)room
|
||||
{
|
||||
XMPPLogTrace();
|
||||
AssertParentQueue();
|
||||
|
||||
XMPPJID *from = [presence from];
|
||||
|
||||
if ([[presence type] isEqualToString:@"unavailable"])
|
||||
{
|
||||
XMPPRoomOccupantMemoryStorageObject *occupant = occupantsDict[from];
|
||||
if (occupant)
|
||||
{
|
||||
// Occupant did leave - remove
|
||||
|
||||
NSUInteger index = [occupantsArray indexOfObjectIdenticalTo:occupant];
|
||||
|
||||
[occupantsArray removeObjectAtIndex:index];
|
||||
[occupantsDict removeObjectForKey:from];
|
||||
|
||||
// Notify delegate(s)
|
||||
|
||||
XMPPRoomOccupantMemoryStorageObject *occupantCopy = [occupant copy];
|
||||
NSArray *occupantsCopy = [[NSArray alloc] initWithArray:occupantsArray copyItems:YES];
|
||||
|
||||
[[self multicastDelegate] xmppRoomMemoryStorage:self
|
||||
occupantDidLeave:occupantCopy
|
||||
atIndex:index
|
||||
fromArray:occupantsCopy];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
XMPPRoomOccupantMemoryStorageObject *occupant = occupantsDict[from];
|
||||
if (occupant == nil)
|
||||
{
|
||||
// Occupant did join - add
|
||||
|
||||
occupant = [[self.occupantClass alloc] initWithPresence:presence];
|
||||
|
||||
NSUInteger index = [self insertOccupant:occupant];
|
||||
occupantsDict[from] = occupant;
|
||||
|
||||
// Notify delegate(s)
|
||||
|
||||
XMPPRoomOccupantMemoryStorageObject *occupantCopy = [occupant copy];
|
||||
NSArray *occupantsCopy = [[NSArray alloc] initWithArray:occupantsArray copyItems:YES];
|
||||
|
||||
[[self multicastDelegate] xmppRoomMemoryStorage:self
|
||||
occupantDidJoin:occupantCopy
|
||||
atIndex:index
|
||||
inArray:occupantsCopy];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Occupant did update - move
|
||||
|
||||
[occupant updateWithPresence:presence];
|
||||
|
||||
NSUInteger oldIndex = [occupantsArray indexOfObjectIdenticalTo:occupant];
|
||||
[occupantsArray removeObjectAtIndex:oldIndex];
|
||||
NSUInteger newIndex = [self insertOccupant:occupant];
|
||||
|
||||
// Notify delegate(s)
|
||||
|
||||
XMPPRoomOccupantMemoryStorageObject *occupantCopy = [occupant copy];
|
||||
NSArray *occupantsCopy = [[NSArray alloc] initWithArray:occupantsArray copyItems:YES];
|
||||
|
||||
[[self multicastDelegate] xmppRoomMemoryStorage:self
|
||||
occupantDidUpdate:occupantCopy
|
||||
fromIndex:oldIndex
|
||||
toIndex:newIndex
|
||||
inArray:occupantsCopy];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleOutgoingMessage:(XMPPMessage *)message room:(XMPPRoom *)room
|
||||
{
|
||||
XMPPLogTrace();
|
||||
AssertParentQueue();
|
||||
|
||||
XMPPJID *msgJID = room.myRoomJID;
|
||||
|
||||
XMPPRoomMessageMemoryStorageObject *roomMsg;
|
||||
roomMsg = [[self.messageClass alloc] initWithOutgoingMessage:message jid:msgJID];
|
||||
|
||||
[self addMessage:roomMsg];
|
||||
}
|
||||
|
||||
- (void)handleIncomingMessage:(XMPPMessage *)message room:(XMPPRoom *)room
|
||||
{
|
||||
XMPPLogTrace();
|
||||
AssertParentQueue();
|
||||
|
||||
XMPPJID *myRoomJID = room.myRoomJID;
|
||||
XMPPJID *messageJID = [message from];
|
||||
|
||||
if ([myRoomJID isEqualToJID:messageJID])
|
||||
{
|
||||
if (![message wasDelayed])
|
||||
{
|
||||
// Ignore - we already stored message in handleOutgoingMessage:room:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ([self existsMessage:message])
|
||||
{
|
||||
XMPPLogVerbose(@"%@: %@ - Duplicate message", THIS_FILE, THIS_METHOD);
|
||||
}
|
||||
else
|
||||
{
|
||||
XMPPRoomMessageMemoryStorageObject *roomMessage = [[self.messageClass alloc] initWithIncomingMessage:message];
|
||||
[self addMessage:roomMessage];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleDidLeaveRoom:(XMPPRoom *)room
|
||||
{
|
||||
XMPPLogTrace();
|
||||
AssertParentQueue();
|
||||
|
||||
[occupantsDict removeAllObjects];
|
||||
[occupantsArray removeAllObjects];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in new issue
Block a user