Add stanza classes XMPPStanza, XMPPIQ, XMPPMessage and XMPPPresence
This commit is contained in:
parent
dde9ac7d85
commit
31f444510d
5 changed files with 313 additions and 3 deletions
|
@ -1,4 +1,5 @@
|
||||||
#import "XMPPConnection.h"
|
#import "XMPPConnection.h"
|
||||||
|
#import "XMPPStanza.h"
|
||||||
|
|
||||||
#define NS_BIND @"urn:ietf:params:xml:ns:xmpp-bind"
|
#define NS_BIND @"urn:ietf:params:xml:ns:xmpp-bind"
|
||||||
#define NS_CLIENT @"jabber:client"
|
#define NS_CLIENT @"jabber:client"
|
||||||
|
@ -135,8 +136,7 @@
|
||||||
|
|
||||||
- (void)_sendResourceBind
|
- (void)_sendResourceBind
|
||||||
{
|
{
|
||||||
OFXMLElement *iq = [OFXMLElement elementWithName: @"iq"];
|
XMPPIQ *iq = [XMPPIQ IQWithType: @"set" ID: @"bind0"];
|
||||||
[iq addAttributeWithName: @"type" stringValue: @"set"];
|
|
||||||
[iq addChild: [OFXMLElement elementWithName: @"bind"
|
[iq addChild: [OFXMLElement elementWithName: @"bind"
|
||||||
namespace: NS_BIND]];
|
namespace: NS_BIND]];
|
||||||
|
|
||||||
|
|
57
XMPPStanza.h
Normal file
57
XMPPStanza.h
Normal 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
213
XMPPStanza.m
Normal 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
BIN
XMPPStanza.o
Normal file
Binary file not shown.
42
test.m
42
test.m
|
@ -1,5 +1,7 @@
|
||||||
#include <ObjFW/ObjFW.h>
|
#include <assert.h>
|
||||||
|
#import <ObjFW/ObjFW.h>
|
||||||
#import "XMPPConnection.h"
|
#import "XMPPConnection.h"
|
||||||
|
#import "XMPPStanza.h"
|
||||||
|
|
||||||
@interface AppDelegate: OFObject
|
@interface AppDelegate: OFObject
|
||||||
{
|
{
|
||||||
|
@ -14,6 +16,44 @@ OF_APPLICATION_DELEGATE(AppDelegate)
|
||||||
{
|
{
|
||||||
OFArray *arguments = [OFApplication arguments];
|
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];
|
conn = [[XMPPConnection alloc] init];
|
||||||
|
|
||||||
if (arguments.count != 3) {
|
if (arguments.count != 3) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue