/* * Grouch.app Copyright (C) 2006 Andy Sveikauskas * ------------------------------------------------------------------------ * This program is free software under the GNU General Public License * -- * The "capabilities" handler for channel 2 messages. * This just manages other handlers. Relevant code is: * OscarCapChatInvite handles chat invitations */ #import #import #include static void Data2String(dest, destlen, src, srclen) char *dest; const unsigned char *src; size_t destlen, srclen; { while(srclen-- && destlen >= 3) { snprintf(dest, destlen, "%.2x", *src++); dest += 2; destlen -= 2; } } static NSString *convertCapString(const void *cap) { char buf[OSCAR_CAP_SIZE*2+1]; Data2String(buf, sizeof(buf), cap, OSCAR_CAP_SIZE); return [NSString stringWithCString:buf]; } @implementation OscarCapHandler + sharedInstance { static id r = nil; if(r) return r; else return r = [self new]; } - init { [super init]; caps = [NSMutableDictionary new]; [self add:[OscarCapChatInvite new]]; return self; } - (void)dealloc { [caps release]; [super dealloc]; } - (void)add:(id)cap { NSData *representation = [cap capabilityBuffer]; const char *bytes = [representation bytes]; size_t n = [representation length]; while(n >= OSCAR_CAP_SIZE) { [caps setObject:cap forKey:convertCapString(bytes)]; bytes += OSCAR_CAP_SIZE; n -= OSCAR_CAP_SIZE; } } - (NSData*)capabilityBuffer { NSMutableData *r = [NSMutableData data]; NSEnumerator *e = [caps objectEnumerator]; id h; while( (h=[e nextObject]) ) [r appendData:[h capabilityBuffer]]; return r; } - (BOOL)handleCapability:(const void *)cap from:(id)user onClient:(OscarClient*)cli type:(int)type cookie:(const void *)cookie tlv:(OscarTlvListIn*)tlv message:(NSString*)str { id h = [caps objectForKey:convertCapString(cap)]; return h ? [h handleCapability:cap from:user onClient:cli type:type cookie:cookie tlv:tlv message:str] : NO; } @end @implementation OscarCapHandlerSimple - (NSData*)capabilityBuffer { return [NSData dataWithBytesNoCopy:(char*)cap length:len freeWhenDone:NO]; } - (BOOL)handleCapability:(const void *)cap from:(id)user onClient:(OscarClient*)cli type:(int)type cookie:(const void *)cookie tlv:(OscarTlvListIn*)tlv message:(NSString*)str { return YES; } @end