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:
@@ -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
90
src/osgDB/ConvertUTF.cpp
Normal 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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
61
src/osgDB/fstream.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user