object: Switch code to use ndn-cxx
This commit also moves code to ndn::chronoshare namespace
Change-Id: I63817cce605620c3c68d98ac4e46e1a265dc3d3b
diff --git a/src/object-db.cpp b/src/object-db.cpp
index e522b51..a77f2a5 100644
--- a/src/object-db.cpp
+++ b/src/object-db.cpp
@@ -18,34 +18,37 @@
* See AUTHORS.md for complete list of ChronoShare authors and contributors.
*/
-#include "object-db.h"
-#include "db-helper.h"
-#include "logging.h"
-#include <boost/make_shared.hpp>
+#include "object-db.hpp"
+#include "db-helper.hpp"
+#include "core/logging.hpp"
+
#include <iostream>
#include <sys/stat.h>
-_LOG_INIT(Object.Db);
+#include <ndn-cxx/util/sqlite3-statement.hpp>
-using namespace std;
-using namespace Ndnx;
-using namespace boost;
+namespace ndn {
+namespace chronoshare {
+
+_LOG_INIT(ObjectDb);
+
namespace fs = boost::filesystem;
+using ndn::util::Sqlite3Statement;
-const std::string INIT_DATABASE = "\
-CREATE TABLE \n \
- File( \n\
- device_name BLOB NOT NULL, \n\
- segment INTEGER, \n\
- content_object BLOB, \n\
- \
- PRIMARY KEY (device_name, segment) \n\
- ); \n\
-CREATE INDEX device ON File(device_name); \n\
-";
+const std::string INIT_DATABASE = R"SQL(
+CREATE TABLE
+ File(
+ device_name BLOB NOT NULL,
+ segment INTEGER,
+ content_object BLOB,
+
+ PRIMARY KEY (device_name, segment)
+ );
+CREATE INDEX device ON File(device_name);
+)SQL";
ObjectDb::ObjectDb(const fs::path& folder, const std::string& hash)
- : m_lastUsed(time(NULL))
+ : m_lastUsed(time::steady_clock::now())
{
fs::path actualFolder = folder / "objects" / hash.substr(0, 2);
fs::create_directories(actualFolder);
@@ -54,30 +57,38 @@
int res = sqlite3_open((actualFolder / hash.substr(2, hash.size() - 2)).c_str(), &m_db);
if (res != SQLITE_OK) {
- BOOST_THROW_EXCEPTION(Error::Db() << errmsg_info_str(
- "Cannot open/create dabatabase: [" +
- (actualFolder / hash.substr(2, hash.size() - 2)).string() + "]"));
+ BOOST_THROW_EXCEPTION(Error("Cannot open/create database: [" +
+ (actualFolder / hash.substr(2, hash.size() - 2)).string() + "]"));
}
// Alex: determine if tables initialized. if not, initialize... not sure what is the best way to go...
// for now, just attempt to create everything
char* errmsg = 0;
- res = sqlite3_exec(m_db, INIT_DATABASE.c_str(), NULL, NULL, &errmsg);
+ res = sqlite3_exec(m_db, INIT_DATABASE.c_str(), nullptr, nullptr, &errmsg);
if (res != SQLITE_OK && errmsg != 0) {
- // _LOG_TRACE ("Init \"error\": " << errmsg);
sqlite3_free(errmsg);
}
- // _LOG_DEBUG ("open db");
-
willStartSave();
}
+ObjectDb::~ObjectDb()
+{
+ didStopSave();
+
+ int res = sqlite3_close(m_db);
+ if (res != SQLITE_OK) {
+ // complain
+ }
+}
+
bool
-ObjectDb::DoesExist(const boost::filesystem::path& folder, const Ccnx::Name& deviceName,
+ObjectDb::doesExist(const boost::filesystem::path& folder, const Name& deviceName,
const std::string& hash)
{
+ BOOST_ASSERT(hash.size() > 2);
+
fs::path actualFolder = folder / "objects" / hash.substr(0, 2);
bool retval = false;
@@ -89,8 +100,8 @@
"SELECT count(*), count(nullif(content_object,0)) FROM File WHERE device_name=?",
-1, &stmt, 0);
- CcnxCharbufPtr buf = deviceName.toCcnxCharbuf();
- sqlite3_bind_blob(stmt, 1, buf->buf(), buf->length(), SQLITE_TRANSIENT);
+ sqlite3_bind_blob(stmt, 1, deviceName.wireEncode().wire(), deviceName.wireEncode().size(),
+ SQLITE_TRANSIENT);
int res = sqlite3_step(stmt);
if (res == SQLITE_ROW) {
@@ -111,105 +122,60 @@
return retval;
}
-
-ObjectDb::~ObjectDb()
-{
- didStopSave();
-
- // _LOG_DEBUG ("close db");
- int res = sqlite3_close(m_db);
- if (res != SQLITE_OK) {
- // complain
- }
-}
-
void
-ObjectDb::saveContentObject(const Ccnx::Name& deviceName, sqlite3_int64 segment,
- const Ccnx::Bytes& data)
+ObjectDb::saveContentObject(const Name& deviceName, sqlite3_int64 segment, const Data& data)
{
- sqlite3_stmt* stmt;
- sqlite3_prepare_v2(m_db, "INSERT INTO File "
- "(device_name, segment, content_object) "
- "VALUES (?, ?, ?)",
- -1, &stmt, 0);
-
- //_LOG_DEBUG ("Saving content object for [" << deviceName << ", seqno: " << segment << ", size: " << data.size () << "]");
-
- CcnxCharbufPtr buf = deviceName.toCcnxCharbuf();
- sqlite3_bind_blob(stmt, 1, buf->buf(), buf->length(), SQLITE_STATIC);
- sqlite3_bind_int64(stmt, 2, segment);
- sqlite3_bind_blob(stmt, 3, &data[0], data.size(), SQLITE_STATIC);
-
- sqlite3_step(stmt);
- //_LOG_DEBUG ("After saving object: " << sqlite3_errmsg (m_db));
- sqlite3_finalize(stmt);
-
// update last used time
- m_lastUsed = time(NULL);
+ m_lastUsed = time::steady_clock::now();
+
+ Sqlite3Statement stmt(m_db, "INSERT INTO File "
+ "(device_name, segment, content_object) "
+ "VALUES (?, ?, ?)");
+
+ _LOG_DEBUG("Saving content object for [" << deviceName << ", seqno: " << segment << ", size: "
+ << data.wireEncode().size()
+ << "]");
+ stmt.bind(1, deviceName.wireEncode(), SQLITE_STATIC);
+ stmt.bind(2, segment);
+ stmt.bind(3, data.wireEncode(), SQLITE_STATIC);
+ stmt.step();
}
-Ccnx::BytesPtr
-ObjectDb::fetchSegment(const Ccnx::Name& deviceName, sqlite3_int64 segment)
+shared_ptr<Data>
+ObjectDb::fetchSegment(const Name& deviceName, sqlite3_int64 segment)
{
- sqlite3_stmt* stmt;
- sqlite3_prepare_v2(m_db, "SELECT content_object FROM File WHERE device_name=? AND segment=?", -1,
- &stmt, 0);
+ // update last used time
+ m_lastUsed = time::steady_clock::now();
- CcnxCharbufPtr buf = deviceName.toCcnxCharbuf();
- sqlite3_bind_blob(stmt, 1, buf->buf(), buf->length(), SQLITE_TRANSIENT);
- sqlite3_bind_int64(stmt, 2, segment);
+ Sqlite3Statement stmt(m_db, "SELECT content_object FROM File WHERE device_name=? AND segment=?");
+ stmt.bind(1, deviceName.wireEncode(), SQLITE_STATIC);
+ stmt.bind(2, segment);
- BytesPtr ret;
-
- int res = sqlite3_step(stmt);
- if (res == SQLITE_ROW) {
- const unsigned char* buf = reinterpret_cast<const unsigned char*>(sqlite3_column_blob(stmt, 0));
- int bufBytes = sqlite3_column_bytes(stmt, 0);
-
- ret = make_shared<Bytes>(buf, buf + bufBytes);
+ if (stmt.step() == SQLITE_ROW) {
+ return make_shared<Data>(stmt.getBlock(0));
}
-
- sqlite3_finalize(stmt);
-
- // update last used time
- m_lastUsed = time(NULL);
-
- return ret;
+ else {
+ return nullptr;
+ }
}
-time_t
-ObjectDb::secondsSinceLastUse()
+const time::steady_clock::TimePoint&
+ObjectDb::getLastUsed() const
{
- return (time(NULL) - m_lastUsed);
+ return m_lastUsed;
}
-// sqlite3_int64
-// ObjectDb::getNumberOfSegments (const Ndnx::Name &deviceName)
-// {
-// sqlite3_stmt *stmt;
-// sqlite3_prepare_v2 (m_db, "SELECT count(*) FROM File WHERE device_name=?", -1, &stmt, 0);
-
-// bool retval = false;
-// int res = sqlite3_step (stmt);
-// if (res == SQLITE_ROW)
-// {
-// retval = true;
-// }
-// sqlite3_finalize (stmt);
-
-// return retval;
-// }
-
void
ObjectDb::willStartSave()
{
sqlite3_exec(m_db, "BEGIN TRANSACTION;", 0, 0, 0);
- // _LOG_DEBUG ("Open transaction: " << sqlite3_errmsg (m_db));
}
void
ObjectDb::didStopSave()
{
sqlite3_exec(m_db, "END TRANSACTION;", 0, 0, 0);
- // _LOG_DEBUG ("Close transaction: " << sqlite3_errmsg (m_db));
}
+
+} // namespace chronoshare
+} // namespace ndn
diff --git a/src/object-db.hpp b/src/object-db.hpp
index 3e6f9cd..a0391b5 100644
--- a/src/object-db.hpp
+++ b/src/object-db.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2016, Regents of the University of California.
+ * Copyright (c) 2013-2017, Regents of the University of California.
*
* This file is part of ChronoShare, a decentralized file sharing application over NDN.
*
@@ -18,40 +18,54 @@
* See AUTHORS.md for complete list of ChronoShare authors and contributors.
*/
-#ifndef OBJECT_DB_H
-#define OBJECT_DB_H
+#ifndef CHRONOSHARE_SRC_OBJECT_DB_HPP
+#define CHRONOSHARE_SRC_OBJECT_DB_HPP
+
+#include "db-helper.hpp"
+#include "core/chronoshare-common.hpp"
+
+#include <sqlite3.h>
+
+#include <ctime>
+#include <vector>
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/name.hpp>
#include <boost/filesystem.hpp>
-#include <boost/shared_ptr.hpp>
-#include <ccnx-common.h>
-#include <ccnx-name.h>
-#include <ctime>
-#include <sqlite3.h>
-#include <string>
-#include <vector>
+
+namespace ndn {
+namespace chronoshare {
class ObjectDb
{
public:
+ class Error : public DbHelper::Error
+ {
+ public:
+ explicit Error(const std::string& what)
+ : DbHelper::Error(what)
+ {
+ }
+ };
+
+public:
// database will be create in <folder>/<first-pair-of-hash-bytes>/<rest-of-hash>
ObjectDb(const boost::filesystem::path& folder, const std::string& hash);
+
~ObjectDb();
void
- saveContentObject(const Ccnx::Name& deviceName, sqlite3_int64 segment, const Ccnx::Bytes& data);
+ saveContentObject(const Name& deviceName, sqlite3_int64 segment, const Data& data);
- Ccnx::BytesPtr
- fetchSegment(const Ccnx::Name& deviceName, sqlite3_int64 segment);
+ shared_ptr<Data>
+ fetchSegment(const Name& deviceName, sqlite3_int64 segment);
- // sqlite3_int64
- // getNumberOfSegments (const Ndnx::Name &deviceName);
-
- time_t
- secondsSinceLastUse();
+ const time::steady_clock::TimePoint&
+ getLastUsed() const;
static bool
- DoesExist(const boost::filesystem::path& folder, const Ccnx::Name& deviceName,
- const std::string& hash);
+ doesExist(const boost::filesystem::path& folder, const Name& deviceName, const std::string& hash);
private:
void
@@ -62,9 +76,10 @@
private:
sqlite3* m_db;
- time_t m_lastUsed;
+ time::steady_clock::TimePoint m_lastUsed;
};
-typedef boost::shared_ptr<ObjectDb> ObjectDbPtr;
+} // namespace chronoshare
+} // namespace ndn
-#endif // OBJECT_DB_H
+#endif // CHRONOSHARE_SRC_OBJECT_DB_HPP
diff --git a/src/object-manager.cpp b/src/object-manager.cpp
index d900098..4ca0361 100644
--- a/src/object-manager.cpp
+++ b/src/object-manager.cpp
@@ -19,31 +19,30 @@
*/
#include "object-manager.hpp"
-#include "ccnx-common.hpp"
-#include "ccnx-name.hpp"
-#include "ccnx-pco.hpp"
-#include "logging.hpp"
#include "object-db.hpp"
+#include "core/logging.hpp"
#include <sys/stat.h>
#include <boost/filesystem/fstream.hpp>
#include <boost/lexical_cast.hpp>
-#include <boost/throw_exception.hpp>
-#include <fstream>
+
+#include <ndn-cxx/util/string-helper.hpp>
+
+namespace ndn {
+namespace chronoshare {
_LOG_INIT(Object.Manager);
-using namespace Ndnx;
-using namespace boost;
-using namespace std;
namespace fs = boost::filesystem;
+using util::Sha256;
const int MAX_FILE_SEGMENT_SIZE = 1024;
-ObjectManager::ObjectManager(Ccnx::CcnxWrapperPtr ccnx, const fs::path& folder,
- const std::string& appName)
- : m_ccnx(ccnx)
+ObjectManager::ObjectManager(Face& face, KeyChain& keyChain,
+ const fs::path& folder, const std::string& appName)
+ : m_face(face)
+ , m_keyChain(keyChain)
, m_folder(folder / ".chronoshare")
, m_appName(appName)
{
@@ -55,11 +54,12 @@
}
// /<devicename>/<appname>/file/<hash>/<segment>
-boost::tuple<HashPtr /*object-db name*/, size_t /* number of segments*/>
-ObjectManager::localFileToObjects(const fs::path& file, const Ccnx::Name& deviceName)
+std::tuple<ConstBufferPtr /*object-db name*/, size_t /* number of segments*/>
+ObjectManager::localFileToObjects(const fs::path& file, const Name& deviceName)
{
- HashPtr fileHash = Hash::FromFileContent(file);
- ObjectDb fileDb(m_folder, lexical_cast<string>(*fileHash));
+ fs::ifstream input1(file, std::ios::in | std::ios::binary);
+ Sha256 fileHash(input1);
+ ObjectDb fileDb(m_folder, fileHash.toString());
fs::ifstream iff(file, std::ios::in | std::ios::binary);
sqlite3_int64 segment = 0;
@@ -71,37 +71,54 @@
break;
}
- Name name = Name("/")(deviceName)(m_appName)("file")(fileHash->GetHash(),
- fileHash->GetHashBytes())(segment);
+ Name name = Name("/");
+ name.append(deviceName)
+ .append(m_appName)
+ .append("file")
+ .appendImplicitSha256Digest(fileHash.computeDigest())
+ .appendNumber(segment);
- // cout << *fileHash << endl;
- // cout << name << endl;
- //_LOG_DEBUG ("Read " << iff.gcount () << " from " << file << " for segment " << segment);
+ shared_ptr<Data> data = make_shared<Data>();
+ data->setName(name);
+ data->setFreshnessPeriod(time::seconds(60));
+ data->setContent(reinterpret_cast<const uint8_t*>(&buf), iff.gcount());
+ m_keyChain.sign(*data);
+ m_face.put(*data);
- Bytes data = m_ccnx->createContentObject(name, buf, iff.gcount());
- fileDb.saveContentObject(deviceName, segment, data);
+ fileDb.saveContentObject(deviceName, segment, *data);
segment++;
}
if (segment == 0) // handle empty files
{
- Name name =
- Name("/")(m_appName)("file")(fileHash->GetHash(), fileHash->GetHashBytes())(deviceName)(0);
- Bytes data = m_ccnx->createContentObject(name, 0, 0);
- fileDb.saveContentObject(deviceName, 0, data);
+ Name name = Name("/");
+ name.append(m_appName)
+ .append("file")
+ .appendImplicitSha256Digest(fileHash.computeDigest())
+ .append(deviceName)
+ .appendNumber(0);
+
+ shared_ptr<Data> data = make_shared<Data>();
+ data->setName(name);
+ data->setFreshnessPeriod(time::seconds(0));
+ data->setContent(0, 0);
+ m_keyChain.sign(*data);
+ m_face.put(*data);
+
+ fileDb.saveContentObject(deviceName, 0, *data);
segment++;
}
- return make_tuple(fileHash, segment);
+ return std::make_tuple(fileHash.computeDigest(), segment);
}
bool
-ObjectManager::objectsToLocalFile(/*in*/ const Ccnx::Name& deviceName, /*in*/ const Hash& fileHash,
+ObjectManager::objectsToLocalFile(/*in*/ const Name& deviceName, /*in*/ const Buffer& fileHash,
/*out*/ const fs::path& file)
{
- string hashStr = lexical_cast<string>(fileHash);
- if (!ObjectDb::DoesExist(m_folder, deviceName, hashStr)) {
+ std::string hashStr = toHex(fileHash);
+ if (!ObjectDb::doesExist(m_folder, deviceName, hashStr)) {
_LOG_ERROR("ObjectDb for [" << m_folder << ", " << deviceName << ", " << hashStr
<< "] does not exist or not all segments are available");
return false;
@@ -115,20 +132,18 @@
ObjectDb fileDb(m_folder, hashStr);
sqlite3_int64 segment = 0;
- BytesPtr bytes = fileDb.fetchSegment(deviceName, 0);
- while (bytes) {
- ParsedContentObject obj(*bytes);
- BytesPtr data = obj.contentPtr();
+ auto data = fileDb.fetchSegment(deviceName, 0);
+ while (data != nullptr) {
+ off.write(reinterpret_cast<const char*>(data->getContent().value()), data->getContent().value_size());
- if (data) {
- off.write(reinterpret_cast<const char*>(head(*data)), data->size());
- }
-
- segment++;
- bytes = fileDb.fetchSegment(deviceName, segment);
+ ++segment;
+ data = fileDb.fetchSegment(deviceName, segment);
}
- // permission and timestamp should be assigned somewhere else (ObjectManager has no idea about that)
+ // permission and timestamp should be assigned somewhere else(ObjectManager has no idea about that)
return true;
}
+
+} // namespace chronoshare
+} // namespace ndn
diff --git a/src/object-manager.hpp b/src/object-manager.hpp
index 51a5880..b00c846 100644
--- a/src/object-manager.hpp
+++ b/src/object-manager.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2016, Regents of the University of California.
+ * Copyright (c) 2013-2017, Regents of the University of California.
*
* This file is part of ChronoShare, a decentralized file sharing application over NDN.
*
@@ -18,48 +18,59 @@
* See AUTHORS.md for complete list of ChronoShare authors and contributors.
*/
-#ifndef OBJECT_MANAGER_H
-#define OBJECT_MANAGER_H
+#ifndef CHRONOSHARE_SRC_OBJECT_MANAGER_HPP
+#define CHRONOSHARE_SRC_OBJECT_MANAGER_HPP
+
+#include "core/chronoshare-common.hpp"
#include <boost/filesystem.hpp>
-#include <boost/tuple/tuple.hpp>
-#include <ccnx-wrapper.h>
-#include <hash-helper.h>
-#include <string>
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/util/digest.hpp>
// everything related to managing object files
+namespace ndn {
+namespace chronoshare {
+
class ObjectManager
{
public:
- ObjectManager(Ccnx::CcnxWrapperPtr ccnx, const boost::filesystem::path& folder,
- const std::string& appName);
- virtual ~ObjectManager();
+ ObjectManager(Face& face, KeyChain& keyChain,
+ const boost::filesystem::path& folder, const std::string& appName);
+
+ virtual
+ ~ObjectManager();
/**
* @brief Creates and saves local file in a local database file
*
* Format: /<appname>/file/<hash>/<devicename>/<segment>
*/
- boost::tuple<HashPtr /*object-db name*/, size_t /* number of segments*/>
- localFileToObjects(const boost::filesystem::path& file, const Ccnx::Name& deviceName);
+ std::tuple<ConstBufferPtr /*object-db name*/, size_t /* number of segments*/>
+ localFileToObjects(const boost::filesystem::path& file, const Name& deviceName);
bool
- objectsToLocalFile(/*in*/ const Ccnx::Name& deviceName, /*in*/ const Hash& hash,
+ objectsToLocalFile(/*in*/ const Name& deviceName, /*in*/ const Buffer& hash,
/*out*/ const boost::filesystem::path& file);
private:
- Ndnx::NdnxWrapperPtr m_ndnx;
+ Face& m_face;
+ KeyChain& m_keyChain;
boost::filesystem::path m_folder;
std::string m_appName;
};
-typedef boost::shared_ptr<ObjectManager> ObjectManagerPtr;
+typedef shared_ptr<ObjectManager> ObjectManagerPtr;
-namespace Error {
+namespace error {
struct ObjectManager : virtual boost::exception, virtual std::exception
{
};
-}
+} // namespace error
-#endif // OBJECT_MANAGER_H
+} // namespace chronoshare
+} // namespace ndn
+
+#endif // CHRONOSHARE_SRC_OBJECT_MANAGER_HPP
diff --git a/wscript b/wscript
index fe8c036..117e90c 100644
--- a/wscript
+++ b/wscript
@@ -107,6 +107,7 @@
'src/sync-*.cpp',
'src/file-state.cpp',
'src/action-log.cpp',
+ 'src/object-*.cpp',
]),
use='core-objects adhoc NDN_CXX BOOST TINYXML SQLITE3',
includes="src",