root/OpenSceneGraph/trunk/src/osgDB/FileUtils.cpp @ 2992

Revision 2992, 7.8 kB (checked in by robert, 10 years ago)

From Bruce Clay, cross platform implemention of fileType(..)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13#if 0 // defined(__APPLE__)
14#include "FileUtils_Mac.cpp" // this is not functional yet -- fix!
15#else
16
17// currently this impl is for _all_ platforms, execpt as defined.
18// the mac version will change soon to reflect the path scheme under osx, but
19// for now, the above include is commented out, and the below code takes precedence.
20
21#if defined(WIN32) && !defined(__CYGWIN__)
22    #include <Io.h>
23    #include <Windows.h>
24    #include <Winbase.h>
25    #include <sys/types.h>
26    #include <sys/stat.h>
27    // set up for windows so acts just like unix access().
28    #define F_OK 4
29#else // unix
30    #include <unistd.h>
31    #include <sys/types.h>
32    #include <sys/stat.h>
33#endif
34
35#include <osg/Notify>
36
37#include <osgDB/FileUtils>
38#include <osgDB/FileNameUtils>
39#include <osgDB/Registry>
40
41
42bool osgDB::fileExists(const std::string& filename)
43{
44    return access( filename.c_str(), F_OK ) == 0;
45}
46
47osgDB::FileType osgDB::fileType(const std::string& filename)
48{
49#if 1
50
51    // proposed single code path, from Bruce Clay.
52    struct stat fileStat;
53    if ( stat(filename.c_str(), &fileStat) != 0 )
54    {
55        return FILE_NOT_FOUND;
56    } // end if
57
58    if ( fileStat.st_mode & S_IFDIR )
59        return DIRECTORY;
60    else if ( fileStat.st_mode & S_IFREG )
61        return REGULAR_FILE;
62
63    return FILE_NOT_FOUND;
64
65#else
66    #if defined(WIN32) && !defined(__CYGWIN__)
67        struct _stat fileStat;
68        if ( _stat(filename.c_str(), &fileStat) != 0 )
69        {
70            return FILE_NOT_FOUND;
71        } // end if
72
73        if ( fileStat.st_mode & _S_IFDIR )
74            return DIRECTORY;
75        else if ( fileStat.st_mode & _S_IFREG )
76            return REGULAR_FILE;
77
78        return FILE_NOT_FOUND;
79
80    #else
81        struct stat fileStat;
82
83        if(stat(filename.c_str(), &fileStat) == -1)
84        {
85            return FILE_NOT_FOUND;
86        }
87
88        if(S_ISREG(fileStat.st_mode))
89        {
90            return REGULAR_FILE;
91        }
92
93        if(S_ISDIR(fileStat.st_mode))
94        {
95            return DIRECTORY;
96        }
97
98        return FILE_NOT_FOUND;
99    #endif
100#endif
101}
102
103std::string osgDB::findFileInPath(const std::string& filename, const FilePathList& filepath,CaseSensitivity caseSensitivity)
104{
105    if (filename.empty())
106        return filename;
107
108    if(fileExists(filename))
109    {
110        osg::notify(osg::DEBUG_INFO) << "FindFileInPath(" << filename << "): returning " << filename << std::endl;
111        return filename;
112    }
113
114    for(FilePathList::const_iterator itr=filepath.begin();
115        itr!=filepath.end();
116        ++itr)
117    {
118        std::string path = *itr + '/'+ filename;
119        osg::notify(osg::DEBUG_INFO) << "FindFileInPath() : trying " << path << " ...\n";
120        if(fileExists(path))
121        {
122            osg::notify(osg::DEBUG_INFO) << "FindFileInPath() : USING " << path << "\n";
123            return path;
124        }
125#ifndef WIN32 
126// windows already case insensitive so no need to retry..
127        else if (caseSensitivity==CASE_INSENSITIVE)
128        {
129            std::string foundfile = findFileInDirectory(filename,*itr,CASE_INSENSITIVE);
130            if (!foundfile.empty()) return foundfile;
131        }
132#endif
133           
134    }
135
136    return std::string();
137}
138
139std::string osgDB::findDataFile(const std::string& filename,CaseSensitivity caseSensitivity)
140{
141    if (filename.empty()) return filename;
142
143    const FilePathList& filepath = Registry::instance()->getDataFilePathList();
144
145    std::string fileFound = findFileInPath(filename, filepath,caseSensitivity);
146    if (!fileFound.empty()) return fileFound;
147
148    // if a directory is included in the filename, get just the (simple) filename itself and try that
149    std::string simpleFileName = getSimpleFileName(filename);
150    if (simpleFileName!=filename)
151    {
152        std::string fileFound = findFileInPath(simpleFileName, filepath,caseSensitivity);
153        if (!fileFound.empty()) return fileFound;
154    }
155
156    // return empty string.
157    return std::string();
158}
159
160std::string osgDB::findLibraryFile(const std::string& filename,CaseSensitivity caseSensitivity)
161{
162    if (filename.empty())
163        return filename;
164
165    const FilePathList& filepath = Registry::instance()->getLibraryFilePathList();
166
167    std::string fileFound = findFileInPath(filename, filepath,caseSensitivity);
168    if (!fileFound.empty())
169        return fileFound;
170
171    // if a directory is included in the filename, get just the (simple) filename itself and try that
172    std::string simpleFileName = getSimpleFileName(filename);
173    if (simpleFileName!=filename)
174    {
175        std::string fileFound = findFileInPath(simpleFileName, filepath,caseSensitivity);
176        if (!fileFound.empty()) return fileFound;
177    }
178
179    // failed with direct paths,
180    // now try prepending the filename with "osgPlugins/"
181    return findFileInPath("osgPlugins/"+simpleFileName,filepath,caseSensitivity);
182}
183
184std::string osgDB::findFileInDirectory(const std::string& fileName,const std::string& dirName,CaseSensitivity caseSensitivity)
185{
186    bool needFollowingBackslash = false;
187    bool needDirectoryName = true;
188    osgDB::DirectoryContents dc;
189
190    if (dirName.empty())
191    {
192        dc = osgDB::getDirectoryContents(".");
193        needFollowingBackslash = false;
194        needDirectoryName = false;
195    }
196    else if (dirName=="." || dirName=="./" || dirName==".\\")
197    {
198        dc = osgDB::getDirectoryContents(".");
199        needFollowingBackslash = false;
200        needDirectoryName = false;
201    }
202    else
203    {
204        dc = osgDB::getDirectoryContents(dirName);
205        char lastChar = dirName[dirName.size()-1];
206        if (lastChar=='/') needFollowingBackslash = false;
207        else if (lastChar=='\\') needFollowingBackslash = false;
208        else needFollowingBackslash = true;
209        needDirectoryName = true;
210    }
211
212    for(osgDB::DirectoryContents::iterator itr=dc.begin();
213        itr!=dc.end();
214        ++itr)
215    {
216        if ((caseSensitivity==CASE_INSENSITIVE && osgDB::equalCaseInsensitive(fileName,*itr)) ||
217            (fileName==*itr))
218        {
219            if (!needDirectoryName) return *itr;
220            else if (needFollowingBackslash) return dirName+'/'+*itr;
221            else return dirName+*itr;
222        }
223    }
224    return "";
225}
226
227#if defined(WIN32) && !defined(__CYGWIN__)
228    #include <io.h>
229    #include <direct.h>
230
231    osgDB::DirectoryContents osgDB::getDirectoryContents(const std::string& dirName)
232    {
233        osgDB::DirectoryContents contents;
234
235        WIN32_FIND_DATA data;
236        HANDLE handle = FindFirstFile((dirName + "\\*").c_str(), &data);
237        if (handle != INVALID_HANDLE_VALUE)
238        {
239            do
240            {
241                contents.push_back(data.cFileName);
242            }
243            while (FindNextFile(handle, &data) != 0);
244
245            FindClose(handle);
246        }
247        return contents;
248    }
249
250#else
251
252    #include <dirent.h>
253    osgDB::DirectoryContents osgDB::getDirectoryContents(const std::string& dirName)
254    {
255        osgDB::DirectoryContents contents;
256
257        DIR *handle = opendir(dirName.c_str());
258        if (handle)
259        {
260            dirent *rc;
261            while((rc = readdir(handle))!=NULL)
262            {
263                contents.push_back(rc->d_name);
264            }
265            closedir(handle);
266        }
267
268        return contents;
269    }
270
271#endif // unix getDirectoryContexts
272
273#endif // ! target mac carbon
Note: See TracBrowser for help on using the browser.