summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swiften/SASL/DIGESTMD5Properties.cpp84
-rw-r--r--Swiften/SASL/DIGESTMD5Properties.h3
-rw-r--r--Swiften/SASL/UnitTest/DIGESTMD5PropertiesTest.cpp11
3 files changed, 96 insertions, 2 deletions
diff --git a/Swiften/SASL/DIGESTMD5Properties.cpp b/Swiften/SASL/DIGESTMD5Properties.cpp
index 23dc097..0853f90 100644
--- a/Swiften/SASL/DIGESTMD5Properties.cpp
+++ b/Swiften/SASL/DIGESTMD5Properties.cpp
@@ -8,11 +8,83 @@
namespace Swift {
+namespace {
+ bool insideQuotes(const ByteArray& v) {
+ if (v.getSize() == 0) {
+ return false;
+ }
+ else if (v.getSize() == 1) {
+ return v[0] == '"';
+ }
+ else if (v[0] == '"') {
+ return !v[v.getSize() - 1] == '"';
+ }
+ else {
+ return false;
+ }
+ }
+
+ ByteArray stripQuotes(const ByteArray& v) {
+ const char* data = v.getData();
+ size_t size = v.getSize();
+ if (v[0] == '"') {
+ data++;
+ size--;
+ }
+ if (v[v.getSize() - 1] == '"') {
+ size--;
+ }
+ return ByteArray(data, size);
+ }
+}
+
DIGESTMD5Properties::DIGESTMD5Properties() {
}
-DIGESTMD5Properties DIGESTMD5Properties::parse(const ByteArray&) {
+DIGESTMD5Properties DIGESTMD5Properties::parse(const ByteArray& data) {
DIGESTMD5Properties result;
+ bool inKey = true;
+ ByteArray currentKey;
+ ByteArray currentValue;
+ for (size_t i = 0; i < data.getSize(); ++i) {
+ char c = data[i];
+ if (inKey) {
+ if (c == '=') {
+ inKey = false;
+ }
+ else {
+ currentKey += c;
+ }
+ }
+ else {
+ if (c == ',' && !insideQuotes(currentValue)) {
+ String key = currentKey.toString();
+ if (isQuoted(key)) {
+ result.setValue(key, stripQuotes(currentValue).toString());
+ }
+ else {
+ result.setValue(key, currentValue.toString());
+ }
+ inKey = true;
+ currentKey = ByteArray();
+ currentValue = ByteArray();
+ }
+ else {
+ currentValue += c;
+ }
+ }
+ }
+
+ if (!currentKey.isEmpty()) {
+ String key = currentKey.toString();
+ if (isQuoted(key)) {
+ result.setValue(key, stripQuotes(currentValue).toString());
+ }
+ else {
+ result.setValue(key, currentValue.toString());
+ }
+ }
+
return result;
}
@@ -34,6 +106,16 @@ ByteArray DIGESTMD5Properties::serialize() const {
return result;
}
+boost::optional<String> DIGESTMD5Properties::getValue(const String& key) {
+ DIGESTMD5PropertiesMap::const_iterator i = properties.find(key);
+ if (i != properties.end()) {
+ return i->second.toString();
+ }
+ else {
+ return boost::optional<String>();
+ }
+}
+
void DIGESTMD5Properties::setValue(const String& key, const String& value) {
properties.insert(DIGESTMD5PropertiesMap::value_type(key, ByteArray(value)));
}
diff --git a/Swiften/SASL/DIGESTMD5Properties.h b/Swiften/SASL/DIGESTMD5Properties.h
index a92f99b..4d3a4fe 100644
--- a/Swiften/SASL/DIGESTMD5Properties.h
+++ b/Swiften/SASL/DIGESTMD5Properties.h
@@ -7,6 +7,7 @@
#pragma once
#include <map>
+#include <boost/optional.hpp>
#include "Swiften/Base/String.h"
#include "Swiften/Base/ByteArray.h"
@@ -16,6 +17,8 @@ namespace Swift {
public:
DIGESTMD5Properties();
+ boost::optional<String> getValue(const String& key);
+
void setValue(const String& key, const String& value);
ByteArray serialize() const;
diff --git a/Swiften/SASL/UnitTest/DIGESTMD5PropertiesTest.cpp b/Swiften/SASL/UnitTest/DIGESTMD5PropertiesTest.cpp
index 0c1543a..1b2c121 100644
--- a/Swiften/SASL/UnitTest/DIGESTMD5PropertiesTest.cpp
+++ b/Swiften/SASL/UnitTest/DIGESTMD5PropertiesTest.cpp
@@ -21,7 +21,16 @@ class DIGESTMD5PropertiesTest : public CppUnit::TestFixture {
void testParse() {
DIGESTMD5Properties properties = DIGESTMD5Properties::parse(ByteArray(
"realm=\"myrealm1\",realm=\"myrealm2\",nonce=\"mynonce\","
- "algorithm=\"md5-sess\""));
+ "algorithm=md5-sess,charset=utf-8"));
+
+ CPPUNIT_ASSERT(properties.getValue("realm"));
+ CPPUNIT_ASSERT_EQUAL(String("myrealm1"), *properties.getValue("realm"));
+ CPPUNIT_ASSERT(properties.getValue("nonce"));
+ CPPUNIT_ASSERT_EQUAL(String("mynonce"), *properties.getValue("nonce"));
+ CPPUNIT_ASSERT(properties.getValue("algorithm"));
+ CPPUNIT_ASSERT_EQUAL(String("md5-sess"), *properties.getValue("algorithm"));
+ CPPUNIT_ASSERT(properties.getValue("charset"));
+ CPPUNIT_ASSERT_EQUAL(String("utf-8"), *properties.getValue("charset"));
}
void testSerialize() {