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

Unified 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, 7 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 side-by-side diff with in-line comments
Download patch
Index: ppapi/examples/filesystem_provider/memfilesystem.cc
diff --git a/ppapi/examples/filesystem_provider/memfilesystem.cc b/ppapi/examples/filesystem_provider/memfilesystem.cc
new file mode 100644
index 0000000000000000000000000000000000000000..93bc7dd21e20665c9c5b3d11c02b12b2dcb1facf
--- /dev/null
+++ b/ppapi/examples/filesystem_provider/memfilesystem.cc
@@ -0,0 +1,456 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "memfilesystem.h"
+
+#include <deque>
+
+namespace filesystem{
+
+Filesystem::Filesystem()
+ :currentInode_(1),
+ root_path("/") {
+ // Adding root directory
+ root_inode = GetNextInodeNumber();
+ InodeDirectory* root_directory = new InodeDirectory(this, root_inode);
+
+ // Add it to the list and increment ref count
+ if (root_directory){
+ PutInode(root_directory->inode_number(), root_directory);
+ AddLink(root_directory->inode_number());
+ }
+}
+
+Filesystem::~Filesystem() {
+ for (ListOfInodesIterator it(inodesList_.begin());
+ it != inodesList_.end(); it++)
+ delete it->second.second;
+
+ inodesList_.clear();
+}
+
+int Filesystem::GetMetadata(
+ const std::string& path,
+ Filesystem::NameInodePair &meta) {
+ std::string filePath = path.substr(path.find_last_of("/")+1);
+ Inode* inode = nullptr;
+
+ if(path.size()==0)//root
+ inode = GetInode(root_inode);
+ else
+ inode = GetInode( GetInodeFromPath(path) );
+
+ if (inode==nullptr)
+ return File_System_Error_NOT_FOUND;
+
+ meta.first = filePath;
+ meta.second = inode;
+
+ return File_System_Error_NONE;
+}
+
+
+int Filesystem::CreateDirectory(const std::string& path, bool recursive) {
+ if (path.size() == 0 ||
+ path[0] != '/')
+ return File_System_Error_NOT_FOUND;
+
+ std::deque<std::string> tree_entries;
+ size_t position = path.find_first_of("/");
+ std::string rest = path.substr( position + 1 );
+
+ // Break the path into components
+ // starting rigth after "/".
+ while (1) {
+ position = rest.find_first_of("/");
+ tree_entries.push_back(rest.substr(0, position) );
+ if (std::string::npos == position)
+ break;
+ rest = rest.substr(position + 1);
+ }
+
+ std::string current_dir = "";
+ unsigned long long workingInode = root_inode;
+ InodeDirectory*
+ current_inode = static_cast<InodeDirectory*>(GetInode(workingInode));
+
+ if (current_inode==nullptr||
+ current_inode->file_type()!=Inode::FILE_TYPE_DIR)
+ return File_System_Error_FAILED;
+
+ // At this point we have the root inode
+ // and we will traverse the path downwards and create
+ // if recursive is true intermediate directories
+ while (tree_entries.size() > 0) {
+ current_dir = tree_entries.front();
+ tree_entries.pop_front();
+ if (tree_entries.size() == 0) { // the new dir
+ InodeDirectory *new_dir =
+ new InodeDirectory(this, GetNextInodeNumber());
+ if (new_dir==nullptr)
+ return File_System_Error_FAILED;
+ // Add to the inode list
+ PutInode(new_dir->inode_number(), new_dir);
+ current_inode->AddEntry(current_dir, new_dir->inode_number());
+ return File_System_Error_NONE;
+ } else {
+ if ((workingInode =
+ current_inode->GetInodeFromName(current_dir))== Inode::NO_INODE) {
+ if (recursive == false) // all dirs must exist
+ return File_System_Error_NOT_FOUND;
+ else {
+ InodeDirectory *new_dir =
+ new InodeDirectory(this, GetNextInodeNumber());
+ if (new_dir==nullptr)
+ return File_System_Error_FAILED;
+ PutInode(new_dir->inode_number(), new_dir);
+ current_inode->AddEntry(current_dir, new_dir->inode_number());
+ // Hop into to the just created directory
+ current_inode = new_dir;
+ workingInode = new_dir->inode_number();
+ }
+ } else {
+ // hope into the directory
+ current_inode = static_cast<InodeDirectory*>( GetInode(workingInode) );
+ if(current_inode->file_type()!=Inode::FILE_TYPE_DIR)
+ return File_System_Error_NOT_FOUND;
+ }
+ }
+ }
+ return File_System_Error_FAILED;
+}
+
+int Filesystem::MoveEntry(
+ const std::string& sourcePath,
+ const std::string& targetPath) {
+ std::string sourceDir = sourcePath.substr(0, sourcePath.find_last_of("/"));
+ std::string targetDir = targetPath.substr(0, targetPath.find_last_of("/"));
+
+ std::string sourceFile = sourcePath.substr(sourcePath.find_last_of("/")+1);
+ std::string targetFile = targetPath.substr(targetPath.find_last_of("/") + 1);
+
+ if (sourceFile.size() == 0 ||
+ targetFile.size() == 0)
+ return File_System_Error_FAILED;
+
+ if (sourceDir.size() == 0)
+ sourceDir = "/";
+ if (targetDir.size() == 0)
+ targetDir = "/";
+
+ // Point to the parent dirs
+ InodeDirectory *srcInode =
+ static_cast<InodeDirectory*>(GetInode(GetInodeFromPath(sourceDir)));
+ InodeDirectory *dstInode =
+ static_cast<InodeDirectory*>(GetInode(GetInodeFromPath(targetDir)));
+
+ if (nullptr == srcInode ||
+ srcInode->file_type()!=Inode::FILE_TYPE_DIR||
+ nullptr == dstInode||
+ dstInode->file_type()!=Inode::FILE_TYPE_DIR)
+ return File_System_Error_NOT_FOUND;
+
+ unsigned long long toBeMoved = srcInode->GetInodeFromName(sourceFile);
+ if (toBeMoved == Inode::NO_INODE)
+ return File_System_Error_FAILED;
+
+ dstInode->AddEntry(targetFile, toBeMoved); // adds link
+ srcInode->DeleteEntry(sourceFile, toBeMoved); // removes link
+
+ return File_System_Error_NONE;
+}
+
+int Filesystem::CopyEntry(
+ const std::string& sourcePath,
+ const std::string& targetPath) {
+ std::string sourceDir = sourcePath.substr(0, sourcePath.find_last_of("/"));
+ std::string targetDir = targetPath.substr(0, targetPath.find_last_of("/"));
+
+ std::string sourceFile = sourcePath.substr(sourcePath.find_last_of("/") + 1);
+ std::string targetFile = targetPath.substr(targetPath.find_last_of("/") + 1);
+
+ if (sourceFile.size() == 0 ||
+ targetFile.size() == 0)
+ return File_System_Error_FAILED;
+
+ if (sourceDir.size() == 0)
+ sourceDir = "/";
+ if (targetDir.size() == 0)
+ targetDir = "/";
+
+ InodeDirectory *srcInode =
+ static_cast<InodeDirectory*>(GetInode(GetInodeFromPath(sourceDir)));
+ InodeDirectory *dstInode =
+ static_cast<InodeDirectory*>(GetInode(GetInodeFromPath(targetDir)));
+
+ if (nullptr == srcInode ||
+ srcInode->file_type()!=Inode::FILE_TYPE_DIR||
+ nullptr == dstInode||
+ dstInode->file_type()!=Inode::FILE_TYPE_DIR)
+ return File_System_Error_NOT_FOUND;
+
+ unsigned long long toBeCopied = srcInode->GetInodeFromName(sourceFile);
+ if (toBeCopied == Inode::NO_INODE)
+ return File_System_Error_FAILED;
+
+ Inode* old_inode = GetInode(toBeCopied);
+
+ if (nullptr == old_inode)
+ return File_System_Error_NOT_FOUND;
+
+ Inode* new_inode = nullptr;
+ if (old_inode->file_type() == Inode::FILE_TYPE_FILE) {
+ InodeFile *temp = static_cast<InodeFile*>(old_inode);
+ new_inode = new InodeFile(*temp);
+ if (nullptr == new_inode)
+ return File_System_Error_FAILED;
+ }
+ else if (old_inode->file_type() == Inode::FILE_TYPE_DIR) {
+ InodeDirectory *temp = static_cast<InodeDirectory*>(old_inode);
+ new_inode = new InodeDirectory(*temp);
+ if (nullptr == new_inode)
+ return File_System_Error_FAILED;
+ }
+
+ new_inode->set_inode_number(GetNextInodeNumber());
+ PutInode(new_inode->inode_number(), new_inode);
+ new_inode->set_inode_modified();
+
+ dstInode->AddEntry(targetFile, new_inode->inode_number());
+ return File_System_Error_NONE;
+}
+
+
+int Filesystem::DeleteEntry(const std::string& path, bool recursive) {
+ unsigned long long workingInode = GetInodeFromPath(path);
+ Inode* current_inode = GetInode(workingInode);
+
+ if (nullptr == current_inode)
+ return File_System_Error_NOT_FOUND;
+
+ if (current_inode->file_type() == Inode::FILE_TYPE_DIR &&
+ !recursive)
+ return File_System_Error_NOT_FOUND;
+
+ std::string dir = path.substr(0, path.find_last_of("/"));
+ if (dir.size() == 0)
+ dir = "/";
+
+ InodeDirectory* parent_inode =
+ static_cast<InodeDirectory*>(GetInode(GetInodeFromPath(dir)));
+ if (nullptr == parent_inode||
+ parent_inode->file_type()!=Inode::FILE_TYPE_DIR)
+ return File_System_Error_NOT_FOUND;
+ parent_inode->DeleteEntry(
+ path.substr(path.find_last_of("/")+1), workingInode);
+
+ return File_System_Error_NONE;
+}
+
+int Filesystem::ReadDirectory (
+ const std::string& path,
+ std::vector<NameInodePair>& metas){
+
+ InodeDirectory* inode_directory =
+ static_cast<InodeDirectory*>(GetInode(GetInodeFromPath(path)));
+
+ if (nullptr==inode_directory||
+ inode_directory->file_type()!=Inode::FILE_TYPE_DIR)
+ return File_System_Error_FAILED;
+ std::vector< InodeDirectory::EntryPair > listOfEntries;
+ inode_directory->GetAllInodes(listOfEntries);
+ Inode* inode = nullptr;
+ for (std::vector< InodeDirectory::EntryPair >::iterator
+ it(listOfEntries.begin());
+ it != listOfEntries.end(); it++) {
+ inode = GetInode(it->second);
+ if (nullptr != inode)
+ metas.push_back(NameInodePair(it->first, inode));
+ }
+ return File_System_Error_NONE;
+}
+
+int Filesystem::CreateFile(const std::string& filePath) {
+ std::string targetDir = filePath.substr(0, filePath.find_last_of("/"));
+ std::string filename = filePath.substr(filePath.find_last_of("/") + 1);
+
+ if (targetDir.size() == 0)
+ targetDir = "/";
+ if (filename.size()==0)
+ return File_System_Error_FAILED;
+ InodeDirectory* inode_directory =
+ static_cast<InodeDirectory*>(GetInode(GetInodeFromPath(targetDir)));
+ if (nullptr == inode_directory||
+ inode_directory->file_type()!=Inode::FILE_TYPE_DIR)
+ return File_System_Error_FAILED;
+
+ InodeFile* inode_file = new InodeFile(GetNextInodeNumber());
+ if (nullptr == inode_file)
+ return File_System_Error_FAILED;
+
+ PutInode(inode_file->inode_number(), inode_file);
+ inode_directory->AddEntry(filename, inode_file->inode_number());
+ return File_System_Error_NONE;
+}
+
+int Filesystem::Truncate(const std::string &filePath, size_t length) {
+ InodeFile *inode_file =
+ static_cast<InodeFile*>( GetInode( GetInodeFromPath(filePath) ) );
+ if (inode_file==nullptr ||
+ inode_file->file_type() != Inode::FILE_TYPE_FILE)
+ return File_System_Error_NOT_FOUND;
+
+ inode_file->Truncate(length);
+ return File_System_Error_NONE;
+}
+
+int Filesystem::WriteToFile(
+ const std::string &filePath,
+ size_t offset,
+ size_t dataSize,
+ const char *data) {
+ InodeFile *inode_file =
+ static_cast<InodeFile*>( GetInode( GetInodeFromPath(filePath) ) );
+ if(inode_file==nullptr||
+ inode_file->file_type()!=Inode::FILE_TYPE_FILE)
+ return File_System_Error_NOT_FOUND;
+
+ if( inode_file->Write(data, offset, dataSize) )
+ return File_System_Error_NONE;
+ return File_System_Error_FAILED;
+}
+
+int Filesystem::ReadFromFile(const std::string &filePath,
+ size_t offset,
+ size_t* inOutLength,
+ const char** outData) {
+ InodeFile *inode_file =
+ static_cast<InodeFile*>( GetInode( GetInodeFromPath(filePath) ) );
+ if (inode_file==nullptr||
+ inode_file->file_type()!=Inode::FILE_TYPE_FILE)
+ return File_System_Error_NOT_FOUND;
+
+ if (inode_file->Read(offset, inOutLength, outData ))
+ return File_System_Error_NONE;
+ return File_System_Error_FAILED;
+}
+
+void Filesystem::AddLink(unsigned long long inode) {
+ ListOfInodesIterator it(inodesList_.find(inode));
+ if (it != inodesList_.end()) {
+ it->second.first++;
+ // If directory add a reference for each entry it contains
+ if (it->second.second->file_type() == Inode::FILE_TYPE_DIR) {
+ InodeDirectory* inode_directory =
+ static_cast<InodeDirectory*>(it->second.second);
+ if (nullptr == inode_directory)
+ return;
+ std::vector<InodeDirectory::EntryPair> entries;
+ inode_directory->GetAllInodes(entries);
+ for (std::vector<InodeDirectory::EntryPair>::iterator
+ entry = entries.begin();
+ entry != entries.end(); ++entry) {
+ AddLink(entry->second);
+ }
+ }
+ }
+}
+void Filesystem::RemoveLink(unsigned long long inode_number) {
+ ListOfInodesIterator it(inodesList_.find(inode_number));
+ if (it != inodesList_.end()) {
+ Inode* inode = it->second.second;
+ if (nullptr == inode)
+ return;
+ if (inode->file_type() == Inode::FILE_TYPE_DIR) {
+ InodeDirectory* inode_directory =
+ static_cast<InodeDirectory*>(inode);
+ if (nullptr == inode_directory)
+ return;
+ // Get all inodes and remove their reference
+ std::vector<InodeDirectory::EntryPair> entries;
+ inode_directory->GetAllInodes(entries);
+ for (std::vector<InodeDirectory::EntryPair>::iterator
+ entry = entries.begin();
+ entry != entries.end(); entry++) {
+ RemoveLink(entry->second);
+ }
+ }
+ // If current reference is down to 0
+ // then remove it
+ if (--it->second.first==0) {
+ delete inode;
+ inodesList_.erase(it);
+ }
+ }
+}
+
+Inode* Filesystem::GetInode(unsigned long long inode) {
+ ListOfInodesIterator it = inodesList_.find(inode);
+ if (it == inodesList_.end())
+ return nullptr;
+ return it->second.second;
+}
+
+void Filesystem::PutInode(unsigned long long inode_number, Inode* inode) {
+ inodesList_.insert(std::pair<unsigned long long,InodePair >(
+ inode_number, InodePair( 0, inode) ) );
+}
+void Filesystem::RemoveInode(unsigned long long inode) {
+ ListOfInodesIterator it = inodesList_.find(inode);
+ inodesList_.erase(it);
+}
+
+unsigned long long Filesystem::GetInodeFromPath(const std::string& path){
+ if (path.size() == 0 ||
+ path[0] != '/')
+ return File_System_Error_NOT_FOUND;
+
+ std::deque<std::string> tree_entries;
+ std::string::size_type position = 0;
+ std::string rest = path.substr(1);
+ std::string temp;
+
+ while (1) {
+ position = rest.find_first_of("/");
+ temp = rest.substr(0, position);
+ if (temp.size()!=0)
+ tree_entries.push_back(temp);
+ if (std::string::npos == position)
+ break;
+ rest = rest.substr(position + 1);
+ }
+
+ std::string current_dir = "";
+ unsigned long long workingInode = root_inode;
+ InodeDirectory* current_inode =
+ static_cast<InodeDirectory*>(GetInode(workingInode));
+ if (current_inode==nullptr||
+ current_inode->file_type()!=Inode::FILE_TYPE_DIR)
+ return Inode::NO_INODE;
+ while ( tree_entries.size() > 0) {
+ current_dir = tree_entries.front();
+ tree_entries.pop_front();
+
+ workingInode = current_inode->GetInodeFromName(current_dir);
+ if (workingInode == Inode::NO_INODE)
+ return File_System_Error_NOT_FOUND;
+ if (tree_entries.size() > 0) {
+ current_inode =
+ static_cast<InodeDirectory*>(GetInode(workingInode));
+ if (current_inode==nullptr||
+ current_inode->file_type()!=Inode::FILE_TYPE_DIR)
+ return Inode::NO_INODE;
+ }
+ }
+ return workingInode;
+}
+
+unsigned long long Filesystem::GetNextInodeNumber(){
+ if (++currentInode_ == Inode::NO_INODE)
+ return ++currentInode_;
+ return currentInode_;
+}
+
+
+}// namespace filesystem

Powered by Google App Engine
This is Rietveld 408576698