Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(881)

Side by Side Diff: ppapi/examples/filesystem_provider/memfilesystem.cc

Issue 1093383002: [WIP] Provided file system from NACL. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Various cleanups Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "memfilesystem.h"
6
7 #include <deque>
8
9 namespace filesystem{
10
11 Filesystem::Filesystem()
12 :currentInode_(1),
13 root_path("/") {
14 // Adding root directory
15 root_inode = GetNextInodeNumber();
16 InodeDirectory* root_directory = new InodeDirectory(this, root_inode);
17
18 // Add it to the list and increment ref count
19 if (root_directory){
20 PutInode(root_directory->inode_number(), root_directory);
21 AddLink(root_directory->inode_number());
22 }
23 }
24
25 Filesystem::~Filesystem() {
26 for (ListOfInodesIterator it(inodesList_.begin());
27 it != inodesList_.end(); it++)
28 delete it->second.second;
29
30 inodesList_.clear();
31 }
32
33 int Filesystem::GetMetadata(
34 const std::string& path,
35 Filesystem::NameInodePair &meta) {
36 std::string filePath = path.substr(path.find_last_of("/")+1);
37 Inode* inode = nullptr;
38
39 if(path.size()==0)//root
40 inode = GetInode(root_inode);
41 else
42 inode = GetInode( GetInodeFromPath(path) );
43
44 if (inode==nullptr)
45 return File_System_Error_NOT_FOUND;
46
47 meta.first = filePath;
48 meta.second = inode;
49
50 return File_System_Error_NONE;
51 }
52
53
54 int Filesystem::CreateDirectory(const std::string& path, bool recursive) {
55 if (path.size() == 0 ||
56 path[0] != '/')
57 return File_System_Error_NOT_FOUND;
58
59 std::deque<std::string> tree_entries;
60 size_t position = path.find_first_of("/");
61 std::string rest = path.substr( position + 1 );
62
63 // Break the path into components
64 // starting rigth after "/".
65 while (1) {
66 position = rest.find_first_of("/");
67 tree_entries.push_back(rest.substr(0, position) );
68 if (std::string::npos == position)
69 break;
70 rest = rest.substr(position + 1);
71 }
72
73 std::string current_dir = "";
74 unsigned long long workingInode = root_inode;
75 InodeDirectory*
76 current_inode = static_cast<InodeDirectory*>(GetInode(workingInode));
77
78 if (current_inode==nullptr||
79 current_inode->file_type()!=Inode::FILE_TYPE_DIR)
80 return File_System_Error_FAILED;
81
82 // At this point we have the root inode
83 // and we will traverse the path downwards and create
84 // if recursive is true intermediate directories
85 while (tree_entries.size() > 0) {
86 current_dir = tree_entries.front();
87 tree_entries.pop_front();
88 if (tree_entries.size() == 0) { // the new dir
89 InodeDirectory *new_dir =
90 new InodeDirectory(this, GetNextInodeNumber());
91 if (new_dir==nullptr)
92 return File_System_Error_FAILED;
93 // Add to the inode list
94 PutInode(new_dir->inode_number(), new_dir);
95 current_inode->AddEntry(current_dir, new_dir->inode_number());
96 return File_System_Error_NONE;
97 } else {
98 if ((workingInode =
99 current_inode->GetInodeFromName(current_dir))== Inode::NO_INODE) {
100 if (recursive == false) // all dirs must exist
101 return File_System_Error_NOT_FOUND;
102 else {
103 InodeDirectory *new_dir =
104 new InodeDirectory(this, GetNextInodeNumber());
105 if (new_dir==nullptr)
106 return File_System_Error_FAILED;
107 PutInode(new_dir->inode_number(), new_dir);
108 current_inode->AddEntry(current_dir, new_dir->inode_number());
109 // Hop into to the just created directory
110 current_inode = new_dir;
111 workingInode = new_dir->inode_number();
112 }
113 } else {
114 // hope into the directory
115 current_inode = static_cast<InodeDirectory*>( GetInode(workingInode) );
116 if(current_inode->file_type()!=Inode::FILE_TYPE_DIR)
117 return File_System_Error_NOT_FOUND;
118 }
119 }
120 }
121 return File_System_Error_FAILED;
122 }
123
124 int Filesystem::MoveEntry(
125 const std::string& sourcePath,
126 const std::string& targetPath) {
127 std::string sourceDir = sourcePath.substr(0, sourcePath.find_last_of("/"));
128 std::string targetDir = targetPath.substr(0, targetPath.find_last_of("/"));
129
130 std::string sourceFile = sourcePath.substr(sourcePath.find_last_of("/")+1);
131 std::string targetFile = targetPath.substr(targetPath.find_last_of("/") + 1);
132
133 if (sourceFile.size() == 0 ||
134 targetFile.size() == 0)
135 return File_System_Error_FAILED;
136
137 if (sourceDir.size() == 0)
138 sourceDir = "/";
139 if (targetDir.size() == 0)
140 targetDir = "/";
141
142 // Point to the parent dirs
143 InodeDirectory *srcInode =
144 static_cast<InodeDirectory*>(GetInode(GetInodeFromPath(sourceDir)));
145 InodeDirectory *dstInode =
146 static_cast<InodeDirectory*>(GetInode(GetInodeFromPath(targetDir)));
147
148 if (nullptr == srcInode ||
149 srcInode->file_type()!=Inode::FILE_TYPE_DIR||
150 nullptr == dstInode||
151 dstInode->file_type()!=Inode::FILE_TYPE_DIR)
152 return File_System_Error_NOT_FOUND;
153
154 unsigned long long toBeMoved = srcInode->GetInodeFromName(sourceFile);
155 if (toBeMoved == Inode::NO_INODE)
156 return File_System_Error_FAILED;
157
158 dstInode->AddEntry(targetFile, toBeMoved); // adds link
159 srcInode->DeleteEntry(sourceFile, toBeMoved); // removes link
160
161 return File_System_Error_NONE;
162 }
163
164 int Filesystem::CopyEntry(
165 const std::string& sourcePath,
166 const std::string& targetPath) {
167 std::string sourceDir = sourcePath.substr(0, sourcePath.find_last_of("/"));
168 std::string targetDir = targetPath.substr(0, targetPath.find_last_of("/"));
169
170 std::string sourceFile = sourcePath.substr(sourcePath.find_last_of("/") + 1);
171 std::string targetFile = targetPath.substr(targetPath.find_last_of("/") + 1);
172
173 if (sourceFile.size() == 0 ||
174 targetFile.size() == 0)
175 return File_System_Error_FAILED;
176
177 if (sourceDir.size() == 0)
178 sourceDir = "/";
179 if (targetDir.size() == 0)
180 targetDir = "/";
181
182 InodeDirectory *srcInode =
183 static_cast<InodeDirectory*>(GetInode(GetInodeFromPath(sourceDir)));
184 InodeDirectory *dstInode =
185 static_cast<InodeDirectory*>(GetInode(GetInodeFromPath(targetDir)));
186
187 if (nullptr == srcInode ||
188 srcInode->file_type()!=Inode::FILE_TYPE_DIR||
189 nullptr == dstInode||
190 dstInode->file_type()!=Inode::FILE_TYPE_DIR)
191 return File_System_Error_NOT_FOUND;
192
193 unsigned long long toBeCopied = srcInode->GetInodeFromName(sourceFile);
194 if (toBeCopied == Inode::NO_INODE)
195 return File_System_Error_FAILED;
196
197 Inode* old_inode = GetInode(toBeCopied);
198
199 if (nullptr == old_inode)
200 return File_System_Error_NOT_FOUND;
201
202 Inode* new_inode = nullptr;
203 if (old_inode->file_type() == Inode::FILE_TYPE_FILE) {
204 InodeFile *temp = static_cast<InodeFile*>(old_inode);
205 new_inode = new InodeFile(*temp);
206 if (nullptr == new_inode)
207 return File_System_Error_FAILED;
208 }
209 else if (old_inode->file_type() == Inode::FILE_TYPE_DIR) {
210 InodeDirectory *temp = static_cast<InodeDirectory*>(old_inode);
211 new_inode = new InodeDirectory(*temp);
212 if (nullptr == new_inode)
213 return File_System_Error_FAILED;
214 }
215
216 new_inode->set_inode_number(GetNextInodeNumber());
217 PutInode(new_inode->inode_number(), new_inode);
218 new_inode->set_inode_modified();
219
220 dstInode->AddEntry(targetFile, new_inode->inode_number());
221 return File_System_Error_NONE;
222 }
223
224
225 int Filesystem::DeleteEntry(const std::string& path, bool recursive) {
226 unsigned long long workingInode = GetInodeFromPath(path);
227 Inode* current_inode = GetInode(workingInode);
228
229 if (nullptr == current_inode)
230 return File_System_Error_NOT_FOUND;
231
232 if (current_inode->file_type() == Inode::FILE_TYPE_DIR &&
233 !recursive)
234 return File_System_Error_NOT_FOUND;
235
236 std::string dir = path.substr(0, path.find_last_of("/"));
237 if (dir.size() == 0)
238 dir = "/";
239
240 InodeDirectory* parent_inode =
241 static_cast<InodeDirectory*>(GetInode(GetInodeFromPath(dir)));
242 if (nullptr == parent_inode||
243 parent_inode->file_type()!=Inode::FILE_TYPE_DIR)
244 return File_System_Error_NOT_FOUND;
245 parent_inode->DeleteEntry(
246 path.substr(path.find_last_of("/")+1), workingInode);
247
248 return File_System_Error_NONE;
249 }
250
251 int Filesystem::ReadDirectory (
252 const std::string& path,
253 std::vector<NameInodePair>& metas){
254
255 InodeDirectory* inode_directory =
256 static_cast<InodeDirectory*>(GetInode(GetInodeFromPath(path)));
257
258 if (nullptr==inode_directory||
259 inode_directory->file_type()!=Inode::FILE_TYPE_DIR)
260 return File_System_Error_FAILED;
261 std::vector< InodeDirectory::EntryPair > listOfEntries;
262 inode_directory->GetAllInodes(listOfEntries);
263 Inode* inode = nullptr;
264 for (std::vector< InodeDirectory::EntryPair >::iterator
265 it(listOfEntries.begin());
266 it != listOfEntries.end(); it++) {
267 inode = GetInode(it->second);
268 if (nullptr != inode)
269 metas.push_back(NameInodePair(it->first, inode));
270 }
271 return File_System_Error_NONE;
272 }
273
274 int Filesystem::CreateFile(const std::string& filePath) {
275 std::string targetDir = filePath.substr(0, filePath.find_last_of("/"));
276 std::string filename = filePath.substr(filePath.find_last_of("/") + 1);
277
278 if (targetDir.size() == 0)
279 targetDir = "/";
280 if (filename.size()==0)
281 return File_System_Error_FAILED;
282 InodeDirectory* inode_directory =
283 static_cast<InodeDirectory*>(GetInode(GetInodeFromPath(targetDir)));
284 if (nullptr == inode_directory||
285 inode_directory->file_type()!=Inode::FILE_TYPE_DIR)
286 return File_System_Error_FAILED;
287
288 InodeFile* inode_file = new InodeFile(GetNextInodeNumber());
289 if (nullptr == inode_file)
290 return File_System_Error_FAILED;
291
292 PutInode(inode_file->inode_number(), inode_file);
293 inode_directory->AddEntry(filename, inode_file->inode_number());
294 return File_System_Error_NONE;
295 }
296
297 int Filesystem::Truncate(const std::string &filePath, size_t length) {
298 InodeFile *inode_file =
299 static_cast<InodeFile*>( GetInode( GetInodeFromPath(filePath) ) );
300 if (inode_file==nullptr ||
301 inode_file->file_type() != Inode::FILE_TYPE_FILE)
302 return File_System_Error_NOT_FOUND;
303
304 inode_file->Truncate(length);
305 return File_System_Error_NONE;
306 }
307
308 int Filesystem::WriteToFile(
309 const std::string &filePath,
310 size_t offset,
311 size_t dataSize,
312 const char *data) {
313 InodeFile *inode_file =
314 static_cast<InodeFile*>( GetInode( GetInodeFromPath(filePath) ) );
315 if(inode_file==nullptr||
316 inode_file->file_type()!=Inode::FILE_TYPE_FILE)
317 return File_System_Error_NOT_FOUND;
318
319 if( inode_file->Write(data, offset, dataSize) )
320 return File_System_Error_NONE;
321 return File_System_Error_FAILED;
322 }
323
324 int Filesystem::ReadFromFile(const std::string &filePath,
325 size_t offset,
326 size_t* inOutLength,
327 const char** outData) {
328 InodeFile *inode_file =
329 static_cast<InodeFile*>( GetInode( GetInodeFromPath(filePath) ) );
330 if (inode_file==nullptr||
331 inode_file->file_type()!=Inode::FILE_TYPE_FILE)
332 return File_System_Error_NOT_FOUND;
333
334 if (inode_file->Read(offset, inOutLength, outData ))
335 return File_System_Error_NONE;
336 return File_System_Error_FAILED;
337 }
338
339 void Filesystem::AddLink(unsigned long long inode) {
340 ListOfInodesIterator it(inodesList_.find(inode));
341 if (it != inodesList_.end()) {
342 it->second.first++;
343 // If directory add a reference for each entry it contains
344 if (it->second.second->file_type() == Inode::FILE_TYPE_DIR) {
345 InodeDirectory* inode_directory =
346 static_cast<InodeDirectory*>(it->second.second);
347 if (nullptr == inode_directory)
348 return;
349 std::vector<InodeDirectory::EntryPair> entries;
350 inode_directory->GetAllInodes(entries);
351 for (std::vector<InodeDirectory::EntryPair>::iterator
352 entry = entries.begin();
353 entry != entries.end(); ++entry) {
354 AddLink(entry->second);
355 }
356 }
357 }
358 }
359 void Filesystem::RemoveLink(unsigned long long inode_number) {
360 ListOfInodesIterator it(inodesList_.find(inode_number));
361 if (it != inodesList_.end()) {
362 Inode* inode = it->second.second;
363 if (nullptr == inode)
364 return;
365 if (inode->file_type() == Inode::FILE_TYPE_DIR) {
366 InodeDirectory* inode_directory =
367 static_cast<InodeDirectory*>(inode);
368 if (nullptr == inode_directory)
369 return;
370 // Get all inodes and remove their reference
371 std::vector<InodeDirectory::EntryPair> entries;
372 inode_directory->GetAllInodes(entries);
373 for (std::vector<InodeDirectory::EntryPair>::iterator
374 entry = entries.begin();
375 entry != entries.end(); entry++) {
376 RemoveLink(entry->second);
377 }
378 }
379 // If current reference is down to 0
380 // then remove it
381 if (--it->second.first==0) {
382 delete inode;
383 inodesList_.erase(it);
384 }
385 }
386 }
387
388 Inode* Filesystem::GetInode(unsigned long long inode) {
389 ListOfInodesIterator it = inodesList_.find(inode);
390 if (it == inodesList_.end())
391 return nullptr;
392 return it->second.second;
393 }
394
395 void Filesystem::PutInode(unsigned long long inode_number, Inode* inode) {
396 inodesList_.insert(std::pair<unsigned long long,InodePair >(
397 inode_number, InodePair( 0, inode) ) );
398 }
399 void Filesystem::RemoveInode(unsigned long long inode) {
400 ListOfInodesIterator it = inodesList_.find(inode);
401 inodesList_.erase(it);
402 }
403
404 unsigned long long Filesystem::GetInodeFromPath(const std::string& path){
405 if (path.size() == 0 ||
406 path[0] != '/')
407 return File_System_Error_NOT_FOUND;
408
409 std::deque<std::string> tree_entries;
410 std::string::size_type position = 0;
411 std::string rest = path.substr(1);
412 std::string temp;
413
414 while (1) {
415 position = rest.find_first_of("/");
416 temp = rest.substr(0, position);
417 if (temp.size()!=0)
418 tree_entries.push_back(temp);
419 if (std::string::npos == position)
420 break;
421 rest = rest.substr(position + 1);
422 }
423
424 std::string current_dir = "";
425 unsigned long long workingInode = root_inode;
426 InodeDirectory* current_inode =
427 static_cast<InodeDirectory*>(GetInode(workingInode));
428 if (current_inode==nullptr||
429 current_inode->file_type()!=Inode::FILE_TYPE_DIR)
430 return Inode::NO_INODE;
431 while ( tree_entries.size() > 0) {
432 current_dir = tree_entries.front();
433 tree_entries.pop_front();
434
435 workingInode = current_inode->GetInodeFromName(current_dir);
436 if (workingInode == Inode::NO_INODE)
437 return File_System_Error_NOT_FOUND;
438 if (tree_entries.size() > 0) {
439 current_inode =
440 static_cast<InodeDirectory*>(GetInode(workingInode));
441 if (current_inode==nullptr||
442 current_inode->file_type()!=Inode::FILE_TYPE_DIR)
443 return Inode::NO_INODE;
444 }
445 }
446 return workingInode;
447 }
448
449 unsigned long long Filesystem::GetNextInodeNumber(){
450 if (++currentInode_ == Inode::NO_INODE)
451 return ++currentInode_;
452 return currentInode_;
453 }
454
455
456 }// namespace filesystem
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698