summaryrefslogtreecommitdiffstats
path: root/logic/URNResolver.cpp
blob: b6bdcf4114630c89b8a0db4966906d2aae2373cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "URNResolver.h"
#include <logger/QsLog.h>
#include "MultiMC.h"
#include "logic/forge/ForgeVersionList.h"
#include "logic/forge/ForgeVersion.h"

QString unescapeNSS(QString RawNSS)
{
	QString NSS;
	NSS.reserve(RawNSS.size());
	enum
	{
		Normal,
		FirstHex,
		SecondHex
	} ParseState = Normal;

	QByteArray translator("  ");

	for (auto ch : RawNSS)
	{
		if(ParseState == Normal)
		{
			if(ch == '%')
			{
				ParseState = FirstHex;
				continue;
			}
			else
			{
				NSS.append(ch);
			}
		}
		if(ParseState == FirstHex)
		{
			translator[0] = ch.toLower().unicode();
			ParseState = SecondHex;
		}
		else if(ParseState == SecondHex)
		{
			translator[1] = ch.toLower().unicode();
			auto result = QByteArray::fromHex(translator);
			if (result[0] == '\0')
				return NSS;
			NSS.append(result);
			ParseState = Normal;
		}
	}
	return NSS;
}

bool URNResolver::parse(const QString &URN, QString &NID, QString &NSS)
{
	QRegExp URNPattern(
		"^urn:([a-z0-9][a-z0-9-]{0,31}):(([a-z0-9()+,\\-.:=@;$_!*']|%[0-9a-f]{2})+).*",
		Qt::CaseInsensitive);
	if (URNPattern.indexIn(URN) == -1)
		return false;
	auto captures = URNPattern.capturedTexts();
	QString RawNID = captures[1];
	QString RawNSS = captures[2];

	NID = RawNID.toLower();
	NSS = unescapeNSS(RawNSS);
	return true;
}

URNResolver::URNResolver()
{
}

QVariant URNResolver::resolve(QString URN)
{
	QString NID, NSS;
	parse(URN, NID, NSS);

	if(NID != "x-mmc")
		return QVariant();
	auto parts = NSS.split(":");
	if(parts.size() < 1)
		return QVariant();
	unsigned int version = parts[0].toUInt();
	switch(version)
	{
		case 1:
			return resolveV1(parts.mid(1));
		default:
			return QVariant();
	}
}

/**
 * TODO: implement.
 */
QVariant URNResolver::resolveV1(QStringList parts)
{
	return QVariant();
}