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

This commit is contained in:
whitequark 2016-10-09 14:58:07 +00:00
parent 359b13bd62
commit bbd106044b
6 changed files with 73 additions and 15 deletions

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

View File

@ -384,7 +384,7 @@ public:
Vector dna = norm.Cross(da).WithMagnitude(1.0); Vector dna = norm.Cross(da).WithMagnitude(1.0);
double thetaf = acos(da.DirectionCosineWith(db)); double thetaf = acos(da.DirectionCosineWith(db));
// Calculate median // Calculate median
Vector m = da.WithMagnitude(1.0).ScaledBy(cos(thetaf/2)).Plus( Vector m = da.WithMagnitude(1.0).ScaledBy(cos(thetaf/2)).Plus(
dna.ScaledBy(sin(thetaf/2))); dna.ScaledBy(sin(thetaf/2)));
@ -684,12 +684,19 @@ void DxfFileWriter::Bezier(SBezier *sb) {
paths.back().beziers.push_back(sb); paths.back().beziers.push_back(sb);
} }
void DxfFileWriter::FinishAndCloseFile(void) { void DxfFileWriter::FinishAndCloseFile() {
dxfRW dxf(filename.c_str()); dxfRW dxf;
DxfWriteInterface interface(this, &dxf); DxfWriteInterface interface(this, &dxf);
dxf.write(&interface, DRW::AC1021, false); std::stringstream stream;
dxf.write(stream, &interface, DRW::AC1021, /*bin=*/false);
paths.clear(); paths.clear();
constraint = NULL; constraint = NULL;
if(!WriteFile(filename, stream.str())) {
Error("Couldn't write to '%s'", filename.c_str());
return;
}
} }
bool DxfFileWriter::NeedToOutput(Constraint *c) { bool DxfFileWriter::NeedToOutput(Constraint *c) {

View File

@ -902,13 +902,21 @@ 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, false)) {
Error("Corrupted DXF file!"); std::string data;
if(!ReadFile(filename, &data)) {
Error("Couldn't read from '%s'", filename.c_str());
return;
} }
SS.UndoRemember();
std::stringstream stream(data);
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());
@ -916,13 +924,21 @@ 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, false)) {
Error("Corrupted DWG file!"); std::string data;
if(!ReadFile(filename, &data)) {
Error("Couldn't read from '%s'", filename.c_str());
return;
} }
SS.UndoRemember();
std::stringstream stream(data);
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

@ -24,6 +24,7 @@
#include <unordered_map> #include <unordered_map>
#include <map> #include <map>
#include <set> #include <set>
#include <sstream>
#ifdef WIN32 #ifdef WIN32
# include <windows.h> // required by GL headers # include <windows.h> // required by GL headers
#endif #endif
@ -135,6 +136,7 @@ class RgbaColor;
#endif #endif
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);
#define MAX_RECENT 8 #define MAX_RECENT 8
@ -374,6 +376,8 @@ void MakeMatrix(double *mat, double a11, double a12, double a13, double a14,
double a41, double a42, double a43, double a44); double a41, double a42, double a43, double a44);
std::string MakeAcceleratorLabel(int accel); std::string MakeAcceleratorLabel(int accel);
bool FilenameHasExtension(const std::string &str, const char *ext); bool FilenameHasExtension(const std::string &str, const char *ext);
bool ReadFile(const std::string &filename, std::string *data);
bool WriteFile(const std::string &filename, const std::string &data);
void Message(const char *str, ...); void Message(const char *str, ...);
void Error(const char *str, ...); void Error(const char *str, ...);
void CnfFreezeBool(bool v, const std::string &name); void CnfFreezeBool(bool v, const std::string &name);

View File

@ -61,6 +61,33 @@ bool SolveSpace::FilenameHasExtension(const std::string &str, const char *ext)
return true; return true;
} }
bool SolveSpace::ReadFile(const std::string &filename, std::string *data)
{
FILE *f = ssfopen(filename.c_str(), "rb");
if(f == NULL)
return false;
fseek(f, 0, SEEK_END);
data->resize(ftell(f));
fseek(f, 0, SEEK_SET);
fread(&(*data)[0], 1, data->size(), f);
fclose(f);
return true;
}
bool SolveSpace::WriteFile(const std::string &filename, const std::string &data)
{
FILE *f = ssfopen(filename.c_str(), "wb");
if(f == NULL)
return false;
fwrite(&data[0], 1, data.size(), f);
fclose(f);
return true;
}
void SolveSpace::MakeMatrix(double *mat, void SolveSpace::MakeMatrix(double *mat,
double a11, double a12, double a13, double a14, double a11, double a12, double a13, double a14,
double a21, double a22, double a23, double a24, double a21, double a22, double a23, double a24,

View File

@ -67,7 +67,7 @@ std::wstring Widen(const std::string &in)
return out; return out;
} }
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
@ -76,9 +76,13 @@ 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)
{
if(filename.length() != strlen(filename.c_str())) oops(); if(filename.length() != strlen(filename.c_str())) oops();
return _wfopen(Widen(uncFilename).c_str(), Widen(mode).c_str()); return _wfopen(Widen(MakeUNCFilename(filename)).c_str(), Widen(mode).c_str());
} }
void ssremove(const std::string &filename) void ssremove(const std::string &filename)