annotate foosdk/sdk/foobar2000/SDK/fsItem.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "foobar2000-sdk-pch.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 t_filestats2 fsItemBase::getStatsOpportunist() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 return filestats2_invalid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 void fsItemBase::remove(abort_callback& aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 getFS()->remove(this->canonicalPath()->c_str(), aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 fb2k::stringRef fsItemBase::shortName() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 return nameWithExt();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 file::ptr fsItemFile::openRead(abort_callback& aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 return open(filesystem::open_mode_read, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 file::ptr fsItemFile::openWriteExisting(abort_callback& aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 return open(filesystem::open_mode_write_existing, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 file::ptr fsItemFile::openWriteNew(abort_callback& aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 return open(filesystem::open_mode_write_new, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 void fsItemFolder::removeRecur(abort_callback& aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 auto list = this->listContents(listMode::filesAndFolders | listMode::hidden | listMode::suppressStats, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 for (auto i : list->typed< fsItemBase >()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 fsItemFolderPtr f;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 if (f &= i) f->removeRecur(aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 else i->remove(aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 this->remove(aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 void fsItemFile::copyToOther(fsItemFilePtr other, abort_callback& aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 aborter.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 auto fSource = this->openRead(aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 auto fTarget = other->openWriteNew(aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 file::g_transfer_file(fSource, fTarget, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 // fTarget->commit(aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 // we cannot transfer other properties, this should be overridden for such
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 fsItemPtr fsItemBase::copyTo(fsItemFolderPtr folder, const char* desiredName, unsigned createMode, abort_callback& aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 aborter.check();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 fsItemFilePtr f;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 if (f &= this) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 auto target = folder->createFile(desiredName, createMode, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 f->copyToOther(target, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 return std::move(target);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 fsItemFolderPtr f;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 if (f &= this) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 auto target = folder->createFolder(desiredName, createMode, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 auto contents = f->listContents(listMode::filesAndFolders | listMode::hidden | listMode::suppressStats, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 for (auto item : contents->typed<fsItemBase>()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 item->copyTo(target, createMode, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 return std::move(target);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 PFC_ASSERT(!"Should not get here, bad fsItemBase object");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 return nullptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 fsItemPtr fsItemBase::copyTo(fsItemFolderPtr folder, unsigned createMode, abort_callback& aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 auto temp = this->nameWithExt();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 return this->copyTo(folder, temp->c_str(), createMode, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 fsItemPtr fsItemBase::moveTo(fsItemFolderPtr folder, const char* desiredName, unsigned createMode, abort_callback& aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 auto ret = this->copyTo(folder, desiredName, createMode, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 fsItemFolder::ptr asFolder;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 if (asFolder &= this) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 asFolder->removeRecur(aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 this->remove(aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 fsItemPtr fsItemBase::moveTo(fsItemFolderPtr folder, unsigned createMode, abort_callback& aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 auto fn = this->nameWithExt();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 return this->moveTo(folder, fn->c_str(), createMode, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 fb2k::memBlockRef fsItemFile::readWhole(size_t sizeSanity, abort_callback& aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 auto file = this->openRead(aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 auto size64 = file->get_size_ex(aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 if (size64 > sizeSanity) throw exception_io_data();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 auto size = (size_t)size64;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 pfc::mem_block block;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 block.resize(size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 file->read_object(block.ptr(), size, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 return fb2k::memBlock::blockWithData(std::move(block));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 static void uniqueFn(pfc::string8& fn, unsigned add) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 if (add > 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 pfc::string8 fnOnly = pfc::remove_ext_v2(fn);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 pfc::string8 ext = pfc::extract_ext_v2(fn);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 fn = std::move(fnOnly);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 fn << " (" << add << ")";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 if (ext.length() > 0) fn << "." << ext;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 using namespace fb2k;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 class fsItemFileStd : public fsItemFile {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 fsItemFileStd(filesystem::ptr fs, stringRef canonicalPath, t_filestats2 const & opportunistStats) : m_fs(fs), m_path(canonicalPath), m_opportunistStats(opportunistStats) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 m_opportunistStats.set_folder(false);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 m_opportunistStats.set_remote(fs->is_remote(canonicalPath->c_str()));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 filesystem::ptr getFS() override { return m_fs; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 bool isRemote() override { return m_fs->is_remote(m_path->c_str()); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 t_filestats2 getStats2(uint32_t s2flags, abort_callback& a) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 auto s = m_fs->get_stats2_(m_path->c_str(), s2flags, a);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 PFC_ASSERT((s2flags & stats2_fileOrFolder) == 0 || !s.is_folder());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 return s;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 fb2k::stringRef canonicalPath() override { return m_path; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 fb2k::stringRef nameWithExt() override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 pfc::string8 temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 m_fs->extract_filename_ext(m_path->c_str(), temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 return makeString(temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 fb2k::stringRef shortName() override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 pfc::string8 temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 if (m_fs->get_display_name_short_(m_path->c_str(), temp)) return makeString(temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 return nameWithExt();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 t_filestats2 getStatsOpportunist() override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 return m_opportunistStats;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 file::ptr open(uint32_t openMode, abort_callback& aborter) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 file::ptr ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 m_fs->open(ret, m_path->c_str(), openMode, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 fb2k::memBlockRef readWhole(size_t sizeSanity, abort_callback& aborter) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 // Prefer fs->readWholeFile over fsItemFile methods as the fs object might implement it
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 return m_fs->readWholeFile(m_path->c_str(), sizeSanity, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 fsItemPtr moveTo(fsItemFolderPtr folder, const char* desiredName, unsigned createMode, abort_callback& aborter) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 for (unsigned add = 0; ; ++add) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 pfc::string8 fn(desiredName); uniqueFn(fn, add);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 pfc::string8 dst(folder->canonicalPath()->c_str());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 dst.end_with(m_fs->pathSeparator());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 dst += fn;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 bool bDidExist = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 if (createMode == createMode::allowExisting) m_fs->move_overwrite(m_path->c_str(), dst, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 else m_fs->move(m_path->c_str(), dst, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 } catch (exception_io_already_exists const &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 bDidExist = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 switch (createMode) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 case createMode::allowExisting:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 break; // OK
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 case createMode::failIfExists:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 if (bDidExist) throw exception_io_already_exists();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177 break; // OK
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 case createMode::generateUniqueName:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 if (bDidExist) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 continue; // the for loop
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 break; // OK
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 PFC_ASSERT(!"Should not get here");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 auto stats = m_opportunistStats;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 stats.set_file();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 return m_fs->makeItemFileStd(dst, stats);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 const filesystem::ptr m_fs;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 const stringRef m_path;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 t_filestats2 m_opportunistStats;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 class fsItemFolderStd : public fsItemFolder {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 fsItemFolderStd(filesystem::ptr fs, stringRef canonicalPath, t_filestats2 const & opportunistStats) : m_fs(fs), m_path(canonicalPath), m_opportunistStats(opportunistStats) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 m_opportunistStats.set_folder(true);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 m_opportunistStats.set_remote(fs->is_remote(canonicalPath->c_str()));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 filesystem::ptr getFS() override { return m_fs; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 t_filestats2 getStatsOpportunist() override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 return m_opportunistStats;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 bool isRemote() override { return m_fs->is_remote(m_path->c_str()); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 t_filestats2 getStats2(uint32_t s2flags, abort_callback& a) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 auto s = m_fs->get_stats2_(m_path->c_str(), s2flags, a);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 PFC_ASSERT((s2flags & stats2_fileOrFolder) == 0 || s.is_folder() );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 return s;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 fb2k::stringRef canonicalPath() override { return m_path; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 fb2k::stringRef nameWithExt() override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 pfc::string8 temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 m_fs->extract_filename_ext(m_path->c_str(), temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 return makeString(temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 fb2k::stringRef shortName() override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 pfc::string8 temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 if (m_fs->get_display_name_short_(m_path->c_str(), temp)) return makeString(temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 return nameWithExt();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 fb2k::arrayRef listContents(unsigned listMode, abort_callback& aborter) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 auto out = arrayMutable::empty();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 filesystem::list_callback_t cb = [&] ( const char * p, t_filestats2 const & stats ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 if (stats.is_folder()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 if (listMode & listMode::folders) out->add(new service_impl_t< fsItemFolderStd >(m_fs, makeString(p), stats));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 if (listMode & listMode::files) out->add(new service_impl_t< fsItemFileStd >(m_fs, makeString(p), stats));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 m_fs->list_directory_(m_path->c_str(), cb, listMode, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 return out->copyConst();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 fsItemFile::ptr findChildFile(const char* fileName, abort_callback& aborter) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 auto sub = subPath(fileName);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 auto stats = m_fs->get_stats2_(sub->c_str(), stats2_fileOrFolder | foobar2000_io::stats2_remote, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246 if (!stats.is_folder()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 return m_fs->makeItemFileStd(sub->c_str(), stats);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 throw exception_io_not_found();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 fsItemFolder::ptr findChildFolder(const char* fileName, abort_callback& aborter) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 auto sub = subPath(fileName);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 auto stats = m_fs->get_stats2_(sub->c_str(), stats2_fileOrFolder | foobar2000_io::stats2_remote, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 if (stats.is_folder()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 return m_fs->makeItemFolderStd(sub->c_str(), stats);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 throw exception_io_not_found();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 fsItemBase::ptr findChild(const char* fileName, abort_callback& aborter) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 auto sub = subPath(fileName);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 auto stats = m_fs->get_stats2_(sub->c_str(), stats2_fileOrFolder | foobar2000_io::stats2_remote, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 if ( stats.is_folder() ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 return m_fs->makeItemFileStd(sub->c_str(), stats );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 return m_fs->makeItemFolderStd(sub->c_str(), stats );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 fsItemFile::ptr createFile(const char* fileName, unsigned createMode, abort_callback& aborter) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 for (unsigned add = 0; ; ++add) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 pfc::string8 fn(fileName); uniqueFn(fn, add);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 auto sub = subPath(fn);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 t_filestats2 stats;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 bool bDidExist = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 stats = m_fs->get_stats2_( sub->c_str(), stats2_all, aborter );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 bDidExist = stats.is_file();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 } catch(exception_io_not_found const &) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 switch (createMode) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 case createMode::allowExisting:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 break; // OK
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 case createMode::failIfExists:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 if (bDidExist) throw exception_io_already_exists();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 break; // OK
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 case createMode::generateUniqueName:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 if (bDidExist) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288 continue; // the for loop
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 PFC_ASSERT(!"Should not get here");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 if (!bDidExist) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 // actually create an empty file if it did not yet exist
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297 // FIX ME this should be atomic with exists() check
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 file::ptr creator;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 m_fs->open(creator, sub->c_str(), filesystem::open_mode_write_new, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 stats = creator->get_stats2_( stats2_all, aborter );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 return m_fs->makeItemFileStd(sub->c_str(), stats);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 fsItemFolder::ptr createFolder(const char* fileName, unsigned createMode, abort_callback& aborter) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306 for (unsigned add = 0; ; ++add) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307 pfc::string8 fn(fileName); uniqueFn(fn, add);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 auto sub = subPath(fn);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 bool bDidExist = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 m_fs->create_directory(sub->c_str(), aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312 } catch (exception_io_already_exists const &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 bDidExist = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 switch (createMode) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316 case createMode::allowExisting:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 break; // OK
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 case createMode::failIfExists:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319 if (bDidExist) throw exception_io_already_exists();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321 case createMode::generateUniqueName:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 if (bDidExist) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 continue; // the for loop
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 PFC_ASSERT(!"Should not get here");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330 // Inherit opportunist stats
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331 return m_fs->makeItemFolderStd(sub->c_str(), this->m_opportunistStats);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 fsItemPtr moveTo(fsItemFolderPtr folder, const char* desiredName, unsigned createMode, abort_callback& aborter) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335 for (unsigned add = 0; ; ++add) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336 pfc::string8 fn(desiredName); uniqueFn(fn, add);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 pfc::string8 dst(folder->canonicalPath()->c_str());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338 dst.end_with(m_fs->pathSeparator());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339 dst += fn;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340 bool bDidExist = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342 if (createMode == createMode::allowExisting) m_fs->move_overwrite(m_path->c_str(), dst, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343 else m_fs->move(m_path->c_str(), dst, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344 } catch (exception_io_already_exists const &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345 bDidExist = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348 switch (createMode) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
349 case createMode::allowExisting:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
350 break; // OK
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
351 case createMode::failIfExists:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
352 if (bDidExist) throw exception_io_already_exists();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
353 break; // OK
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
354 case createMode::generateUniqueName:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
355 if (bDidExist) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
356 continue; // the for loop
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
357 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
358 break; // OK
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
359 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
360 PFC_ASSERT(!"Should not get here");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
361 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
362 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
363
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
364 return m_fs->makeItemFolderStd(dst, m_opportunistStats);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
365
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
366 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
367 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
368 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
369 stringRef subPath(const char* name) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
370 pfc::string8 temp(m_path->c_str());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
371 temp.add_filename(name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
372 return makeString(temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
373 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
374 const filesystem::ptr m_fs;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
375 const stringRef m_path;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
376 t_filestats2 m_opportunistStats;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
377 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
378 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
379
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
380 fsItemFolder::ptr filesystem::makeItemFolderStd(const char* pathCanonical, t_filestats2 const& opportunistStats) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
381 return new service_impl_t<fsItemFolderStd>(this, makeString(pathCanonical), opportunistStats);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
382 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
383
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
384 fsItemFile::ptr filesystem::makeItemFileStd(const char* pathCanonical, t_filestats2 const & opportunistStats) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
385 return new service_impl_t<fsItemFileStd>(this, makeString(pathCanonical), opportunistStats);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
386 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
387 fsItemBase::ptr filesystem::findItem_(const char* path, abort_callback& p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
388 filesystem_v3::ptr v3;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
389 if (v3 &= this) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
390 return v3->findItem(path, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
391 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
392 auto stats = this->get_stats2_(path, stats2_fileOrFolder, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
393 if (stats.is_folder()) return this->makeItemFolderStd(path, stats);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
394 else return this->makeItemFileStd(path, stats);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
395
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
396 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
397 fsItemFile::ptr filesystem::findItemFile_(const char* path, abort_callback& p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
398 filesystem_v3::ptr v3;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
399 if (v3 &= this) return v3->findItemFile(path, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
400
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
401 auto stats = this->get_stats2_(path, stats2_fileOrFolder, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
402 if (!stats.is_folder()) return this->makeItemFileStd(path, stats);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
403 throw exception_io_not_found();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
404 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
405 fsItemFolder::ptr filesystem::findItemFolder_(const char* path, abort_callback& p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
406 filesystem_v3::ptr v3;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
407 if (v3 &= this) return v3->findItemFolder(path, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
408
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
409 auto stats = this->get_stats2_(path, stats2_fileOrFolder, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
410 if (stats.is_folder()) return this->makeItemFolderStd(path, stats);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
411 throw exception_io_not_found();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
412 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
413
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
414
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
415 fsItemBase::ptr fsItemBase::fromPath(const char* path, abort_callback& aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
416 return filesystem::get(path)->findItem_(path, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
417 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
418
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
419 fsItemFile::ptr fsItemFile::fromPath(const char* path, abort_callback& aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
420 return filesystem::get(path)->findItemFile_(path, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
421 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
422
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
423 fsItemFolder::ptr fsItemFolder::fromPath(const char* path, abort_callback& aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
424 return filesystem::get(path)->findItemFolder_(path, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
425 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
426
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
427 t_filestats fsItemBase::getStats(abort_callback& a) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
428 return getStats2(stats2_all, a).to_legacy();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
429 }