blob: 7f66b2aeb927c9762dbf46c523977b76f9b26dfe [file] [log] [blame]
Alexander Afanasyev68f2a952013-01-08 14:34:16 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2012 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 * Zhenkai Zhu <zhenkai@cs.ucla.edu>
20 */
21
22#include "object-manager.h"
23#include "ccnx-name.h"
24#include "ccnx-common.h"
Alexander Afanasyevdbc06712013-01-08 18:30:28 -080025#include "ccnx-pco.h"
Alexander Afanasyev68f2a952013-01-08 14:34:16 -080026#include "object-db.h"
27
28#include <sys/stat.h>
29
30#include <fstream>
31#include <boost/lexical_cast.hpp>
32#include <boost/throw_exception.hpp>
Alexander Afanasyevdbc06712013-01-08 18:30:28 -080033#include <boost/filesystem/fstream.hpp>
Alexander Afanasyev68f2a952013-01-08 14:34:16 -080034
35using namespace Ccnx;
36using namespace boost;
37using namespace std;
38namespace fs = boost::filesystem;
39
40const int MAX_FILE_SEGMENT_SIZE = 1024;
41
Alexander Afanasyevdbc06712013-01-08 18:30:28 -080042ObjectManager::ObjectManager (Ccnx::CcnxWrapperPtr ccnx, const fs::path &folder)
Alexander Afanasyev68f2a952013-01-08 14:34:16 -080043 : m_ccnx (ccnx)
Alexander Afanasyev68f2a952013-01-08 14:34:16 -080044 , m_folder (folder / ".chronoshare")
45{
46 fs::create_directories (m_folder);
47}
48
49ObjectManager::~ObjectManager ()
50{
51}
52
53HashPtr
Alexander Afanasyevdbc06712013-01-08 18:30:28 -080054ObjectManager::localFileToObjects (const fs::path &file, const Ccnx::Name &deviceName)
Alexander Afanasyev68f2a952013-01-08 14:34:16 -080055{
56 HashPtr fileHash = Hash::FromFileContent (file);
57 ObjectDb fileDb (m_folder, lexical_cast<string> (*fileHash));
58
Alexander Afanasyevdbc06712013-01-08 18:30:28 -080059 fs::ifstream iff (file, std::ios::in | std::ios::binary);
60 sqlite3_int64 segment = 0;
Alexander Afanasyev68f2a952013-01-08 14:34:16 -080061 while (iff.good ())
62 {
63 char buf[MAX_FILE_SEGMENT_SIZE];
64 iff.read (buf, MAX_FILE_SEGMENT_SIZE);
65
Alexander Afanasyevdbc06712013-01-08 18:30:28 -080066 Name name (deviceName);
Alexander Afanasyev68f2a952013-01-08 14:34:16 -080067 name
68 .appendComp ("file")
69 .appendComp (fileHash->GetHash (), fileHash->GetHashBytes ())
70 .appendComp (segment);
71
Alexander Afanasyevdbc06712013-01-08 18:30:28 -080072 // cout << *fileHash << endl;
73 // cout << name << endl;
74
75 Bytes data = m_ccnx->createContentObject (name, buf, iff.gcount ());
76 fileDb.saveContentObject (deviceName, segment, data);
Alexander Afanasyev68f2a952013-01-08 14:34:16 -080077
78 segment ++;
79 }
80
81 return fileHash;
82}
Alexander Afanasyevdbc06712013-01-08 18:30:28 -080083
84bool
85ObjectManager::objectsToLocalFile (/*in*/const Ccnx::Name &deviceName, /*in*/const Hash &fileHash, /*out*/ const fs::path &file)
86{
87 string hashStr = lexical_cast<string> (fileHash);
88 if (!ObjectDb::DoesExist (m_folder, deviceName, hashStr))
89 {
90 cout << "Brr" << endl;
91 // file does not exist or not all segments are available
92 return false;
93 }
94
95 fs::ofstream off (file, std::ios::out | std::ios::binary);
96 ObjectDb fileDb (m_folder, hashStr);
97
98 sqlite3_int64 segment = 0;
99 BytesPtr bytes = fileDb.fetchSegment (deviceName, 0);
100 while (bytes != BytesPtr())
101 {
102 ParsedContentObject obj (*bytes);
103 BytesPtr data = obj.contentPtr ();
104
105 off.write (reinterpret_cast<const char*> (head(*data)), data->size());
106
107 segment ++;
108 bytes = fileDb.fetchSegment (deviceName, segment);
109 }
110
111 // permission and timestamp should be assigned somewhere else (ObjectManager has no idea about that)
112
113 return true;
114}