2 Copyright (C) 2001-2006, William Joseph.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "idatastream.h"
31 #include "stream/filestream.h"
32 #include "stream/textfilestream.h"
33 #include "string/string.h"
37 #include "archivelib.h"
41 class DirectoryArchive : public Archive {
44 DirectoryArchive(const char *root) : m_root(root)
53 virtual ArchiveFile *openFile(const char *name)
55 UnixPath path(m_root.c_str());
56 path.push_filename(name);
57 DirectoryArchiveFile *file = new DirectoryArchiveFile(name, path.c_str());
58 if (!file->failed()) {
65 virtual ArchiveTextFile *openTextFile(const char *name)
67 UnixPath path(m_root.c_str());
68 path.push_filename(name);
69 DirectoryArchiveTextFile *file = new DirectoryArchiveTextFile(name, path.c_str());
70 if (!file->failed()) {
77 virtual bool containsFile(const char *name)
79 UnixPath path(m_root.c_str());
80 path.push_filename(name);
81 return file_readable(path.c_str());
84 virtual void forEachFile(VisitorFunc visitor, const char *root)
86 std::vector<Directory *> dirs;
87 UnixPath path(m_root.c_str());
89 dirs.push_back(directory_open(path.c_str()));
91 while (!dirs.empty() && directory_good(dirs.back())) {
92 const char *name = directory_read_and_increment(dirs.back());
95 directory_close(dirs.back());
98 } else if (!string_equal(name, ".") && !string_equal(name, "..")) {
99 path.push_filename(name);
101 bool is_directory = file_is_directory(path.c_str());
104 visitor.file(path_make_relative(path.c_str(), m_root.c_str()));
112 if (!visitor.directory(path_make_relative(path.c_str(), m_root.c_str()), dirs.size())) {
113 dirs.push_back(directory_open(path.c_str()));
123 Archive *OpenArchive(const char *name)
125 return new DirectoryArchive(name);
132 class TestVisitor : public Archive::IVisitor
135 virtual void visit( const char* name ){
141 Archive* archive = OpenArchive( "d:/quake/id1/" );
142 ArchiveFile* file = archive->openFile( "quake101.wad" );
145 file->getInputStream().read( buffer, 1024 );
149 archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 0 ), "" );
153 Archive* archive = OpenArchive( "d:/gtkradiant_root/baseq3/" );
155 archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 2 ), "" );
156 archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFiles, 1 ), "textures" );
157 archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eDirectories, 1 ), "textures" );
158 archive->forEachFile( Archive::VisitorFunc( &visitor, Archive::eFilesAndDirectories, 1 ), "textures" );