Update 58db06d8
to not even try to use std::fstream with Unicode paths.
Unfortunately there is no portable way to open an Unicode path with std::fstream. On *nix, it is enough to call the const char* constructor. On MSVC, it is enough to call a nonstandard const wchar_t* constructor. However, on MinGW, there is no way at all to construct an std::fstream with a wide path, not even using undocumented APIs. (There used to be a const wchar_t* overload added back in libstdc++ 4.7, but it got removed for a reason that I was not able to find out.)pull/33/merge
parent
fb87431ba5
commit
d12bf047b4
|
@ -702,16 +702,16 @@ void DxfFileWriter::FinishAndCloseFile() {
|
||||||
interface.writer = this;
|
interface.writer = this;
|
||||||
interface.dxf = &dxf;
|
interface.dxf = &dxf;
|
||||||
|
|
||||||
std::fstream stream = ssfstream(filename, std::ios_base::out);
|
std::stringstream stream;
|
||||||
if(!stream.good()) {
|
|
||||||
Error("Couldn't write to '%s'", filename.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dxf.write(stream, &interface, DRW::AC1021, /*bin=*/false);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
if(!interface.messages.empty()) {
|
if(!interface.messages.empty()) {
|
||||||
std::string text = "Some aspects of the drawing have no DXF equivalent and "
|
std::string text = "Some aspects of the drawing have no DXF equivalent and "
|
||||||
"were not exported:\n";
|
"were not exported:\n";
|
||||||
|
|
|
@ -903,13 +903,14 @@ void ImportDxf(const std::string &filename) {
|
||||||
DxfReadInterface interface;
|
DxfReadInterface interface;
|
||||||
interface.clearBlockTransform();
|
interface.clearBlockTransform();
|
||||||
|
|
||||||
std::fstream stream = ssfstream(filename, std::ios_base::in);
|
std::string data;
|
||||||
if(!stream.good()) {
|
if(!ReadFile(filename, &data)) {
|
||||||
Error("Couldn't read from '%s'", filename.c_str());
|
Error("Couldn't read from '%s'", filename.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
|
std::stringstream stream(data);
|
||||||
if(!dxfRW().read(stream, &interface, /*ext=*/false)) {
|
if(!dxfRW().read(stream, &interface, /*ext=*/false)) {
|
||||||
Error("Corrupted DXF file.");
|
Error("Corrupted DXF file.");
|
||||||
}
|
}
|
||||||
|
@ -924,13 +925,14 @@ void ImportDwg(const std::string &filename) {
|
||||||
DxfReadInterface interface;
|
DxfReadInterface interface;
|
||||||
interface.clearBlockTransform();
|
interface.clearBlockTransform();
|
||||||
|
|
||||||
std::fstream stream = ssfstream(filename, std::ios_base::in);
|
std::string data;
|
||||||
if(!stream.good()) {
|
if(!ReadFile(filename, &data)) {
|
||||||
Error("Couldn't read from '%s'", filename.c_str());
|
Error("Couldn't read from '%s'", filename.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
|
std::stringstream stream(data);
|
||||||
if(!dwgR().read(stream, &interface, /*ext=*/false)) {
|
if(!dwgR().read(stream, &interface, /*ext=*/false)) {
|
||||||
Error("Corrupted DWG file.");
|
Error("Corrupted DWG file.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,13 +82,6 @@ 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()),
|
||||||
|
|
|
@ -136,14 +136,6 @@ FILE *ssfopen(const std::string &filename, const char *mode)
|
||||||
return _wfopen(Widen(MakeUNCFilename(filename)).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)
|
||||||
{
|
{
|
||||||
ssassert(filename.length() == strlen(filename.c_str()),
|
ssassert(filename.length() == strlen(filename.c_str()),
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <fstream>
|
#include <sstream>
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -367,6 +367,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);
|
||||||
|
|
27
src/util.cpp
27
src/util.cpp
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t SolveSpace::GetMilliseconds()
|
int64_t SolveSpace::GetMilliseconds()
|
||||||
{
|
{
|
||||||
auto timestamp = std::chrono::steady_clock::now().time_since_epoch();
|
auto timestamp = std::chrono::steady_clock::now().time_since_epoch();
|
||||||
|
|
|
@ -95,19 +95,6 @@ static std::string Colorize(Color color, std::string input) {
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string ReadFile(std::string path) {
|
|
||||||
std::string data;
|
|
||||||
FILE *f = ssfopen(path.c_str(), "rb");
|
|
||||||
if(f) {
|
|
||||||
fseek(f, 0, SEEK_END);
|
|
||||||
data.resize(ftell(f));
|
|
||||||
fseek(f, 0, SEEK_SET);
|
|
||||||
fread(&data[0], 1, data.size(), f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normalizes a savefile. Different platforms have slightly different floating-point
|
// Normalizes a savefile. Different platforms have slightly different floating-point
|
||||||
// behavior, so if we want to compare savefiles byte-by-byte, we need to do something
|
// behavior, so if we want to compare savefiles byte-by-byte, we need to do something
|
||||||
// to get rid of irrelevant differences in LSB.
|
// to get rid of irrelevant differences in LSB.
|
||||||
|
@ -211,9 +198,10 @@ bool Test::Helper::CheckSave(const char *file, int line, const char *reference)
|
||||||
ssprintf("saving file '%s'", refPath.c_str()));
|
ssprintf("saving file '%s'", refPath.c_str()));
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
std::string refData = PrepareSavefile(ReadFile(refPath)),
|
std::string refData, outData;
|
||||||
outData = PrepareSavefile(ReadFile(outPath));
|
ReadFile(refPath, &refData);
|
||||||
if(!RecordCheck(refData == outData)) {
|
ReadFile(outPath, &outData);
|
||||||
|
if(!RecordCheck(PrepareSavefile(refData) == PrepareSavefile(outData))) {
|
||||||
PrintFailure(file, line, "savefile doesn't match reference");
|
PrintFailure(file, line, "savefile doesn't match reference");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue