Add stanza classes XMPPStanza, XMPPIQ, XMPPMessage and XMPPPresence

This commit is contained in:
Florian Zeitz 2011-02-10 03:54:08 +01:00
parent dde9ac7d85
commit 31f444510d
5 changed files with 313 additions and 3 deletions

View file

@ -1,4 +1,5 @@
#import "XMPPConnection.h"
#import "XMPPStanza.h"
#define NS_BIND @"urn:ietf:params:xml:ns:xmpp-bind"
#define NS_CLIENT @"jabber:client"
@ -135,8 +136,7 @@
- (void)_sendResourceBind
{
OFXMLElement *iq = [OFXMLElement elementWithName: @"iq"];
[iq addAttributeWithName: @"type" stringValue: @"set"];
XMPPIQ *iq = [XMPPIQ IQWithType: @"set" ID: @"bind0"];
[iq addChild: [OFXMLElement elementWithName: @"bind"
namespace: NS_BIND]];

57
XMPPStanza.h Normal file
View file

@ -0,0 +1,57 @@
#import <ObjFW/ObjFW.h>
@interface XMPPStanza: OFXMLElement
{
OFString *from;
OFString *to;
OFString *type;
OFString *ID;
}
@property (copy) OFString *from;
@property (copy) OFString *to;
@property (copy) OFString *type;
@property (copy) OFString *ID;
+ stanzaWithName: (OFString*)name;
+ stanzaWithElement: (OFXMLElement*)elem;
- initWithName: (OFString*)name;
- initWithElement: (OFXMLElement*)elem;
@end
@interface XMPPIQ: XMPPStanza
{
}
+ IQWithType: (OFString*)type_
ID: (OFString*)ID_;
@end
@interface XMPPMessage: XMPPStanza
{
}
+ message;
+ messageWithID: (OFString*)ID_;
+ messageWithType: (OFString*)type_;
+ messageWithType: (OFString*)type_
ID: (OFString*)ID_;
- (void)addBody: (OFString*)body;
@end
@interface XMPPPresence: XMPPStanza
{
}
+ presence;
+ presenceWithID: (OFString*)ID_;
+ presenceWithType: (OFString*)type_;
+ presenceWithType: (OFString*)type_
ID: (OFString*)ID_;
- (void)addShow: (OFString*)show;
- (void)addStatus: (OFString*)status;
- (void)addPriority: (char)priority;
@end

213
XMPPStanza.m Normal file
View file

@ -0,0 +1,213 @@
#import "XMPPStanza.h"
@implementation XMPPStanza
@synthesize from;
@synthesize to;
@synthesize type;
@synthesize ID;
+ stanzaWithName: (OFString*)name
{
return [[[self alloc] initWithName: name] autorelease];
}
+ stanzaWithElement: (OFXMLElement*)elem {
return [[[self alloc] initWithElement: elem] autorelease];
}
- initWithName: (OFString*)name_
{
if (!([name_ isEqual: @"iq"] ||
[name_ isEqual: @"message"] ||
[name_ isEqual: @"presence"]))
of_log(@"Invalid stanza name!");
self = [super initWithName: name_];
[self setDefaultNamespace: @"jabber:client"];
from = [[OFString alloc] init];
to = [[OFString alloc] init];
type = [[OFString alloc] init];
ID = [[OFString alloc] init];
return self;
}
- initWithElement: (OFXMLElement*)elem
{
self = [super initWithName: elem.name
namespace: elem.namespace];
from = [[OFString alloc] init];
to = [[OFString alloc] init];
type = [[OFString alloc] init];
ID = [[OFString alloc] init];
OFXMLAttribute *attr;
for (attr in elem.attributes) {
if ([attr.name isEqual: @"from"]) {
[self setFrom: [attr stringValue]];
} else if ([attr.name isEqual: @"to"]) {
[self setTo: [attr stringValue]];
} else if ([attr.name isEqual: @"type"]) {
[self setType: [attr stringValue]];
} else if ([attr.name isEqual: @"id"]) {
[self setID: [attr stringValue]];
} else {
[self addAttribute: attr];
}
}
OFXMLElement *el;
for (el in elem.children) {
[self addChild: el];
}
return self;
}
- (void)dealloc
{
[from release];
[to release];
[type release];
[ID release];
[super dealloc];
}
- (void)setFrom: (OFString*)from_
{
OFString* old = from;
from = [from_ copy];
[old release];
[self addAttributeWithName: @"from" stringValue: from_];
}
- (void)setTo: (OFString*)to_
{
OFString* old = to;
to = [to_ copy];
[old release];
[self addAttributeWithName: @"to" stringValue: to];
}
- (void)setType: (OFString*)type_
{
OFString* old = type;
type = [type_ copy];
[old release];
[self addAttributeWithName: @"type" stringValue: type];
}
- (void)setID: (OFString*)ID_
{
OFString* old = ID;
ID = [ID_ copy];
[old release];
[self addAttributeWithName: @"id" stringValue: ID];
}
@end
@implementation XMPPIQ
+ IQWithType: (OFString*)type_
ID: (OFString*)ID_
{
if (!([type_ isEqual: @"get"] ||
[type_ isEqual: @"set"] ||
[type_ isEqual: @"result"] ||
[type_ isEqual: @"error"]))
of_log(@"Invalid IQ type!");
id ret;
ret = [[[self alloc] initWithName: @"iq"] autorelease];
[ret setType: type_];
[ret setID: ID_];
return ret;
}
@end
@implementation XMPPMessage
+ message
{
return [self messageWithType: nil ID: nil];
}
+ messageWithID: (OFString*)ID_
{
return [self messageWithType: nil ID: ID_];
}
+ messageWithType: (OFString*)type_
{
return [self messageWithType: type_ ID: nil];
}
+ messageWithType: (OFString*)type_
ID: (OFString*)ID_
{
id ret;
ret = [[[self alloc] initWithName: @"message"] autorelease];
if (type_)
[ret setType: type_];
if (ID_)
[ret setID: ID_];
return ret;
}
- (void)addBody: (OFString*)body
{
[self addChild: [OFXMLElement elementWithName: @"body"
stringValue: body]];
}
@end
@implementation XMPPPresence
+ presence
{
return [self presenceWithType: nil ID: nil];
}
+ presenceWithID: (OFString*)ID_
{
return [self presenceWithType: nil ID: ID_];
}
+ presenceWithType: (OFString*)type_
{
return [self presenceWithType: type_ ID: nil];
}
+ presenceWithType: (OFString*)type_
ID: (OFString*)ID_
{
id ret;
ret = [[[self alloc] initWithName: @"presence"] autorelease];
if (type_)
[ret setType: type_];
if (ID_)
[ret setID: ID_];
return ret;
}
- (void)addShow: (OFString*)show
{
[self addChild: [OFXMLElement elementWithName: @"show"
stringValue: show]];
}
- (void)addStatus: (OFString*)status
{
[self addChild: [OFXMLElement elementWithName: @"status"
stringValue: status]];
}
- (void)addPriority: (char)priority
{
OFString* prio = [OFString stringWithFormat: @"%d", priority];
[self addChild: [OFXMLElement elementWithName: @"priority"
stringValue: prio]];
}
@end

BIN
XMPPStanza.o Normal file

Binary file not shown.

42
test.m
View file

@ -1,5 +1,7 @@
#include <ObjFW/ObjFW.h>
#include <assert.h>
#import <ObjFW/ObjFW.h>
#import "XMPPConnection.h"
#import "XMPPStanza.h"
@interface AppDelegate: OFObject
{
@ -14,6 +16,44 @@ OF_APPLICATION_DELEGATE(AppDelegate)
{
OFArray *arguments = [OFApplication arguments];
XMPPPresence *pres = [XMPPPresence presence];
[pres addShow: @"chat"];
[pres addStatus: @"Bored"];
[pres addPriority: 20];
pres.to = @"alice@example.com";
pres.from = @"bob@example.org";
assert([[pres stringValue] isEqual: @"<presence to='alice@example.com' "
@"from='bob@example.org'><show>chat</show>"
@"<status>Bored</status><priority>20</priority>"
@"</presence>"]);
XMPPMessage *msg = [XMPPMessage messageWithType: @"chat"];
[msg addBody: @"Hello everyone"];
msg.to = @"jdev@conference.jabber.org";
msg.from = @"alice@example.com";
assert([[msg stringValue] isEqual: @"<message type='chat' "
@"to='jdev@conference.jabber.org' "
@"from='alice@example.com'><body>Hello everyone</body>"
@"</message>"]);
XMPPIQ *iq = [XMPPIQ IQWithType: @"set" ID: @"128"];
iq.to = @"juliet@capulet.lit";
iq.from = @"romeo@montague.lit";
assert([[iq stringValue] isEqual: @"<iq type='set' id='128' "
@"to='juliet@capulet.lit' "
@"from='romeo@montague.lit'/>"]);
OFXMLElement *elem = [OFXMLElement elementWithName: @"iq"];
[elem addAttributeWithName: @"from" stringValue: @"bob@localhost"];
[elem addAttributeWithName: @"to" stringValue: @"alice@localhost"];
[elem addAttributeWithName: @"type" stringValue: @"get"];
[elem addAttributeWithName: @"id" stringValue: @"42"];
XMPPStanza *stanza = [XMPPStanza stanzaWithElement: elem];
assert([[elem stringValue] isEqual: [stanza stringValue]]);
assert(([[OFString stringWithFormat: @"%@, %@, %@, %@", stanza.from,
stanza.to, stanza.type, stanza.ID]
isEqual: @"bob@localhost, alice@localhost, get, 42"]));
conn = [[XMPPConnection alloc] init];
if (arguments.count != 3) {