root/OpenSceneGraph/trunk/src/osgDB/FileNameUtils.cpp @ 10818

Revision 10818, 8.8 kB (checked in by robert, 5 years ago)

From Chris Hanson, " Add support for requesting and setting the current directory (a la getcwd/chdir) via a
C++-friendly string-class API.

Prevent osgDB::concatPaths from faulting if the supplied "left" path string is empty."

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[5328]1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
[1529]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*/
[7151]13#include <stdlib.h>
[7747]14#include <string.h>
[7151]15#include <limits.h>
16
[120]17#include <osgDB/FileNameUtils>
[7667]18#include <osgDB/FileUtils>
[8]19
[6007]20#ifdef WIN32
[7910]21    #define _WIN32_WINNT 0x0500
[6007]22    #include <windows.h>
23#endif
24
[314]25#if defined(__sgi)
[364]26    #include <ctype.h>
[1366]27#elif defined(__GNUC__) || !defined(WIN32) || defined(__MWERKS__)
[313]28    #include <cctype>
29    using std::tolower;
[8]30#endif
31
[416]32using namespace std;
33
[8]34std::string osgDB::getFilePath(const std::string& fileName)
35{
[2204]36    std::string::size_type slash1 = fileName.find_last_of('/');
37    std::string::size_type slash2 = fileName.find_last_of('\\');
38    if (slash1==std::string::npos)
[755]39    {
[2204]40        if (slash2==std::string::npos) return std::string();
41        return std::string(fileName,0,slash2);
[755]42    }
[2204]43    if (slash2==std::string::npos) return std::string(fileName,0,slash1);
44    return std::string(fileName, 0, slash1>slash2 ?  slash1 : slash2);
[8]45}
46
47
48std::string osgDB::getSimpleFileName(const std::string& fileName)
49{
[2204]50    std::string::size_type slash1 = fileName.find_last_of('/');
51    std::string::size_type slash2 = fileName.find_last_of('\\');
52    if (slash1==std::string::npos)
[755]53    {
[2204]54        if (slash2==std::string::npos) return fileName;
[4800]55        return std::string(fileName.begin()+slash2+1,fileName.end());
[755]56    }
[2204]57    if (slash2==std::string::npos) return std::string(fileName.begin()+slash1+1,fileName.end());
58    return std::string(fileName.begin()+(slash1>slash2?slash1:slash2)+1,fileName.end());
[8]59}
60
61
62std::string osgDB::getFileExtension(const std::string& fileName)
63{
64    std::string::size_type dot = fileName.find_last_of('.');
65    if (dot==std::string::npos) return std::string("");
66    return std::string(fileName.begin()+dot+1,fileName.end());
67}
68
[8912]69std::string osgDB::getFileExtensionIncludingDot(const std::string& fileName)
70{
71    std::string::size_type dot = fileName.find_last_of('.');
72    if (dot==std::string::npos) return std::string("");
73    return std::string(fileName.begin()+dot,fileName.end());
74}
75
[3833]76std::string osgDB::convertFileNameToWindowsStyle(const std::string& fileName)
77{
78    std::string new_fileName(fileName);
79   
80    std::string::size_type slash = 0;
81    while( (slash=new_fileName.find_first_of('/',slash)) != std::string::npos)
82    {
83        new_fileName[slash]='\\';
84    }
85    return new_fileName;
86}
[8]87
[3833]88std::string osgDB::convertFileNameToUnixStyle(const std::string& fileName)
89{
90    std::string new_fileName(fileName);
91   
92    std::string::size_type slash = 0;
93    while( (slash=new_fileName.find_first_of('\\',slash)) != std::string::npos)
94    {
95        new_fileName[slash]='/';
96    }
97
98    return new_fileName;
99}
100
101bool osgDB::isFileNameNativeStyle(const std::string& fileName)
102{
[6130]103#if defined(WIN32) && !defined(__CYGWIN__)
[3833]104    return fileName.find('/') == std::string::npos; // return true if no unix style slash exist
105#else
106    return fileName.find('\\') == std::string::npos; // return true if no windows style slash exist
107#endif
108}
109
110std::string osgDB::convertFileNameToNativeStyle(const std::string& fileName)
111{
[6130]112#if defined(WIN32) && !defined(__CYGWIN__)
[3833]113    return convertFileNameToWindowsStyle(fileName);
114#else
115    return convertFileNameToUnixStyle(fileName);
116#endif
117}
118
119
120
[8]121std::string osgDB::getLowerCaseFileExtension(const std::string& filename)
122{
[8577]123    return convertToLowerCase(osgDB::getFileExtension(filename));
124}
125
126std::string osgDB::convertToLowerCase(const std::string& str)
127{
128    std::string lowcase_str(str);
129    for(std::string::iterator itr=lowcase_str.begin();
130        itr!=lowcase_str.end();
[8]131        ++itr)
132    {
133        *itr = tolower(*itr);
134    }
[8577]135    return lowcase_str;
[8]136}
137
[2966]138// strip one level of extension from the filename.
139std::string osgDB::getNameLessExtension(const std::string& fileName)
140{
141    std::string::size_type dot = fileName.find_last_of('.');
142    if (dot==std::string::npos) return fileName;
143    return std::string(fileName.begin(),fileName.begin()+dot);
144}
145
146
[8]147std::string osgDB::getStrippedName(const std::string& fileName)
148{
[755]149    std::string simpleName = getSimpleFileName(fileName);
[2966]150    return getNameLessExtension( simpleName );
[8]151}
152
153
154bool osgDB::equalCaseInsensitive(const std::string& lhs,const std::string& rhs)
155{
156    if (lhs.size()!=rhs.size()) return false;
157    std::string::const_iterator litr = lhs.begin();
158    std::string::const_iterator ritr = rhs.begin();
159    while (litr!=lhs.end())
160    {
161        if (tolower(*litr)!=tolower(*ritr)) return false;
162        ++litr;
163        ++ritr;
164    }
165    return true;
166}
167
168bool osgDB::equalCaseInsensitive(const std::string& lhs,const char* rhs)
169{
170    if (rhs==NULL || lhs.size()!=strlen(rhs)) return false;
171    std::string::const_iterator litr = lhs.begin();
172    const char* cptr = rhs;
173    while (litr!=lhs.end())
174    {
175        if (tolower(*litr)!=tolower(*cptr)) return false;
176        ++litr;
177        ++cptr;
178    }
179    return true;
180}
[755]181
[9884]182
183
[3475]184bool osgDB::containsServerAddress(const std::string& filename)
185{
[9884]186    // need to check for ://
187    std::string::size_type pos(filename.find_first_of("://"));
188    if (pos == std::string::npos)
189        return false;
190    std::string proto(filename.substr(0, pos));
191   
192    return Registry::instance()->isProtocolRegistered(proto);
[3475]193}
194
[9884]195std::string osgDB::getServerProtocol(const std::string& filename)
196{
197    std::string::size_type pos(filename.find_first_of("://"));
198    if (pos != std::string::npos)
199        return filename.substr(0,pos);
200
201    return "";
202}
203
[3475]204std::string osgDB::getServerAddress(const std::string& filename)
205{
[9884]206    std::string::size_type pos(filename.find_first_of("://"));
207   
208    if (pos != std::string::npos)
[3475]209    {
[9884]210        std::string::size_type pos_slash = filename.find_first_of('/',pos+3);
[3475]211        if (pos_slash!=std::string::npos)
212        {
[9884]213            return filename.substr(pos+3,pos_slash-pos-3);
[3475]214        }
215        else
216        {
[9884]217            return filename.substr(pos+3,std::string::npos);
[3475]218        }
219    }
220    return "";
221}
222
223std::string osgDB::getServerFileName(const std::string& filename)
224{
[9884]225    std::string::size_type pos(filename.find_first_of("://"));
226
227    if (pos != std::string::npos)
[3475]228    {
[9884]229        std::string::size_type pos_slash = filename.find_first_of('/',pos+3);
[3475]230        if (pos_slash!=std::string::npos)
231        {
232            return filename.substr(pos_slash+1,std::string::npos);
233        }
234        else
235        {
236            return "";
237        }
238   
239    }
240    return filename;
241}
242
[6005]243std::string osgDB::concatPaths(const std::string& left, const std::string& right)
244{
[6130]245#if defined(WIN32) && !defined(__CYGWIN__)
[6005]246    const char delimiterNative  = '\\';
247    const char delimiterForeign = '/';
248#else
249    const char delimiterNative  = '/';
250    const char delimiterForeign = '\\';
251#endif
[3475]252
[10818]253    if(left.empty())
254    {
255        return(right);
256    }
[6005]257    char lastChar = left[left.size() - 1];
258
259    if(lastChar == delimiterNative)
260    {
261        return left + right;
262    }
263    else if(lastChar == delimiterForeign)
264    {
265        return left.substr(0, left.size() - 1) + delimiterNative + right;
266    }
267    else // lastChar != a delimiter
268    {
269        return left + delimiterNative + right;
270    }
271}
272
273std::string osgDB::getRealPath(const std::string& path)
274{
[6130]275#if defined(WIN32)  && !defined(__CYGWIN__)
[7667]276    // Not unicode compatible should give an error if UNICODE defined
277    char retbuf[MAX_PATH + 1];
278    char tempbuf1[MAX_PATH + 1];
279    GetFullPathName(path.c_str(), sizeof(retbuf), retbuf, NULL);
280    // Force drive letter to upper case
281    if ((retbuf[1] == ':') && islower(retbuf[0]))
282        retbuf[0] = _toupper(retbuf[0]);
283    if (fileExists(std::string(retbuf)))
284    {
285        // Canonicalise the full path
286        GetShortPathName(retbuf, tempbuf1, sizeof(tempbuf1));
287        GetLongPathName(tempbuf1, retbuf, sizeof(retbuf));
288        return std::string(retbuf);
289    }
290    else
291    {
292        // Canonicalise the directories
293        std::string FilePath = getFilePath(retbuf);
294        char tempbuf2[MAX_PATH + 1];
295        if (0 == GetShortPathName(FilePath.c_str(), tempbuf1, sizeof(tempbuf1)))
296            return std::string(retbuf);
297        if (0 == GetLongPathName(tempbuf1, tempbuf2, sizeof(tempbuf2)))
298            return std::string(retbuf);
299        FilePath = std::string(tempbuf2);
300        FilePath.append("\\");
301        FilePath.append(getSimpleFileName(std::string(retbuf)));
302        return FilePath;
303    }
[6005]304#else
305    char resolved_path[PATH_MAX];
306    char* result = realpath(path.c_str(), resolved_path);
307   
308    if (result) return std::string(resolved_path);
309    else return path;
310#endif 
311}
Note: See TracBrowser for help on using the browser.