blob: bb198420897830e769e63d676de14673ac6597bd [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));
Alexander Afanasyev49a30d02013-01-21 21:38:48 -080058
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 Afanasyev49a30d02013-01-21 21:38:48 -080066 Name name = Name (deviceName)("file")(fileHash->GetHash (), fileHash->GetHashBytes ())(segment);
Alexander Afanasyev68f2a952013-01-08 14:34:16 -080067
Alexander Afanasyevdbc06712013-01-08 18:30:28 -080068 // cout << *fileHash << endl;
69 // cout << name << endl;
70
71 Bytes data = m_ccnx->createContentObject (name, buf, iff.gcount ());
72 fileDb.saveContentObject (deviceName, segment, data);
Alexander Afanasyev49a30d02013-01-21 21:38:48 -080073
Alexander Afanasyev68f2a952013-01-08 14:34:16 -080074 segment ++;
75 }
Alexander Afanasyev49a30d02013-01-21 21:38:48 -080076
Alexander Afanasyev68f2a952013-01-08 14:34:16 -080077 return fileHash;
78}
Alexander Afanasyevdbc06712013-01-08 18:30:28 -080079
80bool
81ObjectManager::objectsToLocalFile (/*in*/const Ccnx::Name &deviceName, /*in*/const Hash &fileHash, /*out*/ const fs::path &file)
82{
83 string hashStr = lexical_cast<string> (fileHash);
84 if (!ObjectDb::DoesExist (m_folder, deviceName, hashStr))
85 {
86 cout << "Brr" << endl;
87 // file does not exist or not all segments are available
88 return false;
89 }
90
91 fs::ofstream off (file, std::ios::out | std::ios::binary);
92 ObjectDb fileDb (m_folder, hashStr);
93
94 sqlite3_int64 segment = 0;
95 BytesPtr bytes = fileDb.fetchSegment (deviceName, 0);
96 while (bytes != BytesPtr())
97 {
98 ParsedContentObject obj (*bytes);
99 BytesPtr data = obj.contentPtr ();
100
101 off.write (reinterpret_cast<const char*> (head(*data)), data->size());
Alexander Afanasyev49a30d02013-01-21 21:38:48 -0800102
Alexander Afanasyevdbc06712013-01-08 18:30:28 -0800103 segment ++;
104 bytes = fileDb.fetchSegment (deviceName, segment);
105 }
106
107 // permission and timestamp should be assigned somewhere else (ObjectManager has no idea about that)
Alexander Afanasyev49a30d02013-01-21 21:38:48 -0800108
Alexander Afanasyevdbc06712013-01-08 18:30:28 -0800109 return true;
110}