diff options
-rw-r--r-- | Swiften/SASL/DIGESTMD5Properties.cpp | 84 | ||||
-rw-r--r-- | Swiften/SASL/DIGESTMD5Properties.h | 3 | ||||
-rw-r--r-- | Swiften/SASL/UnitTest/DIGESTMD5PropertiesTest.cpp | 11 |
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() { |