X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=libs%2Ffs_filesystem.h;h=5cd42a63a397826e8d4e650d11b3b792420b0ea8;hp=0c22a4b3a7442bdeb843906f7a0b33f1e59448ff;hb=b7e36c120eb1546a6c6f97f30e42ab7f9a559c61;hpb=d584d9454904666d8de69a99dd4fb29e5dbab433 diff --git a/libs/fs_filesystem.h b/libs/fs_filesystem.h index 0c22a4b3..5cd42a63 100644 --- a/libs/fs_filesystem.h +++ b/libs/fs_filesystem.h @@ -1,25 +1,25 @@ /* -Copyright (C) 2001-2006, William Joseph. -All Rights Reserved. + Copyright (C) 2001-2006, William Joseph. + All Rights Reserved. -This file is part of GtkRadiant. + This file is part of GtkRadiant. -GtkRadiant is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -GtkRadiant is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with GtkRadiant; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ -#if !defined(INCLUDED_FS_FILESYSTEM_H) +#if !defined( INCLUDED_FS_FILESYSTEM_H ) #define INCLUDED_FS_FILESYSTEM_H #include "string/string.h" @@ -27,19 +27,17 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include -inline unsigned int path_get_depth(const char* path) -{ - unsigned int depth = 0; - while(path != 0 && path[0] != '\0') - { - path = strchr(path, '/'); - if(path != 0) - { - ++path; - } - ++depth; - } - return depth; +inline unsigned int path_get_depth( const char* path ){ + unsigned int depth = 0; + while ( path != 0 && path[0] != '\0' ) + { + path = strchr( path, '/' ); + if ( path != 0 ) { + ++path; + } + ++depth; + } + return depth; } /// \brief A generic unix-style file-system which maps paths to files and directories. @@ -48,136 +46,115 @@ inline unsigned int path_get_depth(const char* path) template class GenericFileSystem { - class Path - { - CopiedString m_path; - unsigned int m_depth; - public: - Path(const char* path) - : m_path(path), m_depth(path_get_depth(c_str())) - { - } - Path(StringRange range) - : m_path(range), m_depth(path_get_depth(c_str())) - { - } - bool operator<(const Path& other) const - { - return string_less_nocase(c_str(), other.c_str()); - } - unsigned int depth() const - { - return m_depth; - } - const char* c_str() const - { - return m_path.c_str(); - } - }; - - class Entry - { - file_type* m_file; - public: - Entry() : m_file(0) - { - } - Entry(file_type* file) : m_file(file) - { - } - file_type* file() const - { - return m_file; - } - bool is_directory() const - { - return file() == 0; - } - }; - - typedef std::map Entries; - Entries m_entries; +class Path +{ +CopiedString m_path; +unsigned int m_depth; +public: +Path( const char* path ) + : m_path( path ), m_depth( path_get_depth( c_str() ) ){ +} +Path( StringRange range ) + : m_path( range ), m_depth( path_get_depth( c_str() ) ){ +} +bool operator<( const Path& other ) const { + return string_less_nocase( c_str(), other.c_str() ); +} +unsigned int depth() const { + return m_depth; +} +const char* c_str() const { + return m_path.c_str(); +} +}; +class Entry +{ +file_type* m_file; public: - typedef typename Entries::iterator iterator; - typedef typename Entries::value_type value_type; - typedef Entry entry_type; - - iterator begin() - { - return m_entries.begin(); - } - iterator end() - { - return m_entries.end(); - } - - /// \brief Returns the file at \p path. - /// Creates all directories below \p path if they do not exist. - /// O(log n) on average. - entry_type& operator[](const Path& path) - { - { - const char* end = path_remove_directory(path.c_str()); - while(end[0] != '\0') - { - Path dir(StringRange(path.c_str(), end)); - m_entries.insert(value_type(dir, Entry(0))); - end = path_remove_directory(end); - } - } - - return m_entries[path]; - } - - /// \brief Returns the file at \p path or end() if not found. - iterator find(const Path& path) - { - return m_entries.find(path); - } - - iterator begin(const char* root) - { - if(root[0] == '\0') - { - return m_entries.begin(); - } - iterator i = m_entries.find(root); - if(i == m_entries.end()) - { - return i; - } - return ++i; - } - - /// \brief Performs a depth-first traversal of the file-system subtree rooted at \p root. - /// Traverses the entire tree if \p root is "". - /// Calls \p visitor.file() with the path to each file relative to the filesystem root. - /// Calls \p visitor.directory() with the path to each directory relative to the filesystem root. - template - void traverse(visitor_type visitor, const char* root) - { - unsigned int start_depth = path_get_depth(root); - unsigned int skip_depth = 0; - for(iterator i = begin(root); i != end() && i->first.depth() > start_depth; ++i) - { - if(i->first.depth() == skip_depth) - { - skip_depth = 0; - } - if(skip_depth == 0) - { - if(!i->second.is_directory()) - { - visitor.file(i->first.c_str()); - } - else if(visitor.directory(i->first.c_str(), i->first.depth() - start_depth)) - { - skip_depth = i->first.depth(); - } - } - } - } +Entry() : m_file( 0 ){ +} +Entry( file_type* file ) : m_file( file ){ +} +file_type* file() const { + return m_file; +} +bool is_directory() const { + return file() == 0; +} +}; + +typedef std::map Entries; +Entries m_entries; + +public: +typedef typename Entries::iterator iterator; +typedef typename Entries::value_type value_type; +typedef Entry entry_type; + +iterator begin(){ + return m_entries.begin(); +} +iterator end(){ + return m_entries.end(); +} + +/// \brief Returns the file at \p path. +/// Creates all directories below \p path if they do not exist. +/// O(log n) on average. +entry_type& operator[]( const Path& path ){ + { + const char* end = path_remove_directory( path.c_str() ); + while ( end[0] != '\0' ) + { + Path dir( StringRange( path.c_str(), end ) ); + m_entries.insert( value_type( dir, Entry( 0 ) ) ); + end = path_remove_directory( end ); + } + } + + return m_entries[path]; +} + +/// \brief Returns the file at \p path or end() if not found. +iterator find( const Path& path ){ + return m_entries.find( path ); +} + +iterator begin( const char* root ){ + if ( root[0] == '\0' ) { + return m_entries.begin(); + } + iterator i = m_entries.find( root ); + if ( i == m_entries.end() ) { + return i; + } + return ++i; +} + +/// \brief Performs a depth-first traversal of the file-system subtree rooted at \p root. +/// Traverses the entire tree if \p root is "". +/// Calls \p visitor.file() with the path to each file relative to the filesystem root. +/// Calls \p visitor.directory() with the path to each directory relative to the filesystem root. +template +void traverse( visitor_type visitor, const char* root ){ + unsigned int start_depth = path_get_depth( root ); + unsigned int skip_depth = 0; + for ( iterator i = begin( root ); i != end() && i->first.depth() > start_depth; ++i ) + { + if ( i->first.depth() == skip_depth ) { + skip_depth = 0; + } + if ( skip_depth == 0 ) { + if ( !i->second.is_directory() ) { + visitor.file( i->first.c_str() ); + } + else if ( visitor.directory( i->first.c_str(), i->first.depth() - start_depth ) ) { + skip_depth = i->first.depth(); + } + } + } +} }; #endif