diff options
Diffstat (limited to 'Swift/Controllers/Storages')
23 files changed, 843 insertions, 0 deletions
| diff --git a/Swift/Controllers/Storages/AvatarFileStorage.cpp b/Swift/Controllers/Storages/AvatarFileStorage.cpp new file mode 100644 index 0000000..b39e586 --- /dev/null +++ b/Swift/Controllers/Storages/AvatarFileStorage.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swift/Controllers/Storages/AvatarFileStorage.h> + +#include <iostream> +#include <boost/filesystem/fstream.hpp> +#include <boost/filesystem.hpp> + +#include <Swiften/Base/foreach.h> +#include <Swiften/Base/String.h> +#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/StringCodecs/Hexify.h> + +namespace Swift { + +AvatarFileStorage::AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile) : avatarsDir(avatarsDir), avatarsFile(avatarsFile) { +	if (boost::filesystem::exists(avatarsFile)) { +		try { +			boost::filesystem::ifstream file(avatarsFile); +			std::string line; +			if (file.is_open()) { +				while (!file.eof()) { +					getline(file, line); +					std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' '); +					JID jid(r.second); +					if (jid.isValid()) { +						jidAvatars.insert(std::make_pair(jid, r.first)); +					} +					else if (!r.first.empty() || !r.second.empty()) { +						std::cerr << "Invalid entry in avatars file: " << r.second << std::endl; +					} +				} +			} +		} +		catch (...) { +			std::cerr << "Error reading avatars file" << std::endl; +		} +	} +} + +bool AvatarFileStorage::hasAvatar(const std::string& hash) const {  +	return boost::filesystem::exists(getAvatarPath(hash)); +} + +void AvatarFileStorage::addAvatar(const std::string& hash, const ByteArray& avatar) { +	assert(Hexify::hexify(SHA1::getHash(avatar)) == hash); + +	boost::filesystem::path avatarPath = getAvatarPath(hash); +	if (!boost::filesystem::exists(avatarPath.parent_path())) { +		try { +			boost::filesystem::create_directories(avatarPath.parent_path()); +		} +		catch (const boost::filesystem::filesystem_error& e) { +			std::cerr << "ERROR: " << e.what() << std::endl; +		} +	} +	boost::filesystem::ofstream file(avatarPath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out); +	file.write(reinterpret_cast<const char*>(vecptr(avatar)), static_cast<std::streamsize>(avatar.size())); +	file.close(); +} + +boost::filesystem::path AvatarFileStorage::getAvatarPath(const std::string& hash) const { +	return avatarsDir / hash; +} + +ByteArray AvatarFileStorage::getAvatar(const std::string& hash) const { +	ByteArray data; +	readByteArrayFromFile(data, getAvatarPath(hash).string()); +	return data; +} + +void AvatarFileStorage::setAvatarForJID(const JID& jid, const std::string& hash) { +	std::pair<JIDAvatarMap::iterator, bool> r = jidAvatars.insert(std::make_pair(jid, hash)); +	if (r.second) { +		saveJIDAvatars(); +	} +	else if (r.first->second != hash) { +		r.first->second = hash; +		saveJIDAvatars(); +	} +} + +std::string AvatarFileStorage::getAvatarForJID(const JID& jid) const { +	JIDAvatarMap::const_iterator i = jidAvatars.find(jid); +	return i == jidAvatars.end() ? "" : i->second; +} + +void AvatarFileStorage::saveJIDAvatars() { +	try { +		boost::filesystem::ofstream file(avatarsFile); +		for (JIDAvatarMap::const_iterator i = jidAvatars.begin(); i != jidAvatars.end(); ++i) { +			file << i->second << " " << i->first.toString() << std::endl; +		} +		file.close(); +	} +	catch (...) { +		std::cerr << "Error writing avatars file" << std::endl; +	} +} + +} diff --git a/Swift/Controllers/Storages/AvatarFileStorage.h b/Swift/Controllers/Storages/AvatarFileStorage.h new file mode 100644 index 0000000..b7e73f5 --- /dev/null +++ b/Swift/Controllers/Storages/AvatarFileStorage.h @@ -0,0 +1,41 @@ +/* + * 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 <map> +#include <string> +#include <boost/filesystem/path.hpp> + +#include <Swiften/JID/JID.h> +#include "Swiften/Base/ByteArray.h" +#include "Swiften/Avatars/AvatarStorage.h" + +namespace Swift { +	class AvatarFileStorage : public AvatarStorage { +		public: +			AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile); + +			virtual bool hasAvatar(const std::string& hash) const; +			virtual void addAvatar(const std::string& hash, const ByteArray& avatar); +			virtual ByteArray getAvatar(const std::string& hash) const; + +			virtual boost::filesystem::path getAvatarPath(const std::string& hash) const; + +			virtual void setAvatarForJID(const JID& jid, const std::string& hash); +			virtual std::string getAvatarForJID(const JID& jid) const; + +		private: +			void saveJIDAvatars(); + +		private: +			boost::filesystem::path avatarsDir; +			boost::filesystem::path avatarsFile; +			typedef std::map<JID, std::string> JIDAvatarMap; +			JIDAvatarMap jidAvatars; +	}; + +} diff --git a/Swift/Controllers/Storages/CapsFileStorage.cpp b/Swift/Controllers/Storages/CapsFileStorage.cpp new file mode 100644 index 0000000..b7593fd --- /dev/null +++ b/Swift/Controllers/Storages/CapsFileStorage.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swift/Controllers/Storages/CapsFileStorage.h" + +#include <Swiften/Entity/GenericPayloadPersister.h> +#include "Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h" +#include "Swiften/Parser/PayloadParsers/DiscoInfoParser.h" +#include "Swiften/StringCodecs/Hexify.h" +#include "Swiften/StringCodecs/Base64.h" + +using namespace Swift; + +typedef GenericPayloadPersister<DiscoInfo, DiscoInfoParser, DiscoInfoSerializer> DiscoInfoPersister; + +CapsFileStorage::CapsFileStorage(const boost::filesystem::path& path) : path(path) { +} + +DiscoInfo::ref CapsFileStorage::getDiscoInfo(const std::string& hash) const { +	return DiscoInfoPersister().loadPayloadGeneric(getCapsPath(hash)); +} + +void CapsFileStorage::setDiscoInfo(const std::string& hash, DiscoInfo::ref discoInfo) { +	DiscoInfo::ref bareDiscoInfo(new DiscoInfo(*discoInfo.get())); +	bareDiscoInfo->setNode(""); +	DiscoInfoPersister().savePayload(bareDiscoInfo, getCapsPath(hash)); +} + +boost::filesystem::path CapsFileStorage::getCapsPath(const std::string& hash) const { +	return path / (Hexify::hexify(Base64::decode(hash)) + ".xml"); +} diff --git a/Swift/Controllers/Storages/CapsFileStorage.h b/Swift/Controllers/Storages/CapsFileStorage.h new file mode 100644 index 0000000..b3757e0 --- /dev/null +++ b/Swift/Controllers/Storages/CapsFileStorage.h @@ -0,0 +1,28 @@ +/* + * 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/filesystem/path.hpp> + +#include "Swiften/Disco/CapsStorage.h" +#include <string> + +namespace Swift { +	class CapsFileStorage : public CapsStorage { +		public: +			CapsFileStorage(const boost::filesystem::path& path); + +			virtual DiscoInfo::ref getDiscoInfo(const std::string& hash) const; +			virtual void setDiscoInfo(const std::string& hash, DiscoInfo::ref discoInfo); + +		private: +			boost::filesystem::path getCapsPath(const std::string& hash) const; + +		private: +			boost::filesystem::path path; +	}; +} diff --git a/Swift/Controllers/Storages/CertificateFileStorage.cpp b/Swift/Controllers/Storages/CertificateFileStorage.cpp new file mode 100644 index 0000000..a4a95c7 --- /dev/null +++ b/Swift/Controllers/Storages/CertificateFileStorage.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swift/Controllers/Storages/CertificateFileStorage.h> + +#include <iostream> +#include <boost/filesystem/fstream.hpp> + +#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/TLS/CertificateFactory.h> +#include <Swiften/Base/Log.h> + +namespace Swift { + +CertificateFileStorage::CertificateFileStorage(const boost::filesystem::path& path, CertificateFactory* certificateFactory) : path(path), certificateFactory(certificateFactory) { +} + +bool CertificateFileStorage::hasCertificate(Certificate::ref certificate) const { +	boost::filesystem::path certificatePath = getCertificatePath(certificate); +	if (boost::filesystem::exists(certificatePath)) { +		ByteArray data; +		readByteArrayFromFile(data, certificatePath.string()); +		Certificate::ref storedCertificate = certificateFactory->createCertificateFromDER(data); +		if (storedCertificate && storedCertificate->toDER() == certificate->toDER()) { +			return true; +		} +		else { +			SWIFT_LOG(warning) << "Stored certificate does not match received certificate" << std::endl; +			return false; +		} +	} +	else { +		return false; +	} +} + +void CertificateFileStorage::addCertificate(Certificate::ref certificate) { +	boost::filesystem::path certificatePath = getCertificatePath(certificate); +	if (!boost::filesystem::exists(certificatePath.parent_path())) { +		try { +			boost::filesystem::create_directories(certificatePath.parent_path()); +		} +		catch (const boost::filesystem::filesystem_error& e) { +			std::cerr << "ERROR: " << e.what() << std::endl; +		} +	} +	boost::filesystem::ofstream file(certificatePath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out); +	ByteArray data = certificate->toDER(); +	file.write(reinterpret_cast<const char*>(vecptr(data)), data.size()); +	file.close(); +} + +boost::filesystem::path CertificateFileStorage::getCertificatePath(Certificate::ref certificate) const { +	return path / Hexify::hexify(SHA1::getHash(certificate->toDER())); +} + +} diff --git a/Swift/Controllers/Storages/CertificateFileStorage.h b/Swift/Controllers/Storages/CertificateFileStorage.h new file mode 100644 index 0000000..f7a60b9 --- /dev/null +++ b/Swift/Controllers/Storages/CertificateFileStorage.h @@ -0,0 +1,31 @@ +/* + * 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/filesystem.hpp> + +#include "Swift/Controllers/Storages/CertificateStorage.h" + +namespace Swift { +	class CertificateFactory; + +	class CertificateFileStorage : public CertificateStorage { +		public: +			CertificateFileStorage(const boost::filesystem::path& path, CertificateFactory* certificateFactory); + +			virtual bool hasCertificate(Certificate::ref certificate) const; +			virtual void addCertificate(Certificate::ref certificate); + +		private: +			boost::filesystem::path getCertificatePath(Certificate::ref certificate) const; + +		private: +			boost::filesystem::path path; +			CertificateFactory* certificateFactory; +	}; + +} diff --git a/Swift/Controllers/Storages/CertificateFileStorageFactory.h b/Swift/Controllers/Storages/CertificateFileStorageFactory.h new file mode 100644 index 0000000..b215165 --- /dev/null +++ b/Swift/Controllers/Storages/CertificateFileStorageFactory.h @@ -0,0 +1,28 @@ +/* + * 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 <Swift/Controllers/Storages/CertificateStorageFactory.h> +#include <Swift/Controllers/Storages/CertificateFileStorage.h> + +namespace Swift { +	class CertificateFactory; + +	class CertificateFileStorageFactory : public CertificateStorageFactory { +		public: +			CertificateFileStorageFactory(const boost::filesystem::path& basePath, CertificateFactory* certificateFactory) : basePath(basePath), certificateFactory(certificateFactory) {} + +			virtual CertificateStorage* createCertificateStorage(const JID& profile) const { +				boost::filesystem::path profilePath = basePath / profile.toString(); +				return new CertificateFileStorage(profilePath / "certificates", certificateFactory); +			} + +		private: +			boost::filesystem::path basePath; +			CertificateFactory* certificateFactory; +	}; +} diff --git a/Swift/Controllers/Storages/CertificateMemoryStorage.cpp b/Swift/Controllers/Storages/CertificateMemoryStorage.cpp new file mode 100644 index 0000000..71d7c4a --- /dev/null +++ b/Swift/Controllers/Storages/CertificateMemoryStorage.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swift/Controllers/Storages/CertificateMemoryStorage.h> + +#include <Swiften/Base/foreach.h> + +using namespace Swift; + +CertificateMemoryStorage::CertificateMemoryStorage() { +} + +bool CertificateMemoryStorage::hasCertificate(Certificate::ref certificate) const { +	foreach(Certificate::ref storedCert, certificates) { +		if (storedCert->toDER() == certificate->toDER()) { +			return true; +		} +	} +	return false; +} + +void CertificateMemoryStorage::addCertificate(Certificate::ref certificate) { +	certificates.push_back(certificate); +} diff --git a/Swift/Controllers/Storages/CertificateMemoryStorage.h b/Swift/Controllers/Storages/CertificateMemoryStorage.h new file mode 100644 index 0000000..5c0333d --- /dev/null +++ b/Swift/Controllers/Storages/CertificateMemoryStorage.h @@ -0,0 +1,25 @@ +/* + * 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 <Swift/Controllers/Storages/CertificateStorage.h> + +namespace Swift { +	class CertificateMemoryStorage : public CertificateStorage { +		public: +			CertificateMemoryStorage(); + +			virtual bool hasCertificate(Certificate::ref certificate) const; +			virtual void addCertificate(Certificate::ref certificate); + +		private: +			std::vector<Certificate::ref> certificates; +	}; + +} diff --git a/Swift/Controllers/Storages/CertificateStorage.cpp b/Swift/Controllers/Storages/CertificateStorage.cpp new file mode 100644 index 0000000..ee942c0 --- /dev/null +++ b/Swift/Controllers/Storages/CertificateStorage.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swift/Controllers/Storages/CertificateStorage.h" + +namespace Swift { + +CertificateStorage::~CertificateStorage() { +} + +} diff --git a/Swift/Controllers/Storages/CertificateStorage.h b/Swift/Controllers/Storages/CertificateStorage.h new file mode 100644 index 0000000..f8c6fb5 --- /dev/null +++ b/Swift/Controllers/Storages/CertificateStorage.h @@ -0,0 +1,22 @@ +/* + * 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/filesystem.hpp> + +#include <Swiften/TLS/Certificate.h> + +namespace Swift { +	class CertificateStorage { +		public: +			virtual ~CertificateStorage(); + +			virtual bool hasCertificate(Certificate::ref certificate) const = 0; +			virtual void addCertificate(Certificate::ref certificate) = 0; +	}; + +} diff --git a/Swift/Controllers/Storages/CertificateStorageFactory.cpp b/Swift/Controllers/Storages/CertificateStorageFactory.cpp new file mode 100644 index 0000000..ba0179a --- /dev/null +++ b/Swift/Controllers/Storages/CertificateStorageFactory.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swift/Controllers/Storages/CertificateStorageFactory.h> + +namespace Swift { + +CertificateStorageFactory::~CertificateStorageFactory() { +} + +} diff --git a/Swift/Controllers/Storages/CertificateStorageFactory.h b/Swift/Controllers/Storages/CertificateStorageFactory.h new file mode 100644 index 0000000..5b85757 --- /dev/null +++ b/Swift/Controllers/Storages/CertificateStorageFactory.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +namespace Swift { +	class CertificateStorage; +	class JID; + +	class CertificateStorageFactory { +		public: +			virtual ~CertificateStorageFactory(); + +			virtual CertificateStorage* createCertificateStorage(const JID& profile) const = 0; +	}; +} diff --git a/Swift/Controllers/Storages/CertificateStorageTrustChecker.h b/Swift/Controllers/Storages/CertificateStorageTrustChecker.h new file mode 100644 index 0000000..40838dd --- /dev/null +++ b/Swift/Controllers/Storages/CertificateStorageTrustChecker.h @@ -0,0 +1,34 @@ +/* + * 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 <Swiften/TLS/CertificateTrustChecker.h> +#include <Swift/Controllers/Storages/CertificateStorage.h> + +namespace Swift { +	/** +	 * A certificate trust checker that trusts certificates in a certificate storage. +	 */ +	class CertificateStorageTrustChecker : public CertificateTrustChecker { +		public: +			CertificateStorageTrustChecker(CertificateStorage* storage) : storage(storage) { +			} + +			virtual bool isCertificateTrusted(Certificate::ref certificate) { +				lastCertificate = certificate; +				return storage->hasCertificate(certificate); +			} + +			Certificate::ref getLastCertificate() const { +				return lastCertificate; +			} + +		private: +			CertificateStorage* storage; +			Certificate::ref lastCertificate; +	}; +} diff --git a/Swift/Controllers/Storages/FileStorages.cpp b/Swift/Controllers/Storages/FileStorages.cpp new file mode 100644 index 0000000..6447099 --- /dev/null +++ b/Swift/Controllers/Storages/FileStorages.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swift/Controllers/Storages/FileStorages.h" +#include "Swift/Controllers/Storages/VCardFileStorage.h" +#include "Swift/Controllers/Storages/AvatarFileStorage.h" +#include "Swift/Controllers/Storages/CapsFileStorage.h" +#include "Swift/Controllers/Storages/RosterFileStorage.h" + +namespace Swift { + +FileStorages::FileStorages(const boost::filesystem::path& baseDir, const JID& jid) { +	std::string profile = jid.toBare(); +	vcardStorage = new VCardFileStorage(baseDir / profile / "vcards"); +	capsStorage = new CapsFileStorage(baseDir / "caps"); +	avatarStorage = new AvatarFileStorage(baseDir / "avatars", baseDir / profile / "avatars"); +	rosterStorage = new RosterFileStorage(baseDir / profile / "roster.xml"); +} + +FileStorages::~FileStorages() { +	delete rosterStorage; +	delete avatarStorage; +	delete capsStorage; +	delete vcardStorage; +} + +VCardStorage* FileStorages::getVCardStorage() const { +	return vcardStorage; +} + +CapsStorage* FileStorages::getCapsStorage() const { +	return capsStorage; +} + +AvatarStorage* FileStorages::getAvatarStorage() const { +	return avatarStorage; +} + +RosterStorage* FileStorages::getRosterStorage() const { +	return rosterStorage; +} + +} diff --git a/Swift/Controllers/Storages/FileStorages.h b/Swift/Controllers/Storages/FileStorages.h new file mode 100644 index 0000000..28df314 --- /dev/null +++ b/Swift/Controllers/Storages/FileStorages.h @@ -0,0 +1,53 @@ +/* + * 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/filesystem/path.hpp> + +#include "Swiften/Client/Storages.h" + +namespace Swift { +	class VCardFileStorage; +	class AvatarFileStorage; +	class CapsFileStorage; +	class RosterFileStorage; +	class JID; + +	/** +	 * A storages implementation that stores all controller data on disk. +	 */ +	class FileStorages : public Storages { +		public: +			/** +			 * Creates the storages interface. +			 * +			 * All data will be stored relative to a base directory, and +			 * for some controllers, in a subdirectory for the given profile. +			 * The data is stored in the following places: +			 * - Avatars: <basedir>/avatars +			 * - VCards: <basedir>/<profile>/vcards +			 * - Entity capabilities: <basedir>/caps +			 * +			 * \param baseDir the base dir to store data relative to +			 * \param jid the subdir in which profile-specific data will be stored.  +			 *   The bare JID will be used as the subdir name. +			 */ +			FileStorages(const boost::filesystem::path& baseDir, const JID& jid); +			~FileStorages(); + +			virtual VCardStorage* getVCardStorage() const; +			virtual AvatarStorage* getAvatarStorage() const; +			virtual CapsStorage* getCapsStorage() const; +			virtual RosterStorage* getRosterStorage() const; + +		private: +			VCardFileStorage* vcardStorage; +			AvatarFileStorage* avatarStorage; +			CapsFileStorage* capsStorage; +			RosterFileStorage* rosterStorage; +	}; +} diff --git a/Swift/Controllers/Storages/FileStoragesFactory.h b/Swift/Controllers/Storages/FileStoragesFactory.h new file mode 100644 index 0000000..0676bc3 --- /dev/null +++ b/Swift/Controllers/Storages/FileStoragesFactory.h @@ -0,0 +1,24 @@ +/* + * 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 "Swift/Controllers/Storages/StoragesFactory.h" +#include "Swift/Controllers/Storages/FileStorages.h" + +namespace Swift { +	class FileStoragesFactory : public StoragesFactory { +		public: +			FileStoragesFactory(const boost::filesystem::path& basePath) : basePath(basePath) {} + +			virtual Storages* createStorages(const JID& profile) const { +				return new FileStorages(basePath, profile); +			} + +		private: +			boost::filesystem::path basePath; +	}; +} diff --git a/Swift/Controllers/Storages/MemoryStoragesFactory.h b/Swift/Controllers/Storages/MemoryStoragesFactory.h new file mode 100644 index 0000000..0dea349 --- /dev/null +++ b/Swift/Controllers/Storages/MemoryStoragesFactory.h @@ -0,0 +1,23 @@ +/* + * 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 "Swift/Controllers/Storages/StoragesFactory.h" +#include "Swiften/Client/MemoryStorages.h" + +namespace Swift { +	class JID; +	 +	class MemoryStoragesFactory : public StoragesFactory { +		public: +			MemoryStoragesFactory() {} + +			virtual Storages* createStorages(const JID& profile) const { +				return new MemoryStorages(); +			} +	}; +} diff --git a/Swift/Controllers/Storages/RosterFileStorage.cpp b/Swift/Controllers/Storages/RosterFileStorage.cpp new file mode 100644 index 0000000..73e582f --- /dev/null +++ b/Swift/Controllers/Storages/RosterFileStorage.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swift/Controllers/Storages/RosterFileStorage.h> + +#include <Swiften/Entity/GenericPayloadPersister.h> +#include <Swiften/Serializer/PayloadSerializers/RosterSerializer.h> +#include <Swiften/Parser/PayloadParsers/RosterParser.h> + +using namespace Swift; + +typedef GenericPayloadPersister<RosterPayload, RosterParser, RosterSerializer> RosterPersister; + +RosterFileStorage::RosterFileStorage(const boost::filesystem::path& path) : path(path) { +} + +boost::shared_ptr<RosterPayload> RosterFileStorage::getRoster() const { +	return RosterPersister().loadPayloadGeneric(path); +} + +void RosterFileStorage::setRoster(boost::shared_ptr<RosterPayload> roster) { +	RosterPersister().savePayload(roster, path); +} diff --git a/Swift/Controllers/Storages/RosterFileStorage.h b/Swift/Controllers/Storages/RosterFileStorage.h new file mode 100644 index 0000000..cb00969 --- /dev/null +++ b/Swift/Controllers/Storages/RosterFileStorage.h @@ -0,0 +1,24 @@ +/* + * 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/filesystem/path.hpp> + +#include <Swiften/Roster/RosterStorage.h> + +namespace Swift { +	class RosterFileStorage : public RosterStorage { +		public: +			RosterFileStorage(const boost::filesystem::path& path); + +			virtual boost::shared_ptr<RosterPayload> getRoster() const; +			virtual void setRoster(boost::shared_ptr<RosterPayload>); + +		private: +			boost::filesystem::path path; +	}; +} diff --git a/Swift/Controllers/Storages/StoragesFactory.h b/Swift/Controllers/Storages/StoragesFactory.h new file mode 100644 index 0000000..203f9c9 --- /dev/null +++ b/Swift/Controllers/Storages/StoragesFactory.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +namespace Swift { +	class Storages; +	class JID; + +	class StoragesFactory { +		public: +			virtual ~StoragesFactory() {} + +			virtual Storages* createStorages(const JID& profile) const = 0; +	}; +} diff --git a/Swift/Controllers/Storages/VCardFileStorage.cpp b/Swift/Controllers/Storages/VCardFileStorage.cpp new file mode 100644 index 0000000..5f657a4 --- /dev/null +++ b/Swift/Controllers/Storages/VCardFileStorage.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swift/Controllers/Storages/VCardFileStorage.h" + +#include <boost/filesystem/fstream.hpp> +#include <boost/filesystem.hpp> +#include <iostream> + +#include <Swiften/Entity/GenericPayloadPersister.h> +#include <Swiften/Base/String.h> +#include <Swiften/StringCodecs/Hexify.h> +#include <Swiften/StringCodecs/SHA1.h> +#include <Swiften/Base/foreach.h> +#include "Swiften/JID/JID.h" +#include "Swiften/Elements/VCard.h" +#include "Swiften/Serializer/PayloadSerializers/VCardSerializer.h" +#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h" +#include "Swiften/Parser/PayloadParsers/VCardParser.h" + +using namespace Swift; + +typedef GenericPayloadPersister<VCard, VCardParser, VCardSerializer> VCardPersister; + +VCardFileStorage::VCardFileStorage(boost::filesystem::path dir) : vcardsPath(dir) { +	cacheFile = vcardsPath / "phashes"; +	if (boost::filesystem::exists(cacheFile)) { +		try { +			boost::filesystem::ifstream file(cacheFile); +			std::string line; +			if (file.is_open()) { +				while (!file.eof()) { +					getline(file, line); +					std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' '); +					JID jid(r.second); +					if (jid.isValid()) { +						photoHashes.insert(std::make_pair(jid, r.first)); +					} +					else if (!r.first.empty() || !r.second.empty()) { +						std::cerr << "Invalid entry in phashes file" << std::endl; +					} +				} +			} +		} +		catch (...) { +			std::cerr << "Error reading phashes file" << std::endl; +		} +	} +} + +boost::shared_ptr<VCard> VCardFileStorage::getVCard(const JID& jid) const { +	return VCardPersister().loadPayloadGeneric(getVCardPath(jid)); +} + +void VCardFileStorage::setVCard(const JID& jid, VCard::ref v) { +	VCardPersister().savePayload(v, getVCardPath(jid)); +	getAndUpdatePhotoHash(jid, v); +} + +boost::filesystem::path VCardFileStorage::getVCardPath(const JID& jid) const { +	std::string file(jid.toString()); +	String::replaceAll(file, '/', "%2f"); +	return boost::filesystem::path(vcardsPath / (file + ".xml")); +} + +std::string VCardFileStorage::getPhotoHash(const JID& jid) const { +	PhotoHashMap::const_iterator i = photoHashes.find(jid); +	if (i != photoHashes.end()) { +		return i->second; +	} +	else { +		VCard::ref vCard = getVCard(jid); +		return getAndUpdatePhotoHash(jid, vCard); +	} +} + +std::string VCardFileStorage::getAndUpdatePhotoHash(const JID& jid, VCard::ref vCard) const { +	std::string hash; +	if (vCard && !vCard->getPhoto().empty()) { +		hash = Hexify::hexify(SHA1::getHash(vCard->getPhoto())); +	} +	std::pair<PhotoHashMap::iterator, bool> r = photoHashes.insert(std::make_pair(jid, hash)); +	if (r.second) { +		savePhotoHashes(); +	} +	else if (r.first->second != hash) { +		r.first->second = hash; +		savePhotoHashes(); +	} +	return hash; +} + +void VCardFileStorage::savePhotoHashes() const { +	try { +		boost::filesystem::ofstream file(cacheFile); +		for (PhotoHashMap::const_iterator i = photoHashes.begin(); i != photoHashes.end(); ++i) { +			file << i->second << " " << i->first.toString() << std::endl; +		} +		file.close(); +	} +	catch (...) { +		std::cerr << "Error writing vcards file" << std::endl; +	} +} diff --git a/Swift/Controllers/Storages/VCardFileStorage.h b/Swift/Controllers/Storages/VCardFileStorage.h new file mode 100644 index 0000000..ba422f4 --- /dev/null +++ b/Swift/Controllers/Storages/VCardFileStorage.h @@ -0,0 +1,38 @@ +/* + * 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/shared_ptr.hpp> +#include <boost/filesystem/path.hpp> +#include <string> +#include <map> + +#include "Swiften/VCards/VCardStorage.h" + +namespace Swift { +	class VCardFileStorage : public VCardStorage { +		public: +			VCardFileStorage(boost::filesystem::path dir); + +			virtual VCard::ref getVCard(const JID& jid) const; +			virtual void setVCard(const JID& jid, VCard::ref v); + +			virtual std::string getPhotoHash(const JID&) const; + +		private: +			boost::filesystem::path getVCardPath(const JID&) const; + +			std::string getAndUpdatePhotoHash(const JID& jid, VCard::ref vcard) const; +			void savePhotoHashes() const; + +		private: +			boost::filesystem::path vcardsPath; +			boost::filesystem::path cacheFile; +			typedef std::map<JID, std::string> PhotoHashMap; +			mutable PhotoHashMap photoHashes; +	}; +} | 
 Swift
 Swift