21
21
#include <unity/storage/qt/client/Exceptions.h>
22
22
#include <unity/storage/qt/client/internal/make_future.h>
23
23
#include <unity/storage/qt/client/internal/local_client/FileImpl.h>
24
#include <unity/storage/qt/client/internal/local_client/storage_exception.h>
24
25
#include <unity/storage/qt/client/Root.h>
26
27
using namespace std;
69
70
QString RootImpl::name() const
72
lock_guard<decltype(mutex_)> guard(mutex_);
74
throw_if_destroyed("Root::name()");
74
78
QFuture<QVector<Folder::SPtr>> RootImpl::parents() const
80
lock_guard<decltype(mutex_)> guard(mutex_);
82
throw_if_destroyed("Root::parents()");
76
83
return make_ready_future(QVector<Folder::SPtr>()); // For the root, we return an empty vector.
79
86
QVector<QString> RootImpl::parent_ids() const
88
lock_guard<decltype(mutex_)> guard(mutex_);
90
throw_if_destroyed("Root::parent_ids()");
81
91
return QVector<QString>(); // For the root, we return an empty vector.
84
94
QFuture<void> RootImpl::delete_item()
96
lock_guard<decltype(mutex_)> guard(mutex_);
100
throw_if_destroyed("Root::delete_item()");
102
catch (StorageException const& e)
104
return internal::make_exceptional_future(e);
86
106
// Cannot delete root.
87
return make_exceptional_future(LogicException("Root::delete_item(): Cannot delete root folder"));
107
return internal::make_exceptional_future(LogicException("Root::delete_item(): Cannot delete root folder"));
90
110
QFuture<int64_t> RootImpl::free_space_bytes() const
112
lock_guard<decltype(mutex_)> guard(mutex_);
116
throw_if_destroyed("Root::free_space_bytes()");
118
catch (StorageException const& e)
120
return internal::make_exceptional_future<int64_t>(e);
92
123
using namespace boost::filesystem;
96
127
space_info si = space(identity_.toStdString());
97
128
return make_ready_future<int64_t>(si.available);
99
catch (std::exception const& e)
131
catch (std::exception const&)
101
return make_exceptional_future<int64_t>(ResourceException(QString("Root::free_space_bytes(): ") + e.what()));
133
return make_exceptional_future<int64_t>(QString("Root::free_space_bytes()"), current_exception());
105
138
QFuture<int64_t> RootImpl::used_space_bytes() const
140
lock_guard<decltype(mutex_)> guard(mutex_);
144
throw_if_destroyed("Root::used_space_bytes()");
146
catch (StorageException const& e)
148
return internal::make_exceptional_future<int64_t>(e);
107
151
using namespace boost::filesystem;
111
155
space_info si = space(identity_.toStdString());
112
156
return make_ready_future<int64_t>(si.capacity - si.available);
114
catch (std::exception const& e)
159
catch (std::exception const&)
116
return make_exceptional_future<int64_t>(ResourceException(QString("Root::used_space_bytes(): ") + e.what()));
161
return make_exceptional_future<int64_t>(QString("Root::used_space_bytes()"), current_exception());
120
166
QFuture<Item::SPtr> RootImpl::get(QString native_identity) const
168
lock_guard<decltype(mutex_)> guard(mutex_);
172
throw_if_destroyed("Root::get()");
174
catch (StorageException const& e)
176
return internal::make_exceptional_future<Item::SPtr>(e);
179
auto root = get_root();
182
return internal::make_exceptional_future<Item::SPtr>(RuntimeDestroyedException("Root::get()"));
122
185
using namespace boost::filesystem;
124
187
QFutureInterface<Item::SPtr> qf;
127
190
path id_path = native_identity.toStdString();
128
191
if (!id_path.is_absolute())
130
QString msg = "Root::get(): identity must be an absolute path";
131
return make_exceptional_future<Item::SPtr>(InvalidArgumentException(msg));
193
QString msg = "Root::get(): identity \"" + native_identity + "\" must be an absolute path";
194
throw InvalidArgumentException(msg);
134
197
// Make sure that native_identity is contained in or equal to the root path.
135
198
id_path = canonical(id_path);
136
auto root_path = path(root()->native_identity().toStdString());
199
auto root_path = path(root->native_identity().toStdString());
137
200
auto id_len = std::distance(id_path.begin(), id_path.end());
138
201
auto root_len = std::distance(root_path.begin(), root_path.end());
139
202
if (id_len < root_len || !std::equal(root_path.begin(), root_path.end(), id_path.begin()))
141
204
// Too few components, or wrong path prefix. Therefore, native_identity can't
142
205
// possibly point at something below the root.
143
206
QString msg = QString("Root::get(): identity \"") + native_identity + "\" points outside the root folder";
144
return make_exceptional_future<Item::SPtr>(InvalidArgumentException(msg));
207
throw InvalidArgumentException(msg);
147
210
// Don't allow reserved files to be found.
148
211
if (is_reserved_path(id_path))
150
QString msg = "Root::get(): no such item: " + native_identity;
151
return make_exceptional_future<Item::SPtr>(NotExistsException(msg, native_identity));
213
QString msg = "Root::get(): no such item: \"" + native_identity + "\"";
214
throw NotExistsException(msg, native_identity);
154
217
file_status s = status(id_path);
158
221
if (id_path == root_path)
160
return make_ready_future<Item::SPtr>(make_root(path, account_));
223
return make_ready_future<Item::SPtr>(make_root(path, account()));
162
return make_ready_future<Item::SPtr>(make_folder(path, root_));
225
return make_ready_future<Item::SPtr>(make_folder(path, root));
164
227
if (is_regular_file(s))
166
return make_ready_future<Item::SPtr>(FileImpl::make_file(path, root_));
229
return make_ready_future<Item::SPtr>(FileImpl::make_file(path, root));
168
QString msg = "Root::get(): no such item: " + native_identity;
169
return make_exceptional_future<Item::SPtr>(NotExistsException(msg, native_identity));
231
QString msg = "Root::get(): no such item: \"" + native_identity + "\"";
232
throw NotExistsException(msg, native_identity);
171
catch (std::exception const& e)
234
catch (std::exception const&)
173
return make_exceptional_future<Item::SPtr>(ResourceException(QString("Root::get(): ") + e.what()));
236
return make_exceptional_future<Item::SPtr>(QString("Root::get()"), current_exception(), native_identity);