~michihenning/storage-framework/no-boost-with-remote-client

« back to all changes in this revision

Viewing changes to src/qt/local_client/RootImpl.cpp

  • Committer: Michi Henning
  • Date: 2016-06-21 09:00:56 UTC
  • mfrom: (10.1.34 add_tests)
  • Revision ID: michi.henning@canonical.com-20160621090056-89bbdmj5yq3o5v0s
Merged add_tests branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#include <unity/storage/qt/client/internal/RootImpl.h>
2
2
 
3
3
#include <unity/storage/qt/client/Exceptions.h>
4
 
 
5
 
#include <boost/filesystem.hpp>
 
4
#include <unity/storage/qt/client/internal/FileImpl.h>
6
5
 
7
6
using namespace std;
8
7
 
14
13
{
15
14
namespace client
16
15
{
17
 
 
18
16
namespace internal
19
17
{
20
18
 
 
19
RootImpl::RootImpl(QString const& identity, weak_ptr<Account> const& account)
 
20
    : FolderImpl(identity, ItemType::root)
 
21
    , account_(account)
 
22
{
 
23
    using namespace boost::filesystem;
 
24
 
 
25
    path id_path = path(identity.toStdString());
 
26
    if (!id_path.is_absolute())
 
27
    {
 
28
        throw StorageException();  // TODO
 
29
    }
 
30
    path can_path = canonical(id_path);
 
31
    auto id_len = std::distance(id_path.begin(), id_path.end());
 
32
    auto can_len = std::distance(can_path.begin(), can_path.end());
 
33
    if (id_len != can_len)
 
34
    {
 
35
        // identity denotes a weird path that we won't trust because
 
36
        // it might contain ".." or similar.
 
37
        throw StorageException();  // TODO
 
38
    }
 
39
    assert(account.lock());
 
40
}
 
41
 
 
42
QString RootImpl::name() const
 
43
{
 
44
    return "";
 
45
}
 
46
 
 
47
QFuture<QVector<Folder::SPtr>> RootImpl::parents() const
 
48
{
 
49
    QFutureInterface<QVector<Folder::SPtr>> qf;
 
50
    qf.reportResult(QVector<Folder::SPtr>());  // For the root, we return an empty vector.
 
51
    qf.reportFinished();
 
52
    return qf.future();
 
53
}
 
54
 
 
55
QVector<QString> RootImpl::parent_ids() const
 
56
{
 
57
    return QVector<QString>();  // For the root, we return an empty vector.
 
58
}
 
59
 
21
60
QFuture<void> RootImpl::destroy()
22
61
{
23
62
    // Cannot destroy root.
30
69
    {
31
70
        return acc.get();
32
71
    }
33
 
    throw DestroyedException();  // TODO
 
72
    throw RuntimeDestroyedException();
34
73
}
35
74
 
36
75
QFuture<int64_t> RootImpl::free_space_bytes() const
47
86
    {
48
87
        qf.reportException(StorageException());  // TODO
49
88
    }
 
89
    qf.reportFinished();
50
90
    return qf.future();
51
91
}
52
92
 
64
104
    {
65
105
        qf.reportException(StorageException());  // TODO
66
106
    }
 
107
    qf.reportFinished();
67
108
    return qf.future();
68
109
}
69
110
 
70
111
QFuture<Item::SPtr> RootImpl::get(QString native_identity) const
71
112
{
72
 
    return QFuture<Item::SPtr>();  // TODO
 
113
    using namespace boost::filesystem;
 
114
 
 
115
    QFutureInterface<Item::SPtr> qf;
 
116
    try
 
117
    {
 
118
        path id_path = native_identity.toStdString();
 
119
        if (!id_path.is_absolute())
 
120
        {
 
121
            throw StorageException();  // TODO
 
122
        }
 
123
 
 
124
        // Make sure that native_identity is contained in or equal to the root path.
 
125
        id_path = canonical(id_path);
 
126
        auto root_path = path(root()->native_identity().toStdString());
 
127
        auto id_len = std::distance(id_path.begin(), id_path.end());
 
128
        auto root_len = std::distance(root_path.begin(), root_path.end());
 
129
        if (id_len < root_len)
 
130
        {
 
131
            // native_identity can't possibly point at something below the root.
 
132
            throw StorageException();  // TODO
 
133
        }
 
134
        if (!std::equal(root_path.begin(), root_path.end(), id_path.begin()))
 
135
        {
 
136
            // id_path differs from root path in some path component, so id_path
 
137
            // does not point at a location that's contained in root_path.
 
138
            throw StorageException();
 
139
        }
 
140
 
 
141
        file_status s = status(id_path);
 
142
        QString path = QString::fromStdString(id_path.native());
 
143
        if (is_directory(s))
 
144
        {
 
145
            if (id_path == root_path)
 
146
            {
 
147
                qf.reportResult(make_root(path, account_));
 
148
            }
 
149
            else
 
150
            {
 
151
                qf.reportResult(make_folder(path, root_));
 
152
            }
 
153
        }
 
154
        else if (is_regular_file(s))
 
155
        {
 
156
            qf.reportResult(FileImpl::make_file(path, root_));
 
157
        }
 
158
        else
 
159
        {
 
160
            // Ignore everything that's not a directory or file.
 
161
        }
 
162
    }
 
163
    catch (std::exception const&)
 
164
    {
 
165
        qf.reportException(StorageException());  // TODO
 
166
    }
 
167
    qf.reportFinished();
 
168
    return qf.future();
 
169
}
 
170
 
 
171
Root::SPtr RootImpl::make_root(QString const& identity, std::weak_ptr<Account> const& account)
 
172
{
 
173
    assert(account.lock());
 
174
 
 
175
    auto impl = new RootImpl(identity, account);
 
176
    Root::SPtr root(new Root(impl));
 
177
    impl->set_root(root);
 
178
    impl->set_public_instance(root);
 
179
    return root;
73
180
}
74
181
 
75
182
}  // namespace internal