From fae01f61d2ee6351149449bf1c8c64b2033c67dc Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 26 Nov 2014 16:19:36 -0500 Subject: [PATCH] filesytem-based addressbook --- AddressBook.cpp | 94 +++++++++++++++++++++++++++++++++++++++++++++++-- AddressBook.h | 14 ++++++++ 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/AddressBook.cpp b/AddressBook.cpp index 7fc39841..b2115f2b 100644 --- a/AddressBook.cpp +++ b/AddressBook.cpp @@ -1,23 +1,103 @@ #include +#include #include #include +#include +#include #include "base64.h" #include "util.h" #include "Identity.h" #include "Log.h" #include "AddressBook.h" -#include - namespace i2p { namespace client { + class AddressBookFilesystemStorage: public AddressBookStorage + { + public: + + AddressBookFilesystemStorage (); + bool GetAddress (const i2p::data::IdentHash& ident, i2p::data::IdentityEx& address) const; + void AddAddress (const i2p::data::IdentityEx& address); + void RemoveAddress (const i2p::data::IdentHash& ident); + + private: + + boost::filesystem::path GetPath () const { return i2p::util::filesystem::GetDefaultDataDir() / "addressbook"; }; + }; + + + AddressBookFilesystemStorage::AddressBookFilesystemStorage () + { + auto path = GetPath (); + if (!boost::filesystem::exists (path)) + { + // Create directory is necessary + if (!boost::filesystem::create_directory (path)) + LogPrint (eLogError, "Failed to create addressbook directory"); + } + } + + bool AddressBookFilesystemStorage::GetAddress (const i2p::data::IdentHash& ident, i2p::data::IdentityEx& address) const + { + auto filename = GetPath () / (ident.ToBase32() + ".b32"); + std::ifstream f(filename.c_str (), std::ifstream::binary); + if (f.is_open ()) + { + f.seekg (0,std::ios::end); + size_t len = f.tellg (); + if (len < i2p::data::DEFAULT_IDENTITY_SIZE) + { + LogPrint (eLogError, "File ", filename, " is too short. ", len); + return false; + } + f.seekg(0, std::ios::beg); + uint8_t * buf = new uint8_t[len]; + f.read((char *)buf, len); + address.FromBuffer (buf, len); + delete[] buf; + return true; + } + else + return false; + } + + void AddressBookFilesystemStorage::AddAddress (const i2p::data::IdentityEx& address) + { + auto filename = GetPath () / (address.GetIdentHash ().ToBase32() + ".b32"); + std::ofstream f (filename.c_str (), std::ofstream::binary | std::ofstream::out); + if (f.is_open ()) + { + size_t len = address.GetFullLen (); + uint8_t * buf = new uint8_t[len]; + address.ToBuffer (buf, len); + f.write ((char *)buf, len); + delete[] buf; + } + else + LogPrint (eLogError, "Can't open file ", filename); + } + + void AddressBookFilesystemStorage::RemoveAddress (const i2p::data::IdentHash& ident) + { + auto filename = GetPath () / (ident.ToBase32() + ".b32"); + if (boost::filesystem::exists (filename)) + boost::filesystem::remove (filename); + } + +//--------------------------------------------------------------------- AddressBook::AddressBook (): m_IsLoaded (false), m_IsDowloading (false) { } + AddressBook::~AddressBook () + { + delete m_Storage; + } + bool AddressBook::GetIdentHash (const std::string& address, i2p::data::IdentHash& ident) { auto pos = address.find(".b32.i2p"); @@ -59,10 +139,20 @@ namespace client { i2p::data::IdentityEx ident; ident.FromBase64 (base64); + if (m_Storage) m_Storage->AddAddress (ident); m_Addresses[address] = ident.GetIdentHash (); LogPrint (address,"->",ident.GetIdentHash ().ToBase32 (), ".b32.i2p added"); } + bool AddressBook::GetAddress (const std::string& address, i2p::data::IdentityEx& identity) + { + if (!m_Storage) + m_Storage = new AddressBookFilesystemStorage (); + auto ident = FindAddress (address); + if (!ident) return false; + return m_Storage->GetAddress (*ident, identity); + } + void AddressBook::LoadHostsFromI2P () { std::string content; diff --git a/AddressBook.h b/AddressBook.h index 8131a032..3e903fa3 100644 --- a/AddressBook.h +++ b/AddressBook.h @@ -13,14 +13,27 @@ namespace i2p { namespace client { + class AddressBookStorage // interface for storage + { + public: + + virtual ~AddressBookStorage () {}; + virtual bool GetAddress (const i2p::data::IdentHash& ident, i2p::data::IdentityEx& address) const = 0; + virtual void AddAddress (const i2p::data::IdentityEx& address) = 0; + virtual void RemoveAddress (const i2p::data::IdentHash& ident) = 0; + }; + class AddressBook { public: AddressBook (); + ~AddressBook (); bool GetIdentHash (const std::string& address, i2p::data::IdentHash& ident); + bool GetAddress (const std::string& address, i2p::data::IdentityEx& identity); const i2p::data::IdentHash * FindAddress (const std::string& address); void InsertAddress (const std::string& address, const std::string& base64); // for jump service + private: @@ -28,6 +41,7 @@ namespace client void LoadHostsFromI2P (); std::map m_Addresses; + AddressBookStorage * m_Storage; bool m_IsLoaded, m_IsDowloading; }; }