From 7b6c41de28c0aa5295aa37687b3a0963340e0d36 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 26 Jan 2024 18:29:33 +0100 Subject: [PATCH 01/11] Rest Service now updated mtconnect namespace version to match the schema version --- demo/agent/agent.cfg | 2 +- src/mtconnect/sink/rest_sink/rest_service.cpp | 49 +++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/demo/agent/agent.cfg b/demo/agent/agent.cfg index e9d3f23d..a407915d 100644 --- a/demo/agent/agent.cfg +++ b/demo/agent/agent.cfg @@ -1,5 +1,5 @@ Devices = Devices.xml -SchemaVersion = 2.0 +SchemaVersion = 2.2 WorkerThreads = 3 MonitorConfigFiles = yes Port = 5001 diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 7fd3aa0e..778824e0 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -17,6 +17,8 @@ #include "rest_service.hpp" +#include + #include "mtconnect/configuration/config_options.hpp" #include "mtconnect/entity/xml_parser.hpp" #include "mtconnect/pipeline/shdr_token_mapper.hpp" @@ -270,6 +272,7 @@ namespace mtconnect { void RestService::loadStyle(const ptree &tree, const char *styleName, XmlPrinter *xmlPrinter, StyleFunction styleFunction) { + namespace fs = std::filesystem; auto style = tree.get_child_optional(styleName); if (style) { @@ -281,10 +284,50 @@ namespace mtconnect { else { (xmlPrinter->*styleFunction)(*location); - auto path = style->get_optional("Path"); - if (path) + auto configPath = style->get_optional("Path"); + if (configPath) + { + m_fileCache.registerFile(*location, *configPath, m_schemaVersion); + } + + if (auto fc = m_fileCache.getFile(*location)) + { + FILE *file = nullptr; + char *buffer; + try { + buffer = new char[fc->m_size]; + file = std::fopen(fc->m_path.c_str(), "rb"); + auto len = std::fread(buffer, 1, fc->m_size, file); + std::fclose(file); + file = nullptr; + if (len > 0) + { + string_view sv(buffer, len); + + std::ofstream out(fc->m_path); + std::ostream_iterator oi(out); + + std::regex reg("(xmlns:[A-Za-z]+=\"urn:mtconnect.org:MTConnect[^:]+:)[[:digit:]]+\\.[[:digit:]]+(\")"); + std::regex_replace(oi, sv.begin(), sv.end(), reg, "$01" + m_schemaVersion + "$2", + std::regex_constants::match_default | std::regex_constants::match_any); + } + else + { + LOG(warning) << "Cannot read style file: " << fc->m_path; + } + } + catch (...) + { + LOG(error) << "Cannot update sylesheet"; + if (file != nullptr) + std::fclose(file); + if (buffer != nullptr) + delete buffer; + } + } + else { - m_fileCache.registerFile(*location, *path, m_schemaVersion); + LOG(warning) << "Cannot find path for style file: " << *location; } } } From 9722eb691fbd4d4ba646cf3d453d63e9f070808c Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 26 Jan 2024 18:32:07 +0100 Subject: [PATCH 02/11] formatted with clang --- src/mtconnect/configuration/agent_config.cpp | 2 +- src/mtconnect/sink/rest_sink/rest_service.cpp | 16 ++++++++++------ test_package/agent_test.cpp | 5 +++-- test_package/config_test.cpp | 4 ++-- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/mtconnect/configuration/agent_config.cpp b/src/mtconnect/configuration/agent_config.cpp index eb2aad87..d5166da2 100644 --- a/src/mtconnect/configuration/agent_config.cpp +++ b/src/mtconnect/configuration/agent_config.cpp @@ -964,7 +964,7 @@ namespace mtconnect::configuration { { adapterOptions[configuration::Device] = *device->getUuid(); } - + if (!device) { LOG(warning) << "Cannot locate device name '" << deviceName << "', assuming dynamic"; diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 778824e0..65eac7e6 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -294,7 +294,8 @@ namespace mtconnect { { FILE *file = nullptr; char *buffer; - try { + try + { buffer = new char[fc->m_size]; file = std::fopen(fc->m_path.c_str(), "rb"); auto len = std::fread(buffer, 1, fc->m_size, file); @@ -303,13 +304,16 @@ namespace mtconnect { if (len > 0) { string_view sv(buffer, len); - + std::ofstream out(fc->m_path); std::ostream_iterator oi(out); - - std::regex reg("(xmlns:[A-Za-z]+=\"urn:mtconnect.org:MTConnect[^:]+:)[[:digit:]]+\\.[[:digit:]]+(\")"); - std::regex_replace(oi, sv.begin(), sv.end(), reg, "$01" + m_schemaVersion + "$2", - std::regex_constants::match_default | std::regex_constants::match_any); + + std::regex reg( + "(xmlns:[A-Za-z]+=\"urn:mtconnect.org:MTConnect[^:]+:)" + "[[:digit:]]+\\.[[:digit:]]+(\")"); + std::regex_replace( + oi, sv.begin(), sv.end(), reg, "$01" + m_schemaVersion + "$2", + std::regex_constants::match_default | std::regex_constants::match_any); } else { diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index 45f9ee5e..2615536c 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -3013,8 +3013,9 @@ TEST_F(AgentTest, should_not_add_spaces_to_output) ASSERT_XML_PATH_EQUAL(doc, "//m:DeviceStream//m:Program", ""); ASSERT_XML_PATH_EQUAL(doc, "//m:DeviceStream//m:Block", ""); } - - m_agentTestHelper->m_adapter->processData("2024-01-22T20:00:00Z|program| |block| "); + + m_agentTestHelper->m_adapter->processData( + "2024-01-22T20:00:00Z|program| |block| "); { PARSE_XML_RESPONSE("/current"); diff --git a/test_package/config_test.cpp b/test_package/config_test.cpp index 1a61c044..e70d8f78 100644 --- a/test_package/config_test.cpp +++ b/test_package/config_test.cpp @@ -2257,7 +2257,7 @@ AgentDeviceUUID = SOME_UUID const auto &ad = m_config->getAgent()->getAgentDevice(); ASSERT_EQ("SOME_UUID", *(ad->getUuid())); } - + TEST_F(ConfigTest, should_set_device_uuid_when_specified_in_adapter_config) { string config(R"DOC( @@ -2277,7 +2277,7 @@ Adapters { ASSERT_TRUE(dev); ASSERT_EQ("NEW-UUID", *(dev->getUuid())); } - + TEST_F(ConfigTest, should_set_default_device_uuid_when_specified_in_adapter_config) { string config(R"DOC( From d89981062f3f9605349b804e574cca6c079e81e6 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 26 Jan 2024 18:46:23 +0100 Subject: [PATCH 03/11] Simplified code --- src/mtconnect/sink/rest_sink/rest_service.cpp | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 65eac7e6..e1118bf0 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -298,36 +298,42 @@ namespace mtconnect { { buffer = new char[fc->m_size]; file = std::fopen(fc->m_path.c_str(), "rb"); + if (file == nullptr) + throw std::runtime_error("Cannot open file for reading"); + auto len = std::fread(buffer, 1, fc->m_size, file); std::fclose(file); file = nullptr; - if (len > 0) - { - string_view sv(buffer, len); + if (len <= 0) + throw std::runtime_error("Cannot read from file"); - std::ofstream out(fc->m_path); - std::ostream_iterator oi(out); + string_view sv(buffer, len); - std::regex reg( - "(xmlns:[A-Za-z]+=\"urn:mtconnect.org:MTConnect[^:]+:)" - "[[:digit:]]+\\.[[:digit:]]+(\")"); - std::regex_replace( - oi, sv.begin(), sv.end(), reg, "$01" + m_schemaVersion + "$2", - std::regex_constants::match_default | std::regex_constants::match_any); - } - else - { - LOG(warning) << "Cannot read style file: " << fc->m_path; - } + std::ofstream out(fc->m_path); + if (!out.is_open()) + throw std::runtime_error("Cannot open file for writing"); + + std::ostream_iterator oi(out); + + std::regex reg( + "(xmlns:[A-Za-z]+=\"urn:mtconnect.org:MTConnect[^:]+:)" + "[[:digit:]]+\\.[[:digit:]]+(\")"); + std::regex_replace( + oi, sv.begin(), sv.end(), reg, "$01" + m_schemaVersion + "$2", + std::regex_constants::match_default | std::regex_constants::match_any); + } + catch (std::runtime_error ec) + { + LOG(error) << "Cannot update sylesheet: " << ec.what() << " (" << fc->m_path << ')'; } catch (...) { - LOG(error) << "Cannot update sylesheet"; - if (file != nullptr) - std::fclose(file); - if (buffer != nullptr) - delete buffer; + LOG(error) << "Cannot update sylesheet: (" << fc->m_path << ')'; } + if (file != nullptr) + std::fclose(file); + if (buffer != nullptr) + delete buffer; } else { From 19e23e88189b4e18ad6199727f4446c41a04e5bc Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 26 Jan 2024 18:59:10 +0100 Subject: [PATCH 04/11] use unique pointers to simplify cleanup --- src/mtconnect/sink/rest_sink/rest_service.cpp | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index e1118bf0..8a8b0d27 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -292,22 +292,20 @@ namespace mtconnect { if (auto fc = m_fileCache.getFile(*location)) { - FILE *file = nullptr; - char *buffer; try { - buffer = new char[fc->m_size]; - file = std::fopen(fc->m_path.c_str(), "rb"); - if (file == nullptr) + using unique_file = std::unique_ptr; + unique_ptr buffer(new char[fc->m_size]); + unique_file file(std::fopen(fc->m_path.c_str(), "rb"), &std::fclose); + if (!file) throw std::runtime_error("Cannot open file for reading"); - auto len = std::fread(buffer, 1, fc->m_size, file); - std::fclose(file); - file = nullptr; + auto len = std::fread(buffer.get(), 1, fc->m_size, file.get()); + file.reset(); if (len <= 0) throw std::runtime_error("Cannot read from file"); - string_view sv(buffer, len); + string_view sv(buffer.get(), len); std::ofstream out(fc->m_path); if (!out.is_open()) @@ -330,10 +328,6 @@ namespace mtconnect { { LOG(error) << "Cannot update sylesheet: (" << fc->m_path << ')'; } - if (file != nullptr) - std::fclose(file); - if (buffer != nullptr) - delete buffer; } else { From 20b8b34b6a2d40c4284282dba6d806cb560c3f64 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 26 Jan 2024 21:51:34 +0100 Subject: [PATCH 05/11] windows port --- src/mtconnect/sink/rest_sink/rest_service.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 8a8b0d27..9e79a52e 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -296,7 +296,7 @@ namespace mtconnect { { using unique_file = std::unique_ptr; unique_ptr buffer(new char[fc->m_size]); - unique_file file(std::fopen(fc->m_path.c_str(), "rb"), &std::fclose); + unique_file file(std::fopen(reinterpret_cast(fc->m_path.c_str()), "rb"), &std::fclose); if (!file) throw std::runtime_error("Cannot open file for reading"); From f81d26cc60f2f05dd610aa851f2cba3c66f3470e Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 26 Jan 2024 22:57:09 +0100 Subject: [PATCH 06/11] Added unit test for stylesheet update --- test_package/config_test.cpp | 103 ++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 15 deletions(-) diff --git a/test_package/config_test.cpp b/test_package/config_test.cpp index e70d8f78..6e8d0f75 100644 --- a/test_package/config_test.cpp +++ b/test_package/config_test.cpp @@ -91,9 +91,15 @@ namespace { return root; } - fs::path copyFile(const std::string &src, fs::path target, chrono::seconds delta) + fs::path copySampleFile(const std::string &src, fs::path target, chrono::seconds delta) { - fs::path file {fs::path(TEST_RESOURCE_DIR) / "samples" / src}; + fs::path file { fs::path("samples") / src }; + return copyFile(file, target, delta); + } + + fs::path copyFile(const fs::path src, fs::path target, chrono::seconds delta) + { + fs::path file {fs::path(TEST_RESOURCE_DIR) / src}; fs::copy_file(file, target, fs::copy_options::overwrite_existing); auto t = fs::last_write_time(target); @@ -103,6 +109,7 @@ namespace { return target; } + void replaceTextInFile(fs::path file, const std::string &from, const std::string &to) { ifstream is {file.string(), ios::binary | ios::ate}; @@ -979,7 +986,7 @@ Port = 0 cfg << "Devices = " << devices << endl; } - copyFile("min_config.xml", devices, 60min); + copySampleFile("min_config.xml", devices, 60min); boost::program_options::variables_map options; boost::program_options::variable_value value(boost::optional(config.string()), false); @@ -1058,7 +1065,7 @@ Port = 0 cfg << "Devices = " << devices << endl; } - copyFile("min_config.xml", devices, 1min); + copySampleFile("min_config.xml", devices, 1min); boost::program_options::variables_map options; boost::program_options::variable_value value(boost::optional(config.string()), false); @@ -1125,7 +1132,7 @@ Port = 0 cfg << "Devices = " << devices << endl; } - copyFile("min_config.xml", devices, 0s); + copySampleFile("min_config.xml", devices, 0s); boost::program_options::variables_map options; boost::program_options::variable_value value(boost::optional(config.string()), false); @@ -1199,7 +1206,7 @@ Port = 0 cfg << "Devices = " << devices << endl; } - copyFile("min_config.xml", devices, 1min); + copySampleFile("min_config.xml", devices, 1min); boost::program_options::variables_map options; boost::program_options::variable_value value(boost::optional(config.string()), false); @@ -1316,7 +1323,7 @@ Port = 0 cfg << "Devices = " << devices << endl; } - copyFile("min_config.xml", devices, 10min); + copySampleFile("min_config.xml", devices, 10min); replaceTextInFile(devices, "2.0", "1.2"); boost::program_options::variables_map options; @@ -1415,7 +1422,7 @@ Adapters { cfg << "Devices = " << devices << endl; } - copyFile("empty.xml", devices, 0min); + copySampleFile("empty.xml", devices, 0min); boost::program_options::variables_map options; boost::program_options::variable_value value(boost::optional(config.string()), false); @@ -1527,7 +1534,7 @@ Port = 0 cfg << "Devices = " << devices << endl; } - copyFile("dyn_load.xml", devices, 0min); + copySampleFile("dyn_load.xml", devices, 0min); boost::program_options::variables_map options; boost::program_options::variable_value value(boost::optional(config.string()), false); @@ -1656,7 +1663,7 @@ Port = 0 cfg << "Devices = " << devices << endl; } - copyFile("dyn_load.xml", devices, 0min); + copySampleFile("dyn_load.xml", devices, 0min); boost::program_options::variables_map options; boost::program_options::variable_value value(boost::optional(config.string()), false); @@ -1718,7 +1725,7 @@ Port = 0 cfg << "Devices = " << devices << endl; } - copyFile("dyn_load.xml", devices, 0min); + copySampleFile("dyn_load.xml", devices, 0min); boost::program_options::variables_map options; boost::program_options::variable_value value(boost::optional(config.string()), false); @@ -1836,7 +1843,7 @@ Adapters { cfg << "Devices = " << devices << endl; } - copyFile("empty.xml", devices, 0min); + copySampleFile("empty.xml", devices, 0min); boost::program_options::variables_map options; boost::program_options::variable_value value(boost::optional(config.string()), false); @@ -1941,7 +1948,7 @@ Port = 0 cfg << "Devices = " << devices << endl; } - copyFile("dyn_load.xml", devices, 0min); + copySampleFile("dyn_load.xml", devices, 0min); boost::program_options::variables_map options; boost::program_options::variable_value value(boost::optional(config.string()), false); @@ -2068,7 +2075,7 @@ Adapters { cfg << "Devices = " << devices << endl; } - copyFile("empty.xml", devices, 0min); + copySampleFile("empty.xml", devices, 0min); boost::program_options::variables_map options; boost::program_options::variable_value value(boost::optional(config.string()), false); @@ -2190,7 +2197,7 @@ ServiceName="some_prefix_${CONFIG_TEST}_suffix" TEST_F(ConfigTest, should_find_device_file_in_config_path) { fs::path root {createTempDirectory("13")}; - copyFile("empty.xml", root / "test.xml", 0min); + copySampleFile("empty.xml", root / "test.xml", 0min); chdir(m_cwd.string().c_str()); m_config->updateWorkingDirectory(); @@ -2297,5 +2304,71 @@ Adapters { ASSERT_TRUE(dev); ASSERT_EQ("NEW-UUID", *(dev->getUuid())); } + + TEST_F(ConfigTest, should_update_stylesheet_versions) + { + fs::path root {createTempDirectory("14")}; + + fs::path styleDir { root / "styles" }; + fs::create_directory(styleDir); + + fs::path styles { styleDir / "styles.xsl" }; + copyFile("styles/styles.xsl", styles, 0min); + + fs::path devices(root / "Devices.xml"); + copySampleFile("empty.xml", devices, 0min); + + fs::path config {root / "agent.cfg"}; + { + ofstream cfg(config.string()); + cfg << R"DOC( +SchemaVersion = 2.2 +)DOC"; + cfg << "Devices = " << devices << endl; + cfg << R"DOC( +Files { + styles { + Path = ./styles + Location = /styles/ + } +} +DevicesStyle { Location = /styles/styles.xsl } +)DOC"; + + } + + boost::program_options::variables_map options; + boost::program_options::variable_value value(boost::optional(config.string()), false); + options.insert(make_pair("config-file"s, value)); + m_config->initialize(options); + + ifstream file(styles); + ASSERT_TRUE(file.is_open()); + + stringstream sf; + sf << file.rdbuf(); + + ASSERT_EQ(R"DOC( + + + + + + + + +)DOC", sf.str()); + + m_config->stop(); + } } // namespace From 854999ed66c8f971f035c2d49193599fa0265529 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 26 Jan 2024 23:05:09 +0100 Subject: [PATCH 07/11] added second test with Path option to directly specify the file --- test_package/config_test.cpp | 65 ++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/test_package/config_test.cpp b/test_package/config_test.cpp index 6e8d0f75..be3d91a4 100644 --- a/test_package/config_test.cpp +++ b/test_package/config_test.cpp @@ -2371,4 +2371,69 @@ DevicesStyle { Location = /styles/styles.xsl } m_config->stop(); } + + TEST_F(ConfigTest, should_update_stylesheet_versions_with_path) + { + fs::path root {createTempDirectory("14")}; + + fs::path styleDir { root / "styles" }; + fs::create_directory(styleDir); + + fs::path styles { styleDir / "styles.xsl" }; + copyFile("styles/styles.xsl", styles, 0min); + + fs::path devices(root / "Devices.xml"); + copySampleFile("empty.xml", devices, 0min); + + fs::path config {root / "agent.cfg"}; + { + ofstream cfg(config.string()); + cfg << R"DOC( +SchemaVersion = 2.2 +)DOC"; + cfg << "Devices = " << devices << endl; + cfg << R"DOC( +DevicesStyle { + Location = /styles/styles.xsl + Path = ./styles/styles.xsl +} +)DOC"; + + } + + boost::program_options::variables_map options; + boost::program_options::variable_value value(boost::optional(config.string()), false); + options.insert(make_pair("config-file"s, value)); + + m_config->initialize(options); + + ifstream file(styles); + ASSERT_TRUE(file.is_open()); + + stringstream sf; + sf << file.rdbuf(); + + ASSERT_EQ(R"DOC( + + + + + + + + +)DOC", sf.str()); + + m_config->stop(); + } + } // namespace From 47d20e2af7baa8466ef009e385583b364d12ebe4 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 26 Jan 2024 23:12:15 +0100 Subject: [PATCH 08/11] need new directory for second test --- test_package/config_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_package/config_test.cpp b/test_package/config_test.cpp index be3d91a4..1774c2db 100644 --- a/test_package/config_test.cpp +++ b/test_package/config_test.cpp @@ -2374,7 +2374,7 @@ DevicesStyle { Location = /styles/styles.xsl } TEST_F(ConfigTest, should_update_stylesheet_versions_with_path) { - fs::path root {createTempDirectory("14")}; + fs::path root {createTempDirectory("15")}; fs::path styleDir { root / "styles" }; fs::create_directory(styleDir); From 52207a50efa5fc6c303d70d91ae584b99bcdf872 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 26 Jan 2024 23:16:21 +0100 Subject: [PATCH 09/11] forgot to add styles file --- test_package/resources/styles/styles.xsl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 test_package/resources/styles/styles.xsl diff --git a/test_package/resources/styles/styles.xsl b/test_package/resources/styles/styles.xsl new file mode 100644 index 00000000..7270840e --- /dev/null +++ b/test_package/resources/styles/styles.xsl @@ -0,0 +1,18 @@ + + + + + + + + + From a54ed347ffbcc8bfa6dfcc8c54daa0681f1ad065 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 27 Jan 2024 01:19:53 +0100 Subject: [PATCH 10/11] fixed windows porting issues --- src/mtconnect/sink/rest_sink/rest_service.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 9e79a52e..872a38ad 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -294,23 +294,22 @@ namespace mtconnect { { try { - using unique_file = std::unique_ptr; unique_ptr buffer(new char[fc->m_size]); - unique_file file(std::fopen(reinterpret_cast(fc->m_path.c_str()), "rb"), &std::fclose); - if (!file) + std::filebuf file; + if (file.open(fc->m_path, std::ios::binary | std::ios::in) == nullptr) throw std::runtime_error("Cannot open file for reading"); - auto len = std::fread(buffer.get(), 1, fc->m_size, file.get()); - file.reset(); + auto len = file.sgetn(buffer.get(), fc->m_size); + file.close(); if (len <= 0) throw std::runtime_error("Cannot read from file"); string_view sv(buffer.get(), len); - std::ofstream out(fc->m_path); + std::ofstream out(fc->m_path, std::ios::binary | std::ios_base::out); if (!out.is_open()) throw std::runtime_error("Cannot open file for writing"); - + std::ostream_iterator oi(out); std::regex reg( From 928facaa347f04a7ba73139503ed03e0287d33b5 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 27 Jan 2024 20:54:56 +0100 Subject: [PATCH 11/11] use filebuf for cached file --- src/mtconnect/sink/rest_sink/cached_file.hpp | 10 ++++- src/mtconnect/sink/rest_sink/rest_service.cpp | 2 +- test_package/config_test.cpp | 45 +++++++++---------- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/cached_file.hpp b/src/mtconnect/sink/rest_sink/cached_file.hpp index 417c16e8..da2ca52f 100644 --- a/src/mtconnect/sink/rest_sink/cached_file.hpp +++ b/src/mtconnect/sink/rest_sink/cached_file.hpp @@ -94,8 +94,14 @@ namespace mtconnect::sink::rest_sink { if (cached) { allocate(m_size); - auto file = std::fopen(path.string().c_str(), "rb"); - m_size = std::fread(m_buffer, 1, m_size, file); + std::filebuf file; + if (file.open(m_path, std::ios::binary | std::ios::in) != nullptr) + m_size = file.sgetn(m_buffer, m_size); + else + { + LOG(warning) << "Cannot open cached file: " << path; + m_cached = false; + } } m_lastWrite = std::filesystem::last_write_time(m_path); } diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 872a38ad..34a548f9 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -309,7 +309,7 @@ namespace mtconnect { std::ofstream out(fc->m_path, std::ios::binary | std::ios_base::out); if (!out.is_open()) throw std::runtime_error("Cannot open file for writing"); - + std::ostream_iterator oi(out); std::regex reg( diff --git a/test_package/config_test.cpp b/test_package/config_test.cpp index 1774c2db..2eeba275 100644 --- a/test_package/config_test.cpp +++ b/test_package/config_test.cpp @@ -93,10 +93,10 @@ namespace { fs::path copySampleFile(const std::string &src, fs::path target, chrono::seconds delta) { - fs::path file { fs::path("samples") / src }; + fs::path file {fs::path("samples") / src}; return copyFile(file, target, delta); } - + fs::path copyFile(const fs::path src, fs::path target, chrono::seconds delta) { fs::path file {fs::path(TEST_RESOURCE_DIR) / src}; @@ -109,7 +109,6 @@ namespace { return target; } - void replaceTextInFile(fs::path file, const std::string &from, const std::string &to) { ifstream is {file.string(), ios::binary | ios::ate}; @@ -2304,17 +2303,17 @@ Adapters { ASSERT_TRUE(dev); ASSERT_EQ("NEW-UUID", *(dev->getUuid())); } - + TEST_F(ConfigTest, should_update_stylesheet_versions) { fs::path root {createTempDirectory("14")}; - fs::path styleDir { root / "styles" }; + fs::path styleDir {root / "styles"}; fs::create_directory(styleDir); - - fs::path styles { styleDir / "styles.xsl" }; + + fs::path styles {styleDir / "styles.xsl"}; copyFile("styles/styles.xsl", styles, 0min); - + fs::path devices(root / "Devices.xml"); copySampleFile("empty.xml", devices, 0min); @@ -2334,7 +2333,6 @@ Files { } DevicesStyle { Location = /styles/styles.xsl } )DOC"; - } boost::program_options::variables_map options; @@ -2345,10 +2343,10 @@ DevicesStyle { Location = /styles/styles.xsl } ifstream file(styles); ASSERT_TRUE(file.is_open()); - + stringstream sf; sf << file.rdbuf(); - + ASSERT_EQ(R"DOC( -)DOC", sf.str()); - +)DOC", + sf.str()); + m_config->stop(); } - + TEST_F(ConfigTest, should_update_stylesheet_versions_with_path) { fs::path root {createTempDirectory("15")}; - fs::path styleDir { root / "styles" }; + fs::path styleDir {root / "styles"}; fs::create_directory(styleDir); - - fs::path styles { styleDir / "styles.xsl" }; + + fs::path styles {styleDir / "styles.xsl"}; copyFile("styles/styles.xsl", styles, 0min); - + fs::path devices(root / "Devices.xml"); copySampleFile("empty.xml", devices, 0min); @@ -2398,7 +2397,6 @@ DevicesStyle { Path = ./styles/styles.xsl } )DOC"; - } boost::program_options::variables_map options; @@ -2409,10 +2407,10 @@ DevicesStyle { ifstream file(styles); ASSERT_TRUE(file.is_open()); - + stringstream sf; sf << file.rdbuf(); - + ASSERT_EQ(R"DOC( -)DOC", sf.str()); - +)DOC", + sf.str()); + m_config->stop(); }