parent
55d2ef9c25
commit
763c93857d
@ -6,67 +6,38 @@ class JID {
|
|||||||
const JID(this.local, this.domain, this.resource);
|
const JID(this.local, this.domain, this.resource);
|
||||||
|
|
||||||
factory JID.fromString(String jid) {
|
factory JID.fromString(String jid) {
|
||||||
// 0: Parsing either the local or domain part
|
// Algorithm taken from here: https://blog.samwhited.com/2021/02/xmpp-addresses/
|
||||||
// 1: Parsing the domain part
|
var localPart = '';
|
||||||
// 2: Parsing the resource
|
var domainPart = '';
|
||||||
var state = 0;
|
var resourcePart = '';
|
||||||
var buffer = '';
|
|
||||||
var local_ = '';
|
|
||||||
var domain_ = '';
|
|
||||||
var resource_ = '';
|
|
||||||
|
|
||||||
for (var i = 0; i < jid.length; i++) {
|
final slashParts = jid.split('/');
|
||||||
final c = jid[i];
|
if (slashParts.length == 1) {
|
||||||
final eol = i == jid.length - 1;
|
resourcePart = '';
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case 0: {
|
|
||||||
if (c == '@') {
|
|
||||||
local_ = buffer;
|
|
||||||
buffer = '';
|
|
||||||
state = 1;
|
|
||||||
} else if (c == '/') {
|
|
||||||
domain_ = buffer;
|
|
||||||
buffer = '';
|
|
||||||
state = 2;
|
|
||||||
} else if (eol) {
|
|
||||||
domain_ = buffer + c;
|
|
||||||
} else {
|
} else {
|
||||||
buffer += c;
|
resourcePart = slashParts.sublist(1).join('/');
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1: {
|
|
||||||
if (c == '/') {
|
|
||||||
domain_ = buffer;
|
|
||||||
buffer = '';
|
|
||||||
state = 2;
|
|
||||||
} else if (eol) {
|
|
||||||
domain_ = buffer;
|
|
||||||
|
|
||||||
if (c != ' ') {
|
assert(resourcePart.isNotEmpty, 'Resource part cannot be there and empty');
|
||||||
domain_ = domain_ + c;
|
|
||||||
}
|
|
||||||
} else if (c != ' ') {
|
|
||||||
buffer += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2: {
|
|
||||||
if (eol) {
|
|
||||||
resource_ = buffer;
|
|
||||||
|
|
||||||
if (c != ' ') {
|
|
||||||
resource_ = resource_ + c;
|
|
||||||
}
|
|
||||||
} else if (c != ''){
|
|
||||||
buffer += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return JID(local_, domain_, resource_);
|
final atParts = slashParts.first.split('@');
|
||||||
|
if (atParts.length == 1) {
|
||||||
|
localPart = '';
|
||||||
|
domainPart = atParts.first;
|
||||||
|
} else {
|
||||||
|
localPart = atParts.first;
|
||||||
|
domainPart = atParts.sublist(1).join('@');
|
||||||
|
|
||||||
|
assert(localPart.isNotEmpty, 'Local part cannot be there and empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
return JID(
|
||||||
|
localPart,
|
||||||
|
domainPart.endsWith('.') ?
|
||||||
|
domainPart.substring(0, domainPart.length - 1) :
|
||||||
|
domainPart,
|
||||||
|
resourcePart,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
final String local;
|
final String local;
|
||||||
final String domain;
|
final String domain;
|
||||||
|
@ -34,8 +34,12 @@ void main() {
|
|||||||
expect(JID.fromString('hallo@welt') == JID('hallo', 'welt', 'a'), false);
|
expect(JID.fromString('hallo@welt') == JID('hallo', 'welt', 'a'), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Whitespaces', () {
|
test('Dot suffix at domain part', () {
|
||||||
expect(JID.fromString('hallo@welt ') == JID('hallo', 'welt', ''), true);
|
expect(JID.fromString('hallo@welt.example.') == JID('hallo', 'welt.example', ''), true);
|
||||||
expect(JID.fromString('hallo@welt/abc ') == JID('hallo', 'welt', 'abc'), true);
|
expect(JID.fromString('hallo@welt.example./test') == JID('hallo', 'welt.example', 'test'), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Parse resource with a slash', () {
|
||||||
|
expect(JID.fromString('hallo@welt.example./test/welt') == JID('hallo', 'welt.example', 'test/welt'), true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user