#include "sg_binobj.hxx"
#include <simgear/debug/logstream.hxx>
+#include <simgear/misc/sg_path.hxx>
using std::cout;
using std::endl;
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);
} 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;
// 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;
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));
}
}
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;
}
gzclose(fp);
if ( sgWriteError() ) {
- cout << "Error while writing file " << file.str() << endl;
+ cout << "Error while writing file " << file << endl;
return false;
}
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;
}
// 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);
* @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
#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_)
{
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;
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
#define _SG_FILE_HXX
#include <simgear/compiler.h>
+
+#include <simgear/misc/sg_path.hxx>
+
#include "iochannel.hxx"
#include <string>
*/
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.
* @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
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; };
class SGBinaryFile : public SGFile {
public:
- SGBinaryFile( const std::string& file, int repeat_ = 1 );
+ SGBinaryFile( const SGPath& file, int repeat_ = 1 );
};
#endif // _SG_FILE_HXX
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sgstream.hxx>
+#include <simgear/misc/sg_path.hxx>
#include <simgear/props/props.hxx>
#include "interpolater.hxx"
{
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;
#include <simgear/props/props_io.hxx>
#include <simgear/misc/stdint.hxx>
+#include <simgear/misc/sg_path.hxx>
#include <string.h>
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());
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),
_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
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;
}
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;
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;
}
return s;
#else
- return str();
+ return utf8Str();
#endif
}
{
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;
}
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
}
{
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;
}
}
}
#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;
}
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)
{
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;
+}
+
+
* @return path string
*/
std::string str() const { return path; }
+ std::string utf8Str() const { return path; }
+
+ std::string local8BitStr() const;
+
/**
* Get the path string
*/
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
*/
*/
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();
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.
#include "sgstream.hxx"
+#include <simgear/misc/sg_path.hxx>
+
using std::istream;
using std::ostream;
//
// 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 );
// 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 );
}
}
#include <simgear/misc/zfstream.hxx>
+class SGPath;
+
/**
* An envelope class for gzifstream.
*/
* @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 );
/**
* @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 );
/**
using std::endl;
#include <simgear/misc/sgstream.hxx>
+#include <simgear/misc/sg_path.hxx>
int main()
{
f.close();
}
- sg_gzifstream sg(fileName);
+ SGPath p(fileName);
+ sg_gzifstream sg(p);
std::string stuff;
sg >> skipeol;
sg >> stuff;
#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)
{
*/
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);
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);
}
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)
{
* @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();
}
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()));
}
}
/**
* 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);
/**
* 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);
#include "props.hxx"
#include "props_io.hxx"
+#include <simgear/misc/sg_path.hxx>
+
using std::cout;
using std::cerr;
using std::endl;
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) {
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),
{
}
-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 ()
{
}
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;
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;