diff --git a/extlib/libdxfrw b/extlib/libdxfrw index e389be8..8f95895 160000 --- a/extlib/libdxfrw +++ b/extlib/libdxfrw @@ -1 +1 @@ -Subproject commit e389be82d060ee923b17b9bc574438f3272ef2ad +Subproject commit 8f958955f54668c142ded760dc951ffd16d9c71b diff --git a/src/exportvector.cpp b/src/exportvector.cpp index 1b76b8e..c4f70bd 100644 --- a/src/exportvector.cpp +++ b/src/exportvector.cpp @@ -384,7 +384,7 @@ public: Vector dna = norm.Cross(da).WithMagnitude(1.0); double thetaf = acos(da.DirectionCosineWith(db)); - + // Calculate median Vector m = da.WithMagnitude(1.0).ScaledBy(cos(thetaf/2)).Plus( dna.ScaledBy(sin(thetaf/2))); @@ -684,12 +684,19 @@ void DxfFileWriter::Bezier(SBezier *sb) { paths.back().beziers.push_back(sb); } -void DxfFileWriter::FinishAndCloseFile(void) { - dxfRW dxf(filename.c_str()); +void DxfFileWriter::FinishAndCloseFile() { + dxfRW dxf; + DxfWriteInterface interface(this, &dxf); - dxf.write(&interface, DRW::AC1021, false); + std::stringstream stream; + dxf.write(stream, &interface, DRW::AC1021, /*bin=*/false); paths.clear(); constraint = NULL; + + if(!WriteFile(filename, stream.str())) { + Error("Couldn't write to '%s'", filename.c_str()); + return; + } } bool DxfFileWriter::NeedToOutput(Constraint *c) { diff --git a/src/importdxf.cpp b/src/importdxf.cpp index 5b7d6bd..dbd4e47 100644 --- a/src/importdxf.cpp +++ b/src/importdxf.cpp @@ -902,13 +902,21 @@ public: }; void ImportDxf(const std::string &filename) { - SS.UndoRemember(); - dxfRW dxf(filename.c_str()); DxfReadInterface interface; 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) { Message(ssprintf("%u DXF entities of unknown type were ignored.", interface.unknownEntities).c_str()); @@ -916,13 +924,21 @@ void ImportDxf(const std::string &filename) { } void ImportDwg(const std::string &filename) { - SS.UndoRemember(); - dwgR dwg(filename.c_str()); DxfReadInterface interface; 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) { Message(ssprintf("%u DWG entities of unknown type were ignored.", interface.unknownEntities).c_str()); diff --git a/src/solvespace.h b/src/solvespace.h index 46debb9..a543d5e 100644 --- a/src/solvespace.h +++ b/src/solvespace.h @@ -24,6 +24,7 @@ #include #include #include +#include #ifdef WIN32 # include // required by GL headers #endif @@ -135,6 +136,7 @@ class RgbaColor; #endif 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); #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); std::string MakeAcceleratorLabel(int accel); 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 Error(const char *str, ...); void CnfFreezeBool(bool v, const std::string &name); diff --git a/src/util.cpp b/src/util.cpp index f1c50e4..847f378 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -61,6 +61,33 @@ bool SolveSpace::FilenameHasExtension(const std::string &str, const char *ext) 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, double a11, double a12, double a13, double a14, double a21, double a22, double a23, double a24, diff --git a/src/win32/w32util.cpp b/src/win32/w32util.cpp index 20f3ec6..cba9c78 100644 --- a/src/win32/w32util.cpp +++ b/src/win32/w32util.cpp @@ -67,7 +67,7 @@ std::wstring Widen(const std::string &in) 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. // 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; if(uncFilename.substr(0, 2) != "\\\\") uncFilename = "\\\\?\\" + uncFilename; + return uncFilename; +} +FILE *ssfopen(const std::string &filename, const char *mode) +{ 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)