summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Base')
-rw-r--r--Swiften/Base/Algorithm.h149
-rw-r--r--Swiften/Base/ByteArray.cpp49
-rw-r--r--Swiften/Base/ByteArray.h140
-rw-r--r--Swiften/Base/Concat.h73
-rw-r--r--Swiften/Base/DateTime.cpp34
-rw-r--r--Swiften/Base/DateTime.h22
-rw-r--r--Swiften/Base/Error.cpp2
-rw-r--r--Swiften/Base/IDGenerator.cpp28
-rw-r--r--Swiften/Base/IDGenerator.h8
-rw-r--r--Swiften/Base/Log.cpp2
-rw-r--r--Swiften/Base/Paths.cpp12
-rw-r--r--Swiften/Base/Paths.h2
-rw-r--r--Swiften/Base/Platform.h9
-rw-r--r--Swiften/Base/SConscript2
-rw-r--r--Swiften/Base/SafeAllocator.h30
-rw-r--r--Swiften/Base/SafeByteArray.cpp22
-rw-r--r--Swiften/Base/SafeByteArray.h58
-rw-r--r--Swiften/Base/SafeString.h32
-rw-r--r--Swiften/Base/String.h19
-rw-r--r--Swiften/Base/UnitTest/ByteArrayTest.cpp33
-rw-r--r--Swiften/Base/UnitTest/DateTimeTest.cpp43
-rw-r--r--Swiften/Base/UnitTest/IDGeneratorTest.cpp2
-rw-r--r--Swiften/Base/foreach.h5
-rw-r--r--Swiften/Base/format.h1
-rw-r--r--Swiften/Base/sleep.cpp2
-rw-r--r--Swiften/Base/sleep.h5
26 files changed, 594 insertions, 190 deletions
diff --git a/Swiften/Base/Algorithm.h b/Swiften/Base/Algorithm.h
new file mode 100644
index 0000000..4e68e70
--- /dev/null
+++ b/Swiften/Base/Algorithm.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <vector>
+#include <list>
+#include <map>
+#include <algorithm>
+
+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 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;
+ };
+}
diff --git a/Swiften/Base/ByteArray.cpp b/Swiften/Base/ByteArray.cpp
index 928e145..6be96aa 100644
--- a/Swiften/Base/ByteArray.cpp
+++ b/Swiften/Base/ByteArray.cpp
@@ -4,37 +4,46 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#include "Swiften/Base/ByteArray.h"
+#include <Swiften/Base/ByteArray.h>
#include <fstream>
-std::ostream& operator<<(std::ostream& os, const Swift::ByteArray& s) {
- std::ios::fmtflags oldFlags = os.flags();
- os << std::hex;
- for (Swift::ByteArray::const_iterator i = s.begin(); i != s.end(); ++i) {
- os << "0x" << static_cast<unsigned int>(static_cast<unsigned char>(*i));
- if (i + 1 < s.end()) {
- os << " ";
- }
- }
- os << std::endl;
- os.flags(oldFlags);
- return os;
-}
-
namespace Swift {
static const int BUFFER_SIZE = 4096;
-void ByteArray::readFromFile(const std::string& file) {
+void readByteArrayFromFile(ByteArray& data, const std::string& file) {
std::ifstream input(file.c_str(), 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 + input.gcount());
+ size_t oldSize = data.size();
+ data.resize(oldSize + BUFFER_SIZE);
+ input.read(reinterpret_cast<char*>(&data[oldSize]), BUFFER_SIZE);
+ data.resize(oldSize + input.gcount());
}
input.close();
}
+std::vector<unsigned char> createByteArray(const std::string& s) {
+ 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::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) : "";
+}
+
}
diff --git a/Swiften/Base/ByteArray.h b/Swiften/Base/ByteArray.h
index ad2c1e5..b368ef8 100644
--- a/Swiften/Base/ByteArray.h
+++ b/Swiften/Base/ByteArray.h
@@ -6,135 +6,39 @@
#pragma once
-#include <cstring>
#include <vector>
-#include <iostream>
-
#include <string>
namespace Swift {
- class ByteArray
- {
- public:
- typedef std::vector<unsigned char>::const_iterator const_iterator;
-
- ByteArray() : data_() {}
-
- ByteArray(const std::string& s) : data_(s.begin(), s.end()) {}
-
- ByteArray(const char* c) {
- while (*c) {
- data_.push_back(*c);
- ++c;
- }
- }
-
- ByteArray(const char* c, size_t n) {
- if (n > 0) {
- data_.resize(n);
- memcpy(&data_[0], c, n);
- }
- }
-
- ByteArray(const unsigned char* c, size_t n) {
- if (n > 0) {
- data_.resize(n);
- memcpy(&data_[0], c, n);
- }
- }
-
- ByteArray(const std::vector<unsigned char>& data) : data_(data) {
- }
-
- const unsigned char* getData() const {
- return data_.empty() ? NULL : &data_[0];
- }
-
- unsigned char* getData() {
- return data_.empty() ? NULL : &data_[0];
- }
-
- const std::vector<unsigned char>& getVector() const {
- return data_;
- }
-
- std::vector<unsigned char>& getVector() {
- return data_;
- }
-
- size_t getSize() const {
- return data_.size();
- }
-
- bool isEmpty() const {
- return data_.empty();
- }
-
- void resize(size_t size) {
- return data_.resize(size);
- }
-
- void resize(size_t size, char c) {
- return data_.resize(size, c);
- }
-
- friend ByteArray operator+(const ByteArray& a, const ByteArray&b) {
- ByteArray result(a);
- result.data_.insert(result.data_.end(), b.data_.begin(), b.data_.end());
- return result;
- }
-
- friend ByteArray operator+(const ByteArray& a, char b) {
- ByteArray x;
- x.resize(1);
- x[0] = b;
- return a + x;
- }
-
- ByteArray& operator+=(const ByteArray& b) {
- data_.insert(data_.end(), b.data_.begin(), b.data_.end());
- return *this;
- }
-
- ByteArray& operator+=(char c) {
- data_.push_back(c);
- return *this;
- }
-
- friend bool operator==(const ByteArray& a, const ByteArray& b) {
- return a.data_ == b.data_;
- }
+ typedef std::vector<unsigned char> ByteArray;
+ ByteArray createByteArray(const std::string& s);
+ ByteArray createByteArray(const char* c);
- const unsigned char& operator[](size_t i) const {
- return data_[i];
- }
+ inline ByteArray createByteArray(const unsigned char* c, size_t n) {
+ return ByteArray(c, c + n);
+ }
- unsigned char& operator[](size_t i) {
- return data_[i];
- }
+ inline ByteArray createByteArray(const char* c, size_t n) {
+ return ByteArray(c, c + n);
+ }
- const_iterator begin() const {
- return data_.begin();
- }
-
- const_iterator end() const {
- return data_.end();
- }
+ inline ByteArray createByteArray(char c) {
+ return std::vector<unsigned char>(1, c);
+ }
- std::string toString() const {
- return std::string(reinterpret_cast<const char*>(getData()), getSize());
- }
+ template<typename T, typename A>
+ static const T* vecptr(const std::vector<T, A>& v) {
+ return v.empty() ? NULL : &v[0];
+ }
- void readFromFile(const std::string& file);
+ template<typename T, typename A>
+ static T* vecptr(std::vector<T, A>& v) {
+ return v.empty() ? NULL : &v[0];
+ }
- void clear() {
- data_.clear();
- }
+ std::string byteArrayToString(const ByteArray& b);
- private:
- std::vector<unsigned char> data_;
- };
+ void readByteArrayFromFile(ByteArray&, const std::string& file);
}
-std::ostream& operator<<(std::ostream& os, const Swift::ByteArray& s);
diff --git a/Swiften/Base/Concat.h b/Swiften/Base/Concat.h
new file mode 100644
index 0000000..83a43b6
--- /dev/null
+++ b/Swiften/Base/Concat.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+}
diff --git a/Swiften/Base/DateTime.cpp b/Swiften/Base/DateTime.cpp
new file mode 100644
index 0000000..fae26d4
--- /dev/null
+++ b/Swiften/Base/DateTime.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Base/DateTime.h>
+
+#include <locale>
+#include <boost/date_time/time_facet.hpp>
+#include <boost/date_time/local_time/local_time.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+#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();
+}
+
+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;
+}
+
+}
diff --git a/Swiften/Base/DateTime.h b/Swiften/Base/DateTime.h
new file mode 100644
index 0000000..2407ddc
--- /dev/null
+++ b/Swiften/Base/DateTime.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/date_time/posix_time/ptime.hpp>
+
+namespace Swift {
+ /**
+ * Converts a date formatted according to XEP-0082 into a ptime
+ * object (in UTC).
+ */
+ boost::posix_time::ptime stringToDateTime(const std::string& string);
+
+ /**
+ * Converts a UTC ptime object to a XEP-0082 formatted string.
+ */
+ std::string dateTimeToString(const boost::posix_time::ptime& time);
+}
diff --git a/Swiften/Base/Error.cpp b/Swiften/Base/Error.cpp
index dd127a6..60ad7ac 100644
--- a/Swiften/Base/Error.cpp
+++ b/Swiften/Base/Error.cpp
@@ -4,7 +4,7 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#include "Swiften/Base/Error.h"
+#include <Swiften/Base/Error.h>
namespace Swift {
diff --git a/Swiften/Base/IDGenerator.cpp b/Swiften/Base/IDGenerator.cpp
index 74a0f65..5556f7b 100644
--- a/Swiften/Base/IDGenerator.cpp
+++ b/Swiften/Base/IDGenerator.cpp
@@ -1,10 +1,15 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2011 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#include "Swiften/Base/IDGenerator.h"
+#include <Swiften/Base/IDGenerator.h>
+
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_io.hpp>
+#include <boost/uuid/uuid_generators.hpp>
+#include <boost/lexical_cast.hpp>
namespace Swift {
@@ -12,23 +17,8 @@ IDGenerator::IDGenerator() {
}
std::string IDGenerator::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_;
+ 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 4b6289b..44eeb76 100644
--- a/Swiften/Base/IDGenerator.h
+++ b/Swiften/Base/IDGenerator.h
@@ -4,8 +4,7 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#ifndef SWIFTEN_IDGenerator_H
-#define SWIFTEN_IDGenerator_H
+#pragma once
#include <string>
@@ -15,10 +14,5 @@ namespace Swift {
IDGenerator();
std::string generateID();
-
- private:
- std::string currentID_;
};
}
-
-#endif
diff --git a/Swiften/Base/Log.cpp b/Swiften/Base/Log.cpp
index 2041013..4132353 100644
--- a/Swiften/Base/Log.cpp
+++ b/Swiften/Base/Log.cpp
@@ -4,7 +4,7 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#include "Swiften/Base/Log.h"
+#include <Swiften/Base/Log.h>
namespace Swift {
diff --git a/Swiften/Base/Paths.cpp b/Swiften/Base/Paths.cpp
index 43eee57..b40f9b8 100644
--- a/Swiften/Base/Paths.cpp
+++ b/Swiften/Base/Paths.cpp
@@ -24,22 +24,22 @@ boost::filesystem::path Paths::getExecutablePath() {
ByteArray path;
uint32_t size = 4096;
path.resize(size);
- if (_NSGetExecutablePath(reinterpret_cast<char*>(path.getData()), &size) == 0) {
- return boost::filesystem::path(path.toString().c_str()).parent_path();
+ 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 = readlink("/proc/self/exe", reinterpret_cast<char*>(path.getData()), path.getSize());
+ size_t size = readlink("/proc/self/exe", reinterpret_cast<char*>(vecptr(path)), path.size());
if (size > 0) {
path.resize(size);
- return boost::filesystem::path(path.toString().c_str()).parent_path();
+ return boost::filesystem::path(std::string(reinterpret_cast<const char*>(vecptr(path)), path.size()).c_str()).parent_path();
}
#elif defined(SWIFTEN_PLATFORM_WINDOWS)
ByteArray data;
data.resize(2048);
- GetModuleFileName(NULL, reinterpret_cast<char*>(data.getData()), data.getSize());
- return boost::filesystem::path(data.toString().c_str()).parent_path();
+ GetModuleFileName(NULL, reinterpret_cast<char*>(vecptr(data)), data.size());
+ return boost::filesystem::path(std::string(reinterpret_cast<const char*>(vecptr(data)), data.size()).c_str()).parent_path();
#endif
return boost::filesystem::path();
}
diff --git a/Swiften/Base/Paths.h b/Swiften/Base/Paths.h
index 06c6aeb..8ac4640 100644
--- a/Swiften/Base/Paths.h
+++ b/Swiften/Base/Paths.h
@@ -6,7 +6,7 @@
#pragma once
-#include <boost/filesystem.hpp>
+#include <boost/filesystem/path.hpp>
namespace Swift {
class Paths {
diff --git a/Swiften/Base/Platform.h b/Swiften/Base/Platform.h
index 32e2671..395747c 100644
--- a/Swiften/Base/Platform.h
+++ b/Swiften/Base/Platform.h
@@ -4,8 +4,7 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#ifndef SWIFTEN_Platform_H
-#define SWIFTEN_Platform_H
+#pragma once
// Base platforms
#if defined(linux) || defined(__linux) || defined(__linux__)
@@ -26,6 +25,10 @@
#define SWIFTEN_PLATFORM_BEOS
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
#define SWIFTEN_PLATFORM_MACOSX
+#include <TargetConditionals.h>
+# if defined(TARGET_OS_IPHONE)
+# define SWIFTEN_PLATFORM_IPHONE
+# endif
#elif defined(__IBMCPP__) || defined(_AIX)
#define SWIFTEN_PLATFORM_AIX
#elif defined(__amigaos__)
@@ -46,5 +49,3 @@
#elif defined(BOOST_BIG_ENDIAN)
#define SWIFTEN_BIG_ENDIAN
#endif
-
-#endif
diff --git a/Swiften/Base/SConscript b/Swiften/Base/SConscript
index 01252e5..8752ea8 100644
--- a/Swiften/Base/SConscript
+++ b/Swiften/Base/SConscript
@@ -2,6 +2,8 @@ Import("swiften_env")
objects = swiften_env.SwiftenObject([
"ByteArray.cpp",
+ "DateTime.cpp",
+ "SafeByteArray.cpp",
"Error.cpp",
"Log.cpp",
"Paths.cpp",
diff --git a/Swiften/Base/SafeAllocator.h b/Swiften/Base/SafeAllocator.h
new file mode 100644
index 0000000..9f9dd42
--- /dev/null
+++ b/Swiften/Base/SafeAllocator.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <vector>
+#include <algorithm>
+
+namespace Swift {
+ 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) {
+ std::fill(reinterpret_cast<char*>(p), reinterpret_cast<char*>(p + num), 0);
+ std::allocator<T>::deallocate(p, num);
+ }
+ };
+};
diff --git a/Swiften/Base/SafeByteArray.cpp b/Swiften/Base/SafeByteArray.cpp
new file mode 100644
index 0000000..848b6d8
--- /dev/null
+++ b/Swiften/Base/SafeByteArray.cpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Base/SafeByteArray.h>
+
+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;
+}
+
+}
diff --git a/Swiften/Base/SafeByteArray.h b/Swiften/Base/SafeByteArray.h
new file mode 100644
index 0000000..1ef1d84
--- /dev/null
+++ b/Swiften/Base/SafeByteArray.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <vector>
+
+#include <Swiften/Base/SafeAllocator.h>
+#include <Swiften/Base/ByteArray.h>
+#include <boost/smart_ptr/make_shared.hpp>
+
+namespace Swift {
+ typedef std::vector<unsigned char, SafeAllocator<unsigned char> > SafeByteArray;
+
+ inline SafeByteArray createSafeByteArray(const ByteArray& a) {
+ return SafeByteArray(a.begin(), a.end());
+ }
+
+ SafeByteArray createSafeByteArray(const char* c);
+
+ 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 SafeByteArray createSafeByteArray(char c) {
+ return SafeByteArray(1, c);
+ }
+
+ 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 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);
+ }
+
+ /* 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
new file mode 100644
index 0000000..ef9c7cc
--- /dev/null
+++ b/Swiften/Base/SafeString.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Base/SafeByteArray.h>
+
+namespace Swift {
+ class SafeString {
+ public:
+ SafeString(const SafeByteArray& data) : data(data) {
+ }
+
+ SafeString(const std::string& s) {
+ data = createSafeByteArray(s);
+ }
+
+ SafeString(const char* s) {
+ data = createSafeByteArray(s);
+ }
+
+ operator SafeByteArray () const {
+ return data;
+ }
+
+ private:
+ SafeByteArray data;
+ };
+}
diff --git a/Swiften/Base/String.h b/Swiften/Base/String.h
index 192d53b..db6c28b 100644
--- a/Swiften/Base/String.h
+++ b/Swiften/Base/String.h
@@ -6,9 +6,9 @@
#pragma once
-#include <map>
#include <string>
#include <vector>
+#include <sstream>
#define SWIFTEN_STRING_TO_CFSTRING(a) \
CFStringCreateWithBytes(NULL, reinterpret_cast<const UInt8*>(a.c_str()), a.size(), kCFStringEncodingUTF8, false)
@@ -19,11 +19,28 @@ namespace Swift {
std::pair<std::string, std::string> getSplittedAtFirst(const std::string&, char c);
std::vector<std::string> split(const std::string&, char c);
void replaceAll(std::string&, char c, const std::string& s);
+
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;
}
};
+
+ class makeString {
+ public:
+ template <typename T> makeString& operator<<(T const& v) {
+ stream << v;
+ return *this;
+ }
+
+ operator std::string() const {
+ return stream.str();
+ }
+
+ private:
+ std::ostringstream stream;
+ };
}
diff --git a/Swiften/Base/UnitTest/ByteArrayTest.cpp b/Swiften/Base/UnitTest/ByteArrayTest.cpp
index cb10dd4..ecd0439 100644
--- a/Swiften/Base/UnitTest/ByteArrayTest.cpp
+++ b/Swiften/Base/UnitTest/ByteArrayTest.cpp
@@ -7,20 +7,49 @@
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
-#include "Swiften/Base/ByteArray.h"
+#include <Swiften/Base/ByteArray.h>
+#include <boost/lexical_cast.hpp>
using namespace Swift;
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();
public:
void testGetData_NoData() {
ByteArray testling;
- CPPUNIT_ASSERT_EQUAL(reinterpret_cast<const char*>(NULL), reinterpret_cast<const char*>(testling.getData()));
+ CPPUNIT_ASSERT_EQUAL(reinterpret_cast<const char*>(NULL), reinterpret_cast<const char*>(vecptr(testling)));
+ }
+
+ void testToString() {
+ ByteArray testling(createByteArray("abcde"));
+
+ CPPUNIT_ASSERT_EQUAL(std::string("abcde"), byteArrayToString(testling));
+ }
+
+ void testToString_NullTerminated() {
+ ByteArray testling(createByteArray("abcde\0", 6));
+
+ CPPUNIT_ASSERT_EQUAL(std::string("abcde"), byteArrayToString(testling));
+ }
+
+ void testToString_TwoNullTerminated() {
+ ByteArray testling(createByteArray("abcde\0\0", 7));
+
+ CPPUNIT_ASSERT_EQUAL(std::string("abcde"), byteArrayToString(testling));
+ }
+
+ void testToString_AllNull() {
+ ByteArray testling(createByteArray("\0\0", 2));
+
+ CPPUNIT_ASSERT_EQUAL(std::string(""), byteArrayToString(testling));
}
};
diff --git a/Swiften/Base/UnitTest/DateTimeTest.cpp b/Swiften/Base/UnitTest/DateTimeTest.cpp
new file mode 100644
index 0000000..8c3903a
--- /dev/null
+++ b/Swiften/Base/UnitTest/DateTimeTest.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt 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 <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();
+
+ 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));
+ }
+
+ 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));
+ }
+
+ void testDateTimeToString() {
+ boost::posix_time::ptime time = stringToDateTime("1969-07-20T21:56:15-05:00");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("1969-07-21T02:56:15Z"), dateTimeToString(time));
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DateTimeTest);
diff --git a/Swiften/Base/UnitTest/IDGeneratorTest.cpp b/Swiften/Base/UnitTest/IDGeneratorTest.cpp
index 4874684..610138f 100644
--- a/Swiften/Base/UnitTest/IDGeneratorTest.cpp
+++ b/Swiften/Base/UnitTest/IDGeneratorTest.cpp
@@ -8,7 +8,7 @@
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <set>
-#include "Swiften/Base/IDGenerator.h"
+#include <Swiften/Base/IDGenerator.h>
using namespace Swift;
diff --git a/Swiften/Base/foreach.h b/Swiften/Base/foreach.h
index 05366d6..87f6147 100644
--- a/Swiften/Base/foreach.h
+++ b/Swiften/Base/foreach.h
@@ -4,12 +4,9 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#ifndef SWIFTEN_FOREACH_H
-#define SWIFTEN_FOREACH_H
+#pragma once
#include <boost/foreach.hpp>
#undef foreach
#define foreach BOOST_FOREACH
-
-#endif
diff --git a/Swiften/Base/format.h b/Swiften/Base/format.h
index 4591827..0e49eaa 100644
--- a/Swiften/Base/format.h
+++ b/Swiften/Base/format.h
@@ -7,6 +7,7 @@
#pragma once
#include <boost/format.hpp>
+#include <iostream>
namespace Swift {
inline boost::format format(const std::string& s) {
diff --git a/Swiften/Base/sleep.cpp b/Swiften/Base/sleep.cpp
index 892a3ba..7161217 100644
--- a/Swiften/Base/sleep.cpp
+++ b/Swiften/Base/sleep.cpp
@@ -4,7 +4,7 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#include "Swiften/Base/sleep.h"
+#include <Swiften/Base/sleep.h>
#include <boost/thread.hpp>
diff --git a/Swiften/Base/sleep.h b/Swiften/Base/sleep.h
index c2bc601..a95e907 100644
--- a/Swiften/Base/sleep.h
+++ b/Swiften/Base/sleep.h
@@ -4,11 +4,8 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#ifndef SWIFTEN_sleep_H
-#define SWIFTEN_sleep_H
+#pragma once
namespace Swift {
void sleep(unsigned int msecs);
}
-
-#endif