From Michael Platings, Converted std::fstream/ifstream/ofstream to osgDB::fstream/ifstream/ofstream and

fopen to osgDB::fopen to facilitate support for wide character filenames using UT8 encoding.
This commit is contained in:
Robert Osfield
2008-11-07 15:08:08 +00:00
parent 0ccf7d8383
commit 720551d549
76 changed files with 516 additions and 161 deletions

View File

@@ -10,6 +10,7 @@ SET(HEADER_PATH ${OpenSceneGraph_SOURCE_DIR}/include/${LIB_NAME})
SET(LIB_PUBLIC_HEADERS
${HEADER_PATH}/Archive
${HEADER_PATH}/AuthenticationMap
${HEADER_PATH}/ConvertUTF
${HEADER_PATH}/DatabasePager
${HEADER_PATH}/DotOsgWrapper
${HEADER_PATH}/DynamicLibrary
@@ -20,6 +21,7 @@ SET(LIB_PUBLIC_HEADERS
${HEADER_PATH}/FileCache
${HEADER_PATH}/FileNameUtils
${HEADER_PATH}/FileUtils
${HEADER_PATH}/fstream
${HEADER_PATH}/ImageOptions
${HEADER_PATH}/ImagePager
${HEADER_PATH}/Input
@@ -41,6 +43,7 @@ ADD_LIBRARY(${LIB_NAME}
${LIB_PUBLIC_HEADERS}
Archive.cpp
AuthenticationMap.cpp
ConvertUTF.cpp
DatabasePager.cpp
DotOsgWrapper.cpp
DynamicLibrary.cpp
@@ -50,6 +53,7 @@ ADD_LIBRARY(${LIB_NAME}
FileCache.cpp
FileNameUtils.cpp
FileUtils.cpp
fstream.cpp
ImageOptions.cpp
ImagePager.cpp
Input.cpp

90
src/osgDB/ConvertUTF.cpp Normal file
View File

@@ -0,0 +1,90 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 2008 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library 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
* OpenSceneGraph Public License for more details.
*/
#include <osgDB/ConvertUTF>
#include <osg/Notify>
#if defined(WIN32) && !defined(__CYGWIN__)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
namespace osgDB
{
std::string convertUTF16toUTF8(const wchar_t* source, unsigned sourceLength)
{
#if defined(WIN32) && !defined(__CYGWIN__)
if (sourceLength == 0)
{
return std::string();
}
int destLen = WideCharToMultiByte(CP_UTF8, 0, source, sourceLength, 0, 0, 0, 0);
if (destLen <= 0)
{
osg::notify(osg::WARN) << "Cannot convert UTF-16 string to UTF-8." << std::endl;
return std::string();
}
std::string sDest(destLen, '\0');
destLen = WideCharToMultiByte(CP_UTF8, 0, source, sourceLength, &sDest[0], destLen, 0, 0);
if (destLen <= 0)
{
osg::notify(osg::WARN) << "Cannot convert UTF-16 string to UTF-8." << std::endl;
return std::string();
}
return sDest;
#else
//TODO: Implement for other platforms
osg::notify(osg::WARN) << "ConvertUTF16toUTF8 not implemented." << std::endl;
return std::string();
#endif
}
std::wstring convertUTF8toUTF16(const char* source, unsigned sourceLength)
{
#if defined(WIN32) && !defined(__CYGWIN__)
if (sourceLength == 0)
{
return std::wstring();
}
int destLen = MultiByteToWideChar(CP_UTF8, 0, source, sourceLength, 0, 0);
if (destLen <= 0)
{
osg::notify(osg::WARN) << "Cannot convert UTF-8 string to UTF-16." << std::endl;
return std::wstring();
}
std::wstring sDest(destLen, L'\0');
destLen = MultiByteToWideChar(CP_UTF8, 0, source, sourceLength, &sDest[0], destLen);
if (destLen <= 0)
{
osg::notify(osg::WARN) << "Cannot convert UTF-8 string to UTF-16." << std::endl;
return std::wstring();
}
return sDest;
#else
//TODO: Implement for other platforms
osg::notify(osg::WARN) << "ConvertUTF8toUTF16 not implemented." << std::endl;
return std::wstring();
#endif
}
}

View File

@@ -11,7 +11,7 @@
* OpenSceneGraph Public License for more details.
*/
// currently this impl is for _all_ platforms, execpt as defined.
// currently this impl is for _all_ platforms, except as defined.
// the mac version will change soon to reflect the path scheme under osx, but
// for now, the above include is commented out, and the below code takes precedence.
@@ -64,6 +64,8 @@
# define S_ISDIR(mode) (mode&__S_IFDIR)
#endif
#include <osg/Config>
#include <osgDB/ConvertUTF>
#include <osg/Notify>
#include <osgDB/FileUtils>
@@ -73,7 +75,33 @@
#include <errno.h>
#include <stack>
namespace osgDB
{
#ifdef OSG_USE_UTF8_FILENAME
#define OSGDB_STRING_TO_FILENAME(s) osgDB::convertUTF8toUTF16(s)
#define OSGDB_FILENAME_TO_STRING(s) osgDB::convertUTF16toUTF8(s)
#define OSGDB_FILENAME_TEXT(x) L ## x
#define OSGDB_WINDOWS_FUNCT(x) x ## W
typedef wchar_t filenamechar;
typedef std::wstring filenamestring;
#else
#define OSGDB_STRING_TO_FILENAME(s) s
#define OSGDB_FILENAME_TO_STRING(s) s
#define OSGDB_FILENAME_TEXT(x) x
#define OSGDB_WINDOWS_FUNCT(x) x ## A
typedef char filenamechar;
typedef std::string filenamestring;
#endif
}
FILE* osgDB::fopen(const char* filename, const char* mode)
{
#ifdef OSG_USE_UTF8_FILENAME
return ::_wfopen(convertUTF8toUTF16(filename).c_str(), convertUTF8toUTF16(mode).c_str());
#else
return ::fopen(filename, mode);
#endif
}
bool osgDB::makeDirectory( const std::string &path )
{
@@ -84,7 +112,11 @@ bool osgDB::makeDirectory( const std::string &path )
}
struct stat64 stbuf;
#ifdef OSG_USE_UTF8_FILENAME
if( _wstat64( OSGDB_STRING_TO_FILENAME(path).c_str(), &stbuf ) == 0 )
#else
if( stat64( path.c_str(), &stbuf ) == 0 )
#endif
{
if( S_ISDIR(stbuf.st_mode))
return true;
@@ -103,7 +135,11 @@ bool osgDB::makeDirectory( const std::string &path )
if( dir.empty() )
break;
#ifdef OSG_USE_UTF8_FILENAME
if( _wstat64( OSGDB_STRING_TO_FILENAME(dir).c_str(), &stbuf ) < 0 )
#else
if( stat64( dir.c_str(), &stbuf ) < 0 )
#endif
{
switch( errno )
{
@@ -132,7 +168,11 @@ bool osgDB::makeDirectory( const std::string &path )
}
#endif
#ifdef OSG_USE_UTF8_FILENAME
if ( _wmkdir(OSGDB_STRING_TO_FILENAME(dir).c_str())< 0 )
#else
if( mkdir( dir.c_str(), 0755 )< 0 )
#endif
{
osg::notify(osg::DEBUG_INFO) << "osgDB::makeDirectory(): " << strerror(errno) << std::endl;
return false;
@@ -174,13 +214,21 @@ void osgDB::convertStringPathIntoFilePathList(const std::string& paths,FilePathL
bool osgDB::fileExists(const std::string& filename)
{
#ifdef OSG_USE_UTF8_FILENAME
return _waccess( OSGDB_STRING_TO_FILENAME(filename).c_str(), F_OK ) == 0;
#else
return access( filename.c_str(), F_OK ) == 0;
#endif
}
osgDB::FileType osgDB::fileType(const std::string& filename)
{
struct stat64 fileStat;
if ( stat64(filename.c_str(), &fileStat) != 0 )
#ifdef OSG_USE_UTF8_FILENAME
if ( _wstat64(OSGDB_STRING_TO_FILENAME(filename).c_str(), &fileStat) != 0 )
#else
if ( stat64(filename.c_str(), &fileStat) != 0 )
#endif
{
return FILE_NOT_FOUND;
} // end if
@@ -381,15 +429,15 @@ static void appendInstallationLibraryFilePaths(osgDB::FilePathList& filepath)
{
osgDB::DirectoryContents contents;
WIN32_FIND_DATA data;
HANDLE handle = FindFirstFile((dirName + "\\*").c_str(), &data);
OSGDB_WINDOWS_FUNCT(WIN32_FIND_DATA) data;
HANDLE handle = OSGDB_WINDOWS_FUNCT(FindFirstFile)((OSGDB_STRING_TO_FILENAME(dirName) + OSGDB_FILENAME_TEXT("\\*")).c_str(), &data);
if (handle != INVALID_HANDLE_VALUE)
{
do
{
contents.push_back(data.cFileName);
contents.push_back(OSGDB_FILENAME_TO_STRING(data.cFileName));
}
while (FindNextFile(handle, &data) != 0);
while (OSGDB_WINDOWS_FUNCT(FindNextFile)(handle, &data) != 0);
FindClose(handle);
}
@@ -497,14 +545,14 @@ static void appendInstallationLibraryFilePaths(osgDB::FilePathList& filepath)
// 1. The directory from which the application loaded.
DWORD retval = 0;
const DWORD size = MAX_PATH;
char path[size];
retval = GetModuleFileName(NULL, path, size);
filenamechar path[size];
retval = OSGDB_WINDOWS_FUNCT(GetModuleFileName)(NULL, path, size);
if (retval != 0 && retval < size)
{
std::string pathstr(path);
std::string executableDir(pathstr, 0,
pathstr.find_last_of("\\/"));
convertStringPathIntoFilePathList(executableDir, filepath);
filenamestring pathstr(path);
filenamestring executableDir(pathstr, 0,
pathstr.find_last_of(OSGDB_FILENAME_TEXT("\\/")));
convertStringPathIntoFilePathList(OSGDB_FILENAME_TO_STRING(executableDir), filepath);
}
else
{
@@ -514,11 +562,12 @@ static void appendInstallationLibraryFilePaths(osgDB::FilePathList& filepath)
// 2. The system directory. Use the GetSystemDirectory function to
// get the path of this directory.
char systemDir[(UINT)size];
retval = GetSystemDirectory(systemDir, (UINT)size);
filenamechar systemDir[(UINT)size];
retval = OSGDB_WINDOWS_FUNCT(GetSystemDirectory)(systemDir, (UINT)size);
if (retval != 0 && retval < size)
{
convertStringPathIntoFilePathList(std::string(systemDir),
convertStringPathIntoFilePathList(OSGDB_FILENAME_TO_STRING(systemDir),
filepath);
}
else
@@ -533,13 +582,13 @@ static void appendInstallationLibraryFilePaths(osgDB::FilePathList& filepath)
// the path of this directory, but it is searched.
// 4. The Windows directory. Use the GetWindowsDirectory function to
// get the path of this directory.
char windowsDir[(UINT)size];
retval = GetWindowsDirectory(windowsDir, (UINT)size);
filenamechar windowsDir[(UINT)size];
retval = OSGDB_WINDOWS_FUNCT(GetWindowsDirectory)(windowsDir, (UINT)size);
if (retval != 0 && retval < size)
{
convertStringPathIntoFilePathList(std::string(windowsDir) +
convertStringPathIntoFilePathList(std::string(OSGDB_FILENAME_TO_STRING(windowsDir)) +
"\\System", filepath);
convertStringPathIntoFilePathList(std::string(windowsDir),
convertStringPathIntoFilePathList(OSGDB_FILENAME_TO_STRING(windowsDir),
filepath);
}
else
@@ -557,14 +606,18 @@ static void appendInstallationLibraryFilePaths(osgDB::FilePathList& filepath)
// 6. The directories that are listed in the PATH environment
// variable. Note that this does not include the per-application
// path specified by the App Paths registry key.
char* ptr;
if ((ptr = getenv( "PATH" )))
filenamechar* ptr;
#ifdef OSG_USE_UTF8_FILENAME
if (ptr = _wgetenv(OSGDB_FILENAME_TEXT("PATH")))
#else
if (ptr = getenv("PATH"))
#endif
{
// Note that on any sane Windows system, some of the paths above
// will also be on the PATH (the values gotten in systemDir and
// windowsDir), but the DLL search goes sequentially and stops
// when a DLL is found, so I see no point in removing duplicates.
convertStringPathIntoFilePathList(ptr, filepath);
convertStringPathIntoFilePathList(OSGDB_FILENAME_TO_STRING(ptr), filepath);
}
appendInstallationLibraryFilePaths(filepath);

View File

@@ -29,7 +29,7 @@ Output::Output()
init();
}
Output::Output(const char* name) : ofstream(name)
Output::Output(const char* name) : osgDB::ofstream(name)
{
init();
_filename = name;
@@ -70,7 +70,7 @@ void Output::setOptions(const ReaderWriter::Options* options)
void Output::open(const char *name)
{
init();
ofstream::open(name);
osgDB::ofstream::open(name);
_filename = name;
}

View File

@@ -28,6 +28,7 @@
#include <osgDB/Registry>
#include <osgDB/FileUtils>
#include <osgDB/FileNameUtils>
#include <osgDB/fstream>
#include <osgDB/Archive>
#include <algorithm>
@@ -574,7 +575,7 @@ bool Registry::readPluginAliasConfigurationFile( const std::string& file )
return false;
}
std::ifstream ifs;
osgDB::ifstream ifs;
ifs.open( fileName.c_str() );
if (!ifs.good())
{

61
src/osgDB/fstream.cpp Normal file
View File

@@ -0,0 +1,61 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library 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
* OpenSceneGraph Public License for more details.
*/
#include <osgDB/fstream>
#include <osgDB/ConvertUTF>
#include <osg/Config>
namespace osgDB
{
#ifdef OSG_USE_UTF8_FILENAME
#define OSGDB_CONVERT_UTF8_FILENAME(s) convertUTF8toUTF16(s).c_str()
#else
#define OSGDB_CONVERT_UTF8_FILENAME(s) s
#endif
fstream::fstream(){}
fstream::fstream(const char* filename,
std::ios_base::openmode mode) : std::fstream(OSGDB_CONVERT_UTF8_FILENAME(filename), mode)
{}
fstream::~fstream(){}
void fstream::open(const char* filename,
std::ios_base::openmode mode)
{
std::fstream::open(OSGDB_CONVERT_UTF8_FILENAME(filename), mode);
}
ifstream::ifstream(){}
ifstream::ifstream(const char* filename,
std::ios_base::openmode mode) : std::ifstream(OSGDB_CONVERT_UTF8_FILENAME(filename), mode)
{}
ifstream::~ifstream(){}
void ifstream::open(const char* filename,
std::ios_base::openmode mode)
{
std::ifstream::open(OSGDB_CONVERT_UTF8_FILENAME(filename), mode);
}
ofstream::ofstream(){}
ofstream::ofstream(const char* filename,
std::ios_base::openmode mode) : std::ofstream(OSGDB_CONVERT_UTF8_FILENAME(filename), mode)
{}
ofstream::~ofstream(){}
void ofstream::open(const char* filename,
std::ios_base::openmode mode)
{
std::ofstream::open(OSGDB_CONVERT_UTF8_FILENAME(filename), mode);
}
}