summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Base')
-rw-r--r--Swiften/Base/API.h27
-rw-r--r--Swiften/Base/Algorithm.h319
-rw-r--r--Swiften/Base/Atomic.h44
-rw-r--r--Swiften/Base/BoostFilesystemVersion.h6
-rw-r--r--Swiften/Base/BoostRandomGenerator.cpp26
-rw-r--r--Swiften/Base/BoostRandomGenerator.h24
-rw-r--r--Swiften/Base/ByteArray.cpp52
-rw-r--r--Swiften/Base/ByteArray.h57
-rw-r--r--Swiften/Base/Concat.h98
-rw-r--r--Swiften/Base/DateTime.cpp41
-rw-r--r--Swiften/Base/DateTime.h35
-rw-r--r--Swiften/Base/Debug.cpp190
-rw-r--r--Swiften/Base/Debug.h22
-rw-r--r--Swiften/Base/Error.cpp6
-rw-r--r--Swiften/Base/Error.h17
-rw-r--r--Swiften/Base/FileSize.cpp24
-rw-r--r--Swiften/Base/FileSize.h19
-rw-r--r--Swiften/Base/IDGenerator.cpp17
-rw-r--r--Swiften/Base/IDGenerator.h17
-rw-r--r--Swiften/Base/LRUCache.h79
-rw-r--r--Swiften/Base/Listenable.h85
-rw-r--r--Swiften/Base/Log.cpp70
-rw-r--r--Swiften/Base/Log.h77
-rw-r--r--Swiften/Base/LogSerializers.cpp130
-rw-r--r--Swiften/Base/LogSerializers.h79
-rw-r--r--Swiften/Base/Override.h34
-rw-r--r--Swiften/Base/Path.cpp12
-rw-r--r--Swiften/Base/Path.h32
-rw-r--r--Swiften/Base/Paths.cpp44
-rw-r--r--Swiften/Base/Paths.h14
-rw-r--r--Swiften/Base/Platform.h12
-rw-r--r--Swiften/Base/RandomGenerator.cpp10
-rw-r--r--Swiften/Base/RandomGenerator.h27
-rw-r--r--Swiften/Base/Regex.cpp36
-rw-r--r--Swiften/Base/Regex.h12
-rw-r--r--Swiften/Base/SConscript36
-rw-r--r--Swiften/Base/SafeAllocator.cpp18
-rw-r--r--Swiften/Base/SafeAllocator.h52
-rw-r--r--Swiften/Base/SafeByteArray.cpp18
-rw-r--r--Swiften/Base/SafeByteArray.h72
-rw-r--r--Swiften/Base/SafeString.h39
-rw-r--r--Swiften/Base/SimpleIDGenerator.cpp45
-rw-r--r--Swiften/Base/SimpleIDGenerator.h28
-rw-r--r--Swiften/Base/StartStopper.h30
-rw-r--r--Swiften/Base/StdRandomGenerator.cpp33
-rw-r--r--Swiften/Base/StdRandomGenerator.h24
-rw-r--r--Swiften/Base/String.cpp304
-rw-r--r--Swiften/Base/String.h70
-rw-r--r--Swiften/Base/Tristate.h13
-rw-r--r--Swiften/Base/URL.cpp313
-rw-r--r--Swiften/Base/URL.h132
-rw-r--r--Swiften/Base/UnitTest/ByteArrayTest.cpp65
-rw-r--r--Swiften/Base/UnitTest/DateTimeTest.cpp55
-rw-r--r--Swiften/Base/UnitTest/IDGeneratorTest.cpp51
-rw-r--r--Swiften/Base/UnitTest/LRUCacheTest.cpp117
-rw-r--r--Swiften/Base/UnitTest/LogTest.cpp49
-rw-r--r--Swiften/Base/UnitTest/PathTest.cpp30
-rw-r--r--Swiften/Base/UnitTest/SimpleIDGeneratorTest.cpp53
-rw-r--r--Swiften/Base/UnitTest/StringTest.cpp261
-rw-r--r--Swiften/Base/UnitTest/URLTest.cpp324
-rw-r--r--Swiften/Base/WindowsRegistry.h96
-rw-r--r--Swiften/Base/boost_bsignals.h26
-rw-r--r--Swiften/Base/foreach.h13
-rw-r--r--Swiften/Base/format.h33
-rw-r--r--Swiften/Base/sleep.cpp19
-rw-r--r--Swiften/Base/sleep.h8
66 files changed, 2661 insertions, 1560 deletions
diff --git a/Swiften/Base/API.h b/Swiften/Base/API.h
index 388ad0a..06359ba 100644
--- a/Swiften/Base/API.h
+++ b/Swiften/Base/API.h
@@ -1,15 +1,16 @@
/*
- * Copyright (c) 2012-2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2012-2014 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
#include <Swiften/Base/Platform.h>
+#include <boost/config.hpp>
#ifdef SWIFTEN_STATIC
-# define SWIFTEN_API
+# define SWIFTEN_API
#else
# ifdef SWIFTEN_PLATFORM_WINDOWS
# ifdef SWIFTEN_BUILDING
@@ -20,6 +21,22 @@
# elif __GNUC__ >= 4
# define SWIFTEN_API __attribute__((visibility("default")))
# else
-# define SWIFTEN_API
+# define SWIFTEN_API
# endif
#endif
+
+#ifdef BOOST_NO_DEFAULTED_FUNCTIONS
+# define SWIFTEN_DEFAULT_COPY_CONSTRUCTOR(cls)
+# define SWIFTEN_DEFAULT_COPY_ASSIGMNENT_OPERATOR(cls)
+#else
+# define SWIFTEN_DEFAULT_COPY_CONSTRUCTOR(cls) \
+ cls(const cls&) = default;
+# define SWIFTEN_DEFAULT_COPY_ASSIGMNENT_OPERATOR(cls) \
+ cls& operator=(const cls&) = default;
+#endif
+
+#ifdef BOOST_NO_NOEXCEPT
+#define SWIFTEN_NOEXCEPT throw()
+#else
+#define SWIFTEN_NOEXCEPT noexcept
+#endif
diff --git a/Swiften/Base/Algorithm.h b/Swiften/Base/Algorithm.h
index d5edab1..ee761b7 100644
--- a/Swiften/Base/Algorithm.h
+++ b/Swiften/Base/Algorithm.h
@@ -1,154 +1,187 @@
/*
- * Copyright (c) 2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011-2018 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
-#include <vector>
+#include <algorithm>
#include <list>
#include <map>
-#include <algorithm>
+#include <string>
+#include <vector>
namespace Swift {
- /*
- * Generic erase()
- */
- namespace Detail {
- struct VectorCategory {};
- struct ListCategory {};
- struct MapCategory {};
-
- template<typename T>
- struct ContainerTraits;
-
- template<typename A, typename B>
- struct ContainerTraits< std::vector<A, B> > {
- typedef VectorCategory Category;
- };
-
- template<>
- struct ContainerTraits< std::string > {
- typedef VectorCategory Category;
- };
-
- template<typename A, typename B>
- struct ContainerTraits< std::list<A, B> > {
- typedef ListCategory Category;
- };
-
- template<typename A, typename B, typename C, typename D>
- struct ContainerTraits< std::map<A, B, C, D> > {
- typedef MapCategory Category;
- };
-
- template<typename C, typename V>
- void eraseImpl(C& c, const V& v, VectorCategory) {
- c.erase(std::remove(c.begin(), c.end(), v), c.end());
- }
-
- template<typename C, typename V>
- void eraseImpl(C& c, const V& v, ListCategory) {
- c.remove(v);
- }
-
- template<typename C, typename V>
- void eraseImpl(C& c, const V& v, MapCategory) {
- for (typename C::iterator it = c.begin(); it != c.end(); ) {
- if (it->second == v) {
- c.erase(it++);
- }
- else {
- ++it;
- }
- }
- }
-
- template<typename C, typename P>
- void eraseIfImpl(C& c, const P& p, MapCategory) {
- for (typename C::iterator it = c.begin(); it != c.end(); ) {
- if (p(*it)) {
- c.erase(it++);
- }
- else {
- ++it;
- }
- }
- }
-
- template<typename C, typename P>
- void eraseIfImpl(C& c, const P& p, VectorCategory) {
- c.erase(std::remove_if(c.begin(), c.end(), p), c.end());
- }
- }
-
- template<typename C, typename V>
- void erase(C& container, const V& value) {
- Detail::eraseImpl(container, value, typename Detail::ContainerTraits<C>::Category());
- }
-
- template<typename C, typename P>
- void eraseIf(C& container, const P& predicate) {
- Detail::eraseIfImpl(container, predicate, typename Detail::ContainerTraits<C>::Category());
- }
-
- template<typename Source, typename Target>
- void append(Target& target, const Source& source) {
- target.insert(target.end(), source.begin(), source.end());
- }
-
- template<typename Source, typename Target>
- void assign(Target& target, const Source& source) {
- target.assign(source.begin(), source.end());
- }
-
- template<typename A, typename B, typename C, typename D>
- B get(const std::map<A, B, C, D>& map, const A& key, const B& defaultValue) {
- typename std::map<A, B, C, D>::const_iterator i = map.find(key);
- if (i != map.end()) {
- return i->second;
- }
- else {
- return defaultValue;
- }
- }
-
- template<typename Container>
- void safeClear(Container& c) {
- std::fill(c.begin(), c.end(), 0);
- c.clear();
- }
-
- /*
- * Functors
- */
- template<typename K, typename V>
- class PairFirstEquals {
- public:
- PairFirstEquals(const K& value) : value(value) {
- }
-
- bool operator()(const std::pair<K,V>& pair) const {
- return pair.first == value;
- }
-
- private:
- K value;
- };
-
- template<typename K, typename V>
- class PairSecondEquals {
- public:
- PairSecondEquals(const V& value) : value(value) {
- }
-
- bool operator()(const std::pair<K,V>& pair) const {
- return pair.second == value;
- }
-
- private:
- V value;
- };
+ /*
+ * Generic erase()
+ */
+ namespace Detail {
+ struct VectorCategory {};
+ struct ListCategory {};
+ struct MapCategory {};
+
+ template<typename T>
+ struct ContainerTraits;
+
+ template<typename A, typename B>
+ struct ContainerTraits< std::vector<A, B> > {
+ typedef VectorCategory Category;
+ };
+
+ template<>
+ struct ContainerTraits< std::string > {
+ typedef VectorCategory Category;
+ };
+
+ template<typename A, typename B>
+ struct ContainerTraits< std::list<A, B> > {
+ typedef ListCategory Category;
+ };
+
+ template<typename A, typename B, typename C, typename D>
+ struct ContainerTraits< std::map<A, B, C, D> > {
+ typedef MapCategory Category;
+ };
+
+ template<typename C, typename V>
+ void eraseImpl(C& c, const V& v, VectorCategory) {
+ c.erase(std::remove(c.begin(), c.end(), v), c.end());
+ }
+
+ template<typename C, typename V>
+ void eraseImpl(C& c, const V& v, ListCategory) {
+ c.remove(v);
+ }
+
+ template<typename C, typename V>
+ void eraseImpl(C& c, const V& v, MapCategory) {
+ for (typename C::iterator it = c.begin(); it != c.end(); ) {
+ if (it->second == v) {
+ c.erase(it++);
+ }
+ else {
+ ++it;
+ }
+ }
+ }
+
+ template<typename C, typename P>
+ void eraseIfImpl(C& c, const P& p, MapCategory) {
+ for (typename C::iterator it = c.begin(); it != c.end(); ) {
+ if (p(*it)) {
+ c.erase(it++);
+ }
+ else {
+ ++it;
+ }
+ }
+ }
+
+ template<typename C, typename P>
+ void eraseIfImpl(C& c, const P& p, VectorCategory) {
+ c.erase(std::remove_if(c.begin(), c.end(), p), c.end());
+ }
+ }
+
+ template<typename C, typename V>
+ void erase(C& container, const V& value) {
+ Detail::eraseImpl(container, value, typename Detail::ContainerTraits<C>::Category());
+ }
+
+ template<typename C, typename P>
+ void eraseIf(C& container, const P& predicate) {
+ Detail::eraseIfImpl(container, predicate, typename Detail::ContainerTraits<C>::Category());
+ }
+
+ template<typename Source, typename Target>
+ void append(Target& target, const Source& source) {
+ target.insert(target.end(), source.begin(), source.end());
+ }
+
+ template<typename Source, typename Target>
+ void assign(Target& target, const Source& source) {
+ target.assign(source.begin(), source.end());
+ }
+
+ template<typename A, typename B, typename C, typename D>
+ B get(const std::map<A, B, C, D>& map, const A& key, const B& defaultValue) {
+ typename std::map<A, B, C, D>::const_iterator i = map.find(key);
+ if (i != map.end()) {
+ return i->second;
+ }
+ else {
+ return defaultValue;
+ }
+ }
+
+ template<typename Container>
+ void safeClear(Container& c) {
+ std::fill(c.begin(), c.end(), 0);
+ c.clear();
+ }
+
+ /*
+ * Functors
+ */
+ template<typename K, typename V>
+ class PairFirstEquals {
+ public:
+ PairFirstEquals(const K& value) : value(value) {
+ }
+
+ bool operator()(const std::pair<K,V>& pair) const {
+ return pair.first == value;
+ }
+
+ private:
+ K value;
+ };
+
+ template<typename K, typename V>
+ class PairSecondEquals {
+ public:
+ PairSecondEquals(const V& value) : value(value) {
+ }
+
+ bool operator()(const std::pair<K,V>& pair) const {
+ return pair.second == value;
+ }
+
+ private:
+ V value;
+ };
+
+ template <typename Map>
+ bool key_compare(Map const& lhs, Map const& rhs) {
+
+ auto pred = [](decltype(*lhs.begin()) a, decltype(a) b) { return a.first == b.first; };
+
+ return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin(), pred);
+ }
+
+ /**
+ * Ranges
+ */
+ template <typename T>
+ class range_t {
+ public:
+ range_t(T b, T e) : b_(b), e_(e) {}
+
+ T begin() {
+ return b_;
+ }
+ T end() {
+ return e_;
+ }
+ private:
+ T b_;
+ T e_;
+ };
+
+ template <typename T>
+ range_t<T> range(T b, T e) {
+ return range_t<T>(b, e);
+ }
}
diff --git a/Swiften/Base/Atomic.h b/Swiften/Base/Atomic.h
new file mode 100644
index 0000000..ae065d4
--- /dev/null
+++ b/Swiften/Base/Atomic.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <mutex>
+
+namespace Swift {
+
+/**
+ * This class template provides a read/write access synchronized wrapper for other types.
+ */
+template <typename ValueType>
+class Atomic {
+ public:
+ Atomic(const ValueType& v) : value_(v) {
+ }
+
+ /**
+ * Synchronized write access.
+ */
+ Atomic<ValueType>& operator=(const ValueType& newValue) {
+ std::lock_guard<std::mutex> lock(valueMutex_);
+ value_ = newValue;
+ return *this;
+ }
+
+ /**
+ * Synchronized read access.
+ */
+ operator ValueType() {
+ std::lock_guard<std::mutex> lock(valueMutex_);
+ return value_;
+ }
+
+ private:
+ std::mutex valueMutex_;
+ ValueType value_;
+};
+
+}
diff --git a/Swiften/Base/BoostFilesystemVersion.h b/Swiften/Base/BoostFilesystemVersion.h
index 1b1676c..fff6ce9 100644
--- a/Swiften/Base/BoostFilesystemVersion.h
+++ b/Swiften/Base/BoostFilesystemVersion.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2010-2012 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2012 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
diff --git a/Swiften/Base/BoostRandomGenerator.cpp b/Swiften/Base/BoostRandomGenerator.cpp
deleted file mode 100644
index a661639..0000000
--- a/Swiften/Base/BoostRandomGenerator.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2012 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#include <Swiften/Base/BoostRandomGenerator.h>
-
-#include <numeric>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/variate_generator.hpp>
-#include <ctime>
-
-namespace Swift {
-
-BoostRandomGenerator::BoostRandomGenerator() {
- // FIXME: Not a good seed
- generator.seed(static_cast<unsigned int>(std::time(0)));
-}
-
-int BoostRandomGenerator::generateRandomInteger(int maximum) {
- boost::uniform_int<> distribution(0, maximum);
- return distribution(generator);
-}
-
-}
diff --git a/Swiften/Base/BoostRandomGenerator.h b/Swiften/Base/BoostRandomGenerator.h
deleted file mode 100644
index 6065ff3..0000000
--- a/Swiften/Base/BoostRandomGenerator.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2012 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#include <Swiften/Base/RandomGenerator.h>
-#include <Swiften/Base/Override.h>
-
-#include <boost/random/mersenne_twister.hpp>
-
-namespace Swift {
- class BoostRandomGenerator : public RandomGenerator{
- public:
- BoostRandomGenerator();
-
- int generateRandomInteger(int max) SWIFTEN_OVERRIDE;
-
- private:
- boost::mt19937 generator;
- };
-}
diff --git a/Swiften/Base/ByteArray.cpp b/Swiften/Base/ByteArray.cpp
index 466db5f..882421d 100644
--- a/Swiften/Base/ByteArray.cpp
+++ b/Swiften/Base/ByteArray.cpp
@@ -1,50 +1,50 @@
/*
- * Copyright (c) 2010-2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <Swiften/Base/ByteArray.h>
-#include <boost/numeric/conversion/cast.hpp>
#include <boost/filesystem/fstream.hpp>
+#include <boost/numeric/conversion/cast.hpp>
namespace Swift {
static const int BUFFER_SIZE = 4096;
void readByteArrayFromFile(ByteArray& data, const boost::filesystem::path& file) {
- boost::filesystem::ifstream input(file, std::ios_base::in|std::ios_base::binary);
- while (input.good()) {
- size_t oldSize = data.size();
- data.resize(oldSize + BUFFER_SIZE);
- input.read(reinterpret_cast<char*>(&data[oldSize]), BUFFER_SIZE);
- data.resize(oldSize + boost::numeric_cast<size_t>(input.gcount()));
- }
- input.close();
+ boost::filesystem::ifstream input(file, std::ios_base::in|std::ios_base::binary);
+ while (input.good()) {
+ size_t oldSize = data.size();
+ data.resize(oldSize + BUFFER_SIZE);
+ input.read(reinterpret_cast<char*>(&data[oldSize]), BUFFER_SIZE);
+ data.resize(oldSize + boost::numeric_cast<size_t>(input.gcount()));
+ }
+ input.close();
}
std::vector<unsigned char> createByteArray(const std::string& s) {
- return std::vector<unsigned char>(s.begin(), s.end());
+ return std::vector<unsigned char>(s.begin(), s.end());
}
std::vector<unsigned char> createByteArray(const char* c) {
- std::vector<unsigned char> data;
- while (*c) {
- data.push_back(static_cast<unsigned char>(*c));
- ++c;
- }
- return data;
+ std::vector<unsigned char> data;
+ while (*c) {
+ data.push_back(static_cast<unsigned char>(*c));
+ ++c;
+ }
+ return data;
}
std::string byteArrayToString(const ByteArray& b) {
- size_t i;
- for (i = b.size(); i > 0; --i) {
- if (b[i - 1] != 0) {
- break;
- }
- }
- return i > 0 ? std::string(reinterpret_cast<const char*>(vecptr(b)), i) : "";
+ size_t i;
+ for (i = b.size(); i > 0; --i) {
+ if (b[i - 1] != 0) {
+ break;
+ }
+ }
+ return i > 0 ? std::string(reinterpret_cast<const char*>(vecptr(b)), i) : "";
}
}
diff --git a/Swiften/Base/ByteArray.h b/Swiften/Base/ByteArray.h
index 133b75f..b567b5a 100644
--- a/Swiften/Base/ByteArray.h
+++ b/Swiften/Base/ByteArray.h
@@ -1,47 +1,48 @@
/*
- * Copyright (c) 2010-2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
-#include <vector>
#include <string>
+#include <vector>
-#include <Swiften/Base/API.h>
#include <boost/filesystem/path.hpp>
+#include <Swiften/Base/API.h>
+
namespace Swift {
- typedef std::vector<unsigned char> ByteArray;
+ typedef std::vector<unsigned char> ByteArray;
+
+ SWIFTEN_API ByteArray createByteArray(const std::string& s);
+ SWIFTEN_API ByteArray createByteArray(const char* c);
- SWIFTEN_API ByteArray createByteArray(const std::string& s);
- SWIFTEN_API ByteArray createByteArray(const char* c);
+ inline ByteArray createByteArray(const unsigned char* c, size_t n) {
+ return ByteArray(c, c + n);
+ }
- inline ByteArray createByteArray(const unsigned char* c, size_t n) {
- return ByteArray(c, c + n);
- }
+ inline ByteArray createByteArray(const char* c, size_t n) {
+ return ByteArray(c, c + n);
+ }
- inline ByteArray createByteArray(const char* c, size_t n) {
- return ByteArray(c, c + n);
- }
+ inline ByteArray createByteArray(char c) {
+ return std::vector<unsigned char>(1, static_cast<unsigned char>(c));
+ }
- inline ByteArray createByteArray(char c) {
- return std::vector<unsigned char>(1, static_cast<unsigned char>(c));
- }
+ template<typename T, typename A>
+ static const T* vecptr(const std::vector<T, A>& v) {
+ return v.empty() ? nullptr : &v[0];
+ }
- template<typename T, typename A>
- static const T* vecptr(const std::vector<T, A>& v) {
- return v.empty() ? NULL : &v[0];
- }
+ template<typename T, typename A>
+ static T* vecptr(std::vector<T, A>& v) {
+ return v.empty() ? nullptr : &v[0];
+ }
- template<typename T, typename A>
- static T* vecptr(std::vector<T, A>& v) {
- return v.empty() ? NULL : &v[0];
- }
-
- SWIFTEN_API std::string byteArrayToString(const ByteArray& b);
+ SWIFTEN_API std::string byteArrayToString(const ByteArray& b);
- SWIFTEN_API void readByteArrayFromFile(ByteArray&, const boost::filesystem::path& file);
+ SWIFTEN_API void readByteArrayFromFile(ByteArray&, const boost::filesystem::path& file);
}
diff --git a/Swiften/Base/Concat.h b/Swiften/Base/Concat.h
index 83a43b6..8923a8f 100644
--- a/Swiften/Base/Concat.h
+++ b/Swiften/Base/Concat.h
@@ -1,73 +1,41 @@
/*
- * Copyright (c) 2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
-namespace Swift {
- template<typename C>
- C concat(const C& c1, const C& c2) {
- C result;
- result.resize(c1.size() + c2.size());
- std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin()));
- return result;
- }
-
- template<typename C>
- C concat(const C& c1, const C& c2, const C& c3) {
- C result;
- result.resize(c1.size() + c2.size() + c3.size());
- std::copy(c3.begin(), c3.end(), std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin())));
- return result;
- }
-
- template<typename C>
- C concat(const C& c1, const C& c2, const C& c3, const C& c4) {
- C result;
- result.resize(c1.size() + c2.size() + c3.size() + c4.size());
- std::copy(c4.begin(), c4.end(), std::copy(c3.begin(), c3.end(), std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin()))));
- return result;
- }
-
- template<typename C>
- C concat(const C& c1, const C& c2, const C& c3, const C& c4, const C& c5) {
- C result;
- result.resize(c1.size() + c2.size() + c3.size() + c4.size() + c5.size());
- std::copy(c5.begin(), c5.end(), std::copy(c4.begin(), c4.end(), std::copy(c3.begin(), c3.end(), std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin())))));
- return result;
- }
+#include <algorithm>
+#include <type_traits>
- template<typename C>
- C concat(const C& c1, const C& c2, const C& c3, const C& c4, const C& c5, const C& c6) {
- C result;
- result.resize(c1.size() + c2.size() + c3.size() + c4.size() + c5.size() + c6.size());
- std::copy(c6.begin(), c6.end(), std::copy(c5.begin(), c5.end(), std::copy(c4.begin(), c4.end(), std::copy(c3.begin(), c3.end(), std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin()))))));
- return result;
- }
-
- template<typename C>
- C concat(const C& c1, const C& c2, const C& c3, const C& c4, const C& c5, const C& c6, const C& c7) {
- C result;
- result.resize(c1.size() + c2.size() + c3.size() + c4.size() + c5.size() + c6.size() + c7.size());
- std::copy(c7.begin(), c7.end(), std::copy(c6.begin(), c6.end(), std::copy(c5.begin(), c5.end(), std::copy(c4.begin(), c4.end(), std::copy(c3.begin(), c3.end(), std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin())))))));
- return result;
- }
-
- template<typename C>
- C concat(const C& c1, const C& c2, const C& c3, const C& c4, const C& c5, const C& c6, const C& c7, const C& c8) {
- C result;
- result.resize(c1.size() + c2.size() + c3.size() + c4.size() + c5.size() + c6.size() + c7.size() + c8.size());
- std::copy(c8.begin(), c8.end(), std::copy(c7.begin(), c7.end(), std::copy(c6.begin(), c6.end(), std::copy(c5.begin(), c5.end(), std::copy(c4.begin(), c4.end(), std::copy(c3.begin(), c3.end(), std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin()))))))));
- return result;
- }
+namespace Swift {
+ template<typename V1, typename V2, typename... Rest>
+ std::size_t getReserveAmount(V1 const& v1, V2 const& v2, Rest const&... rest) SWIFTEN_NOEXCEPT
+ {
+ // Total size of the concatenated output is equal to sum of sizes of all the containers that were passed in.
+ // Two first can be accessed directly:
+ std::size_t sizeSum = v1.size() + v2.size();
+ // While the rest needs to be calculated in parameter pack expansion:
+ // http://stackoverflow.com/a/25683817/61574
+ // Pack expansion can occur inside a braced-init-list - dummy array is used for that (with side effect of accumulating the size)
+ int dummy[] = {0, ((sizeSum += rest.size()), void(), 0)...};
+
+ (void)dummy; // dummy is unused - suppress compiler warning
+ return sizeSum;
+}
- template<typename C>
- C concat(const C& c1, const C& c2, const C& c3, const C& c4, const C& c5, const C& c6, const C& c7, const C& c8, const C& c9) {
- C result;
- result.resize(c1.size() + c2.size() + c3.size() + c4.size() + c5.size() + c6.size() + c7.size() + c8.size() + c9.size());
- std::copy(c9.begin(), c9.end(), std::copy(c8.begin(), c8.end(), std::copy(c7.begin(), c7.end(), std::copy(c6.begin(), c6.end(), std::copy(c5.begin(), c5.end(), std::copy(c4.begin(), c4.end(), std::copy(c3.begin(), c3.end(), std::copy(c2.begin(), c2.end(), std::copy(c1.begin(), c1.end(), result.begin())))))))));
- return result;
- }
+ template<typename V1, typename V2, typename... Rest>
+ typename std::decay<V1>::type concat(V1&& v1, V2&& v2, Rest&&... rest) {
+ // Create the output container and reserve the required amount of space
+ typename std::decay<V1>::type v;
+ v.reserve(getReserveAmount(v1, v2, rest...));
+ // Insert the elements from input containers to output. Directly for the first two:
+ v.insert(v.cend(), v1.cbegin(), v1.cend());
+ v.insert(v.cend(), v2.cbegin(), v2.cend());
+ // Use pack expansion for the others:
+ int dummy[] = {0, ((v.insert(v.cend(), rest.cbegin(), rest.cend())), void(), 0 )...};
+ (void)dummy;
+ return v;
+ }
}
diff --git a/Swiften/Base/DateTime.cpp b/Swiften/Base/DateTime.cpp
index 5d192c4..23b3b84 100644
--- a/Swiften/Base/DateTime.cpp
+++ b/Swiften/Base/DateTime.cpp
@@ -1,39 +1,48 @@
/*
- * Copyright (c) 2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011-2019 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <Swiften/Base/DateTime.h>
#include <locale>
-#include <boost/date_time/time_facet.hpp>
+
+#include <boost/date_time/c_local_time_adjustor.hpp>
#include <boost/date_time/local_time/local_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/date_time/c_local_time_adjustor.hpp>
+#include <boost/date_time/time_facet.hpp>
+#include <Swiften/Base/Log.h>
#include <Swiften/Base/String.h>
namespace Swift {
boost::posix_time::ptime stringToDateTime(const std::string& string) {
- static std::locale locale(std::locale::classic(), new boost::local_time::local_time_input_facet("%Y-%m-%d %H:%M:%S%F%ZP"));
- std::istringstream stream(string);
- stream.imbue(locale);
- boost::local_time::local_date_time result(boost::date_time::not_a_date_time);
- stream >> result;
- return result.utc_time();
+ static std::locale locale(std::locale::classic(), new boost::local_time::local_time_input_facet("%Y-%m-%d %H:%M:%S%F%ZP"));
+ std::istringstream stream(string);
+ stream.imbue(locale);
+ boost::local_time::local_date_time result(boost::date_time::not_a_date_time);
+ stream >> result;
+ return result.utc_time();
}
std::string dateTimeToString(const boost::posix_time::ptime& time) {
- std::string stampString = std::string(boost::posix_time::to_iso_extended_string(time));
- String::replaceAll(stampString, ',', ".");
- stampString += "Z";
- return stampString;
+ std::string stampString = std::string(boost::posix_time::to_iso_extended_string(time));
+ String::replaceAll(stampString, ',', ".");
+ stampString += "Z";
+ return stampString;
}
std::string dateTimeToLocalString(const boost::posix_time::ptime& time) {
- return boost::posix_time::to_simple_string(boost::date_time::c_local_adjustor<boost::posix_time::ptime>::utc_to_local(time));
+ std::string localString;
+ try {
+ localString = boost::posix_time::to_simple_string(boost::date_time::c_local_adjustor<boost::posix_time::ptime>::utc_to_local(time));
+ }
+ catch(std::out_of_range& exception) {
+ SWIFT_LOG(debug) << exception.what();
+ }
+ return localString;
}
}
diff --git a/Swiften/Base/DateTime.h b/Swiften/Base/DateTime.h
index 891b170..36cff65 100644
--- a/Swiften/Base/DateTime.h
+++ b/Swiften/Base/DateTime.h
@@ -1,28 +1,29 @@
/*
- * Copyright (c) 2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/API.h>
#include <boost/date_time/posix_time/ptime.hpp>
+#include <Swiften/Base/API.h>
+
namespace Swift {
- /**
- * Converts a date formatted according to XEP-0082 into a ptime
- * object (in UTC).
- */
- SWIFTEN_API boost::posix_time::ptime stringToDateTime(const std::string& string);
+ /**
+ * Converts a date formatted according to XEP-0082 into a ptime
+ * object (in UTC).
+ */
+ SWIFTEN_API boost::posix_time::ptime stringToDateTime(const std::string& string);
- /**
- * Converts a UTC ptime object to a XEP-0082 formatted string.
- */
- SWIFTEN_API std::string dateTimeToString(const boost::posix_time::ptime& time);
+ /**
+ * Converts a UTC ptime object to a XEP-0082 formatted string.
+ */
+ SWIFTEN_API std::string dateTimeToString(const boost::posix_time::ptime& time);
- /**
- * Converts a UTC ptime object to a localized human readable string.
- */
- SWIFTEN_API std::string dateTimeToLocalString(const boost::posix_time::ptime& time);
+ /**
+ * Converts a UTC ptime object to a localized human readable string.
+ */
+ SWIFTEN_API std::string dateTimeToLocalString(const boost::posix_time::ptime& time);
}
diff --git a/Swiften/Base/Debug.cpp b/Swiften/Base/Debug.cpp
new file mode 100644
index 0000000..b4245c3
--- /dev/null
+++ b/Swiften/Base/Debug.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2015-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swiften/Base/Debug.h>
+
+#include <iostream>
+#include <memory>
+
+#include <Swiften/Client/ClientError.h>
+#include <Swiften/Client/ClientSession.h>
+#include <Swiften/Serializer/PayloadSerializer.h>
+#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h>
+#include <Swiften/Serializer/XMPPSerializer.h>
+
+std::ostream& operator<<(std::ostream& os, const Swift::ClientError& error) {
+ os << "ClientError(";
+ switch(error.getType()) {
+ case Swift::ClientError::UnknownError:
+ os << "UnknownError";
+ break;
+ case Swift::ClientError::DomainNameResolveError:
+ os << "DomainNameResolveError";
+ break;
+ case Swift::ClientError::ConnectionError:
+ os << "ConnectionError";
+ break;
+ case Swift::ClientError::ConnectionReadError:
+ os << "ConnectionReadError";
+ break;
+ case Swift::ClientError::ConnectionWriteError:
+ os << "ConnectionWriteError";
+ break;
+ case Swift::ClientError::XMLError:
+ os << "XMLError";
+ break;
+ case Swift::ClientError::AuthenticationFailedError:
+ os << "AuthenticationFailedError";
+ break;
+ case Swift::ClientError::CompressionFailedError:
+ os << "CompressionFailedError";
+ break;
+ case Swift::ClientError::ServerVerificationFailedError:
+ os << "ServerVerificationFailedError";
+ break;
+ case Swift::ClientError::NoSupportedAuthMechanismsError:
+ os << "NoSupportedAuthMechanismsError";
+ break;
+ case Swift::ClientError::UnexpectedElementError:
+ os << "UnexpectedElementError";
+ break;
+ case Swift::ClientError::ResourceBindError:
+ os << "ResourceBindError";
+ break;
+ case Swift::ClientError::SessionStartError:
+ os << "SessionStartError";
+ break;
+ case Swift::ClientError::StreamError:
+ os << "StreamError";
+ break;
+ case Swift::ClientError::TLSError:
+ os << "TLSError";
+ break;
+ case Swift::ClientError::ClientCertificateLoadError:
+ os << "ClientCertificateLoadError";
+ break;
+ case Swift::ClientError::ClientCertificateError:
+ os << "ClientCertificateError";
+ break;
+ case Swift::ClientError::CertificateCardRemoved:
+ os << "CertificateCardRemoved";
+ break;
+ case Swift::ClientError::UnknownCertificateError:
+ os << "UnknownCertificateError";
+ break;
+ case Swift::ClientError::CertificateExpiredError:
+ os << "CertificateExpiredError";
+ break;
+ case Swift::ClientError::CertificateNotYetValidError:
+ os << "CertificateNotYetValidError";
+ break;
+ case Swift::ClientError::CertificateSelfSignedError:
+ os << "CertificateSelfSignedError";
+ break;
+ case Swift::ClientError::CertificateRejectedError:
+ os << "CertificateRejectedError";
+ break;
+ case Swift::ClientError::CertificateUntrustedError:
+ os << "CertificateUntrustedError";
+ break;
+ case Swift::ClientError::InvalidCertificatePurposeError:
+ os << "InvalidCertificatePurposeError";
+ break;
+ case Swift::ClientError::CertificatePathLengthExceededError:
+ os << "CertificatePathLengthExceededError";
+ break;
+ case Swift::ClientError::InvalidCertificateSignatureError:
+ os << "InvalidCertificateSignatureError";
+ break;
+ case Swift::ClientError::InvalidCAError:
+ os << "InvalidCAError";
+ break;
+ case Swift::ClientError::InvalidServerIdentityError:
+ os << "InvalidServerIdentityError";
+ break;
+ case Swift::ClientError::RevokedError:
+ os << "RevokedError";
+ break;
+ case Swift::ClientError::RevocationCheckFailedError:
+ os << "RevocationCheckFailedError";
+ break;
+ }
+ os << ")";
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os, Swift::Element* ele) {
+ using namespace Swift;
+
+ std::shared_ptr<Element> element = std::shared_ptr<Element>(ele);
+
+ std::shared_ptr<Payload> payload = std::dynamic_pointer_cast<Payload>(element);
+ if (payload) {
+ FullPayloadSerializerCollection payloadSerializerCollection;
+ PayloadSerializer *serializer = payloadSerializerCollection.getPayloadSerializer(payload);
+ os << "Payload(" << serializer->serialize(payload) << ")";
+ return os;
+ }
+ std::shared_ptr<ToplevelElement> topLevelElement = std::dynamic_pointer_cast<ToplevelElement>(element);
+ if (topLevelElement) {
+ FullPayloadSerializerCollection payloadSerializerCollection;
+ XMPPSerializer xmppSerializer(&payloadSerializerCollection, ClientStreamType, false);
+ SafeByteArray serialized = xmppSerializer.serializeElement(topLevelElement);
+ os << "TopLevelElement(" << safeByteArrayToString(serialized) << ")";
+ return os;
+ }
+ os << "Element(Unknown)";
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os, Swift::ClientSession::State state) {
+ using CS = Swift::ClientSession;
+ switch (state) {
+ case CS::State::Initial:
+ os << "ClientSession::State::Initial";
+ break;
+ case CS::State::WaitingForStreamStart:
+ os << "ClientSession::State::WaitingForStreamStart";
+ break;
+ case CS::State::Negotiating:
+ os << "ClientSession::State::Negotiating";
+ break;
+ case CS::State::Compressing:
+ os << "ClientSession::State::Compressing";
+ break;
+ case CS::State::WaitingForEncrypt:
+ os << "ClientSession::State::WaitingForEncrypt";
+ break;
+ case CS::State::Encrypting:
+ os << "ClientSession::State::Encrypting";
+ break;
+ case CS::State::WaitingForCredentials:
+ os << "ClientSession::State::WaitingForCredentials";
+ break;
+ case CS::State::Authenticating:
+ os << "ClientSession::State::Authenticating";
+ break;
+ case CS::State::EnablingSessionManagement:
+ os << "ClientSession::State::EnablingSessionManagement";
+ break;
+ case CS::State::BindingResource:
+ os << "ClientSession::State::BindingResource";
+ break;
+ case CS::State::StartingSession:
+ os << "ClientSession::State::StartingSession";
+ break;
+ case CS::State::Initialized:
+ os << "ClientSession::State::Initialized";
+ break;
+ case CS::State::Finishing:
+ os << "ClientSession::State::Finishing";
+ break;
+ case CS::State::Finished:
+ os << "ClientSession::State::Finished";
+ break;
+ }
+ return os;
+}
diff --git a/Swiften/Base/Debug.h b/Swiften/Base/Debug.h
new file mode 100644
index 0000000..75575de
--- /dev/null
+++ b/Swiften/Base/Debug.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2015-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <iosfwd>
+
+#include <Swiften/Client/ClientSession.h>
+
+namespace Swift {
+ class ClientError;
+ class Element;
+}
+
+SWIFTEN_API std::ostream& operator<<(std::ostream& os, const Swift::ClientError& error);
+
+SWIFTEN_API std::ostream& operator<<(std::ostream& os, Swift::Element* ele);
+
+SWIFTEN_API std::ostream& operator<<(std::ostream& os, Swift::ClientSession::State state);
diff --git a/Swiften/Base/Error.cpp b/Swiften/Base/Error.cpp
index 60ad7ac..4745f34 100644
--- a/Swiften/Base/Error.cpp
+++ b/Swiften/Base/Error.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <Swiften/Base/Error.h>
diff --git a/Swiften/Base/Error.h b/Swiften/Base/Error.h
index d9f3b91..af4f27e 100644
--- a/Swiften/Base/Error.h
+++ b/Swiften/Base/Error.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
@@ -9,8 +9,11 @@
#include <Swiften/Base/API.h>
namespace Swift {
- class SWIFTEN_API Error {
- public:
- virtual ~Error();
- };
+ class SWIFTEN_API Error {
+ public:
+ Error() {}
+ SWIFTEN_DEFAULT_COPY_CONSTRUCTOR(Error)
+ SWIFTEN_DEFAULT_COPY_ASSIGMNENT_OPERATOR(Error)
+ virtual ~Error();
+ };
}
diff --git a/Swiften/Base/FileSize.cpp b/Swiften/Base/FileSize.cpp
new file mode 100644
index 0000000..a335337
--- /dev/null
+++ b/Swiften/Base/FileSize.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swiften/Base/FileSize.h>
+
+#include <boost/format.hpp>
+
+namespace Swift {
+
+std::string formatSize(const boost::uintmax_t bytes) {
+ static const char *siPrefix[] = {"k", "M", "G", "T", "P", "E", "Z", "Y", nullptr};
+ int power = 0;
+ double engBytes = bytes;
+ while (engBytes >= 1000) {
+ ++power;
+ engBytes = engBytes / 1000.0;
+ }
+ return str( boost::format("%.1lf %sB") % engBytes % (power > 0 ? siPrefix[power-1] : "") );
+}
+
+}
diff --git a/Swiften/Base/FileSize.h b/Swiften/Base/FileSize.h
new file mode 100644
index 0000000..af303cc
--- /dev/null
+++ b/Swiften/Base/FileSize.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <string>
+
+#include <boost/cstdint.hpp>
+
+#include <Swiften/Base/API.h>
+
+namespace Swift {
+
+SWIFTEN_API std::string formatSize(const boost::uintmax_t bytes);
+
+}
diff --git a/Swiften/Base/IDGenerator.cpp b/Swiften/Base/IDGenerator.cpp
index 5556f7b..b59a39c 100644
--- a/Swiften/Base/IDGenerator.cpp
+++ b/Swiften/Base/IDGenerator.cpp
@@ -1,24 +1,27 @@
/*
- * Copyright (c) 2010-2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <Swiften/Base/IDGenerator.h>
+#include <boost/lexical_cast.hpp>
#include <boost/uuid/uuid.hpp>
-#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/uuid_generators.hpp>
-#include <boost/lexical_cast.hpp>
+#include <boost/uuid/uuid_io.hpp>
namespace Swift {
IDGenerator::IDGenerator() {
}
+IDGenerator::~IDGenerator() {
+}
+
std::string IDGenerator::generateID() {
- static boost::uuids::random_generator generator;
- return boost::lexical_cast<std::string>(generator());
+ static boost::uuids::random_generator generator;
+ return boost::lexical_cast<std::string>(generator());
}
}
diff --git a/Swiften/Base/IDGenerator.h b/Swiften/Base/IDGenerator.h
index 14ecfdc..6b53994 100644
--- a/Swiften/Base/IDGenerator.h
+++ b/Swiften/Base/IDGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
@@ -11,10 +11,11 @@
#include <Swiften/Base/API.h>
namespace Swift {
- class SWIFTEN_API IDGenerator {
- public:
- IDGenerator();
+ class SWIFTEN_API IDGenerator {
+ public:
+ IDGenerator();
+ virtual ~IDGenerator();
- std::string generateID();
- };
+ virtual std::string generateID();
+ };
}
diff --git a/Swiften/Base/LRUCache.h b/Swiften/Base/LRUCache.h
new file mode 100644
index 0000000..1f92612
--- /dev/null
+++ b/Swiften/Base/LRUCache.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <functional>
+#include <utility>
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/optional.hpp>
+
+namespace Swift {
+
+
+/**
+ * The \ref LRUCache template class implements a lookup cache which removes
+ * the least recently used cached item from the cache, if the cache size hits
+ * the \p MAX_SIZE limit.
+ *
+ * An example use is a cache for entity capabilities hash to DiscoInfo.
+ */
+template <typename KEY_TYPE, typename VALUE_TYPE, size_t MAX_SIZE>
+class LRUCache {
+public:
+ using cacheMissFunction = std::function<boost::optional<VALUE_TYPE>(const KEY_TYPE& )>;
+
+public:
+ /**
+ * Inserts the key/value pair in the front of the cache. If the \p key
+ * already exists in the cache, it is moved to the front instead. If
+ * afterwards, the cahe size exceeds the \p MAX_SIZE limit, the least
+ * recently item is removed from the cache.
+ */
+ void insert(const KEY_TYPE& key, VALUE_TYPE value) {
+ auto pushResult = cache.push_front(entry_t(key, value));
+ if (!pushResult.second) {
+ cache.relocate(cache.begin(), pushResult.first);
+ }
+ else if (cache.size() > MAX_SIZE) {
+ cache.pop_back();
+ }
+ }
+
+ /**
+ * Looks up a cache entry based on the provided \p key and moves it back
+ * to the front of the cache. If there is no cache entry for the provided
+ * \p key, an uninitialized \p boost::optional is returned.
+ * If the optional \p missFunction is provided, it is called on a cache miss.
+ * If the \p missFunction returns an initialized \p boost::optional, the
+ * value is inserted in the cache.
+ */
+ boost::optional<VALUE_TYPE> get(const KEY_TYPE& key, cacheMissFunction missFunction = cacheMissFunction()) {
+ boost::optional<VALUE_TYPE> cachedValue;
+ auto cacheItemIterator = boost::multi_index::get<1>(cache).find(key);
+ if (cacheItemIterator != boost::multi_index::get<1>(cache).end()) {
+ cachedValue = cacheItemIterator->second;
+ cache.relocate(cache.begin(), cache.iterator_to(*cacheItemIterator));
+ }
+ else if (missFunction && (cachedValue = missFunction(key))) {
+ insert(key, cachedValue.get());
+ }
+ return cachedValue;
+ }
+
+private:
+ using entry_t = std::pair<KEY_TYPE, VALUE_TYPE>;
+
+private:
+ boost::multi_index_container< entry_t, boost::multi_index::indexed_by< boost::multi_index::sequenced<>, boost::multi_index::hashed_unique<
+ BOOST_MULTI_INDEX_MEMBER(entry_t, KEY_TYPE, first)> > > cache;
+};
+
+}
diff --git a/Swiften/Base/Listenable.h b/Swiften/Base/Listenable.h
index 445dfd7..ae83f4e 100644
--- a/Swiften/Base/Listenable.h
+++ b/Swiften/Base/Listenable.h
@@ -1,52 +1,55 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2015 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/API.h>
-#include <boost/bind.hpp>
#include <algorithm>
+#include <vector>
+
+#include <boost/bind.hpp>
+
+#include <Swiften/Base/API.h>
namespace Swift {
- template<typename T>
- class SWIFTEN_API Listenable {
- public:
- void addListener(T* listener) {
- listeners.push_back(listener);
- }
-
- void removeListener(T* listener) {
- listeners.erase(std::remove(listeners.begin(), listeners.end(), listener), listeners.end());
- }
-
- protected:
- template<typename F>
- void notifyListeners(F event) {
- for (typename std::vector<T*>::iterator i = listeners.begin(); i != listeners.end(); ++i) {
- event(*i);
- }
- }
-
- template<typename F, typename A1>
- void notifyListeners(F f, const A1& a1) {
- notifyListeners(boost::bind(f, _1, a1));
- }
-
- template<typename F, typename A1, typename A2>
- void notifyListeners(F f, const A1& a1, const A2& a2) {
- notifyListeners(boost::bind(f, _1, a1, a2));
- }
-
- template<typename F, typename A1, typename A2, typename A3>
- void notifyListeners(F f, const A1& a1, const A2& a2, const A3& a3) {
- notifyListeners(boost::bind(f, _1, a1, a2, a3));
- }
-
- private:
- std::vector<T*> listeners;
- };
+ template<typename T>
+ class SWIFTEN_API Listenable {
+ public:
+ void addListener(T* listener) {
+ listeners.push_back(listener);
+ }
+
+ void removeListener(T* listener) {
+ listeners.erase(std::remove(listeners.begin(), listeners.end(), listener), listeners.end());
+ }
+
+ protected:
+ template<typename F>
+ void notifyListeners(F event) {
+ for (typename std::vector<T*>::iterator i = listeners.begin(); i != listeners.end(); ++i) {
+ event(*i);
+ }
+ }
+
+ template<typename F, typename A1>
+ void notifyListeners(F f, const A1& a1) {
+ notifyListeners(boost::bind(f, _1, a1));
+ }
+
+ template<typename F, typename A1, typename A2>
+ void notifyListeners(F f, const A1& a1, const A2& a2) {
+ notifyListeners(boost::bind(f, _1, a1, a2));
+ }
+
+ template<typename F, typename A1, typename A2, typename A3>
+ void notifyListeners(F f, const A1& a1, const A2& a2, const A3& a3) {
+ notifyListeners(boost::bind(f, _1, a1, a2, a3));
+ }
+
+ private:
+ std::vector<T*> listeners;
+ };
}
diff --git a/Swiften/Base/Log.cpp b/Swiften/Base/Log.cpp
index 317798c..b6f1851 100644
--- a/Swiften/Base/Log.cpp
+++ b/Swiften/Base/Log.cpp
@@ -1,43 +1,83 @@
/*
- * Copyright (c) 2010-2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2019 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <Swiften/Base/Log.h>
#include <cstdio>
+#if defined(SWIFT_ANDROID_LOGGING) && defined(__ANDROID__)
+#include <android/log.h>
+#endif
+
namespace Swift {
static Log::Severity logLevel = Log::warning;
+std::unique_ptr<FILE, Log::LogFileClose> Log::logfile;
+Log::Callback Log::logCallback;
Log::Log() {
}
Log::~Log() {
- // Using stdio for thread safety (POSIX file i/o calls are guaranteed to be atomic)
- fprintf(stderr, "%s", stream.str().c_str());
- fflush(stderr);
+#if defined(SWIFT_ANDROID_LOGGING) && defined(__ANDROID__)
+ __android_log_print(ANDROID_LOG_VERBOSE, "Swift", stream.str().c_str(), 1);
+#else
+ // Using stdio for thread safety (POSIX file i/o calls are guaranteed to be atomic)
+ if (logCallback) {
+ logCallback(severity_, std::move(file_), line_, std::move(function_), stream.str());
+ }
+ else {
+ stream << std::endl;
+ if (logfile) {
+ fwrite(stream.str().c_str(), sizeof(char), stream.str().size(), logfile.get());
+ fflush(logfile.get());
+ }
+ else {
+ fwrite(stream.str().c_str(), sizeof(char), stream.str().size(), stderr);
+ fflush(stderr);
+ }
+ }
+#endif
}
std::ostringstream& Log::getStream(
- Severity /*severity*/,
- const std::string& severityString,
- const std::string& file,
- int line,
- const std::string& function) {
- stream << "[" << severityString << "] " << file << ":" << line << " " << function << ": ";
- return stream;
+ Severity severity,
+ std::string severityString,
+ std::string file,
+ int line,
+ std::string function) {
+ if (logCallback) {
+ severity_ = severity;
+ file_ = std::move(file);
+ line_ = line;
+ function_ = std::move(function);
+ }
+ else {
+ stream << "[" << severityString << "] " << file << ":" << line << " " << function << ": ";
+ }
+ return stream;
}
Log::Severity Log::getLogLevel() {
- return logLevel;
+ return logLevel;
}
void Log::setLogLevel(Severity level) {
- logLevel = level;
+ logLevel = level;
+}
+
+void Log::setLogFile(const std::string& fileName) {
+ if (!fileName.empty()) {
+ logfile = std::unique_ptr<FILE, Log::LogFileClose>(fopen(fileName.c_str(), "a"));
+ }
+}
+
+void Log::setLogCallback(Callback callback) {
+ Log::logCallback = callback;
}
}
diff --git a/Swiften/Base/Log.h b/Swiften/Base/Log.h
index a46860f..255e478 100644
--- a/Swiften/Base/Log.h
+++ b/Swiften/Base/Log.h
@@ -1,44 +1,63 @@
/*
- * Copyright (c) 2010-2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
+#include <cstdio>
+#include <functional>
+#include <memory>
#include <sstream>
#include <Swiften/Base/API.h>
namespace Swift {
- class SWIFTEN_API Log {
- public:
- enum Severity {
- error, warning, info, debug
- };
-
- Log();
- ~Log();
-
- std::ostringstream& getStream(
- Severity severity,
- const std::string& severityString,
- const std::string& file,
- int line,
- const std::string& function);
-
- static Severity getLogLevel();
- static void setLogLevel(Severity level);
-
- private:
- std::ostringstream stream;
- };
+ class SWIFTEN_API Log {
+ public:
+ enum Severity {
+ error, warning, info, debug
+ };
+ using Callback = std::function<void(Severity severity, std::string file, int line, std::string function, std::string message)>;
+
+ Log();
+ ~Log();
+
+ std::ostringstream& getStream(
+ Severity severity,
+ std::string severityString,
+ std::string file,
+ int line,
+ std::string function);
+
+ static Severity getLogLevel();
+ static void setLogLevel(Severity level);
+ static void setLogFile(const std::string& fileName);
+ static void setLogCallback(Callback callback);
+
+ private:
+ struct LogFileClose {
+ void operator()(FILE* p) {
+ if (p) {
+ fclose(p);
+ }
+ }
+ };
+ std::ostringstream stream;
+ static std::unique_ptr<FILE, LogFileClose> logfile;
+ static Callback logCallback;
+ Severity severity_;
+ std::string file_;
+ int line_;
+ std::string function_;
+ };
}
#define SWIFT_LOG(severity) \
- if (Log::severity > Log::getLogLevel()) ; \
- else Log().getStream(Log::severity, #severity, __FILE__, __LINE__, __FUNCTION__)
+ if (Log::severity > Log::getLogLevel()) ; \
+ else Log().getStream(Log::severity, #severity, __FILE__, __LINE__, __FUNCTION__)
#define SWIFT_LOG_ASSERT(test, severity) \
- if (Log::severity > Log::getLogLevel() || (test)) ; \
- else Log().getStream(Log::severity, #severity, __FILE__, __LINE__, __FUNCTION__) << "Assertion failed: " << #test << ". "
+ if (Log::severity > Log::getLogLevel() || (test)) ; \
+ else Log().getStream(Log::severity, #severity, __FILE__, __LINE__, __FUNCTION__) << "Assertion failed: " << #test << ". "
diff --git a/Swiften/Base/LogSerializers.cpp b/Swiften/Base/LogSerializers.cpp
new file mode 100644
index 0000000..3f8e9ce
--- /dev/null
+++ b/Swiften/Base/LogSerializers.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swiften/Base/LogSerializers.h>
+
+#include <Swiften/Elements/Presence.h>
+#include <Swiften/Network/BOSHConnection.h>
+
+namespace Swift {
+
+std::ostream& operator<<(std::ostream& stream, const Presence& presence) {
+ std::string typeString;
+ switch (presence.getType()) {
+ case Presence::Available:
+ typeString = "Available";
+ break;
+ case Presence::Error:
+ typeString = "Error";
+ break;
+ case Presence::Probe:
+ typeString = "Probe";
+ break;
+ case Presence::Subscribe:
+ typeString = "Subscribe";
+ break;
+ case Presence::Subscribed:
+ typeString = "Subscribed";
+ break;
+ case Presence::Unavailable:
+ typeString = "Unavailable";
+ break;
+ case Presence::Unsubscribe:
+ typeString = "Unsubscribe";
+ break;
+ case Presence::Unsubscribed:
+ typeString = "Unsubscribed";
+ break;
+ }
+
+ std::string showTypeString;
+ switch (presence.getShow()) {
+ case StatusShow::Online:
+ showTypeString = "Online";
+ break;
+ case StatusShow::Away:
+ showTypeString = "Away";
+ break;
+ case StatusShow::FFC:
+ showTypeString = "FFC";
+ break;
+ case StatusShow::DND:
+ showTypeString = "DND";
+ break;
+ case StatusShow::XA:
+ showTypeString = "XA";
+ break;
+ case StatusShow::None:
+ showTypeString = "None";
+ break;
+ }
+
+ stream << "Presence(" << "from: " << presence.getFrom() << ", to: " << presence.getTo() << ", type: " << typeString << ", status: " << showTypeString << ", priority: " << presence.getPriority() << ", '" << presence.getStatus() << "'" << " )";
+ return stream;
+}
+
+std::ostream& operator<<(std::ostream& stream, const BOSHError& boshError) {
+ std::string errorString;
+ switch (boshError.getType()) {
+ case BOSHError::BadRequest:
+ errorString = "BadRequest";
+ break;
+ case BOSHError::HostGone:
+ errorString = "HostGone";
+ break;
+ case BOSHError::HostUnknown:
+ errorString = "HostUnknown";
+ break;
+ case BOSHError::ImproperAddressing:
+ errorString = "ImproperAddressing";
+ break;
+ case BOSHError::InternalServerError:
+ errorString = "InternalServerError";
+ break;
+ case BOSHError::ItemNotFound:
+ errorString = "ItemNotFound";
+ break;
+ case BOSHError::OtherRequest:
+ errorString = "OtherRequest";
+ break;
+ case BOSHError::PolicyViolation:
+ errorString = "PolicyViolation";
+ break;
+ case BOSHError::RemoteConnectionFailed:
+ errorString = "RemoteConnectionFailed";
+ break;
+ case BOSHError::RemoteStreamError:
+ errorString = "RemoteStreamError";
+ break;
+ case BOSHError::SeeOtherURI:
+ errorString = "SeeOtherURI";
+ break;
+ case BOSHError::SystemShutdown:
+ errorString = "SystemShutdown";
+ break;
+ case BOSHError::UndefinedCondition:
+ errorString = "UndefinedCondition";
+ break;
+ case BOSHError::NoError:
+ errorString = "NoError";
+ break;
+ }
+
+ stream << "BOSHError( " << errorString << " )";
+ return stream;
+}
+
+};
+
+::std::ostream& operator<<(::std::ostream& os, const boost::optional<std::string>& optStr) {
+ if (optStr.is_initialized()) {
+ return os << "boost::optional<std::string>(\"" << optStr.get() << "\")";
+ }
+ else {
+ return os << "boost::optional<std::string>()";
+ }
+}
+
diff --git a/Swiften/Base/LogSerializers.h b/Swiften/Base/LogSerializers.h
new file mode 100644
index 0000000..7f73686
--- /dev/null
+++ b/Swiften/Base/LogSerializers.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <map>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <boost/optional.hpp>
+
+namespace Swift {
+
+class Presence;
+class BOSHError;
+
+template <typename T>
+std::ostream& operator<<(std::ostream& stream, const std::shared_ptr<T>& ptr) {
+ if (ptr) {
+ stream << *ptr;
+ }
+ else {
+ stream << "nullptr";
+ }
+ return stream;
+}
+
+template <typename T>
+std::ostream& operator<<(std::ostream& stream, const std::vector<T>& vec) {
+ stream << "[";
+ if (!vec.empty()) {
+ auto it = std::begin(vec);
+ stream << *it;
+
+ ++it;
+ for (auto end = std::end(vec); it != end; ++it) {
+ stream << ", " << *it;
+ }
+ }
+ stream << "]";
+ return stream;
+}
+
+template <typename KEY, typename VALUE>
+std::ostream& operator<<(std::ostream& stream, const std::pair<KEY, VALUE>& pair) {
+ stream << pair.first << ":" << pair.second;
+ return stream;
+}
+
+template <typename KEY, typename VALUE>
+std::ostream& operator<<(std::ostream& stream, const std::map<KEY, VALUE>& map) {
+ stream << "{";
+ if (!map.empty()) {
+ auto it = std::begin(map);
+ stream << *it;
+
+ ++it;
+ for (auto end = std::end(map); it != end; ++it) {
+ stream << ", " << *it;
+ }
+ }
+ stream << "}";
+ return stream;
+}
+
+std::ostream& operator<<(std::ostream& stream, const Presence& presence);
+
+std::ostream& operator<<(std::ostream& stream, const BOSHError& boshError);
+
+};
+
+::std::ostream& operator<<(::std::ostream& os, const boost::optional<std::string>& optStr);
+
diff --git a/Swiften/Base/Override.h b/Swiften/Base/Override.h
deleted file mode 100644
index 6d9baaa..0000000
--- a/Swiften/Base/Override.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#if defined(__clang__)
-# if __has_feature(cxx_override_control) || __has_extension(cxx_override_control)
-# define SWIFTEN_OVERRIDE override
-# else
-# define SWIFTEN_OVERRIDE
-# endif
-
-#elif defined(__GNUC__)
-# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))) && defined(__GXX_EXPERIMENTAL_CXX0X__)
-# define SWIFTEN_OVERRIDE override
-# else
-# define SWIFTEN_OVERRIDE
-# endif
-
-#elif defined(_MSC_VER)
-// Actually, 1700 is the first version that supports the C++11 override, but
-// older versions apparently support a similar keyword.
-# if _MSC_VER >= 1400
-# define SWIFTEN_OVERRIDE override
-# else
-# define SWIFTEN_OVERRIDE
-# endif
-
-#else
-# define SWIFTEN_OVERRIDE
-#endif
diff --git a/Swiften/Base/Path.cpp b/Swiften/Base/Path.cpp
index 2a49676..ffee09b 100644
--- a/Swiften/Base/Path.cpp
+++ b/Swiften/Base/Path.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
@@ -13,16 +13,16 @@ using namespace Swift;
boost::filesystem::path Swift::stringToPath(const std::string& path) {
#ifdef SWIFTEN_PLATFORM_WINDOWS
- return boost::filesystem::path(convertStringToWString(path));
+ return boost::filesystem::path(convertStringToWString(path));
#else
- return boost::filesystem::path(path);
+ return boost::filesystem::path(path);
#endif
}
std::string Swift::pathToString(const boost::filesystem::path& path) {
#ifdef SWIFTEN_PLATFORM_WINDOWS
- return convertWStringToString(path.native());
+ return convertWStringToString(path.native());
#else
- return path.native();
+ return path.native();
#endif
}
diff --git a/Swiften/Base/Path.h b/Swiften/Base/Path.h
index ea99be9..40141b5 100644
--- a/Swiften/Base/Path.h
+++ b/Swiften/Base/Path.h
@@ -1,27 +1,29 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/API.h>
-#include <boost/filesystem/path.hpp>
#include <string>
+#include <boost/filesystem/path.hpp>
+
+#include <Swiften/Base/API.h>
+
namespace Swift {
- /**
- * Creates a path for the given UTF-8 encoded string.
- * This works independently of global locale settings.
- */
- SWIFTEN_API boost::filesystem::path stringToPath(const std::string&);
-
- /**
- * Returns the UTF-8 representation of the given path
- * This works independently of global locale settings.
- */
- SWIFTEN_API std::string pathToString(const boost::filesystem::path&);
+ /**
+ * Creates a path for the given UTF-8 encoded string.
+ * This works independently of global locale settings.
+ */
+ SWIFTEN_API boost::filesystem::path stringToPath(const std::string&);
+
+ /**
+ * Returns the UTF-8 representation of the given path
+ * This works independently of global locale settings.
+ */
+ SWIFTEN_API std::string pathToString(const boost::filesystem::path&);
}
diff --git a/Swiften/Base/Paths.cpp b/Swiften/Base/Paths.cpp
index 8ad1159..cbb16f3 100644
--- a/Swiften/Base/Paths.cpp
+++ b/Swiften/Base/Paths.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <Swiften/Base/Paths.h>
@@ -21,28 +21,28 @@ namespace Swift {
boost::filesystem::path Paths::getExecutablePath() {
#if defined(SWIFTEN_PLATFORM_MACOSX)
- ByteArray path;
- uint32_t size = 4096;
- path.resize(size);
- if (_NSGetExecutablePath(const_cast<char*>(reinterpret_cast<const char*>(vecptr(path))), &size) == 0) {
- return boost::filesystem::path(std::string(reinterpret_cast<const char*>(vecptr(path)), path.size()).c_str()).parent_path();
- }
+ ByteArray path;
+ uint32_t size = 4096;
+ path.resize(size);
+ if (_NSGetExecutablePath(const_cast<char*>(reinterpret_cast<const char*>(vecptr(path))), &size) == 0) {
+ return boost::filesystem::path(std::string(reinterpret_cast<const char*>(vecptr(path)), path.size()).c_str()).parent_path();
+ }
#elif defined(SWIFTEN_PLATFORM_LINUX)
- ByteArray path;
- path.resize(4096);
- size_t size = static_cast<size_t>(readlink("/proc/self/exe", reinterpret_cast<char*>(vecptr(path)), path.size()));
- if (size > 0) {
- path.resize(size);
- return boost::filesystem::path(std::string(reinterpret_cast<const char*>(vecptr(path)), path.size()).c_str()).parent_path();
- }
+ ByteArray path;
+ path.resize(4096);
+ size_t size = static_cast<size_t>(readlink("/proc/self/exe", reinterpret_cast<char*>(vecptr(path)), path.size()));
+ if (size > 0) {
+ path.resize(size);
+ return boost::filesystem::path(std::string(reinterpret_cast<const char*>(vecptr(path)), path.size()).c_str()).parent_path();
+ }
#elif defined(SWIFTEN_PLATFORM_WINDOWS)
- std::vector<wchar_t> data;
- data.resize(2048);
- GetModuleFileNameW(NULL, vecptr(data), data.size());
- return boost::filesystem::path(
- std::wstring(vecptr(data), data.size())).parent_path();
+ std::vector<wchar_t> data;
+ data.resize(2048);
+ GetModuleFileNameW(NULL, vecptr(data), data.size());
+ return boost::filesystem::path(
+ std::wstring(vecptr(data), data.size())).parent_path();
#endif
- return boost::filesystem::path();
+ return boost::filesystem::path();
}
}
diff --git a/Swiften/Base/Paths.h b/Swiften/Base/Paths.h
index 94e62d1..71b55fb 100644
--- a/Swiften/Base/Paths.h
+++ b/Swiften/Base/Paths.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
@@ -11,8 +11,8 @@
#include <Swiften/Base/API.h>
namespace Swift {
- class SWIFTEN_API Paths {
- public:
- static boost::filesystem::path getExecutablePath();
- };
+ class SWIFTEN_API Paths {
+ public:
+ static boost::filesystem::path getExecutablePath();
+ };
}
diff --git a/Swiften/Base/Platform.h b/Swiften/Base/Platform.h
index a22f556..22dff30 100644
--- a/Swiften/Base/Platform.h
+++ b/Swiften/Base/Platform.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2019 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
@@ -43,9 +43,9 @@
#endif
// Endianness
-#include <boost/detail/endian.hpp>
-#if defined(BOOST_LITTLE_ENDIAN)
+#include <boost/predef/other/endian.h>
+#if defined(BOOST_ENDIAN_LITTLE_BYTE)
#define SWIFTEN_LITTLE_ENDIAN
-#elif defined(BOOST_BIG_ENDIAN)
+#elif defined(BOOST_ENDIAN_BIG_BYTE)
#define SWIFTEN_BIG_ENDIAN
#endif
diff --git a/Swiften/Base/RandomGenerator.cpp b/Swiften/Base/RandomGenerator.cpp
index f2dcca3..e43c01a 100644
--- a/Swiften/Base/RandomGenerator.cpp
+++ b/Swiften/Base/RandomGenerator.cpp
@@ -1,15 +1,13 @@
/*
- * Copyright (c) 2012 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2012 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <Swiften/Base/RandomGenerator.h>
namespace Swift {
-RandomGenerator::~RandomGenerator() {
-
-}
+RandomGenerator::~RandomGenerator() = default;
}
diff --git a/Swiften/Base/RandomGenerator.h b/Swiften/Base/RandomGenerator.h
index eb5b84d..06677ec 100644
--- a/Swiften/Base/RandomGenerator.h
+++ b/Swiften/Base/RandomGenerator.h
@@ -1,23 +1,24 @@
/*
- * Copyright (c) 2012 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2012-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/API.h>
#include <vector>
+#include <Swiften/Base/API.h>
+
namespace Swift {
- class SWIFTEN_API RandomGenerator {
- public:
- virtual ~RandomGenerator();
+ class SWIFTEN_API RandomGenerator {
+ public:
+ virtual ~RandomGenerator();
- /**
- * Generates a random integer between 0 and 'max',
- * 'max' inclusive.
- */
- virtual int generateRandomInteger(int max) = 0;
- };
+ /**
+ * Generates a random integer between 0 and 'max',
+ * 'max' inclusive.
+ */
+ virtual int generateRandomInteger(int max) = 0;
+ };
}
diff --git a/Swiften/Base/Regex.cpp b/Swiften/Base/Regex.cpp
index 5e3d89a..7843833 100644
--- a/Swiften/Base/Regex.cpp
+++ b/Swiften/Base/Regex.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2013 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
/*
@@ -18,20 +18,20 @@
namespace Swift {
- namespace Regex {
- std::string escape(const std::string& source) {
- // escape regex special characters: ^.$| etc
- // these need to be escaped: [\^\$\|.........]
- // and then C++ requires '\' to be escaped, too....
- static const boost::regex esc("([\\^\\.\\$\\|\\(\\)\\[\\]\\*\\+\\?\\/\\{\\}\\\\])");
- // matched character should be prepended with '\'
- // replace matched special character with \\\1
- // and escape once more for C++ rules...
- static const std::string rep("\\\\\\1");
- return boost::regex_replace(source, esc, rep);
- }
-
- }
+ namespace Regex {
+ std::string escape(const std::string& source) {
+ // escape regex special characters: ^.$| etc
+ // these need to be escaped: [\^\$\|.........]
+ // and then C++ requires '\' to be escaped, too....
+ static const boost::regex esc("([\\^\\.\\$\\|\\(\\)\\[\\]\\*\\+\\?\\/\\{\\}\\\\])");
+ // matched character should be prepended with '\'
+ // replace matched special character with \\\1
+ // and escape once more for C++ rules...
+ static const std::string rep("\\\\\\1");
+ return boost::regex_replace(source, esc, rep);
+ }
+
+ }
}
-
+
diff --git a/Swiften/Base/Regex.h b/Swiften/Base/Regex.h
index 6d12a60..7d352c0 100644
--- a/Swiften/Base/Regex.h
+++ b/Swiften/Base/Regex.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2013 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
@@ -12,8 +12,8 @@
namespace Swift {
- namespace Regex {
- SWIFTEN_API std::string escape(const std::string& source);
- }
+ namespace Regex {
+ SWIFTEN_API std::string escape(const std::string& source);
+ }
}
diff --git a/Swiften/Base/SConscript b/Swiften/Base/SConscript
index 094059a..1f48f19 100644
--- a/Swiften/Base/SConscript
+++ b/Swiften/Base/SConscript
@@ -1,21 +1,23 @@
Import("swiften_env")
objects = swiften_env.SwiftenObject([
- "ByteArray.cpp",
- "DateTime.cpp",
- "SafeByteArray.cpp",
- "SafeAllocator.cpp",
- "Error.cpp",
- "Log.cpp",
- "Path.cpp",
- "Paths.cpp",
- "String.cpp",
- "IDGenerator.cpp",
- "SimpleIDGenerator.cpp",
- "RandomGenerator.cpp",
- "BoostRandomGenerator.cpp",
- "sleep.cpp",
- "URL.cpp",
- "Regex.cpp"
- ])
+ "ByteArray.cpp",
+ "DateTime.cpp",
+ "Error.cpp",
+ "FileSize.cpp",
+ "IDGenerator.cpp",
+ "Log.cpp",
+ "LogSerializers.cpp",
+ "Path.cpp",
+ "Paths.cpp",
+ "RandomGenerator.cpp",
+ "Regex.cpp",
+ "SafeAllocator.cpp",
+ "SafeByteArray.cpp",
+ "SimpleIDGenerator.cpp",
+ "StdRandomGenerator.cpp",
+ "String.cpp",
+ "URL.cpp",
+ "sleep.cpp",
+ ])
swiften_env.Append(SWIFTEN_OBJECTS = [objects])
diff --git a/Swiften/Base/SafeAllocator.cpp b/Swiften/Base/SafeAllocator.cpp
index d61d8b9..df51e20 100644
--- a/Swiften/Base/SafeAllocator.cpp
+++ b/Swiften/Base/SafeAllocator.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <Swiften/Base/SafeByteArray.h>
@@ -13,14 +13,14 @@
namespace Swift {
-void secureZeroMemory(char* memory, size_t numberOfBytes) {
+SWIFTEN_API void secureZeroMemory(char* memory, size_t numberOfBytes) {
#ifdef SWIFTEN_PLATFORM_WINDOWS
- SecureZeroMemory(memory, numberOfBytes);
+ SecureZeroMemory(memory, numberOfBytes);
#else
- volatile char* p = memory;
- for (size_t i = 0; i < numberOfBytes; ++i) {
- *(p++) = 0;
- }
+ volatile char* p = memory;
+ for (size_t i = 0; i < numberOfBytes; ++i) {
+ *(p++) = 0;
+ }
#endif
}
diff --git a/Swiften/Base/SafeAllocator.h b/Swiften/Base/SafeAllocator.h
index b01d77d..d47bb02 100644
--- a/Swiften/Base/SafeAllocator.h
+++ b/Swiften/Base/SafeAllocator.h
@@ -1,34 +1,36 @@
/*
- * Copyright (c) 2011-2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
-#include <vector>
#include <algorithm>
+#include <vector>
+
+#include <Swiften/Base/API.h>
namespace Swift {
- void secureZeroMemory(char* memory, size_t numberOfBytes);
-
- template<typename T>
- class SafeAllocator : public std::allocator<T> {
- public:
- template <class U> struct rebind {
- typedef SafeAllocator<U> other;
- };
-
- SafeAllocator() throw() {}
- SafeAllocator(const SafeAllocator&) throw() : std::allocator<T>() {}
- template <class U> SafeAllocator(const SafeAllocator<U>&) throw() {}
- ~SafeAllocator() throw() {}
-
- void deallocate (T* p, size_t num) {
- secureZeroMemory(reinterpret_cast<char*>(p), num);
- std::allocator<T>::deallocate(p, num);
- }
-
- private:
- };
+ SWIFTEN_API void secureZeroMemory(char* memory, size_t numberOfBytes);
+
+ template<typename T>
+ class SWIFTEN_API SafeAllocator : public std::allocator<T> {
+ public:
+ template <class U> struct rebind {
+ typedef SafeAllocator<U> other;
+ };
+
+ SafeAllocator() SWIFTEN_NOEXCEPT {}
+ SafeAllocator(const SafeAllocator&) SWIFTEN_NOEXCEPT : std::allocator<T>() {}
+ template <class U> SafeAllocator(const SafeAllocator<U>&) SWIFTEN_NOEXCEPT {}
+ ~SafeAllocator() SWIFTEN_NOEXCEPT {}
+
+ void deallocate (T* p, size_t num) {
+ secureZeroMemory(reinterpret_cast<char*>(p), num);
+ std::allocator<T>::deallocate(p, num);
+ }
+
+ SWIFTEN_DEFAULT_COPY_ASSIGMNENT_OPERATOR(SafeAllocator)
+ };
}
diff --git a/Swiften/Base/SafeByteArray.cpp b/Swiften/Base/SafeByteArray.cpp
index 848b6d8..dd3736e 100644
--- a/Swiften/Base/SafeByteArray.cpp
+++ b/Swiften/Base/SafeByteArray.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <Swiften/Base/SafeByteArray.h>
@@ -11,12 +11,12 @@ using namespace Swift;
namespace Swift {
SafeByteArray createSafeByteArray(const char* c) {
- SafeByteArray data;
- while (*c) {
- data.push_back(static_cast<unsigned char>(*c));
- ++c;
- }
- return data;
+ SafeByteArray data;
+ while (*c) {
+ data.push_back(static_cast<unsigned char>(*c));
+ ++c;
+ }
+ return data;
}
}
diff --git a/Swiften/Base/SafeByteArray.h b/Swiften/Base/SafeByteArray.h
index b85373c..342c185 100644
--- a/Swiften/Base/SafeByteArray.h
+++ b/Swiften/Base/SafeByteArray.h
@@ -1,59 +1,59 @@
/*
- * Copyright (c) 2011-2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
+#include <memory>
#include <vector>
#include <Swiften/Base/API.h>
-#include <Swiften/Base/SafeAllocator.h>
#include <Swiften/Base/ByteArray.h>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <Swiften/Base/SafeAllocator.h>
namespace Swift {
- typedef std::vector<unsigned char, SafeAllocator<unsigned char> > SafeByteArray;
+ typedef std::vector<unsigned char, SafeAllocator<unsigned char> > SafeByteArray;
- inline SafeByteArray createSafeByteArray(const ByteArray& a) {
- return SafeByteArray(a.begin(), a.end());
- }
+ inline SafeByteArray createSafeByteArray(const ByteArray& a) {
+ return SafeByteArray(a.begin(), a.end());
+ }
- SWIFTEN_API SafeByteArray createSafeByteArray(const char* c);
+ SWIFTEN_API SafeByteArray createSafeByteArray(const char* c);
- inline SafeByteArray createSafeByteArray(const std::string& s) {
- return SafeByteArray(s.begin(), s.end());
- }
+ inline SafeByteArray createSafeByteArray(const std::string& s) {
+ return SafeByteArray(s.begin(), s.end());
+ }
- inline boost::shared_ptr<SafeByteArray> createSafeByteArrayRef(const std::string& s) {
- return boost::make_shared<SafeByteArray>(s.begin(), s.end());
- }
+ inline std::shared_ptr<SafeByteArray> createSafeByteArrayRef(const std::string& s) {
+ return std::make_shared<SafeByteArray>(s.begin(), s.end());
+ }
- inline SafeByteArray createSafeByteArray(char c) {
- return SafeByteArray(1, static_cast<unsigned char>(c));
- }
+ inline SafeByteArray createSafeByteArray(char c) {
+ return SafeByteArray(1, static_cast<unsigned char>(c));
+ }
- inline SafeByteArray createSafeByteArray(const char* c, size_t n) {
- return SafeByteArray(c, c + n);
- }
+ inline SafeByteArray createSafeByteArray(const char* c, size_t n) {
+ return SafeByteArray(c, c + n);
+ }
- inline boost::shared_ptr<SafeByteArray> createSafeByteArrayRef(const char* c, size_t n) {
- return boost::make_shared<SafeByteArray>(c, c + n);
- }
+ inline std::shared_ptr<SafeByteArray> createSafeByteArrayRef(const char* c, size_t n) {
+ return std::make_shared<SafeByteArray>(c, c + n);
+ }
- inline SafeByteArray createSafeByteArray(const unsigned char* c, size_t n) {
- return SafeByteArray(c, c + n);
- }
+ inline SafeByteArray createSafeByteArray(const unsigned char* c, size_t n) {
+ return SafeByteArray(c, c + n);
+ }
- inline boost::shared_ptr<SafeByteArray> createSafeByteArrayRef(const unsigned char* c, size_t n) {
- return boost::make_shared<SafeByteArray>(c, c + n);
- }
+ inline std::shared_ptr<SafeByteArray> createSafeByteArrayRef(const unsigned char* c, size_t n) {
+ return std::make_shared<SafeByteArray>(c, c + n);
+ }
- /* WARNING! This breaks the safety of the data in the safe byte array.
- * Do not use in modes that require data safety. */
- inline std::string safeByteArrayToString(const SafeByteArray& b) {
- return byteArrayToString(ByteArray(b.begin(), b.end()));
- }
+ /* WARNING! This breaks the safety of the data in the safe byte array.
+ * Do not use in modes that require data safety. */
+ inline std::string safeByteArrayToString(const SafeByteArray& b) {
+ return byteArrayToString(ByteArray(b.begin(), b.end()));
+ }
}
diff --git a/Swiften/Base/SafeString.h b/Swiften/Base/SafeString.h
index ef9c7cc..5e54537 100644
--- a/Swiften/Base/SafeString.h
+++ b/Swiften/Base/SafeString.h
@@ -1,32 +1,33 @@
/*
- * Copyright (c) 2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
+#include <Swiften/Base/API.h>
#include <Swiften/Base/SafeByteArray.h>
namespace Swift {
- class SafeString {
- public:
- SafeString(const SafeByteArray& data) : data(data) {
- }
+ class SWIFTEN_API SafeString {
+ public:
+ SafeString(const SafeByteArray& data) : data(data) {
+ }
- SafeString(const std::string& s) {
- data = createSafeByteArray(s);
- }
+ SafeString(const std::string& s) {
+ data = createSafeByteArray(s);
+ }
- SafeString(const char* s) {
- data = createSafeByteArray(s);
- }
+ SafeString(const char* s) {
+ data = createSafeByteArray(s);
+ }
- operator SafeByteArray () const {
- return data;
- }
+ operator SafeByteArray () const {
+ return data;
+ }
- private:
- SafeByteArray data;
- };
+ private:
+ SafeByteArray data;
+ };
}
diff --git a/Swiften/Base/SimpleIDGenerator.cpp b/Swiften/Base/SimpleIDGenerator.cpp
index 06cccea..e6d72b3 100644
--- a/Swiften/Base/SimpleIDGenerator.cpp
+++ b/Swiften/Base/SimpleIDGenerator.cpp
@@ -1,34 +1,37 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
-#include "Swiften/Base/SimpleIDGenerator.h"
+#include <Swiften/Base/SimpleIDGenerator.h>
namespace Swift {
SimpleIDGenerator::SimpleIDGenerator() {
}
+SimpleIDGenerator::~SimpleIDGenerator() {
+}
+
std::string SimpleIDGenerator::generateID() {
- bool carry = true;
- size_t i = 0;
- while (carry && i < currentID.size()) {
- char c = currentID[i];
- if (c >= 'z') {
- currentID[i] = 'a';
- }
- else {
- currentID[i] = c+1;
- carry = false;
- }
- ++i;
- }
- if (carry) {
- currentID += 'a';
- }
- return currentID;
+ bool carry = true;
+ size_t i = 0;
+ while (carry && i < currentID.size()) {
+ char c = currentID[i];
+ if (c >= 'z') {
+ currentID[i] = 'a';
+ }
+ else {
+ currentID[i] = c+1;
+ carry = false;
+ }
+ ++i;
+ }
+ if (carry) {
+ currentID += 'a';
+ }
+ return currentID;
}
}
diff --git a/Swiften/Base/SimpleIDGenerator.h b/Swiften/Base/SimpleIDGenerator.h
index fee857d..09e01de 100644
--- a/Swiften/Base/SimpleIDGenerator.h
+++ b/Swiften/Base/SimpleIDGenerator.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
@@ -9,15 +9,23 @@
#include <string>
#include <Swiften/Base/API.h>
+#include <Swiften/Base/IDGenerator.h>
namespace Swift {
- class SWIFTEN_API SimpleIDGenerator {
- public:
- SimpleIDGenerator();
- std::string generateID();
+ /**
+ * @brief The SimpleIDGenerator class implements a IDGenerator generating consecutive ID strings from
+ * the lower case latin alphabet.
+ */
- private:
- std::string currentID;
- };
+ class SWIFTEN_API SimpleIDGenerator : public IDGenerator {
+ public:
+ SimpleIDGenerator();
+ ~SimpleIDGenerator() override;
+
+ std::string generateID() override;
+
+ private:
+ std::string currentID;
+ };
}
diff --git a/Swiften/Base/StartStopper.h b/Swiften/Base/StartStopper.h
index 7ea6049..af1a72d 100644
--- a/Swiften/Base/StartStopper.h
+++ b/Swiften/Base/StartStopper.h
@@ -1,23 +1,23 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
namespace Swift {
- template<typename T> class StartStopper {
- public:
- StartStopper(T* target) : target(target) {
- target->start();
- }
+ template<typename T> class StartStopper {
+ public:
+ StartStopper(T* target) : target(target) {
+ target->start();
+ }
- ~StartStopper() {
- target->stop();
- }
-
- private:
- T* target;
- };
+ ~StartStopper() {
+ target->stop();
+ }
+
+ private:
+ T* target;
+ };
}
diff --git a/Swiften/Base/StdRandomGenerator.cpp b/Swiften/Base/StdRandomGenerator.cpp
new file mode 100644
index 0000000..8b1dee0
--- /dev/null
+++ b/Swiften/Base/StdRandomGenerator.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swiften/Base/StdRandomGenerator.h>
+
+#include <algorithm>
+#include <functional>
+
+namespace {
+ template<class T = std::mt19937, std::size_t N = T::state_size>
+ typename std::enable_if<!!N, T>::type createSeededRandomEngine() {
+ typename T::result_type random_data[N];
+ std::random_device source;
+ std::generate(std::begin(random_data), std::end(random_data), std::ref(source));
+ std::seed_seq seeds(std::begin(random_data), std::end(random_data));
+ return T(seeds);
+ }
+}
+
+namespace Swift {
+
+StdRandomGenerator::StdRandomGenerator() : generator(createSeededRandomEngine()) {
+}
+
+int StdRandomGenerator::generateRandomInteger(int maximum) {
+ std::uniform_int_distribution<> distribution(0, maximum);
+ return distribution(generator);
+}
+
+}
diff --git a/Swiften/Base/StdRandomGenerator.h b/Swiften/Base/StdRandomGenerator.h
new file mode 100644
index 0000000..159d361
--- /dev/null
+++ b/Swiften/Base/StdRandomGenerator.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <random>
+
+#include <Swiften/Base/API.h>
+#include <Swiften/Base/RandomGenerator.h>
+
+namespace Swift {
+ class SWIFTEN_API StdRandomGenerator : public RandomGenerator {
+ public:
+ StdRandomGenerator();
+
+ int generateRandomInteger(int max) override;
+
+ private:
+ std::mt19937 generator;
+ };
+}
diff --git a/Swiften/Base/String.cpp b/Swiften/Base/String.cpp
index 40ea2e1..bbc3003 100644
--- a/Swiften/Base/String.cpp
+++ b/Swiften/Base/String.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2010-2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <Swiften/Base/Platform.h>
@@ -17,136 +17,232 @@
#include <Swiften/Base/String.h>
#include <Swiften/Base/ByteArray.h>
+namespace {
+const static std::uint32_t UTF8_ACCEPT = 0;
+
+const static std::uint8_t UTF8D[] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
+ 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
+ 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
+ 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
+ 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
+ 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
+ 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
+ 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
+};
+
+//http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
+std::uint32_t decode(std::uint32_t & state, std::uint32_t & codepoint, std::uint8_t byte) {
+ const auto type = UTF8D[byte];
+ codepoint = (state != UTF8_ACCEPT) ? (byte & 0x3fu) | (codepoint << 6) : (0xff >> type) & (byte);
+ state = UTF8D[256 + state * 16 + type];
+ return state;
+}
+
+std::uint32_t getNextCodepoint(const char * begin, const char * end, std::size_t & consumed, bool & ok) {
+ consumed = 0;
+ ok = true;
+
+ std::uint32_t state = 0;
+ std::uint32_t codepoint = 0;
+
+ for (auto it = begin; it != end; ++it) {
+ ++consumed;
+ if (!decode(state, codepoint, static_cast<std::uint8_t>(*it)))
+ return codepoint;
+ }
+ if (state != UTF8_ACCEPT) {
+ ok = false;
+ }
+ return codepoint;
+}
+
+}
+
namespace Swift {
static inline size_t sequenceLength(char firstByte) {
- if ((firstByte & 0x80) == 0) {
- return 1;
- }
- if ((firstByte & 0xE0) == 0xC0) {
- return 2;
- }
- if ((firstByte & 0xF0) == 0xE0) {
- return 3;
- }
- if ((firstByte & 0xF8) == 0xF0) {
- return 4;
- }
- if ((firstByte & 0xFC) == 0xF8) {
- return 5;
- }
- if ((firstByte & 0xFE) == 0xFC) {
- return 6;
- }
- assert(false);
- return 1;
+ if ((firstByte & 0x80) == 0) {
+ return 1;
+ }
+ if ((firstByte & 0xE0) == 0xC0) {
+ return 2;
+ }
+ if ((firstByte & 0xF0) == 0xE0) {
+ return 3;
+ }
+ if ((firstByte & 0xF8) == 0xF0) {
+ return 4;
+ }
+ if ((firstByte & 0xFC) == 0xF8) {
+ return 5;
+ }
+ if ((firstByte & 0xFE) == 0xFC) {
+ return 6;
+ }
+ assert(false);
+ return 1;
}
std::vector<unsigned int> String::getUnicodeCodePoints(const std::string& s) {
- std::vector<unsigned int> result;
- for (size_t i = 0; i < s.size();) {
- unsigned int codePoint = 0;
- char firstChar = s[i];
- size_t length = sequenceLength(firstChar);
-
- // First character is special
- size_t firstCharBitSize = 7 - length;
- if (length == 1) {
- firstCharBitSize = 7;
- }
- codePoint = firstChar & ((1<<(firstCharBitSize+1)) - 1);
-
- for (size_t j = 1; j < length; ++j) {
- codePoint = (codePoint<<6) | (s[i+j] & 0x3F);
- }
- result.push_back(codePoint);
- i += length;
- }
- return result;
+ std::vector<unsigned int> result;
+ for (size_t i = 0; i < s.size();) {
+ unsigned int codePoint = 0;
+ char firstChar = s[i];
+ size_t length = sequenceLength(firstChar);
+
+ // First character is special
+ size_t firstCharBitSize = 7 - length;
+ if (length == 1) {
+ firstCharBitSize = 7;
+ }
+ codePoint = firstChar & ((1<<(firstCharBitSize+1)) - 1);
+
+ for (size_t j = 1; j < length; ++j) {
+ codePoint = (codePoint<<6) | (s[i+j] & 0x3F);
+ }
+ result.push_back(codePoint);
+ i += length;
+ }
+ return result;
}
std::pair<std::string,std::string> String::getSplittedAtFirst(const std::string& s, char c) {
- assert((c & 0x80) == 0);
- size_t firstMatch = s.find(c);
- if (firstMatch != s.npos) {
- return std::make_pair(s.substr(0,firstMatch),s.substr(firstMatch+1,s.npos));
- }
- else {
- return std::make_pair(s, "");
- }
+ assert((c & 0x80) == 0);
+ size_t firstMatch = s.find(c);
+ if (firstMatch != s.npos) {
+ return std::make_pair(s.substr(0,firstMatch),s.substr(firstMatch+1,s.npos));
+ }
+ else {
+ return std::make_pair(s, "");
+ }
}
void String::replaceAll(std::string& src, char c, const std::string& s) {
- size_t lastPos = 0;
- size_t matchingIndex = 0;
- while ((matchingIndex = src.find(c, lastPos)) != src.npos) {
- src.replace(matchingIndex, 1, s);
- lastPos = matchingIndex + s.size();
- }
+ size_t lastPos = 0;
+ size_t matchingIndex = 0;
+ while ((matchingIndex = src.find(c, lastPos)) != src.npos) {
+ src.replace(matchingIndex, 1, s);
+ lastPos = matchingIndex + s.size();
+ }
+}
+
+bool String::isValidXMPPCharacter(std::uint32_t codepoint) {
+ // Special accepted characters:
+ if (codepoint == '\t' || codepoint == '\r' || codepoint == '\n')
+ return true;
+ // Discouraged characters:
+ if (codepoint >= 0x7Fu && codepoint <= 0x84u)
+ return false;
+ if (codepoint >= 0x86u && codepoint <= 0x9Fu)
+ return false;
+ if (codepoint >= 0xFDD0u && codepoint <= 0xFDEFu)
+ return false;
+ if (((codepoint & 0xFFFEu) == 0xFFEEu) || ((codepoint & 0xFFFFu) == 0xFFFFu))
+ return false;
+ // Other valid characters (after filtering for discouraged ones above)
+ if (codepoint >= 0x20u && codepoint <= 0xD7FFu)
+ return true;
+ if (codepoint >= 0xE000u && codepoint <= 0xFFFDu)
+ return true;
+ if (codepoint >= 0x10000u && codepoint <= 0x10FFFFu)
+ return true;
+ return false;
+}
+
+std::string String::sanitizeXMPPString(const std::string& input) {
+ std::string result;
+ result.reserve(input.length());
+
+ auto it = input.data();
+ const auto end = it + input.length();
+
+ std::size_t consumed;
+ bool status = UTF8_ACCEPT;
+
+ while (it < end) {
+ const auto codepoint = getNextCodepoint(it, end, consumed, status);
+ if (status) {
+ if (isValidXMPPCharacter(codepoint)) {
+ std::copy(it, it + consumed, std::back_inserter(result));
+ }
+ it += consumed;
+ }
+ else {
+ ++it;
+ }
+ }
+ result.shrink_to_fit();
+ return result;
}
std::vector<std::string> String::split(const std::string& s, char c) {
- assert((c & 0x80) == 0);
- std::vector<std::string> result;
- std::string accumulator;
- for (size_t i = 0; i < s.size(); ++i) {
- if (s[i] == c) {
- result.push_back(accumulator);
- accumulator = "";
- }
- else {
- accumulator += s[i];
- }
- }
- result.push_back(accumulator);
- return result;
+ assert((c & 0x80) == 0);
+ std::vector<std::string> result;
+ std::string accumulator;
+ for (char i : s) {
+ if (i == c) {
+ result.push_back(accumulator);
+ accumulator = "";
+ }
+ else {
+ accumulator += i;
+ }
+ }
+ result.push_back(accumulator);
+ return result;
}
std::string String::convertIntToHexString(int h) {
- std::stringstream ss;
- ss << std::setbase(16);
- ss << h;
- return ss.str();
+ std::stringstream ss;
+ ss << std::setbase(16);
+ ss << h;
+ return ss.str();
}
int String::convertHexStringToInt(const std::string& s) {
- std::stringstream ss;
- int h;
- ss << std::setbase(16);
- ss << s;
- ss >> h;
- return h;
+ std::stringstream ss;
+ int h;
+ ss << std::setbase(16);
+ ss << s;
+ ss >> h;
+ return h;
}
-
#ifdef SWIFTEN_PLATFORM_WINDOWS
std::string convertWStringToString(const std::wstring& s) {
- int utf8Size = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, NULL, 0, NULL, NULL);
- if (utf8Size < 0) {
- throw std::runtime_error("Conversion error");
- }
- std::vector<char> utf8Data(utf8Size);
- int result = WideCharToMultiByte(
- CP_UTF8, 0, s.c_str(), -1, vecptr(utf8Data), utf8Data.size(), NULL, NULL);
- if (result < 0) {
- throw std::runtime_error("Conversion error");
- }
- return std::string(vecptr(utf8Data), utf8Size-1 /* trailing 0 character */);
+ int utf8Size = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, NULL, 0, NULL, NULL);
+ if (utf8Size < 0) {
+ throw std::runtime_error("Conversion error");
+ }
+ std::vector<char> utf8Data(utf8Size);
+ int result = WideCharToMultiByte(
+ CP_UTF8, 0, s.c_str(), -1, vecptr(utf8Data), utf8Data.size(), NULL, NULL);
+ if (result < 0) {
+ throw std::runtime_error("Conversion error");
+ }
+ return std::string(vecptr(utf8Data), utf8Size-1 /* trailing 0 character */);
}
std::wstring convertStringToWString(const std::string& s) {
- int utf16Size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0);
- if (utf16Size < 0) {
- throw std::runtime_error("Conversion error");
- }
- std::vector<wchar_t> utf16Data(utf16Size);
- int result = MultiByteToWideChar(
- CP_UTF8, 0, s.c_str(), -1, vecptr(utf16Data), utf16Data.size());
- if (result < 0) {
- throw std::runtime_error("Conversion error");
- }
- return std::wstring(vecptr(utf16Data), utf16Size-1 /* trailing 0 character */);
+ int utf16Size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0);
+ if (utf16Size < 0) {
+ throw std::runtime_error("Conversion error");
+ }
+ std::vector<wchar_t> utf16Data(utf16Size);
+ int result = MultiByteToWideChar(
+ CP_UTF8, 0, s.c_str(), -1, vecptr(utf16Data), utf16Data.size());
+ if (result < 0) {
+ throw std::runtime_error("Conversion error");
+ }
+ return std::wstring(vecptr(utf16Data), utf16Size-1 /* trailing 0 character */);
}
#endif
diff --git a/Swiften/Base/String.h b/Swiften/Base/String.h
index 5a5642e..3a7ca65 100644
--- a/Swiften/Base/String.h
+++ b/Swiften/Base/String.h
@@ -1,58 +1,60 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
+#include <cstdint>
+#include <sstream>
#include <string>
#include <vector>
-#include <sstream>
#include <Swiften/Base/API.h>
#include <Swiften/Base/Platform.h>
-
#define SWIFTEN_STRING_TO_CFSTRING(a) \
- CFStringCreateWithBytes(NULL, reinterpret_cast<const UInt8*>(a.c_str()), a.size(), kCFStringEncodingUTF8, false)
+ CFStringCreateWithBytes(NULL, reinterpret_cast<const UInt8*>(a.c_str()), a.size(), kCFStringEncodingUTF8, false)
namespace Swift {
- namespace String {
- SWIFTEN_API std::vector<unsigned int> getUnicodeCodePoints(const std::string&);
- SWIFTEN_API std::pair<std::string, std::string> getSplittedAtFirst(const std::string&, char c);
- SWIFTEN_API std::vector<std::string> split(const std::string&, char c);
- SWIFTEN_API void replaceAll(std::string&, char c, const std::string& s);
+ namespace String {
+ SWIFTEN_API std::vector<unsigned int> getUnicodeCodePoints(const std::string&);
+ SWIFTEN_API std::pair<std::string, std::string> getSplittedAtFirst(const std::string&, char c);
+ SWIFTEN_API std::vector<std::string> split(const std::string&, char c);
+ SWIFTEN_API void replaceAll(std::string&, char c, const std::string& s);
+ SWIFTEN_API bool isValidXMPPCharacter(std::uint32_t codepoint);
+ SWIFTEN_API std::string sanitizeXMPPString(const std::string& input);
- inline bool beginsWith(const std::string& s, char c) {
- return s.size() > 0 && s[0] == c;
- }
+ inline bool beginsWith(const std::string& s, char c) {
+ return s.size() > 0 && s[0] == c;
+ }
- inline bool endsWith(const std::string& s, char c) {
- return s.size() > 0 && s[s.size()-1] == c;
- }
+ inline bool endsWith(const std::string& s, char c) {
+ return s.size() > 0 && s[s.size()-1] == c;
+ }
- std::string convertIntToHexString(int h);
- int convertHexStringToInt(const std::string& s);
+ std::string convertIntToHexString(int h);
+ int convertHexStringToInt(const std::string& s);
- }
+ }
#ifdef SWIFTEN_PLATFORM_WINDOWS
- SWIFTEN_API std::string convertWStringToString(const std::wstring& s);
- SWIFTEN_API std::wstring convertStringToWString(const std::string& s);
+ SWIFTEN_API std::string convertWStringToString(const std::wstring& s);
+ SWIFTEN_API std::wstring convertStringToWString(const std::string& s);
#endif
- class SWIFTEN_API makeString {
- public:
- template <typename T> makeString& operator<<(T const& v) {
- stream << v;
- return *this;
- }
+ class SWIFTEN_API makeString {
+ public:
+ template <typename T> makeString& operator<<(T const& v) {
+ stream << v;
+ return *this;
+ }
- operator std::string() const {
- return stream.str();
- }
+ operator std::string() const {
+ return stream.str();
+ }
- private:
- std::ostringstream stream;
- };
+ private:
+ std::ostringstream stream;
+ };
}
diff --git a/Swiften/Base/Tristate.h b/Swiften/Base/Tristate.h
new file mode 100644
index 0000000..edb7444
--- /dev/null
+++ b/Swiften/Base/Tristate.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+namespace Swift {
+
+enum Tristate {Yes, No, Maybe};
+
+}
diff --git a/Swiften/Base/URL.cpp b/Swiften/Base/URL.cpp
index 866cd45..5c0f0d7 100644
--- a/Swiften/Base/URL.cpp
+++ b/Swiften/Base/URL.cpp
@@ -1,114 +1,141 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2018 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <Swiften/Base/URL.h>
+#include <algorithm>
#include <iostream>
namespace Swift {
-int URL::getPortOrDefaultPort(const URL& url) {
- if (url.getPort()) {
- return *url.getPort();
- }
- else if (url.getScheme() == "http") {
- return 80;
- }
- else if (url.getScheme() == "https") {
- return 443;
- }
- else {
- std::cerr << "Unknown scheme: " + url.getScheme() << std::endl;
- return 80;
- }
+unsigned short URL::getPortOrDefaultPort(const URL& url) {
+ if (url.getPort()) {
+ return *url.getPort();
+ }
+ else if (url.getScheme() == "http") {
+ return 80;
+ }
+ else if (url.getScheme() == "https") {
+ return 443;
+ }
+ else {
+ std::cerr << "Unknown scheme: " + url.getScheme() << std::endl;
+ return 80;
+ }
}
URL URL::fromString(const std::string& urlString) {
- size_t colonIndex = urlString.find(':');
- if (colonIndex == std::string::npos) {
- return URL();
- }
- std::string scheme = urlString.substr(0, colonIndex);
+ size_t colonIndex = urlString.find(':');
+ if (colonIndex == std::string::npos) {
+ return URL();
+ }
+ std::string scheme = urlString.substr(0, colonIndex);
- // Authority
- if (urlString.size() > colonIndex + 2 && urlString[colonIndex+1] == '/' && urlString[colonIndex+2] == '/') {
- size_t authorityIndex = colonIndex + 3;
- size_t slashIndex = urlString.find('/', authorityIndex);
- std::string authority;
- std::string path;
- if (slashIndex == std::string::npos) {
- authority = urlString.substr(authorityIndex);
- path = "";
- }
- else {
- authority = urlString.substr(authorityIndex, slashIndex - authorityIndex);
- path = unescape(urlString.substr(slashIndex));
- }
+ // Authority
+ if (urlString.size() > colonIndex + 2 && urlString[colonIndex+1] == '/' && urlString[colonIndex+2] == '/') {
+ size_t authorityIndex = colonIndex + 3;
+ size_t slashIndex = urlString.find('/', authorityIndex);
+ std::string authority;
+ std::string path;
+ if (slashIndex == std::string::npos) {
+ authority = urlString.substr(authorityIndex);
+ path = "";
+ }
+ else {
+ authority = urlString.substr(authorityIndex, slashIndex - authorityIndex);
+ path = unescape(urlString.substr(slashIndex));
+ }
- size_t atIndex = authority.find('@');
- std::string userInfo;
- std::string hostAndPort;
- if (atIndex != std::string::npos) {
- userInfo = authority.substr(0, atIndex);
- hostAndPort = authority.substr(atIndex + 1);
- }
- else {
- userInfo = "";
- hostAndPort = authority;
- }
+ size_t atIndex = authority.find('@');
+ std::string userInfo;
+ std::string hostAndPort;
+ if (atIndex != std::string::npos) {
+ userInfo = authority.substr(0, atIndex);
+ hostAndPort = authority.substr(atIndex + 1);
+ }
+ else {
+ userInfo = "";
+ hostAndPort = authority;
+ }
- std::string host;
- boost::optional<int> port;
- colonIndex = hostAndPort.find(':');
- if (colonIndex != std::string::npos) {
- host = unescape(hostAndPort.substr(0, colonIndex));
- try {
- port = boost::lexical_cast<int>(hostAndPort.substr(colonIndex + 1));
- }
- catch (const boost::bad_lexical_cast&) {
- return URL();
- }
- }
- else {
- host = unescape(hostAndPort);
- }
+ std::string host;
+ boost::optional<unsigned short> port;
+ if (hostAndPort[0] == '[') {
+ // handle IPv6 address literals
+ size_t addressEndIndex = hostAndPort.find(']');
+ if (addressEndIndex != std::string::npos) {
+ host = hostAndPort.substr(1, addressEndIndex - 1);
+ colonIndex = hostAndPort.find(':', addressEndIndex);
+ if (colonIndex != std::string::npos) {
+ try {
+ port = boost::numeric_cast<unsigned short>(boost::lexical_cast<int>(hostAndPort.substr(colonIndex + 1)));
+ }
+ catch (...) {
+ return URL();
+ }
+ }
+ }
+ else {
+ return URL();
+ }
+ }
+ else {
+ colonIndex = hostAndPort.find(':');
+ if (colonIndex != std::string::npos) {
+ host = unescape(hostAndPort.substr(0, colonIndex));
+ try {
+ port = boost::numeric_cast<unsigned short>(boost::lexical_cast<int>(hostAndPort.substr(colonIndex + 1)));
+ }
+ catch (const boost::bad_lexical_cast&) {
+ return URL();
+ }
+ }
+ else {
+ host = unescape(hostAndPort);
+ }
+ }
- if (port) {
- return URL(scheme, host, *port, path);
- }
- else {
- return URL(scheme, host, path);
- }
- }
- else {
- // We don't support URLs without authorities yet
- return URL();
- }
+ if (port) {
+ return URL(scheme, host, *port, path);
+ }
+ else {
+ return URL(scheme, host, path);
+ }
+ }
+ else {
+ // We don't support URLs without authorities yet
+ return URL();
+ }
}
// FIXME: Escape non-ascii characters
std::string URL::toString() const {
- if (empty) {
- return "";
- }
- std::string result = scheme + "://";
- if (!user.empty()) {
- result += user;
- if (!password.empty()) {
- result += ":" + password;
- }
- result += "@";
- }
- result += host;
- if (port) {
- result += ":";
- result += boost::lexical_cast<std::string>(*port);
- }
- result += path;
- return result;
+ if (empty) {
+ return "";
+ }
+ std::string result = scheme + "://";
+ if (!user.empty()) {
+ result += user;
+ if (!password.empty()) {
+ result += ":" + password;
+ }
+ result += "@";
+ }
+ if (host.find(':') != std::string::npos) {
+ result += "[" + host + "]";
+ }
+ else {
+ result += host;
+ }
+ if (port) {
+ result += ":";
+ result += std::to_string(*port);
+ }
+ result += path;
+ return result;
}
// Disabling this code for now, since GCC4.5+boost1.42 (on ubuntu) seems to
@@ -118,72 +145,72 @@ std::string URL::toString() const {
struct PercentEncodedCharacterFinder {
template<typename Iterator>
boost::iterator_range<Iterator> operator()(Iterator begin, Iterator end) {
- boost::iterator_range<Iterator> r = boost::first_finder("%")(begin, end);
- if (r.end() == end) {
- return r;
- }
- else {
- if (r.end() + 1 == end || r.end() + 2 == end) {
- throw std::runtime_error("Incomplete escape character");
- }
- else {
- r.advance_end(2);
- return r;
- }
- }
+ boost::iterator_range<Iterator> r = boost::first_finder("%")(begin, end);
+ if (r.end() == end) {
+ return r;
+ }
+ else {
+ if (r.end() + 1 == end || r.end() + 2 == end) {
+ throw std::runtime_error("Incomplete escape character");
+ }
+ else {
+ r.advance_end(2);
+ return r;
+ }
+ }
}
};
struct PercentUnencodeFormatter {
template<typename FindResult>
std::string operator()(const FindResult& match) const {
- std::stringstream s;
- s << std::hex << std::string(match.begin() + 1, match.end());
- unsigned int value;
- s >> value;
- if (s.fail() || s.bad()) {
- throw std::runtime_error("Invalid escape character");
- }
- unsigned char charValue = static_cast<unsigned char>(value);
- return std::string(reinterpret_cast<const char*>(&charValue), 1);
+ std::stringstream s;
+ s << std::hex << std::string(match.begin() + 1, match.end());
+ unsigned int value;
+ s >> value;
+ if (s.fail() || s.bad()) {
+ throw std::runtime_error("Invalid escape character");
+ }
+ unsigned char charValue = static_cast<unsigned char>(value);
+ return std::string(reinterpret_cast<const char*>(&charValue), 1);
}
};
std::string unescape(const std::string& s) {
- try {
- return boost::find_format_all_copy(s, PercentEncodedCharacterFinder(), PercentUnencodeFormatter());
- }
- catch (const std::exception&) {
- return "";
- }
+ try {
+ return boost::find_format_all_copy(s, PercentEncodedCharacterFinder(), PercentUnencodeFormatter());
+ }
+ catch (const std::exception&) {
+ return "";
+ }
}
#endif
std::string URL::unescape(const std::string& str) {
- std::string result;
- for (size_t i = 0; i < str.size(); ++i) {
- if (str[i] == '%') {
- if (i + 3 < str.size()) {
- std::stringstream s;
- s << std::hex << str.substr(i+1, 2);
- unsigned int value;
- s >> value;
- if (s.fail() || s.bad()) {
- return "";
- }
- unsigned char charValue = static_cast<unsigned char>(value);
- result += std::string(reinterpret_cast<const char*>(&charValue), 1);
- i += 2;
- }
- else {
- return "";
- }
- }
- else {
- result += str[i];
- }
- }
- return result;
+ std::string result;
+ for (size_t i = 0; i < str.size(); ++i) {
+ if (str[i] == '%') {
+ if (i + 3 < str.size()) {
+ std::stringstream s;
+ s << std::hex << str.substr(i+1, 2);
+ unsigned int value;
+ s >> value;
+ if (s.fail() || s.bad()) {
+ return "";
+ }
+ unsigned char charValue = static_cast<unsigned char>(value);
+ result += std::string(reinterpret_cast<const char*>(&charValue), 1);
+ i += 2;
+ }
+ else {
+ return "";
+ }
+ }
+ else {
+ result += str[i];
+ }
+ }
+ return result;
}
}
diff --git a/Swiften/Base/URL.h b/Swiften/Base/URL.h
index 75cf1a6..8fdb018 100644
--- a/Swiften/Base/URL.h
+++ b/Swiften/Base/URL.h
@@ -1,79 +1,81 @@
/*
- * Copyright (c) 2011 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011-2018 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
#include <string>
+
#include <boost/lexical_cast.hpp>
#include <boost/optional.hpp>
+
#include <Swiften/Base/API.h>
namespace Swift {
class SWIFTEN_API URL {
- public:
-
- URL() : scheme(""), user(""), password(""), host(""), path(""), empty(true) {
- }
-
- URL(const std::string& scheme, const std::string& host, int port, const std::string& path) : scheme(scheme), user(), password(), host(host), port(port), path(path), empty(false) {
- }
-
- URL(const std::string& scheme, const std::string& host, const std::string& path) : scheme(scheme), user(), password(), host(host), path(path), empty(false) {
- }
-
- /**
- * Whether the URL is empty.
- */
- bool isEmpty() const {
- return empty;
- }
-
- /**
- * Scheme used for the URL (http, https etc.)
- */
- const std::string& getScheme() const {
- return scheme;
- }
-
- /**
- * Hostname
- */
- const std::string& getHost() const {
- return host;
- }
-
- /**
- * Port number
- */
- boost::optional<int> getPort() const {
- return port;
- }
-
- /**
- * Path
- */
- const std::string& getPath() const {
- return path;
- }
-
- std::string toString() const;
-
- static int getPortOrDefaultPort(const URL& url);
- static URL fromString(const std::string&);
- static std::string unescape(const std::string&);
-
-
- private:
- std::string scheme;
- std::string user;
- std::string password;
- std::string host;
- boost::optional<int> port;
- std::string path;
- bool empty;
- };
+ public:
+
+ URL() : scheme(""), user(""), password(""), host(""), path(""), empty(true) {
+ }
+
+ URL(const std::string& scheme, const std::string& host, unsigned short port, const std::string& path) : scheme(scheme), user(), password(), host(host), port(port), path(path), empty(false) {
+ }
+
+ URL(const std::string& scheme, const std::string& host, const std::string& path) : scheme(scheme), user(), password(), host(host), path(path), empty(false) {
+ }
+
+ /**
+ * Whether the URL is empty.
+ */
+ bool isEmpty() const {
+ return empty;
+ }
+
+ /**
+ * Scheme used for the URL (http, https etc.)
+ */
+ const std::string& getScheme() const {
+ return scheme;
+ }
+
+ /**
+ * Hostname
+ */
+ const std::string& getHost() const {
+ return host;
+ }
+
+ /**
+ * Port number
+ */
+ boost::optional<unsigned short> getPort() const {
+ return port;
+ }
+
+ /**
+ * Path
+ */
+ const std::string& getPath() const {
+ return path;
+ }
+
+ std::string toString() const;
+
+ static unsigned short getPortOrDefaultPort(const URL& url);
+ static URL fromString(const std::string&);
+ static std::string unescape(const std::string&);
+
+
+ private:
+ std::string scheme;
+ std::string user;
+ std::string password;
+ std::string host;
+ boost::optional<unsigned short> port;
+ std::string path;
+ bool empty;
+ };
}
diff --git a/Swiften/Base/UnitTest/ByteArrayTest.cpp b/Swiften/Base/UnitTest/ByteArrayTest.cpp
index ecd0439..f1732ae 100644
--- a/Swiften/Base/UnitTest/ByteArrayTest.cpp
+++ b/Swiften/Base/UnitTest/ByteArrayTest.cpp
@@ -1,56 +1,43 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/extensions/TestFactoryRegistry.h>
-
-#include <Swiften/Base/ByteArray.h>
#include <boost/lexical_cast.hpp>
-using namespace Swift;
+#include <gtest/gtest.h>
-class ByteArrayTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(ByteArrayTest);
- CPPUNIT_TEST(testGetData_NoData);
- CPPUNIT_TEST(testToString);
- CPPUNIT_TEST(testToString_NullTerminated);
- CPPUNIT_TEST(testToString_TwoNullTerminated);
- CPPUNIT_TEST(testToString_AllNull);
- CPPUNIT_TEST_SUITE_END();
+#include <Swiften/Base/ByteArray.h>
- public:
- void testGetData_NoData() {
- ByteArray testling;
+using namespace Swift;
- CPPUNIT_ASSERT_EQUAL(reinterpret_cast<const char*>(NULL), reinterpret_cast<const char*>(vecptr(testling)));
- }
+TEST(ByteArrayTest, testGetData_NoData) {
+ ByteArray testling;
- void testToString() {
- ByteArray testling(createByteArray("abcde"));
+ ASSERT_EQ(reinterpret_cast<const char*>(NULL), reinterpret_cast<const char*>(vecptr(testling)));
+}
- CPPUNIT_ASSERT_EQUAL(std::string("abcde"), byteArrayToString(testling));
- }
+TEST(ByteArrayTest, testToString) {
+ ByteArray testling(createByteArray("abcde"));
- void testToString_NullTerminated() {
- ByteArray testling(createByteArray("abcde\0", 6));
+ ASSERT_EQ(std::string("abcde"), byteArrayToString(testling));
+}
- CPPUNIT_ASSERT_EQUAL(std::string("abcde"), byteArrayToString(testling));
- }
+TEST(ByteArrayTest, testToString_NullTerminated) {
+ ByteArray testling(createByteArray("abcde\0", 6));
- void testToString_TwoNullTerminated() {
- ByteArray testling(createByteArray("abcde\0\0", 7));
+ ASSERT_EQ(std::string("abcde"), byteArrayToString(testling));
+}
- CPPUNIT_ASSERT_EQUAL(std::string("abcde"), byteArrayToString(testling));
- }
+TEST(ByteArrayTest, testToString_TwoNullTerminated) {
+ ByteArray testling(createByteArray("abcde\0\0", 7));
- void testToString_AllNull() {
- ByteArray testling(createByteArray("\0\0", 2));
+ ASSERT_EQ(std::string("abcde"), byteArrayToString(testling));
+}
- CPPUNIT_ASSERT_EQUAL(std::string(""), byteArrayToString(testling));
- }
-};
+TEST(ByteArrayTest, testToString_AllNull) {
+ ByteArray testling(createByteArray("\0\0", 2));
-CPPUNIT_TEST_SUITE_REGISTRATION(ByteArrayTest);
+ ASSERT_EQ(std::string(""), byteArrayToString(testling));
+}
diff --git a/Swiften/Base/UnitTest/DateTimeTest.cpp b/Swiften/Base/UnitTest/DateTimeTest.cpp
index 8c3903a..6a82d96 100644
--- a/Swiften/Base/UnitTest/DateTimeTest.cpp
+++ b/Swiften/Base/UnitTest/DateTimeTest.cpp
@@ -1,43 +1,52 @@
/*
- * Copyright (c) 2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/extensions/TestFactoryRegistry.h>
#include <string>
+
#include <boost/date_time/posix_time/posix_time.hpp>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
#include <Swiften/Base/DateTime.h>
using namespace Swift;
class DateTimeTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(DateTimeTest);
- CPPUNIT_TEST(testStringToDateTime_UTC);
- CPPUNIT_TEST(testStringToDateTime_WithTimezone);
- CPPUNIT_TEST(testDateTimeToString);
- CPPUNIT_TEST_SUITE_END();
+ CPPUNIT_TEST_SUITE(DateTimeTest);
+ CPPUNIT_TEST(testStringToDateTime_UTC);
+ CPPUNIT_TEST(testStringToDateTime_WithTimezone);
+ CPPUNIT_TEST(testDateTimeToString);
+ CPPUNIT_TEST(testDateTimeToLocalStringNotThrowingException);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void testStringToDateTime_UTC() {
+ boost::posix_time::ptime time = stringToDateTime("1969-07-21T02:56:15Z");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("1969-07-21T02:56:15"), boost::posix_time::to_iso_extended_string(time));
+ }
- public:
- void testStringToDateTime_UTC() {
- boost::posix_time::ptime time = stringToDateTime("1969-07-21T02:56:15Z");
+ void testStringToDateTime_WithTimezone() {
+ boost::posix_time::ptime time = stringToDateTime("1969-07-20T21:56:15-05:00");
- CPPUNIT_ASSERT_EQUAL(std::string("1969-07-21T02:56:15"), boost::posix_time::to_iso_extended_string(time));
- }
+ CPPUNIT_ASSERT_EQUAL(std::string("1969-07-21T02:56:15"), boost::posix_time::to_iso_extended_string(time));
+ }
- void testStringToDateTime_WithTimezone() {
- boost::posix_time::ptime time = stringToDateTime("1969-07-20T21:56:15-05:00");
+ void testDateTimeToString() {
+ boost::posix_time::ptime time = stringToDateTime("1969-07-20T21:56:15-05:00");
- CPPUNIT_ASSERT_EQUAL(std::string("1969-07-21T02:56:15"), boost::posix_time::to_iso_extended_string(time));
- }
+ CPPUNIT_ASSERT_EQUAL(std::string("1969-07-21T02:56:15Z"), dateTimeToString(time));
+ }
- void testDateTimeToString() {
- boost::posix_time::ptime time = stringToDateTime("1969-07-20T21:56:15-05:00");
+ void testDateTimeToLocalStringNotThrowingException() {
+ boost::posix_time::ptime time = stringToDateTime("1954-07-20T21:56:15-05:00");
- CPPUNIT_ASSERT_EQUAL(std::string("1969-07-21T02:56:15Z"), dateTimeToString(time));
- }
+ CPPUNIT_ASSERT_EQUAL(std::string(""), dateTimeToLocalString(time));
+ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(DateTimeTest);
diff --git a/Swiften/Base/UnitTest/IDGeneratorTest.cpp b/Swiften/Base/UnitTest/IDGeneratorTest.cpp
index 610138f..08bd48b 100644
--- a/Swiften/Base/UnitTest/IDGeneratorTest.cpp
+++ b/Swiften/Base/UnitTest/IDGeneratorTest.cpp
@@ -1,12 +1,13 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
+#include <set>
+
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <set>
#include <Swiften/Base/IDGenerator.h>
@@ -14,27 +15,27 @@ using namespace Swift;
class IDGeneratorTest : public CppUnit::TestFixture
{
- CPPUNIT_TEST_SUITE(IDGeneratorTest);
- CPPUNIT_TEST(testGenerate);
- CPPUNIT_TEST_SUITE_END();
-
- public:
- IDGeneratorTest() {}
-
- void setUp() {
- generatedIDs_.clear();
- }
-
- void testGenerate() {
- IDGenerator testling;
- for (unsigned int i = 0; i < 26*4; ++i) {
- std::string id = testling.generateID();
- CPPUNIT_ASSERT(generatedIDs_.insert(id).second);
- }
- }
-
- private:
- std::set<std::string> generatedIDs_;
+ CPPUNIT_TEST_SUITE(IDGeneratorTest);
+ CPPUNIT_TEST(testGenerate);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ IDGeneratorTest() {}
+
+ void setUp() {
+ generatedIDs_.clear();
+ }
+
+ void testGenerate() {
+ IDGenerator testling;
+ for (unsigned int i = 0; i < 26*4; ++i) {
+ std::string id = testling.generateID();
+ CPPUNIT_ASSERT(generatedIDs_.insert(id).second);
+ }
+ }
+
+ private:
+ std::set<std::string> generatedIDs_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(IDGeneratorTest);
diff --git a/Swiften/Base/UnitTest/LRUCacheTest.cpp b/Swiften/Base/UnitTest/LRUCacheTest.cpp
new file mode 100644
index 0000000..7d54c5c
--- /dev/null
+++ b/Swiften/Base/UnitTest/LRUCacheTest.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <string>
+
+#include <boost/optional.hpp>
+
+#include <Swiften/Base/LogSerializers.h>
+#include <Swiften/Base/LRUCache.h>
+
+#include <gtest/gtest.h> // This has to go after Swiften/Base/LogSerializers.h.
+
+using namespace Swift;
+namespace b = boost;
+
+TEST(LRUCacheTest, testCacheLimit) {
+ LRUCache<std::string, std::string, 3> testling;
+
+ testling.insert("A", "AA");
+ testling.insert("B", "BB");
+ testling.insert("C", "CC");
+
+ ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A"));
+ ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B"));
+ ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C"));
+ ASSERT_EQ(b::optional<std::string>(), testling.get("D"));
+
+ testling.insert("D", "DD");
+
+ ASSERT_EQ(b::optional<std::string>(), testling.get("A"));
+ ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B"));
+ ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C"));
+ ASSERT_EQ(b::optional<std::string>("DD"), testling.get("D"));
+}
+
+TEST(LRUCacheTest, testMoveRecentToFrontOnGet) {
+ LRUCache<std::string, std::string, 3> testling;
+
+ testling.insert("A", "AA");
+ testling.insert("B", "BB");
+ testling.insert("C", "CC");
+
+ ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A"));
+ ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B"));
+ ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C"));
+ ASSERT_EQ(b::optional<std::string>(), testling.get("D"));
+ ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A"));
+
+ testling.insert("D", "DD");
+
+ ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A"));
+ ASSERT_EQ(b::optional<std::string>(), testling.get("B"));
+ ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C"));
+ ASSERT_EQ(b::optional<std::string>("DD"), testling.get("D"));
+}
+
+TEST(LRUCacheTest, testMoveRecentToFrontOnReinsert) {
+ LRUCache<std::string, std::string, 3> testling;
+
+ testling.insert("A", "AA");
+ testling.insert("B", "BB");
+ testling.insert("C", "CC");
+
+ ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A"));
+ ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B"));
+ ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C"));
+ ASSERT_EQ(b::optional<std::string>(), testling.get("D"));
+
+ testling.insert("B", "BB");
+
+ ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A"));
+ ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B"));
+ ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C"));
+ ASSERT_EQ(b::optional<std::string>(), testling.get("D"));
+
+ testling.insert("D", "DD");
+
+ ASSERT_EQ(b::optional<std::string>(), testling.get("A"));
+ ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B"));
+ ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C"));
+ ASSERT_EQ(b::optional<std::string>("DD"), testling.get("D"));
+}
+
+TEST(LRUCacheTest, testCacheReturnsValuesPreviouslyInserted) {
+ LRUCache<std::string, std::string, 3> testling;
+
+ testling.insert("A", "AA");
+ testling.insert("B", "BB");
+ testling.insert("C", "CC");
+
+ ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A"));
+ ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B"));
+ ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C"));
+}
+
+TEST(LRUCacheTest, testCacheMissFunctionIsUsedOnCacheMiss) {
+ LRUCache<std::string, std::string, 3> testling;
+
+ testling.insert("A", "AA");
+ testling.insert("B", "BB");
+
+ ASSERT_EQ(b::optional<std::string>("AA"), testling.get("A"));
+ ASSERT_EQ(b::optional<std::string>("BB"), testling.get("B"));
+
+ ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C", [](const std::string&) {
+ return boost::optional<std::string>(std::string("CC"));
+ }));
+ ASSERT_EQ(b::optional<std::string>("CC"), testling.get("C"));
+
+ ASSERT_EQ(b::optional<std::string>(), testling.get("D", [](const std::string&) {
+ return boost::optional<std::string>();
+ }));
+ ASSERT_EQ(b::optional<std::string>(), testling.get("D"));
+}
diff --git a/Swiften/Base/UnitTest/LogTest.cpp b/Swiften/Base/UnitTest/LogTest.cpp
new file mode 100644
index 0000000..5d710db
--- /dev/null
+++ b/Swiften/Base/UnitTest/LogTest.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <vector>
+
+#include <boost/algorithm/string/predicate.hpp>
+
+#include <gtest/gtest.h>
+
+#include <Swiften/Base/Log.h>
+
+using namespace Swift;
+
+struct LogEntry {
+ LogEntry(Log::Severity severity, std::string file, int line, std::string function, std::string message) : severity(severity), file(std::move(file)), line(line), function(std::move(function)), message(std::move(message)) {}
+
+ Log::Severity severity;
+ std::string file;
+ int line;
+ std::string function;
+ std::string message;
+};
+
+// Helper class to set the logging callback. Using this class to set it will ensure the
+// logCallback is reset to empty (its default state) after each test.
+class LogCallbackSetter {
+public:
+ LogCallbackSetter(Log::Callback callback) {
+ Log::setLogCallback(callback);
+ }
+ ~LogCallbackSetter() {
+ Log::setLogCallback({});
+ }
+};
+
+TEST(LogTest, testCallback) {
+ std::vector<LogEntry> logEntries;
+ LogCallbackSetter callbackSetter = {[&](Log::Severity severity, const std::string& file, int line, const std::string& function, const std::string& message) {
+ logEntries.emplace_back(severity, file, line, function, message);
+ }};
+
+ SWIFT_LOG(error) << "An error";
+ ASSERT_EQ(1, logEntries.size());
+ ASSERT_EQ(Log::error, logEntries[0].severity);
+ ASSERT_EQ("An error", logEntries[0].message);
+}
diff --git a/Swiften/Base/UnitTest/PathTest.cpp b/Swiften/Base/UnitTest/PathTest.cpp
index f5f99e7..dd2233b 100644
--- a/Swiften/Base/UnitTest/PathTest.cpp
+++ b/Swiften/Base/UnitTest/PathTest.cpp
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <cppunit/extensions/HelperMacros.h>
@@ -13,23 +13,23 @@
using namespace Swift;
class PathTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(PathTest);
- CPPUNIT_TEST(testStringToPath);
- CPPUNIT_TEST(testPathToString);
- CPPUNIT_TEST_SUITE_END();
+ CPPUNIT_TEST_SUITE(PathTest);
+ CPPUNIT_TEST(testStringToPath);
+ CPPUNIT_TEST(testPathToString);
+ CPPUNIT_TEST_SUITE_END();
- public:
- void testStringToPath() {
+ public:
+ void testStringToPath() {
#ifdef SWIFTEN_PLATFORM_WINDOWS
- CPPUNIT_ASSERT(std::wstring(L"tron\xe7on") == stringToPath("tron\xc3\xa7on").native());
+ CPPUNIT_ASSERT(std::wstring(L"tron\xe7on") == stringToPath("tron\xc3\xa7on").native());
#else
- CPPUNIT_ASSERT_EQUAL(std::string("tron\xc3\xa7on"), stringToPath("tron\xc3\xa7on").native());
+ CPPUNIT_ASSERT_EQUAL(std::string("tron\xc3\xa7on"), stringToPath("tron\xc3\xa7on").native());
#endif
- }
+ }
- void testPathToString() {
- CPPUNIT_ASSERT_EQUAL(std::string("tron\xc3\xa7on"), pathToString(stringToPath("tron\xc3\xa7on")));
- }
+ void testPathToString() {
+ CPPUNIT_ASSERT_EQUAL(std::string("tron\xc3\xa7on"), pathToString(stringToPath("tron\xc3\xa7on")));
+ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(PathTest);
diff --git a/Swiften/Base/UnitTest/SimpleIDGeneratorTest.cpp b/Swiften/Base/UnitTest/SimpleIDGeneratorTest.cpp
index 80aff02..9b49c0a 100644
--- a/Swiften/Base/UnitTest/SimpleIDGeneratorTest.cpp
+++ b/Swiften/Base/UnitTest/SimpleIDGeneratorTest.cpp
@@ -1,40 +1,41 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
+#include <set>
+
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <set>
-#include "Swiften/Base/SimpleIDGenerator.h"
+#include <Swiften/Base/SimpleIDGenerator.h>
using namespace Swift;
class SimpleIDGeneratorTest : public CppUnit::TestFixture
{
- CPPUNIT_TEST_SUITE(SimpleIDGeneratorTest);
- CPPUNIT_TEST(testGenerate);
- CPPUNIT_TEST_SUITE_END();
-
- public:
- SimpleIDGeneratorTest() {}
-
- void setUp() {
- generatedIDs_.clear();
- }
-
- void testGenerate() {
- SimpleIDGenerator testling;
- for (unsigned int i = 0; i < 26*4; ++i) {
- std::string id = testling.generateID();
- CPPUNIT_ASSERT(generatedIDs_.insert(id).second);
- }
- }
-
- private:
- std::set<std::string> generatedIDs_;
+ CPPUNIT_TEST_SUITE(SimpleIDGeneratorTest);
+ CPPUNIT_TEST(testGenerate);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ SimpleIDGeneratorTest() {}
+
+ void setUp() {
+ generatedIDs_.clear();
+ }
+
+ void testGenerate() {
+ SimpleIDGenerator testling;
+ for (unsigned int i = 0; i < 26*4; ++i) {
+ std::string id = testling.generateID();
+ CPPUNIT_ASSERT(generatedIDs_.insert(id).second);
+ }
+ }
+
+ private:
+ std::set<std::string> generatedIDs_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(SimpleIDGeneratorTest);
diff --git a/Swiften/Base/UnitTest/StringTest.cpp b/Swiften/Base/UnitTest/StringTest.cpp
index ffca98a..889c9c7 100644
--- a/Swiften/Base/UnitTest/StringTest.cpp
+++ b/Swiften/Base/UnitTest/StringTest.cpp
@@ -1,128 +1,171 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
+#include <string>
+
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <string>
-#include <Swiften/Base/String.h>
#include <Swiften/Base/Platform.h>
+#include <Swiften/Base/String.h>
+
+#include <boost/format.hpp>
using namespace Swift;
-class StringTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(StringTest);
- CPPUNIT_TEST(testGetUnicodeCodePoints);
- CPPUNIT_TEST(testGetSplittedAtFirst);
- CPPUNIT_TEST(testGetSplittedAtFirst_CharacterAtBegin);
- CPPUNIT_TEST(testGetSplittedAtFirst_CharacterAtEnd);
- CPPUNIT_TEST(testGetSplittedAtFirst_NoSuchCharacter);
- CPPUNIT_TEST(testReplaceAll);
- CPPUNIT_TEST(testReplaceAll_LastChar);
- CPPUNIT_TEST(testReplaceAll_ConsecutiveChars);
- CPPUNIT_TEST(testReplaceAll_MatchingReplace);
- CPPUNIT_TEST(testSplit);
+ class StringTest : public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(StringTest);
+ CPPUNIT_TEST(testGetUnicodeCodePoints);
+ CPPUNIT_TEST(testGetSplittedAtFirst);
+ CPPUNIT_TEST(testGetSplittedAtFirst_CharacterAtBegin);
+ CPPUNIT_TEST(testGetSplittedAtFirst_CharacterAtEnd);
+ CPPUNIT_TEST(testGetSplittedAtFirst_NoSuchCharacter);
+ CPPUNIT_TEST(testReplaceAll);
+ CPPUNIT_TEST(testReplaceAll_LastChar);
+ CPPUNIT_TEST(testReplaceAll_ConsecutiveChars);
+ CPPUNIT_TEST(testReplaceAll_MatchingReplace);
+ CPPUNIT_TEST(testIsValidXMPPCharacter);
+ CPPUNIT_TEST(testSanitizeXMPPString);
+ CPPUNIT_TEST(testSplit);
#ifdef SWIFTEN_PLATFORM_WINDOWS
- CPPUNIT_TEST(testConvertWStringToString);
- CPPUNIT_TEST(testConvertStringToWString);
+ CPPUNIT_TEST(testConvertWStringToString);
+ CPPUNIT_TEST(testConvertStringToWString);
#endif
- CPPUNIT_TEST_SUITE_END();
-
- public:
- void testGetUnicodeCodePoints() {
- std::string testling("$\xc2\xa2\xe2\x82\xac\xf4\x8a\xaf\x8d");
- std::vector<unsigned int> points = String::getUnicodeCodePoints(testling);
-
- CPPUNIT_ASSERT_EQUAL(0x24U, points[0]);
- CPPUNIT_ASSERT_EQUAL(0xA2U, points[1]);
- CPPUNIT_ASSERT_EQUAL(0x20ACU, points[2]);
- CPPUNIT_ASSERT_EQUAL(0x10ABCDU, points[3]);
- }
-
- void testGetSplittedAtFirst() {
- std::string testling("ab@cd@ef");
-
- std::pair<std::string,std::string> result = String::getSplittedAtFirst(testling, '@');
- CPPUNIT_ASSERT_EQUAL(std::string("ab"), result.first);
- CPPUNIT_ASSERT_EQUAL(std::string("cd@ef"), result.second);
- }
-
- void testGetSplittedAtFirst_CharacterAtBegin() {
- std::string testling(" ab");
-
- std::pair<std::string,std::string> result = String::getSplittedAtFirst(testling, ' ');
- CPPUNIT_ASSERT(result.first.empty());
- CPPUNIT_ASSERT_EQUAL(std::string("ab"), result.second);
- }
-
- void testGetSplittedAtFirst_CharacterAtEnd() {
- std::string testling("ab@");
-
- std::pair<std::string,std::string> result = String::getSplittedAtFirst(testling, '@');
- CPPUNIT_ASSERT_EQUAL(std::string("ab"), result.first);
- CPPUNIT_ASSERT(result.second.empty());
- }
-
- void testGetSplittedAtFirst_NoSuchCharacter() {
- std::string testling("ab");
-
- std::pair<std::string,std::string> result = String::getSplittedAtFirst(testling, '@');
- CPPUNIT_ASSERT_EQUAL(std::string("ab"), result.first);
- CPPUNIT_ASSERT(result.second.empty());
- }
-
- void testReplaceAll() {
- std::string testling("abcbd");
-
- String::replaceAll(testling, 'b', "xyz");
-
- CPPUNIT_ASSERT_EQUAL(std::string("axyzcxyzd"), testling);
- }
-
- void testReplaceAll_LastChar() {
- std::string testling("abc");
-
- String::replaceAll(testling, 'c', "xyz");
-
- CPPUNIT_ASSERT_EQUAL(std::string("abxyz"), testling);
- }
-
- void testReplaceAll_ConsecutiveChars() {
- std::string testling("abbc");
-
- String::replaceAll(testling, 'b',"xyz");
-
- CPPUNIT_ASSERT_EQUAL(std::string("axyzxyzc"), testling);
- }
-
- void testReplaceAll_MatchingReplace() {
- std::string testling("abc");
-
- String::replaceAll(testling, 'b',"bbb");
-
- CPPUNIT_ASSERT_EQUAL(std::string("abbbc"), testling);
- }
-
- void testSplit() {
- std::vector<std::string> result = String::split("abc def ghi", ' ');
+ CPPUNIT_TEST_SUITE_END();
- CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(result.size()));
- CPPUNIT_ASSERT_EQUAL(std::string("abc"), result[0]);
- CPPUNIT_ASSERT_EQUAL(std::string("def"), result[1]);
- CPPUNIT_ASSERT_EQUAL(std::string("ghi"), result[2]);
- }
+ public:
+ void testGetUnicodeCodePoints() {
+ std::string testling("$\xc2\xa2\xe2\x82\xac\xf4\x8a\xaf\x8d");
+ std::vector<unsigned int> points = String::getUnicodeCodePoints(testling);
+
+ CPPUNIT_ASSERT_EQUAL(0x24U, points[0]);
+ CPPUNIT_ASSERT_EQUAL(0xA2U, points[1]);
+ CPPUNIT_ASSERT_EQUAL(0x20ACU, points[2]);
+ CPPUNIT_ASSERT_EQUAL(0x10ABCDU, points[3]);
+ }
+
+ void testGetSplittedAtFirst() {
+ std::string testling("ab@cd@ef");
+
+ std::pair<std::string,std::string> result = String::getSplittedAtFirst(testling, '@');
+ CPPUNIT_ASSERT_EQUAL(std::string("ab"), result.first);
+ CPPUNIT_ASSERT_EQUAL(std::string("cd@ef"), result.second);
+ }
+
+ void testGetSplittedAtFirst_CharacterAtBegin() {
+ std::string testling(" ab");
+
+ std::pair<std::string,std::string> result = String::getSplittedAtFirst(testling, ' ');
+ CPPUNIT_ASSERT(result.first.empty());
+ CPPUNIT_ASSERT_EQUAL(std::string("ab"), result.second);
+ }
+
+ void testGetSplittedAtFirst_CharacterAtEnd() {
+ std::string testling("ab@");
+
+ std::pair<std::string,std::string> result = String::getSplittedAtFirst(testling, '@');
+ CPPUNIT_ASSERT_EQUAL(std::string("ab"), result.first);
+ CPPUNIT_ASSERT(result.second.empty());
+ }
+
+ void testGetSplittedAtFirst_NoSuchCharacter() {
+ std::string testling("ab");
+
+ std::pair<std::string,std::string> result = String::getSplittedAtFirst(testling, '@');
+ CPPUNIT_ASSERT_EQUAL(std::string("ab"), result.first);
+ CPPUNIT_ASSERT(result.second.empty());
+ }
+
+ void testReplaceAll() {
+ std::string testling("abcbd");
+
+ String::replaceAll(testling, 'b', "xyz");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("axyzcxyzd"), testling);
+ }
+
+ void testReplaceAll_LastChar() {
+ std::string testling("abc");
+
+ String::replaceAll(testling, 'c', "xyz");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("abxyz"), testling);
+ }
+
+ void testReplaceAll_ConsecutiveChars() {
+ std::string testling("abbc");
+
+ String::replaceAll(testling, 'b',"xyz");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("axyzxyzc"), testling);
+ }
+
+ void testReplaceAll_MatchingReplace() {
+ std::string testling("abc");
+
+ String::replaceAll(testling, 'b',"bbb");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("abbbc"), testling);
+ }
+
+ void testIsValidXMPPCharacter() {
+ const std::uint32_t testCharacters[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x7F, 0x80, 0x84, 0x85, 0xFF };
+ const auto testLength = sizeof(testCharacters) / sizeof(std::uint32_t);
+ const bool expectedValid[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1, 1 };
+ static_assert(testLength == sizeof(expectedValid), "size of test data must match");
+
+ for (std::size_t i = 0; i != testLength; ++i) {
+ const auto c = testCharacters[i];
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(boost::str(boost::format("While testing at idx=%d: 0x%02x") % i % c), expectedValid[i], String::isValidXMPPCharacter(c));
+ }
+ }
+
+ void testSanitizeXMPPString() {
+ std::vector<std::pair<std::string, std::string>> testData = {
+ { "\0", "" },
+ { std::string("\0\t", 3), "\t" },
+ { "", "" },
+ { std::string("\0", 1) , std::string() },
+ { std::string("\0blah\0", 6) , std::string("blah", 4) },
+ { "z\xC3\x9F\xE6\xB0\xB4\xF0\x9D\x84\x8B" , "z\xC3\x9F\xE6\xB0\xB4\xF0\x9D\x84\x8B" }, // or in u8 notation: u8"z\u00df\u6c34\U0001d10b"
+ { "\x7FT\t\x0c\xff\xfeT", "T\tT" },
+ { "\x01Q\x0BW\x81T", "QWT" },
+ { "\xF0\x9F\x98\x83" "ABC" "\xE2\xBE\xA6", "\xF0\x9F\x98\x83" "ABC" "\xE2\xBE\xA6" }
+ };
+
+ for (std::size_t i = 0; i != testData.size(); ++i) {
+ const auto & t = testData[i];
+ const auto actual = String::sanitizeXMPPString(t.first);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(boost::str(boost::format("While testing string idx=%d") % i), std::string(actual), t.second);
+ }
+ }
+
+ void testSplit() {
+ std::vector<std::string> result = String::split("abc def ghi", ' ');
+
+ CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(result.size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("abc"), result[0]);
+ CPPUNIT_ASSERT_EQUAL(std::string("def"), result[1]);
+ CPPUNIT_ASSERT_EQUAL(std::string("ghi"), result[2]);
+ }
#ifdef SWIFTEN_PLATFORM_WINDOWS
- void testConvertWStringToString() {
- CPPUNIT_ASSERT_EQUAL(std::string("tron\xc3\xa7on"), convertWStringToString(std::wstring(L"tron\xe7on")));
- }
+ void testConvertWStringToString() {
+ CPPUNIT_ASSERT_EQUAL(std::string("tron\xc3\xa7on"), convertWStringToString(std::wstring(L"tron\xe7on")));
+ }
- void testConvertStringToWString() {
- CPPUNIT_ASSERT(std::wstring(L"tron\xe7on") == convertStringToWString(std::string("tron\xc3\xa7on")));
- }
+ void testConvertStringToWString() {
+ CPPUNIT_ASSERT(std::wstring(L"tron\xe7on") == convertStringToWString(std::string("tron\xc3\xa7on")));
+ }
#endif
};
diff --git a/Swiften/Base/UnitTest/URLTest.cpp b/Swiften/Base/UnitTest/URLTest.cpp
index e82321f..da9f15c 100644
--- a/Swiften/Base/UnitTest/URLTest.cpp
+++ b/Swiften/Base/UnitTest/URLTest.cpp
@@ -1,114 +1,238 @@
/*
- * Copyright (c) 2012 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2012-2018 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
+#include <boost/lexical_cast.hpp>
+
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <Swiften/Base/URL.h>
-#include <boost/lexical_cast.hpp>
using namespace Swift;
class URLTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(URLTest);
- CPPUNIT_TEST(testFromString);
- CPPUNIT_TEST(testFromString_WithoutPath);
- CPPUNIT_TEST(testFromString_WithRootPath);
- CPPUNIT_TEST(testFromString_WithPort);
- CPPUNIT_TEST(testFromString_WithPortOnePartPath);
- CPPUNIT_TEST(testFromString_WithPortWithoutPath);
- CPPUNIT_TEST(testFromString_WithUserInfo);
- CPPUNIT_TEST(testFromString_NonASCIIHost);
- CPPUNIT_TEST(testFromString_NonASCIIPath);
- CPPUNIT_TEST(testToString);
- CPPUNIT_TEST(testToString_WithPort);
- CPPUNIT_TEST_SUITE_END();
-
- public:
- void testFromString() {
- URL url = URL::fromString("http://foo.bar/baz/bam");
-
- CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
- CPPUNIT_ASSERT_EQUAL(std::string("foo.bar"), url.getHost());
- CPPUNIT_ASSERT(!url.getPort());
- CPPUNIT_ASSERT_EQUAL(std::string("/baz/bam"), url.getPath());
- }
-
- void testFromString_WithoutPath() {
- URL url = URL::fromString("http://foo.bar");
-
- CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
- CPPUNIT_ASSERT_EQUAL(std::string("foo.bar"), url.getHost());
- CPPUNIT_ASSERT(!url.getPort());
- CPPUNIT_ASSERT_EQUAL(std::string(""), url.getPath());
- }
-
- void testFromString_WithRootPath() {
- URL url = URL::fromString("http://foo.bar/");
-
- CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
- CPPUNIT_ASSERT_EQUAL(std::string("foo.bar"), url.getHost());
- CPPUNIT_ASSERT(!url.getPort());
- CPPUNIT_ASSERT_EQUAL(std::string("/"), url.getPath());
- }
-
- void testFromString_WithPort() {
- URL url = URL::fromString("http://foo.bar:1234/baz/bam");
-
- CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
- CPPUNIT_ASSERT_EQUAL(std::string("foo.bar"), url.getHost());
- CPPUNIT_ASSERT_EQUAL(1234, *url.getPort());
- CPPUNIT_ASSERT_EQUAL(std::string("/baz/bam"), url.getPath());
- }
-
- void testFromString_WithPortOnePartPath() {
- URL url = URL::fromString("http://foo.bar:11440/http-bind/");
-
- CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
- CPPUNIT_ASSERT_EQUAL(std::string("foo.bar"), url.getHost());
- CPPUNIT_ASSERT_EQUAL(11440, *url.getPort());
- CPPUNIT_ASSERT_EQUAL(std::string("/http-bind/"), url.getPath());
- }
-
- void testFromString_WithPortWithoutPath() {
- URL url = URL::fromString("http://foo.bar:1234");
-
- CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
- CPPUNIT_ASSERT_EQUAL(std::string("foo.bar"), url.getHost());
- CPPUNIT_ASSERT_EQUAL(1234, *url.getPort());
- CPPUNIT_ASSERT_EQUAL(std::string(""), url.getPath());
- }
-
- void testFromString_WithUserInfo() {
- URL url = URL::fromString("http://user:pass@foo.bar/baz/bam");
-
- CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
- CPPUNIT_ASSERT_EQUAL(std::string("foo.bar"), url.getHost());
- CPPUNIT_ASSERT_EQUAL(std::string("/baz/bam"), url.getPath());
- }
-
- void testFromString_NonASCIIHost() {
- URL url = URL::fromString("http://www.tron%C3%A7on.be/baz/bam");
-
- CPPUNIT_ASSERT_EQUAL(std::string("www.tron\xc3\xa7on.be"), url.getHost());
- }
-
- void testFromString_NonASCIIPath() {
- URL url = URL::fromString("http://foo.bar/baz/tron%C3%A7on/bam");
-
- CPPUNIT_ASSERT_EQUAL(std::string("/baz/tron\xc3\xa7on/bam"), url.getPath());
- }
-
- void testToString() {
- CPPUNIT_ASSERT_EQUAL(std::string("http://foo.bar/baz/bam"), URL("http", "foo.bar", "/baz/bam").toString());
- }
-
- void testToString_WithPort() {
- CPPUNIT_ASSERT_EQUAL(std::string("http://foo.bar:1234/baz/bam"), URL("http", "foo.bar", 1234, "/baz/bam").toString());
- }
+ CPPUNIT_TEST_SUITE(URLTest);
+ CPPUNIT_TEST(testFromString);
+ CPPUNIT_TEST(testFromString_WithoutPath);
+ CPPUNIT_TEST(testFromString_WithRootPath);
+ CPPUNIT_TEST(testFromString_WithPort);
+ CPPUNIT_TEST(testFromString_WithPortOnePartPath);
+ CPPUNIT_TEST(testFromString_WithPortWithoutPath);
+ CPPUNIT_TEST(testFromString_WithUserInfo);
+ CPPUNIT_TEST(testFromString_NonASCIIHost);
+ CPPUNIT_TEST(testFromString_NonASCIIPath);
+ CPPUNIT_TEST(testFromString_IPv4Address);
+ CPPUNIT_TEST(testFromString_IPv4AddressWithPort);
+ CPPUNIT_TEST(testFromString_IPv6Address);
+ CPPUNIT_TEST(testFromString_IPv6AddressWithPort);
+ CPPUNIT_TEST(testToString);
+ CPPUNIT_TEST(testToString_WithPort);
+ CPPUNIT_TEST(test_FromString_ToString_IPv6RFC2732);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void testFromString() {
+ URL url = URL::fromString("http://foo.bar/baz/bam");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("foo.bar"), url.getHost());
+ CPPUNIT_ASSERT(!url.getPort());
+ CPPUNIT_ASSERT_EQUAL(std::string("/baz/bam"), url.getPath());
+ }
+
+ void testFromString_WithoutPath() {
+ URL url = URL::fromString("http://foo.bar");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("foo.bar"), url.getHost());
+ CPPUNIT_ASSERT(!url.getPort());
+ CPPUNIT_ASSERT_EQUAL(std::string(""), url.getPath());
+ }
+
+ void testFromString_WithRootPath() {
+ URL url = URL::fromString("http://foo.bar/");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("foo.bar"), url.getHost());
+ CPPUNIT_ASSERT(!url.getPort());
+ CPPUNIT_ASSERT_EQUAL(std::string("/"), url.getPath());
+ }
+
+ void testFromString_WithPort() {
+ URL url = URL::fromString("http://foo.bar:1234/baz/bam");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("foo.bar"), url.getHost());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(1234), *url.getPort());
+ CPPUNIT_ASSERT_EQUAL(std::string("/baz/bam"), url.getPath());
+ }
+
+ void testFromString_WithPortOnePartPath() {
+ URL url = URL::fromString("http://foo.bar:11440/http-bind/");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("foo.bar"), url.getHost());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(11440), *url.getPort());
+ CPPUNIT_ASSERT_EQUAL(std::string("/http-bind/"), url.getPath());
+ }
+
+ void testFromString_WithPortWithoutPath() {
+ URL url = URL::fromString("http://foo.bar:1234");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("foo.bar"), url.getHost());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(1234), *url.getPort());
+ CPPUNIT_ASSERT_EQUAL(std::string(""), url.getPath());
+ }
+
+ void testFromString_WithUserInfo() {
+ URL url = URL::fromString("http://user:pass@foo.bar/baz/bam");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("foo.bar"), url.getHost());
+ CPPUNIT_ASSERT_EQUAL(std::string("/baz/bam"), url.getPath());
+ }
+
+ void testFromString_NonASCIIHost() {
+ URL url = URL::fromString("http://www.tron%C3%A7on.be/baz/bam");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("www.tron\xc3\xa7on.be"), url.getHost());
+ }
+
+ void testFromString_NonASCIIPath() {
+ URL url = URL::fromString("http://foo.bar/baz/tron%C3%A7on/bam");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("/baz/tron\xc3\xa7on/bam"), url.getPath());
+ }
+
+ void testFromString_IPv4Address() {
+ URL url = URL::fromString("http://127.0.0.1/foobar");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("127.0.0.1"), url.getHost());
+ CPPUNIT_ASSERT_EQUAL(std::string("/foobar"), url.getPath());
+ }
+
+ void testFromString_IPv4AddressWithPort() {
+ URL url = URL::fromString("http://127.0.0.1:12345/foobar");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("127.0.0.1"), url.getHost());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(12345), url.getPort().get_value_or(0));
+ CPPUNIT_ASSERT_EQUAL(std::string("/foobar"), url.getPath());
+ }
+
+ void testFromString_IPv6Address() {
+ URL url = URL::fromString("http://[fdf8:f53b:82e4::53]/foobar");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("fdf8:f53b:82e4::53"), url.getHost());
+ }
+
+ void testFromString_IPv6AddressWithPort() {
+ URL url = URL::fromString("http://[fdf8:f53b:82e4::53]:12435/foobar");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("fdf8:f53b:82e4::53"), url.getHost());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(12435), url.getPort().get_value_or(0));
+ }
+
+ void test_FromString_ToString_IPv6RFC2732() {
+ {
+ const char* testVector = "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html";
+ URL url = URL::fromString(testVector);
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210"), url.getHost());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(80), url.getPort().get_value_or(2));
+ CPPUNIT_ASSERT_EQUAL(std::string("/index.html"), url.getPath());
+
+ CPPUNIT_ASSERT_EQUAL(std::string(testVector), url.toString());
+ }
+
+ {
+ const char* testVector = "http://[1080:0:0:0:8:800:200C:417A]/index.html";
+ URL url = URL::fromString(testVector);
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("1080:0:0:0:8:800:200C:417A"), url.getHost());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(2), url.getPort().get_value_or(2));
+ CPPUNIT_ASSERT_EQUAL(std::string("/index.html"), url.getPath());
+
+ CPPUNIT_ASSERT_EQUAL(std::string(testVector), url.toString());
+ }
+
+ {
+ const char* testVector = "http://[3ffe:2a00:100:7031::1]";
+ URL url = URL::fromString(testVector);
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("3ffe:2a00:100:7031::1"), url.getHost());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(2), url.getPort().get_value_or(2));
+ CPPUNIT_ASSERT_EQUAL(std::string(""), url.getPath());
+
+ CPPUNIT_ASSERT_EQUAL(std::string(testVector), url.toString());
+ }
+
+ {
+ const char* testVector = "http://[1080::8:800:200C:417A]/foo";
+ URL url = URL::fromString(testVector);
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("1080::8:800:200C:417A"), url.getHost());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(2), url.getPort().get_value_or(2));
+ CPPUNIT_ASSERT_EQUAL(std::string("/foo"), url.getPath());
+
+ CPPUNIT_ASSERT_EQUAL(std::string(testVector), url.toString());
+ }
+
+ {
+ const char* testVector = "http://[::192.9.5.5]/ipng";
+ URL url = URL::fromString(testVector);
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("::192.9.5.5"), url.getHost());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(2), url.getPort().get_value_or(2));
+ CPPUNIT_ASSERT_EQUAL(std::string("/ipng"), url.getPath());
+
+ CPPUNIT_ASSERT_EQUAL(std::string(testVector), url.toString());
+ }
+
+ {
+ const char* testVector = "http://[::FFFF:129.144.52.38]:80/index.html";
+ URL url = URL::fromString(testVector);
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("::FFFF:129.144.52.38"), url.getHost());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(80), url.getPort().get_value_or(2));
+ CPPUNIT_ASSERT_EQUAL(std::string("/index.html"), url.getPath());
+
+ CPPUNIT_ASSERT_EQUAL(std::string(testVector), url.toString());
+ }
+
+ {
+ const char* testVector = "http://[2010:836B:4179::836B:4179]";
+ URL url = URL::fromString(testVector);
+
+ CPPUNIT_ASSERT_EQUAL(std::string("http"), url.getScheme());
+ CPPUNIT_ASSERT_EQUAL(std::string("2010:836B:4179::836B:4179"), url.getHost());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(2), url.getPort().get_value_or(2));
+ CPPUNIT_ASSERT_EQUAL(std::string(), url.getPath());
+
+ CPPUNIT_ASSERT_EQUAL(std::string(testVector), url.toString());
+ }
+ }
+
+ void testToString() {
+ CPPUNIT_ASSERT_EQUAL(std::string("http://foo.bar/baz/bam"), URL("http", "foo.bar", "/baz/bam").toString());
+ }
+
+ void testToString_WithPort() {
+ CPPUNIT_ASSERT_EQUAL(std::string("http://foo.bar:1234/baz/bam"), URL("http", "foo.bar", 1234, "/baz/bam").toString());
+ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(URLTest);
diff --git a/Swiften/Base/WindowsRegistry.h b/Swiften/Base/WindowsRegistry.h
index 11a26b3..6243dd2 100644
--- a/Swiften/Base/WindowsRegistry.h
+++ b/Swiften/Base/WindowsRegistry.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2012 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2012 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
@@ -9,49 +9,49 @@
#include <windows.h>
namespace Swift {
- class WindowsRegistry {
- public:
- static bool isFIPSEnabled() {
- char* pathForXP = "System\\CurrentControlSet\\Control\\Lsa";
- char* pathSinceVista = "System\\CurrentControlSet\\Control\\Lsa\\FIPSAlgorithmPolicy";
- char* keyForXP = "FIPSAlgorithmPolicy";
- char* keySinceVista = "Enabled";
-
- OSVERSIONINFO osvi;
- ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&osvi);
-
- char* keyForOS = osvi.dwMajorVersion < 6 ? keyForXP : keySinceVista;
- char* pathForOS = osvi.dwMajorVersion < 6 ? pathForXP : pathSinceVista;
-
- /* http://support.microsoft.com/kb/811833 */
- /* http://msdn.microsoft.com/en-us/library/ms724911%28VS.85%29.aspx */
- HKEY key;
- bool result = false;
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- pathForOS,
- 0,
- KEY_READ,
- &key) != ERROR_SUCCESS) {
- /* If we can't find the key that says we're FIPS, we're not FIPS */
- return result;
- }
- DWORD keyType = REG_DWORD;
- DWORD data;
- DWORD length = sizeof(data);
-
- if (RegQueryValueEx(key,
- keyForOS,
- NULL,
- &keyType,
- (LPBYTE)&data,
- &length) == ERROR_SUCCESS) {
- result = data != 0;
- }
-
- RegCloseKey(key);
- return result;
- }
- };
+ class WindowsRegistry {
+ public:
+ static bool isFIPSEnabled() {
+ char* pathForXP = "System\\CurrentControlSet\\Control\\Lsa";
+ char* pathSinceVista = "System\\CurrentControlSet\\Control\\Lsa\\FIPSAlgorithmPolicy";
+ char* keyForXP = "FIPSAlgorithmPolicy";
+ char* keySinceVista = "Enabled";
+
+ OSVERSIONINFO osvi;
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&osvi);
+
+ char* keyForOS = osvi.dwMajorVersion < 6 ? keyForXP : keySinceVista;
+ char* pathForOS = osvi.dwMajorVersion < 6 ? pathForXP : pathSinceVista;
+
+ /* http://support.microsoft.com/kb/811833 */
+ /* http://msdn.microsoft.com/en-us/library/ms724911%28VS.85%29.aspx */
+ HKEY key;
+ bool result = false;
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ pathForOS,
+ 0,
+ KEY_READ,
+ &key) != ERROR_SUCCESS) {
+ /* If we can't find the key that says we're FIPS, we're not FIPS */
+ return result;
+ }
+ DWORD keyType = REG_DWORD;
+ DWORD data;
+ DWORD length = sizeof(data);
+
+ if (RegQueryValueEx(key,
+ keyForOS,
+ NULL,
+ &keyType,
+ (LPBYTE)&data,
+ &length) == ERROR_SUCCESS) {
+ result = data != 0;
+ }
+
+ RegCloseKey(key);
+ return result;
+ }
+ };
}
diff --git a/Swiften/Base/boost_bsignals.h b/Swiften/Base/boost_bsignals.h
deleted file mode 100644
index 7609c94..0000000
--- a/Swiften/Base/boost_bsignals.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-// Work around for the boost::signals / Qt signals keyword clash.
-// Based on an example from Frank Hess, improved by Niels Dekker
-
-#pragma once
-
-#if defined(signals) && defined(Q_SIGNALS) && !defined(QT_MOC_CPP)
-#undef signals
-#define signals signals
-#endif
-
-#include <boost/signal.hpp>
-
-namespace boost {
- namespace bsignals = signals;
-}
-
-#if defined(signals) && defined(Q_SIGNALS) && !defined(QT_MOC_CPP)
-#undef signals
-#define signals Q_SIGNALS
-#endif
diff --git a/Swiften/Base/foreach.h b/Swiften/Base/foreach.h
deleted file mode 100644
index 3ad506d..0000000
--- a/Swiften/Base/foreach.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#include <boost/foreach.hpp>
-
-#undef foreach
-#define foreach BOOST_FOREACH
-#define reverse_foreach BOOST_REVERSE_FOREACH
diff --git a/Swiften/Base/format.h b/Swiften/Base/format.h
index 0e49eaa..e5696b0 100644
--- a/Swiften/Base/format.h
+++ b/Swiften/Base/format.h
@@ -1,25 +1,26 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
-#include <boost/format.hpp>
#include <iostream>
+#include <boost/format.hpp>
+
namespace Swift {
- inline boost::format format(const std::string& s) {
- using namespace boost::io;
- try {
- boost::format fmter(s);
- fmter.exceptions(no_error_bits);
- return fmter;
- }
- catch (...) {
- std::cerr << "Error: Invalid translation: " << s << std::endl;
- throw;
- }
- }
+ inline boost::format format(const std::string& s) {
+ using namespace boost::io;
+ try {
+ boost::format fmter(s);
+ fmter.exceptions(no_error_bits);
+ return fmter;
+ }
+ catch (...) {
+ std::cerr << "Error: Invalid translation: " << s << std::endl;
+ throw;
+ }
+ }
}
diff --git a/Swiften/Base/sleep.cpp b/Swiften/Base/sleep.cpp
index 0f1937b..48eae51 100644
--- a/Swiften/Base/sleep.cpp
+++ b/Swiften/Base/sleep.cpp
@@ -1,25 +1,18 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <Swiften/Base/sleep.h>
-#include <boost/thread.hpp>
-#include <boost/version.hpp>
+#include <chrono>
+#include <thread>
namespace Swift {
void sleep(unsigned int msecs) {
- boost::xtime xt;
-#if BOOST_VERSION >= 105000
- boost::xtime_get(&xt, boost::TIME_UTC_);
-#else
- boost::xtime_get(&xt, boost::TIME_UTC);
-#endif
- xt.nsec += msecs*1000000;
- boost::thread::sleep(xt);
+ std::this_thread::sleep_for(std::chrono::milliseconds(msecs));
}
}
diff --git a/Swiften/Base/sleep.h b/Swiften/Base/sleep.h
index afcf6c7..744e19f 100644
--- a/Swiften/Base/sleep.h
+++ b/Swiften/Base/sleep.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
@@ -9,5 +9,5 @@
#include <Swiften/Base/API.h>
namespace Swift {
- SWIFTEN_API void sleep(unsigned int msecs);
+ SWIFTEN_API void sleep(unsigned int msecs);
}