feat: Simplify the JID parser

Fixes #13.
This commit is contained in:
PapaTutuWawa 2023-01-04 17:19:37 +01:00
parent 55d2ef9c25
commit 763c93857d
2 changed files with 52 additions and 77 deletions

View File

@ -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;

View File

@ -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);
}); });
} }