Changing SGPath APIs, using SGPath in more places.
Change most places we control (i.e not helper libs) to use SGPath to represent a path, instead of using std::string. Extend SGPath API to explicitly expose the path in either UTF-8 or the system 8-bit encoding.
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "sg_binobj.hxx"
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
@@ -31,7 +32,7 @@ int main( int argc, char **argv ) {
|
||||
sglog().setLogLevels( SG_ALL, SG_ALERT );
|
||||
|
||||
SGBinObject obj;
|
||||
bool result = obj.read_bin( argv[1] );
|
||||
bool result = obj.read_bin( SGPath::fromLocal8Bit(argv[1]) );
|
||||
if ( !result ) {
|
||||
cout << "error loading: " << argv[1] << endl;
|
||||
exit(-1);
|
||||
|
||||
@@ -83,7 +83,7 @@ int main(int argc, char* argv[])
|
||||
} else if (!strcmp(argv[a], "--auth")) {
|
||||
proxyAuth = argv[++a];
|
||||
} else if (!strcmp(argv[a], "-f") || !strcmp(argv[a], "--file")) {
|
||||
outFile = new SGFile(argv[++a]);
|
||||
outFile = new SGFile(SGPath::fromLocal8Bit(argv[++a]));
|
||||
if (!outFile->open(SG_IO_OUT)) {
|
||||
cerr << "failed to open output for writing:" << outFile->get_file_name() << endl;
|
||||
return EXIT_FAILURE;
|
||||
|
||||
@@ -491,7 +491,7 @@ void SGBinObject::read_object( gzFile fp,
|
||||
|
||||
|
||||
// read a binary file and populate the provided structures.
|
||||
bool SGBinObject::read_bin( const string& file ) {
|
||||
bool SGBinObject::read_bin( const SGPath& file ) {
|
||||
SGVec3d p;
|
||||
int i, k;
|
||||
size_t j;
|
||||
@@ -535,13 +535,14 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
fan_materials.clear();
|
||||
|
||||
gzFile fp;
|
||||
if ( (fp = gzopen( file.c_str(), "rb" )) == NULL ) {
|
||||
string filegz = file + ".gz";
|
||||
string f = file.local8BitStr();
|
||||
if ( (fp = gzopen( f.c_str(), "rb" )) == NULL ) {
|
||||
string filegz = f + ".gz";
|
||||
if ( (fp = gzopen( filegz.c_str(), "rb" )) == NULL ) {
|
||||
SG_LOG( SG_EVENT, SG_ALERT,
|
||||
"ERROR: opening " << file << " or " << filegz << " for reading!");
|
||||
|
||||
throw sg_io_exception("Error opening for reading (and .gz)", sg_location(file));
|
||||
throw sg_io_exception("Error opening for reading (and .gz)", sg_location(f));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -958,7 +959,7 @@ bool SGBinObject::write_bin_file(const SGPath& file)
|
||||
|
||||
gzFile fp;
|
||||
if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
|
||||
cout << "ERROR: opening " << file.str() << " for writing!" << endl;
|
||||
cout << "ERROR: opening " << file << " for writing!" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1064,7 +1065,7 @@ bool SGBinObject::write_bin_file(const SGPath& file)
|
||||
gzclose(fp);
|
||||
|
||||
if ( sgWriteError() ) {
|
||||
cout << "Error while writing file " << file.str() << endl;
|
||||
cout << "Error while writing file " << file << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1082,11 +1083,11 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
|
||||
|
||||
SGPath file = base + "/" + b.gen_base_path() + "/" + name;
|
||||
file.create_dir( 0755 );
|
||||
cout << "Output file = " << file.str() << endl;
|
||||
cout << "Output file = " << file << endl;
|
||||
|
||||
FILE *fp;
|
||||
if ( (fp = fopen( file.c_str(), "w" )) == NULL ) {
|
||||
cout << "ERROR: opening " << file.str() << " for writing!" << endl;
|
||||
cout << "ERROR: opening " << file << " for writing!" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1240,11 +1241,11 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
|
||||
// close the file
|
||||
fclose(fp);
|
||||
|
||||
string command = "gzip --force --best " + file.str();
|
||||
string command = "gzip --force --best " + file.local8BitStr();
|
||||
int err = system(command.c_str());
|
||||
if (err)
|
||||
{
|
||||
cout << "ERROR: gzip " << file.str() << " failed!" << endl;
|
||||
cout << "ERROR: gzip " << file << " failed!" << endl;
|
||||
}
|
||||
|
||||
return (err == 0);
|
||||
|
||||
@@ -268,7 +268,7 @@ public:
|
||||
* @param file input file name
|
||||
* @return result of read
|
||||
*/
|
||||
bool read_bin( const std::string& file );
|
||||
bool read_bin( const SGPath& file );
|
||||
|
||||
/**
|
||||
* Write out the structures to a binary file. We assume that the
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
#include "sg_file.hxx"
|
||||
|
||||
|
||||
SGFile::SGFile(const std::string &file, int repeat_, int extraoflags_ )
|
||||
SGFile::SGFile(const SGPath &file, int repeat_, int extraoflags_ )
|
||||
: file_name(file), fp(-1), eof_flag(true), repeat(repeat_), iteration(0),
|
||||
extraoflags(extraoflags_)
|
||||
{
|
||||
@@ -69,24 +69,25 @@ SGFile::~SGFile() {
|
||||
bool SGFile::open( const SGProtocolDir d ) {
|
||||
set_dir( d );
|
||||
|
||||
std::string n = file_name.local8BitStr();
|
||||
if ( get_dir() == SG_IO_OUT ) {
|
||||
#ifdef _WIN32
|
||||
int mode = _S_IREAD | _S_IWRITE;
|
||||
#else
|
||||
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
||||
#endif
|
||||
fp = ::open( file_name.c_str(), O_WRONLY | O_CREAT | O_TRUNC | extraoflags, mode );
|
||||
fp = ::open( n.c_str(), O_WRONLY | O_CREAT | O_TRUNC | extraoflags, mode );
|
||||
} else if ( get_dir() == SG_IO_IN ) {
|
||||
fp = ::open( file_name.c_str(), O_RDONLY | extraoflags );
|
||||
fp = ::open( n.c_str(), O_RDONLY | extraoflags );
|
||||
} else {
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: bidirection mode not available for files." );
|
||||
return false;
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: bidirection mode not available for files." );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( fp == -1 ) {
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error opening file: " << file_name );
|
||||
return false;
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error opening file: " << file_name );
|
||||
return false;
|
||||
}
|
||||
|
||||
eof_flag = false;
|
||||
@@ -180,7 +181,7 @@ bool SGFile::close() {
|
||||
return true;
|
||||
}
|
||||
|
||||
SGBinaryFile::SGBinaryFile( const std::string& file, int repeat_ ) :
|
||||
SGBinaryFile::SGBinaryFile( const SGPath& file, int repeat_ ) :
|
||||
#ifdef _WIN32
|
||||
SGFile(file,repeat_, _O_BINARY)
|
||||
#else
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
#define _SG_FILE_HXX
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
#include "iochannel.hxx"
|
||||
|
||||
#include <string>
|
||||
@@ -32,7 +35,7 @@
|
||||
*/
|
||||
class SGFile : public SGIOChannel {
|
||||
|
||||
std::string file_name;
|
||||
SGPath file_name;
|
||||
int fp;
|
||||
bool eof_flag;
|
||||
// Number of repetitions to play. -1 means loop infinitely.
|
||||
@@ -51,7 +54,7 @@ public:
|
||||
* @param file name of file to open
|
||||
* @param repeat On eof restart at the beginning of the file
|
||||
*/
|
||||
SGFile( const std::string& file, int repeat_ = 1, int extraoflags = 0);
|
||||
SGFile( const SGPath& file, int repeat_ = 1, int extraoflags = 0);
|
||||
|
||||
/**
|
||||
* Create an SGFile from an existing, open file-descriptor
|
||||
@@ -80,7 +83,7 @@ public:
|
||||
bool close();
|
||||
|
||||
/** @return the name of the file being manipulated. */
|
||||
inline std::string get_file_name() const { return file_name; }
|
||||
std::string get_file_name() const { return file_name.utf8Str(); }
|
||||
|
||||
/** @return true of eof conditions exists */
|
||||
virtual bool eof() const { return eof_flag; };
|
||||
@@ -88,7 +91,7 @@ public:
|
||||
|
||||
class SGBinaryFile : public SGFile {
|
||||
public:
|
||||
SGBinaryFile( const std::string& file, int repeat_ = 1 );
|
||||
SGBinaryFile( const SGPath& file, int repeat_ = 1 );
|
||||
};
|
||||
|
||||
#endif // _SG_FILE_HXX
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/sgstream.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
|
||||
#include "interpolater.hxx"
|
||||
@@ -57,7 +58,7 @@ SGInterpTable::SGInterpTable( const std::string& file )
|
||||
{
|
||||
SG_LOG( SG_MATH, SG_INFO, "Initializing Interpolator for " << file );
|
||||
|
||||
sg_gzifstream in( file );
|
||||
sg_gzifstream in( SGPath::fromUtf8(file) );
|
||||
if ( !in.is_open() ) {
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file );
|
||||
return;
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
|
||||
#include <simgear/props/props_io.hxx>
|
||||
#include <simgear/misc/stdint.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -139,7 +140,7 @@ gzContainerWriter::writeContainer(ContainerType Type, SGPropertyNode* root)
|
||||
|
||||
gzContainerReader::gzContainerReader(const std::string& name,
|
||||
const std::string& fileMagic) :
|
||||
sg_gzifstream(name, ios_in | ios_binary),
|
||||
sg_gzifstream(SGPath(name), ios_in | ios_binary),
|
||||
filename(name)
|
||||
{
|
||||
bool ok = (good() && !eof());
|
||||
|
||||
@@ -222,6 +222,17 @@ SGPath::SGPath( const SGPath& p,
|
||||
fix();
|
||||
}
|
||||
|
||||
SGPath SGPath::fromLocal8Bit(const char *name)
|
||||
{
|
||||
return SGPath(simgear::strutils::convertWindowsLocal8BitToUtf8(name));
|
||||
}
|
||||
|
||||
SGPath SGPath::fromUtf8(const std::string& bytes, PermissionChecker p)
|
||||
{
|
||||
return SGPath(bytes, p);
|
||||
}
|
||||
|
||||
|
||||
SGPath::SGPath(const SGPath& p) :
|
||||
path(p.path),
|
||||
_permission_checker(p._permission_checker),
|
||||
@@ -330,6 +341,10 @@ void SGPath::concat( const string& p ) {
|
||||
_rwCached = false;
|
||||
}
|
||||
|
||||
std::string SGPath::local8BitStr() const
|
||||
{
|
||||
return simgear::strutils::convertUtf8ToWindowsLocal8Bit(path);
|
||||
}
|
||||
|
||||
// Get the file part of the path (everything after the last path sep)
|
||||
string SGPath::file() const
|
||||
@@ -533,7 +548,7 @@ int SGPath::create_dir(mode_t mode)
|
||||
if( !canWrite() )
|
||||
{
|
||||
SG_LOG( SG_IO,
|
||||
SG_WARN, "Error creating directory for '" << str() << "'"
|
||||
SG_WARN, "Error creating directory for '" << *this << "'"
|
||||
" reason: access denied" );
|
||||
return -3;
|
||||
}
|
||||
@@ -566,11 +581,11 @@ int SGPath::create_dir(mode_t mode)
|
||||
if( sgMkDir(dir.c_str(), mode) )
|
||||
{
|
||||
SG_LOG( SG_IO,
|
||||
SG_ALERT, "Error creating directory: (" << dir.str() << ")" );
|
||||
SG_ALERT, "Error creating directory: (" << dir << ")" );
|
||||
return -2;
|
||||
}
|
||||
else
|
||||
SG_LOG(SG_IO, SG_DEBUG, "Directory created: " << dir.str());
|
||||
SG_LOG(SG_IO, SG_DEBUG, "Directory created: " << dir);
|
||||
|
||||
if( i >= path_elements.size() )
|
||||
return 0;
|
||||
@@ -648,7 +663,7 @@ bool SGPath::isNull() const
|
||||
std::string SGPath::str_native() const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
std::string s = str();
|
||||
std::string s = local8BitStr();
|
||||
std::string::size_type pos;
|
||||
std::string nativeSeparator;
|
||||
nativeSeparator = sgDirPathSepBad;
|
||||
@@ -658,7 +673,7 @@ std::string SGPath::str_native() const
|
||||
}
|
||||
return s;
|
||||
#else
|
||||
return str();
|
||||
return utf8Str();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -667,7 +682,7 @@ bool SGPath::remove()
|
||||
{
|
||||
if( !canWrite() )
|
||||
{
|
||||
SG_LOG( SG_IO, SG_WARN, "file remove failed: (" << str() << ")"
|
||||
SG_LOG( SG_IO, SG_WARN, "file remove failed: (" << *this << ")"
|
||||
" reason: access denied" );
|
||||
return false;
|
||||
}
|
||||
@@ -675,7 +690,7 @@ bool SGPath::remove()
|
||||
int err = ::unlink(c_str());
|
||||
if( err )
|
||||
{
|
||||
SG_LOG( SG_IO, SG_WARN, "file remove failed: (" << str() << ") "
|
||||
SG_LOG( SG_IO, SG_WARN, "file remove failed: (" << *this << ") "
|
||||
" reason: " << strerror(errno) );
|
||||
// TODO check if failed unlink can really change any of the cached values
|
||||
}
|
||||
@@ -712,8 +727,8 @@ bool SGPath::rename(const SGPath& newName)
|
||||
{
|
||||
if( !canRead() || !canWrite() || !newName.canWrite() )
|
||||
{
|
||||
SG_LOG( SG_IO, SG_WARN, "rename failed: from " << str() <<
|
||||
" to " << newName.str() <<
|
||||
SG_LOG( SG_IO, SG_WARN, "rename failed: from " << *this <<
|
||||
" to " << newName <<
|
||||
" reason: access denied" );
|
||||
return false;
|
||||
}
|
||||
@@ -726,10 +741,13 @@ bool SGPath::rename(const SGPath& newName)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if( ::rename(c_str(), newName.c_str()) != 0 )
|
||||
std::string p = local8BitStr();
|
||||
std::string np = newName.local8BitStr();
|
||||
|
||||
if( ::rename(p.c_str(), np.c_str()) != 0 )
|
||||
{
|
||||
SG_LOG( SG_IO, SG_WARN, "rename failed: from " << str() <<
|
||||
" to " << newName.str() <<
|
||||
SG_LOG( SG_IO, SG_WARN, "rename failed: from " << *this <<
|
||||
" to " << newName <<
|
||||
" reason: " << strerror(errno) );
|
||||
return false;
|
||||
}
|
||||
@@ -821,6 +839,39 @@ SGPath SGPath::fromEnv(const char* name, const SGPath& def)
|
||||
return def;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
std::vector<SGPath> SGPath::pathsFromEnv(const char *name)
|
||||
{
|
||||
std::vector<SGPath> r;
|
||||
const char* val = getenv(name);
|
||||
if (!val) {
|
||||
return r;
|
||||
}
|
||||
|
||||
string_list items = sgPathSplit(val);
|
||||
string_list_iterator it;
|
||||
for (it = items.begin(); it != items.end(); ++it) {
|
||||
r.push_back(SGPath::fromLocal8Bit(it->c_str()));
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
std::vector<SGPath> SGPath::pathsFromLocal8Bit(const std::string& paths)
|
||||
{
|
||||
std::vector<SGPath> r;
|
||||
string_list items = sgPathSplit(paths);
|
||||
string_list_iterator it;
|
||||
for (it = items.begin(); it != items.end(); ++it) {
|
||||
r.push_back(SGPath::fromLocal8Bit(it->c_str()));
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
SGPath SGPath::home(const SGPath& def)
|
||||
{
|
||||
@@ -882,3 +933,22 @@ std::string SGPath::realpath() const
|
||||
free(buf);
|
||||
return p;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
std::string SGPath::join(const std::vector<SGPath>& paths, const std::string& joinWith)
|
||||
{
|
||||
std::string r;
|
||||
if (paths.empty()) {
|
||||
return r;
|
||||
}
|
||||
|
||||
r = paths[0].utf8Str();
|
||||
for (size_t i=1; i<paths.size(); ++i) {
|
||||
r += joinWith + paths[i].utf8Str();
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -186,6 +186,10 @@ public:
|
||||
* @return path string
|
||||
*/
|
||||
std::string str() const { return path; }
|
||||
std::string utf8Str() const { return path; }
|
||||
|
||||
std::string local8BitStr() const;
|
||||
|
||||
|
||||
/**
|
||||
* Get the path string
|
||||
@@ -286,6 +290,10 @@ public:
|
||||
*/
|
||||
static SGPath fromEnv(const char* name, const SGPath& def = SGPath());
|
||||
|
||||
static SGPath fromUtf8(const std::string& bytes, PermissionChecker p = NULL);
|
||||
|
||||
static SGPath fromLocal8Bit(const char* name);
|
||||
|
||||
/**
|
||||
* Get path to user's home directory
|
||||
*/
|
||||
@@ -301,6 +309,11 @@ public:
|
||||
*/
|
||||
static SGPath documents(const SGPath& def = SGPath());
|
||||
|
||||
static std::vector<SGPath> pathsFromEnv(const char* name);
|
||||
|
||||
static std::vector<SGPath> pathsFromLocal8Bit(const std::string& paths);
|
||||
|
||||
static std::string join(const std::vector<SGPath>& paths, const std::string& joinWith);
|
||||
private:
|
||||
|
||||
void fix();
|
||||
@@ -328,8 +341,7 @@ template<typename char_type, typename traits_type>
|
||||
inline
|
||||
std::basic_ostream<char_type, traits_type>&
|
||||
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGPath& p)
|
||||
{ return s << "Path \"" << p.str() << "\""; }
|
||||
|
||||
{ return s << "Path \"" << p.utf8Str() << "\""; }
|
||||
|
||||
/**
|
||||
* Split a directory string into a list of it's parent directories.
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "sgstream.hxx"
|
||||
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
using std::istream;
|
||||
using std::ostream;
|
||||
|
||||
@@ -39,7 +41,7 @@ sg_gzifstream::sg_gzifstream()
|
||||
//
|
||||
// Open a possibly gzipped file for reading.
|
||||
//
|
||||
sg_gzifstream::sg_gzifstream( const std::string& name, ios_openmode io_mode )
|
||||
sg_gzifstream::sg_gzifstream( const SGPath& name, ios_openmode io_mode )
|
||||
: istream(&gzbuf)
|
||||
{
|
||||
this->open( name, io_mode );
|
||||
@@ -64,26 +66,27 @@ sg_gzifstream::sg_gzifstream( int fd, ios_openmode io_mode )
|
||||
// then append ".gz" and try again.
|
||||
//
|
||||
void
|
||||
sg_gzifstream::open( const std::string& name, ios_openmode io_mode )
|
||||
sg_gzifstream::open( const SGPath& name, ios_openmode io_mode )
|
||||
{
|
||||
gzbuf.open( name.c_str(), io_mode );
|
||||
std::string s = name.local8BitStr();
|
||||
|
||||
gzbuf.open( s.c_str(), io_mode );
|
||||
if ( ! gzbuf.is_open() )
|
||||
{
|
||||
std::string s = name;
|
||||
if ( s.substr( s.length() - 3, 3 ) == ".gz" )
|
||||
{
|
||||
// remove ".gz" suffix
|
||||
s.replace( s.length() - 3, 3, "" );
|
||||
// s.erase( s.length() - 3, 3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append ".gz" suffix
|
||||
s += ".gz";
|
||||
}
|
||||
if ( s.substr( s.length() - 3, 3 ) == ".gz" )
|
||||
{
|
||||
// remove ".gz" suffix
|
||||
s.replace( s.length() - 3, 3, "" );
|
||||
// s.erase( s.length() - 3, 3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append ".gz" suffix
|
||||
s += ".gz";
|
||||
}
|
||||
|
||||
// Try again.
|
||||
gzbuf.open( s.c_str(), io_mode );
|
||||
// Try again.
|
||||
gzbuf.open( s.c_str(), io_mode );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
|
||||
#include <simgear/misc/zfstream.hxx>
|
||||
|
||||
class SGPath;
|
||||
|
||||
/**
|
||||
* An envelope class for gzifstream.
|
||||
*/
|
||||
@@ -55,7 +57,7 @@ public:
|
||||
* @param name name of file
|
||||
* @param io_mode file open mode(s) "or'd" together
|
||||
*/
|
||||
sg_gzifstream( const std::string& name,
|
||||
sg_gzifstream( const SGPath& name,
|
||||
ios_openmode io_mode = ios_in | ios_binary );
|
||||
|
||||
/**
|
||||
@@ -70,7 +72,7 @@ public:
|
||||
* @param name name of file
|
||||
* @param io_mode file open mode(s) "or'd" together
|
||||
*/
|
||||
void open( const std::string& name,
|
||||
void open( const SGPath& name,
|
||||
ios_openmode io_mode = ios_in|ios_binary );
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,6 +8,7 @@ using std::cout;
|
||||
using std::endl;
|
||||
|
||||
#include <simgear/misc/sgstream.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
int main()
|
||||
{
|
||||
@@ -24,7 +25,8 @@ int main()
|
||||
f.close();
|
||||
}
|
||||
|
||||
sg_gzifstream sg(fileName);
|
||||
SGPath p(fileName);
|
||||
sg_gzifstream sg(p);
|
||||
std::string stuff;
|
||||
sg >> skipeol;
|
||||
sg >> stuff;
|
||||
|
||||
@@ -407,6 +407,27 @@ std::string convertWindowsLocal8BitToUtf8(const std::string& a)
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string convertUtf8ToWindowsLocal8Bit(const std::string& a)
|
||||
{
|
||||
#ifdef SG_WINDOWS
|
||||
DWORD flags = 0;
|
||||
WCharVec wideString = convertMultiByteToWString(CP_UTF8, a);
|
||||
|
||||
// convert down to local multi-byte
|
||||
std::vector<char> result;
|
||||
int requiredChars = WideCharToMultiByte(CP_ACP, flags,
|
||||
wideString.data(), wideString.size(),
|
||||
NULL, 0, NULL, NULL);
|
||||
result.resize(requiredChars);
|
||||
WideCharToMultiByte(CP_ACP, flags,
|
||||
wideString.data(), wideString.size(),
|
||||
result.data(), result.size(), NULL, NULL);
|
||||
return std::string(result.data(), result.size());
|
||||
#else
|
||||
return a;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
std::string md5(const unsigned char* data, size_t num)
|
||||
{
|
||||
|
||||
@@ -171,6 +171,11 @@ namespace simgear {
|
||||
*/
|
||||
std::string convertWindowsLocal8BitToUtf8(const std::string& a);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
std::string convertUtf8ToWindowsLocal8Bit(const std::string& a);
|
||||
|
||||
#if defined(SG_WINDOWS)
|
||||
typedef std::vector<wchar_t> WCharVec;
|
||||
WCharVec convertUtf8ToWString(const std::string& a);
|
||||
|
||||
@@ -191,7 +191,7 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
|
||||
throw sg_io_exception(message, location,
|
||||
"SimGear Property Reader");
|
||||
}
|
||||
readProperties(path.str(), _root, 0, _extended);
|
||||
readProperties(path, _root, 0, _extended);
|
||||
} catch (sg_io_exception &e) {
|
||||
setException(e);
|
||||
}
|
||||
@@ -278,7 +278,7 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
|
||||
message += val;
|
||||
throw sg_io_exception(message, location, "SimGear Property Reader");
|
||||
}
|
||||
readProperties(path.str(), node, 0, _extended);
|
||||
readProperties(path, node, 0, _extended);
|
||||
}
|
||||
catch (sg_io_exception &e)
|
||||
{
|
||||
@@ -434,11 +434,11 @@ readProperties (istream &input, SGPropertyNode * start_node,
|
||||
* @return true if the read succeeded, false otherwise.
|
||||
*/
|
||||
void
|
||||
readProperties (const string &file, SGPropertyNode * start_node,
|
||||
readProperties (const SGPath &file, SGPropertyNode * start_node,
|
||||
int default_mode, bool extended)
|
||||
{
|
||||
PropsVisitor visitor(start_node, file, default_mode, extended);
|
||||
readXML(file, visitor);
|
||||
PropsVisitor visitor(start_node, file.utf8Str(), default_mode, extended);
|
||||
readXML(file.local8BitStr(), visitor);
|
||||
if (visitor.hasException())
|
||||
throw visitor.getException();
|
||||
}
|
||||
@@ -690,17 +690,17 @@ writeProperties (ostream &output, const SGPropertyNode * start_node,
|
||||
|
||||
|
||||
void
|
||||
writeProperties (const string &file, const SGPropertyNode * start_node,
|
||||
writeProperties (const SGPath &path, const SGPropertyNode * start_node,
|
||||
bool write_all, SGPropertyNode::Attribute archive_flag)
|
||||
{
|
||||
SGPath path(file.c_str());
|
||||
path.create_dir(0755);
|
||||
SGPath dpath(path);
|
||||
dpath.create_dir(0755);
|
||||
|
||||
ofstream output(file.c_str());
|
||||
ofstream output(path.local8BitStr().c_str());
|
||||
if (output.good()) {
|
||||
writeProperties(output, start_node, write_all, archive_flag);
|
||||
} else {
|
||||
throw sg_io_exception("Cannot open file", sg_location(file));
|
||||
throw sg_io_exception("Cannot open file", sg_location(path.utf8Str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ void readProperties (std::istream &input, SGPropertyNode * start_node,
|
||||
/**
|
||||
* Read properties from an XML file.
|
||||
*/
|
||||
void readProperties (const std::string &file, SGPropertyNode * start_node,
|
||||
void readProperties (const SGPath &file, SGPropertyNode * start_node,
|
||||
int default_mode = 0, bool extended = false);
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ void writeProperties (std::ostream &output, const SGPropertyNode * start_node,
|
||||
/**
|
||||
* Write properties to an XML file.
|
||||
*/
|
||||
void writeProperties (const std::string &file,
|
||||
void writeProperties (const SGPath &file,
|
||||
const SGPropertyNode * start_node,
|
||||
bool write_all = false,
|
||||
SGPropertyNode::Attribute archive_flag = SGPropertyNode::ARCHIVE);
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include "props.hxx"
|
||||
#include "props_io.hxx"
|
||||
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
@@ -394,7 +396,7 @@ int main (int ac, char ** av)
|
||||
try {
|
||||
cout << "Reading " << av[i] << endl;
|
||||
SGPropertyNode root;
|
||||
readProperties(av[i], &root);
|
||||
readProperties(SGPath::fromLocal8Bit(av[i]), &root);
|
||||
writeProperties(cout, &root, true);
|
||||
cout << endl;
|
||||
} catch (std::string &message) {
|
||||
|
||||
@@ -33,6 +33,14 @@ sg_location::sg_location (const std::string& path, int line, int column)
|
||||
setPath(path.c_str());
|
||||
}
|
||||
|
||||
sg_location::sg_location (const SGPath& path, int line, int column)
|
||||
: _line(line),
|
||||
_column(column),
|
||||
_byte(-1)
|
||||
{
|
||||
setPath(path.utf8Str().c_str());
|
||||
}
|
||||
|
||||
sg_location::sg_location (const char* path, int line, int column)
|
||||
: _line(line),
|
||||
_column(column),
|
||||
@@ -271,13 +279,6 @@ sg_io_exception::sg_io_exception( const std::string& message,
|
||||
{
|
||||
}
|
||||
|
||||
sg_io_exception::sg_io_exception( const std::string &message,
|
||||
const SGPath& origin )
|
||||
: sg_exception(message, origin.str())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
sg_io_exception::~sg_io_exception () throw ()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@ class sg_location
|
||||
public:
|
||||
enum {max_path = 1024};
|
||||
sg_location ();
|
||||
sg_location(const std::string& path, int line = -1, int column = -1);
|
||||
sg_location(const std::string& path, int line = -1, int column = -1);
|
||||
sg_location(const SGPath& path, int line = -1, int column = -1);
|
||||
explicit sg_location(const char* path, int line = -1, int column = -1);
|
||||
virtual ~sg_location() throw ();
|
||||
virtual const char* getPath() const;
|
||||
@@ -135,7 +136,6 @@ public:
|
||||
sg_io_exception (const std::string &message, const std::string &origin = "");
|
||||
sg_io_exception (const std::string &message, const sg_location &location,
|
||||
const std::string &origin = "");
|
||||
sg_io_exception (const std::string &message, const SGPath& origin);
|
||||
|
||||
virtual ~sg_io_exception () throw ();
|
||||
virtual const std::string getFormattedMessage () const;
|
||||
|
||||
Reference in New Issue
Block a user