Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreFileSystem.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 9.8 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreStableHeaders.h"
30#include "OgreFileSystem.h"
31#include "OgreLogManager.h"
32#include "OgreException.h"
33#include "OgreStringVector.h"
34#include "OgreRoot.h"
35
36#include <sys/types.h>
37#include <sys/stat.h>
38
39#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE
40#   include "OgreSearchOps.h"
41#   include <sys/param.h>
42#   define MAX_PATH MAXPATHLEN
43#endif
44
45#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
46#   include <windows.h>
47#   include <direct.h>
48#   include <io.h>
49#endif
50
51namespace Ogre {
52
53    //-----------------------------------------------------------------------
54    FileSystemArchive::FileSystemArchive(const String& name, const String& archType )
55        : Archive(name, archType)
56    {
57    }
58    //-----------------------------------------------------------------------
59    bool FileSystemArchive::isCaseSensitive(void) const
60    {
61        #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
62            return false;
63        #else
64            return true;
65        #endif
66
67    }
68    //-----------------------------------------------------------------------
69    static bool is_reserved_dir (const char *fn)
70    {
71        return (fn [0] == '.' && (fn [1] == 0 || (fn [1] == '.' && fn [2] == 0)));
72    }
73    //-----------------------------------------------------------------------
74    static bool is_absolute_path(const char* path)
75    {
76#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
77        if (isalpha(uchar(path[0])) && path[1] == ':')
78            return true;
79#endif
80        return path[0] == '/' || path[0] == '\\';
81    }
82    //-----------------------------------------------------------------------
83    static String concatenate_path(const String& base, const String& name)
84    {
85        if (base.empty() || is_absolute_path(name.c_str()))
86            return name;
87        else
88            return base + '/' + name;
89    }
90    //-----------------------------------------------------------------------
91    void FileSystemArchive::findFiles(const String& pattern, bool recursive, 
92        bool dirs, StringVector* simpleList, FileInfoList* detailList)
93    {
94        long lHandle, res;
95        struct _finddata_t tagData;
96
97        // pattern can contain a directory name, separate it from mask
98        size_t pos1 = pattern.rfind ('/');
99        size_t pos2 = pattern.rfind ('\\');
100        if (pos1 == pattern.npos || ((pos2 != pattern.npos) && (pos1 < pos2)))
101            pos1 = pos2;
102        String directory;
103        if (pos1 != pattern.npos)
104            directory = pattern.substr (0, pos1 + 1);
105
106        String full_pattern = concatenate_path(mName, pattern);
107
108        lHandle = _findfirst(full_pattern.c_str(), &tagData);
109        res = 0;
110        while (lHandle != -1 && res != -1)
111        {
112            if ((dirs == ((tagData.attrib & _A_SUBDIR) != 0)) &&
113                (!dirs || !is_reserved_dir (tagData.name)))
114            {
115                if (simpleList)
116                {
117                    simpleList->push_back(directory + tagData.name);
118                }
119                else if (detailList)
120                {
121                    FileInfo fi;
122                    fi.archive = this;
123                    fi.filename = directory + tagData.name;
124                    fi.basename = tagData.name;
125                    fi.path = directory;
126                    fi.compressedSize = tagData.size;
127                    fi.uncompressedSize = tagData.size;
128                    detailList->push_back(fi);
129                }
130            }
131            res = _findnext( lHandle, &tagData );
132        }
133        // Close if we found any files
134        if(lHandle != -1)
135            _findclose(lHandle);
136
137        // Now find directories
138        if (recursive)
139        {
140            String base_dir = mName;
141            if (!directory.empty ())
142            {
143                base_dir = concatenate_path(mName, directory);
144                // Remove the last '/'
145                base_dir.erase (base_dir.length () - 1);
146            }
147            base_dir.append ("/*");
148
149            // Remove directory name from pattern
150            String mask ("/");
151            if (pos1 != pattern.npos)
152                mask.append (pattern.substr (pos1 + 1));
153            else
154                mask.append (pattern);
155
156            lHandle = _findfirst(base_dir.c_str (), &tagData);
157            res = 0;
158            while (lHandle != -1 && res != -1)
159            {
160                if ((tagData.attrib & _A_SUBDIR) &&
161                    !is_reserved_dir (tagData.name))
162                {
163                    // recurse
164                    base_dir = directory;
165                    base_dir.append (tagData.name).append (mask);
166                    findFiles(base_dir, recursive, dirs, simpleList, detailList);
167                }
168                res = _findnext( lHandle, &tagData );
169            }
170            // Close if we found any files
171            if(lHandle != -1)
172                _findclose(lHandle);
173        }
174    }
175    //-----------------------------------------------------------------------
176    FileSystemArchive::~FileSystemArchive()
177    {
178        unload();
179    }
180    //-----------------------------------------------------------------------
181    void FileSystemArchive::load()
182    {
183        // do nothing here, what has to be said will be said later
184    }
185    //-----------------------------------------------------------------------
186    void FileSystemArchive::unload()
187    {
188        // nothing to see here, move along
189    }
190    //-----------------------------------------------------------------------
191    DataStreamPtr FileSystemArchive::open(const String& filename) const
192    {
193        String full_path = concatenate_path(mName, filename);
194
195        // Use filesystem to determine size
196        // (quicker than streaming to the end and back)
197        struct stat tagStat;
198        int ret = stat(full_path.c_str(), &tagStat);
199        assert(ret == 0 && "Problem getting file size" );
200
201        // Always open in binary mode
202        std::ifstream *origStream = new std::ifstream();
203        origStream->open(full_path.c_str(), std::ios::in | std::ios::binary);
204
205        // Should check ensure open succeeded, in case fail for some reason.
206        if (origStream->fail())
207        {
208            delete origStream;
209            OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND,
210                "Cannot open file: " + filename,
211                "FileSystemArchive::open");
212        }
213
214        /// Construct return stream, tell it to delete on destroy
215        FileStreamDataStream* stream = new FileStreamDataStream(filename,
216            origStream, tagStat.st_size, true);
217        return DataStreamPtr(stream);
218    }
219    //-----------------------------------------------------------------------
220    StringVectorPtr FileSystemArchive::list(bool recursive, bool dirs)
221    {
222                // directory change requires locking due to saved returns
223        StringVectorPtr ret(new StringVector());
224
225        findFiles("*", recursive, dirs, ret.getPointer(), 0);
226
227        return ret;
228    }
229    //-----------------------------------------------------------------------
230    FileInfoListPtr FileSystemArchive::listFileInfo(bool recursive, bool dirs)
231    {
232        FileInfoListPtr ret(new FileInfoList());
233
234        findFiles("*", recursive, dirs, 0, ret.getPointer());
235
236        return ret;
237    }
238    //-----------------------------------------------------------------------
239    StringVectorPtr FileSystemArchive::find(const String& pattern,
240                                            bool recursive, bool dirs)
241    {
242        StringVectorPtr ret(new StringVector());
243
244        findFiles(pattern, recursive, dirs, ret.getPointer(), 0);
245
246        return ret;
247
248    }
249    //-----------------------------------------------------------------------
250    FileInfoListPtr FileSystemArchive::findFileInfo(const String& pattern, 
251        bool recursive, bool dirs)
252    {
253        FileInfoListPtr ret(new FileInfoList());
254
255        findFiles(pattern, recursive, dirs, 0, ret.getPointer());
256
257        return ret;
258    }
259    //-----------------------------------------------------------------------
260        bool FileSystemArchive::exists(const String& filename)
261        {
262        String full_path = concatenate_path(mName, filename);
263
264        struct stat tagStat;
265        bool ret = (stat(full_path.c_str(), &tagStat) == 0);
266
267                return ret;
268        }
269    //-----------------------------------------------------------------------
270    const String& FileSystemArchiveFactory::getType(void) const
271    {
272        static String name = "FileSystem";
273        return name;
274    }
275
276}
Note: See TracBrowser for help on using the repository browser.