DXF: update to use Unicode-aware file open routines on Windows.

pull/33/merge
whitequark 2016-10-09 14:58:07 +00:00
parent fd54e5ac27
commit 58db06d845
6 changed files with 56 additions and 13 deletions

@ -1 +1 @@
Subproject commit e389be82d060ee923b17b9bc574438f3272ef2ad Subproject commit 8f958955f54668c142ded760dc951ffd16d9c71b

View File

@ -696,11 +696,19 @@ void DxfFileWriter::Bezier(SBezier *sb) {
} }
void DxfFileWriter::FinishAndCloseFile() { void DxfFileWriter::FinishAndCloseFile() {
dxfRW dxf(filename.c_str()); dxfRW dxf;
DxfWriteInterface interface = {}; DxfWriteInterface interface = {};
interface.writer = this; interface.writer = this;
interface.dxf = &dxf; interface.dxf = &dxf;
dxf.write(&interface, DRW::AC1021, /*bin=*/false);
std::fstream stream = ssfstream(filename, std::ios_base::out);
if(!stream.good()) {
Error("Couldn't write to '%s'", filename.c_str());
return;
}
dxf.write(stream, &interface, DRW::AC1021, /*bin=*/false);
paths.clear(); paths.clear();
constraint = NULL; constraint = NULL;

View File

@ -900,13 +900,20 @@ public:
}; };
void ImportDxf(const std::string &filename) { void ImportDxf(const std::string &filename) {
SS.UndoRemember();
dxfRW dxf(filename.c_str());
DxfReadInterface interface; DxfReadInterface interface;
interface.clearBlockTransform(); interface.clearBlockTransform();
if(!dxf.read(&interface, /*ext=*/false)) {
Error("Corrupted DXF file!"); std::fstream stream = ssfstream(filename, std::ios_base::in);
if(!stream.good()) {
Error("Couldn't read from '%s'", filename.c_str());
return;
} }
SS.UndoRemember();
if(!dxfRW().read(stream, &interface, /*ext=*/false)) {
Error("Corrupted DXF file.");
}
if(interface.unknownEntities > 0) { if(interface.unknownEntities > 0) {
Message(ssprintf("%u DXF entities of unknown type were ignored.", Message(ssprintf("%u DXF entities of unknown type were ignored.",
interface.unknownEntities).c_str()); interface.unknownEntities).c_str());
@ -914,13 +921,20 @@ void ImportDxf(const std::string &filename) {
} }
void ImportDwg(const std::string &filename) { void ImportDwg(const std::string &filename) {
SS.UndoRemember();
dwgR dwg(filename.c_str());
DxfReadInterface interface; DxfReadInterface interface;
interface.clearBlockTransform(); interface.clearBlockTransform();
if(!dwg.read(&interface, /*ext=*/false)) {
Error("Corrupted DWG file!"); std::fstream stream = ssfstream(filename, std::ios_base::in);
if(!stream.good()) {
Error("Couldn't read from '%s'", filename.c_str());
return;
} }
SS.UndoRemember();
if(!dwgR().read(stream, &interface, /*ext=*/false)) {
Error("Corrupted DWG file.");
}
if(interface.unknownEntities > 0) { if(interface.unknownEntities > 0) {
Message(ssprintf("%u DWG entities of unknown type were ignored.", Message(ssprintf("%u DWG entities of unknown type were ignored.",
interface.unknownEntities).c_str()); interface.unknownEntities).c_str());

View File

@ -82,6 +82,13 @@ FILE *ssfopen(const std::string &filename, const char *mode)
return fopen(filename.c_str(), mode); return fopen(filename.c_str(), mode);
} }
std::fstream ssfstream(const std::string &filename, std::ios_base::openmode mode)
{
ssassert(filename.length() == strlen(filename.c_str()),
"Unexpected null byte in middle of a path");
return std::fstream(filename, mode);
}
void ssremove(const std::string &filename) void ssremove(const std::string &filename)
{ {
ssassert(filename.length() == strlen(filename.c_str()), ssassert(filename.length() == strlen(filename.c_str()),

View File

@ -117,7 +117,7 @@ std::string PathSepUnixToPlatform(const std::string &filename)
return result; return result;
} }
FILE *ssfopen(const std::string &filename, const char *mode) static std::string MakeUNCFilename(const std::string &filename)
{ {
// Prepend \\?\ UNC prefix unless already an UNC path. // Prepend \\?\ UNC prefix unless already an UNC path.
// We never try to fopen paths that are not absolute or // We never try to fopen paths that are not absolute or
@ -126,10 +126,22 @@ FILE *ssfopen(const std::string &filename, const char *mode)
std::string uncFilename = filename; std::string uncFilename = filename;
if(uncFilename.substr(0, 2) != "\\\\") if(uncFilename.substr(0, 2) != "\\\\")
uncFilename = "\\\\?\\" + uncFilename; uncFilename = "\\\\?\\" + uncFilename;
return uncFilename;
}
FILE *ssfopen(const std::string &filename, const char *mode)
{
ssassert(filename.length() == strlen(filename.c_str()), ssassert(filename.length() == strlen(filename.c_str()),
"Unexpected null byte in middle of a path"); "Unexpected null byte in middle of a path");
return _wfopen(Widen(uncFilename).c_str(), Widen(mode).c_str()); return _wfopen(Widen(MakeUNCFilename(filename)).c_str(), Widen(mode).c_str());
}
std::fstream ssfstream(const std::string &filename, std::ios_base::openmode mode)
{
std::string uncFilename = MakeUNCFilename(filename);
ssassert(filename.length() == strlen(filename.c_str()),
"Unexpected null byte in middle of a path");
return std::fstream(Widen(MakeUNCFilename(filename)).c_str(), mode);
} }
void ssremove(const std::string &filename) void ssremove(const std::string &filename)

View File

@ -29,6 +29,7 @@
#include <map> #include <map>
#include <set> #include <set>
#include <chrono> #include <chrono>
#include <fstream>
// We declare these in advance instead of simply using FT_Library // We declare these in advance instead of simply using FT_Library
// (defined as typedef FT_LibraryRec_* FT_Library) because including // (defined as typedef FT_LibraryRec_* FT_Library) because including
@ -154,6 +155,7 @@ bool PathEqual(const std::string &a, const std::string &b);
std::string PathSepPlatformToUnix(const std::string &filename); std::string PathSepPlatformToUnix(const std::string &filename);
std::string PathSepUnixToPlatform(const std::string &filename); std::string PathSepUnixToPlatform(const std::string &filename);
FILE *ssfopen(const std::string &filename, const char *mode); FILE *ssfopen(const std::string &filename, const char *mode);
std::fstream ssfstream(const std::string &filename, std::ios_base::openmode mode);
void ssremove(const std::string &filename); void ssremove(const std::string &filename);
const size_t MAX_RECENT = 8; const size_t MAX_RECENT = 8;