viewer: fix MSVC compatibility in viewer-reachable code
Address portability issues found building jfjoch_viewer with MSVC:
- common/{ADUHistogram,AzimuthalIntegrationProfile}.h and
image_analysis/spot_finding/StrongPixelSet.h only need DeviceOutput,
so include fpga/pcie_driver/jfjoch_fpga.h (plain-C, self-contained)
directly instead of acquisition_device/AcquisitionDevice.h, which
dragged <unistd.h> into the viewer tree.
- common/time_utc.h: guard gmtime_r/timegm/localtime_r with the MSVC
equivalents (gmtime_s/_mkgmtime/localtime_s) under _WIN32; drop the
duplicated includes and add the headers used directly.
- gemmi_gph/gemmi/utf.hpp: vendor the upstream gemmi header; fileutil.hpp
includes it on Windows for UTF8_to_wchar but it was never vendored.
- writer/HDF5Objects.cpp: ExtractFilename returns path.filename().string()
(std::filesystem::path has no implicit conversion to std::string on
Windows, where it is wchar_t-based).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
#include <mutex>
|
||||
#include "MultiLinePlot.h"
|
||||
#include "../acquisition_device/AcquisitionDevice.h"
|
||||
#include "../fpga/pcie_driver/jfjoch_fpga.h" // DeviceOutput
|
||||
|
||||
class ADUHistogram {
|
||||
mutable std::mutex m;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "MultiLinePlot.h"
|
||||
|
||||
#include "AzimuthalIntegrationMapping.h"
|
||||
#include "../acquisition_device/AcquisitionDevice.h"
|
||||
#include "../fpga/pcie_driver/jfjoch_fpga.h" // DeviceOutput
|
||||
|
||||
class AzimuthalIntegrationProfile {
|
||||
mutable std::mutex m;
|
||||
|
||||
+17
-5
@@ -7,10 +7,10 @@
|
||||
#include <chrono>
|
||||
#include <regex>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <regex>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <ctime>
|
||||
#include <cstdio>
|
||||
|
||||
inline std::string time_UTC(const std::chrono::time_point<std::chrono::system_clock> &input) {
|
||||
auto time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(input.time_since_epoch()).count();
|
||||
@@ -19,8 +19,12 @@ inline std::string time_UTC(const std::chrono::time_point<std::chrono::system_cl
|
||||
time_t time = time_ms / (1000);
|
||||
|
||||
std::tm tm_utc{};
|
||||
#ifdef _WIN32
|
||||
if (gmtime_s(&tm_utc, &time) != 0)
|
||||
#else
|
||||
if (gmtime_r(&time, &tm_utc) == nullptr)
|
||||
throw std::runtime_error("gmtime_r failed");
|
||||
#endif
|
||||
throw std::runtime_error("gmtime failed");
|
||||
|
||||
strftime(buf1, sizeof(buf1), "%FT%T", &tm_utc);
|
||||
snprintf(buf2, sizeof(buf2), ".%03ld", time_ms % 1000);
|
||||
@@ -58,7 +62,11 @@ inline uint64_t parse_UTC_to_ms(const std::string& utc_string) {
|
||||
milliseconds = std::stoi(frac);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
time_t t = _mkgmtime(&tm);
|
||||
#else
|
||||
time_t t = timegm(&tm);
|
||||
#endif
|
||||
return static_cast<uint64_t>(t) * 1000ULL + milliseconds;
|
||||
}
|
||||
|
||||
@@ -71,7 +79,11 @@ inline std::string utc_to_local_human_readable(const std::string& utc_string) {
|
||||
time_t t = system_clock::to_time_t(tp);
|
||||
|
||||
std::tm tm_local{};
|
||||
#ifdef _WIN32
|
||||
if (localtime_s(&tm_local, &t) != 0)
|
||||
#else
|
||||
if (localtime_r(&t, &tm_local) == nullptr)
|
||||
#endif
|
||||
return "";
|
||||
|
||||
static const char* months[] = {
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright 2017 Global Phasing Ltd.
|
||||
//
|
||||
// Conversion between UTF-8 and wchar. Used only for file names on Windows.
|
||||
|
||||
#ifndef GEMMI_UTF_HPP_
|
||||
#define GEMMI_UTF_HPP_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace gemmi {
|
||||
|
||||
// from Mark Ransom's answer
|
||||
// https://stackoverflow.com/questions/148403/utf8-to-from-wide-char-conversion-in-stl/148766#148766
|
||||
inline std::wstring UTF8_to_wchar(const char* in) {
|
||||
std::wstring out;
|
||||
unsigned int codepoint = 0;
|
||||
while (*in != 0) {
|
||||
unsigned char ch = static_cast<unsigned char>(*in);
|
||||
if (ch <= 0x7f)
|
||||
codepoint = ch;
|
||||
else if (ch <= 0xbf)
|
||||
codepoint = (codepoint << 6) | (ch & 0x3f);
|
||||
else if (ch <= 0xdf)
|
||||
codepoint = ch & 0x1f;
|
||||
else if (ch <= 0xef)
|
||||
codepoint = ch & 0x0f;
|
||||
else
|
||||
codepoint = ch & 0x07;
|
||||
++in;
|
||||
if ((*in & 0xc0) != 0x80 && codepoint <= 0x10ffff) {
|
||||
if (sizeof(wchar_t) > 2) {
|
||||
out.append(1, static_cast<wchar_t>(codepoint));
|
||||
} else if (codepoint > 0xffff) {
|
||||
out.append(1, static_cast<wchar_t>(0xd800 + (codepoint >> 10)));
|
||||
out.append(1, static_cast<wchar_t>(0xdc00 + (codepoint & 0x03ff)));
|
||||
} else if (codepoint < 0xd800 || codepoint >= 0xe000) {
|
||||
out.append(1, static_cast<wchar_t>(codepoint));
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
inline std::string wchar_to_UTF8(const wchar_t* in) {
|
||||
std::string out;
|
||||
unsigned int codepoint = 0;
|
||||
while (*in != 0) {
|
||||
if (*in >= 0xd800 && *in <= 0xdbff) {
|
||||
codepoint = ((*in - 0xd800) << 10) + 0x10000;
|
||||
} else {
|
||||
if (*in >= 0xdc00 && *in <= 0xdfff)
|
||||
codepoint |= *in - 0xdc00;
|
||||
else
|
||||
codepoint = *in;
|
||||
if (codepoint <= 0x7f) {
|
||||
out += static_cast<char>(codepoint);
|
||||
} else if (codepoint <= 0x7ff) {
|
||||
out += static_cast<char>(0xc0 | ((codepoint >> 6) & 0x1f));
|
||||
out += static_cast<char>(0x80 | (codepoint & 0x3f));
|
||||
} else if (codepoint <= 0xffff) {
|
||||
out += static_cast<char>(0xe0 | ((codepoint >> 12) & 0x0f));
|
||||
out += static_cast<char>(0x80 | ((codepoint >> 6) & 0x3f));
|
||||
out += static_cast<char>(0x80 | (codepoint & 0x3f));
|
||||
} else {
|
||||
out += static_cast<char>(0xf0 | ((codepoint >> 18) & 0x07));
|
||||
out += static_cast<char>(0x80 | ((codepoint >> 12) & 0x3f));
|
||||
out += static_cast<char>(0x80 | ((codepoint >> 6) & 0x3f));
|
||||
out += static_cast<char>(0x80 | (codepoint & 0x3f));
|
||||
}
|
||||
codepoint = 0;
|
||||
}
|
||||
++in;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace gemmi
|
||||
#endif
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "../../common/DiffractionExperiment.h"
|
||||
#include "../../common/DiffractionSpot.h"
|
||||
#include "../../acquisition_device/AcquisitionDevice.h"
|
||||
#include "../../fpga/pcie_driver/jfjoch_fpga.h" // DeviceOutput
|
||||
#include "SpotFindingSettings.h"
|
||||
|
||||
struct strong_pixel {
|
||||
|
||||
@@ -1014,7 +1014,7 @@ CompressionAlgorithm HDF5Dcpl::GetCompression() {
|
||||
std::string ExtractFilename(const std::string& str) {
|
||||
std::filesystem::path path(str);
|
||||
// if (std::filesystem::is_regular_file(path))
|
||||
return path.filename();
|
||||
return path.filename().string();
|
||||
}
|
||||
|
||||
bool HDF5Object::GetBool(const std::string &name) const {
|
||||
|
||||
Reference in New Issue
Block a user