Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
set(AGENT_VERSION_MAJOR 2)
set(AGENT_VERSION_MINOR 6)
set(AGENT_VERSION_PATCH 0)
set(AGENT_VERSION_BUILD 6)
set(AGENT_VERSION_BUILD 7)
set(AGENT_VERSION_RC "")

# This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent
Expand Down
2 changes: 1 addition & 1 deletion agent_lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ target_include_directories(
target_link_libraries(
agent_lib
PUBLIC
boost::boost LibXml2::LibXml2 date::date-tz openssl::openssl
boost::boost LibXml2::LibXml2 date::date openssl::openssl
nlohmann_json::nlohmann_json mqtt_cpp::mqtt_cpp
rapidjson BZip2::BZip2

Expand Down
2 changes: 1 addition & 1 deletion cmake/osx_no_app_or_frameworks.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ set(CMAKE_FIND_FRAMEWORK NEVER FORCE)
# ms suffix which was added post 11.
if (APPLE)
# set(COVERAGE_FLAGS "-fcoverage-mapping -fprofile-instr-generate")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++17")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++20")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-local-typedef -Wno-deprecated-declarations -Wall")
endif()
6 changes: 3 additions & 3 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class MTConnectAgentConan(ConanFile):

"openssl*:shared": False,

"date*:use_system_tz_db": True
"date*:header_only": True
}

exports_sources = "*", "!build", "!test_package/build", "!*~"
Expand Down Expand Up @@ -112,14 +112,14 @@ def tool_requires_version(self, package, version):
def build_requirements(self):
self.tool_requires_version("cmake", [3, 26, 4])
if self.options.with_docs:
self.tool_requires_version("doxygen", [1, 14, 0])
self.tool_requires_version("doxygen", [1, 15, 0])

def requirements(self):
self.requires("boost/1.88.0", headers=True, libs=True, transitive_headers=True, transitive_libs=True)
self.requires("libxml2/2.14.5", headers=True, libs=True, visible=True, transitive_headers=True, transitive_libs=True)
self.requires("date/3.0.4", headers=True, libs=True, transitive_headers=True, transitive_libs=True)
self.requires("nlohmann_json/3.12.0", headers=True, libs=False, transitive_headers=True, transitive_libs=False)
self.requires("openssl/3.5.4", headers=True, libs=True, transitive_headers=True, transitive_libs=True)
self.requires("openssl/3.6.0", headers=True, libs=True, transitive_headers=True, transitive_libs=True)
self.requires("rapidjson/cci.20230929", headers=True, libs=False, transitive_headers=True, transitive_libs=False)
self.requires("mqtt_cpp/13.2.2", headers=True, libs=False, transitive_headers=True, transitive_libs=False)
self.requires("bzip2/1.0.8", headers=True, libs=True, transitive_headers=True, transitive_libs=True)
Expand Down
3 changes: 2 additions & 1 deletion docker/alpine/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
# ---------------------------------------------------------------------

# base image - alpine 3.18
FROM alpine:3.19 AS os
FROM alpine:3.22 AS os

# ---------------------------------------------------------------------
# build
Expand All @@ -53,6 +53,7 @@ ENV CONAN_PROFILE="$HOME/agent/cppagent/conan/profiles/docker"
RUN apk --update add \
autoconf \
automake \
bash \
cmake \
g++ \
gcompat \
Expand Down
2 changes: 1 addition & 1 deletion src/mtconnect/agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,7 @@ namespace mtconnect {
stringstream msg;
msg << "Device " << *device->getUuid() << " already exists. "
<< " Update not supported yet";
throw msg;
throw msg.str();
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/mtconnect/configuration/agent_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -941,7 +941,7 @@ namespace mtconnect::configuration {
loadAdapters(config, options);

m_afterAgentHooks.exec(*this);

#ifdef WITH_PYTHON
configurePython(config, options);
#endif
Expand Down
62 changes: 32 additions & 30 deletions src/mtconnect/entity/entity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -716,73 +716,75 @@ namespace mtconnect {

return changed;
}

/// @brief variant visitor to output Value to stream
struct StreamOutputVisitor
{
/// @brief constructor
/// @param os the output stream
StreamOutputVisitor(std::ostream& os) : m_os(os) {}

void operator()(const std::monostate&) {
m_os << "null";
}

void operator()(const EntityPtr& entity) {
StreamOutputVisitor(std::ostream &os) : m_os(os) {}

void operator()(const std::monostate &) { m_os << "null"; }

void operator()(const EntityPtr &entity)
{
const auto &id = entity->getIdentity();
m_os << "Entity(" << entity->getName() << ":";
StreamOutputVisitor visitor(m_os);
std::visit(visitor, id);
m_os << ")";
}

void operator()(const EntityList& list) {

void operator()(const EntityList &list)
{
m_os << "EntityList[";
for (auto e : list) {
for (auto e : list)
{
StreamOutputVisitor visitor(m_os);
visitor(e);
m_os << " ";
}
m_os << "]";
}

void operator()(const DataSet& dataSet) {
m_os << "DataSet(" << dataSet.size() << " items)";
}

void operator()(const QName& qname) {
m_os << qname.str();
}

void operator()(const Vector& vec) {

void operator()(const DataSet &dataSet) { m_os << "DataSet(" << dataSet.size() << " items)"; }

void operator()(const QName &qname) { m_os << qname.str(); }

void operator()(const Vector &vec)
{
m_os << "Vector[";
for (const auto &v : vec) {
for (const auto &v : vec)
{
m_os << v << " ";
}
m_os << "]";
}

template <typename T>
void operator()(const T& value) {
void operator()(const T &value)
{
m_os << value;
}
std::ostream& m_os;

std::ostream &m_os;
};

/// @brief output operator for Value
/// @param os the output stream
/// @param v the Value to output
inline std::ostream& operator<<(std::ostream& os, const Value &v) {
inline std::ostream &operator<<(std::ostream &os, const Value &v)
{
StreamOutputVisitor visitor(os);
std::visit(visitor, v);
return os;
}

/// @brief output operator for Value
/// @param os the output stream
/// @param v the Value to output
inline std::ostream& operator<<(std::ostream& os, const EntityPtr &v) {
inline std::ostream &operator<<(std::ostream &os, const EntityPtr &v)
{
StreamOutputVisitor visitor(os);
visitor(v);
return os;
Expand Down
5 changes: 3 additions & 2 deletions src/mtconnect/entity/requirement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,13 @@ namespace mtconnect {
// If there isa a time portion in the string, parse the time
if (arg.find('T') != string::npos)
{
in >> std::setw(6) >> date::parse("%FT%T", ts);
in >> std::setw(6);
date::from_stream(in, "%FT%T", ts);
}
else
{
// Just parse the date
in >> date::parse("%F", ts);
date::from_stream(in, "%F", ts);
}
}
void operator()(const string &arg, Vector &r)
Expand Down
15 changes: 1 addition & 14 deletions src/mtconnect/pipeline/response_document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "mtconnect/entity/xml_parser.hpp"
#include "mtconnect/observation/observation.hpp"
#include "mtconnect/pipeline/timestamp_extractor.hpp"
#include "mtconnect/utilities.hpp"

using namespace std;

Expand Down Expand Up @@ -280,20 +281,6 @@ namespace mtconnect::pipeline {
});
}

inline static Timestamp parseTimestamp(const std::string value)
{
Timestamp ts;
istringstream in(value);
in >> std::setw(6) >> date::parse("%FT%T", ts);
if (!in.good())
{
LOG(error) << "Cound not parse XML timestamp: " << value;
ts = std::chrono::system_clock::now();
}

return ts;
}

inline static DataItemPtr findDataItem(const std::string &name, DevicePtr device,
const entity::Properties &properties)
{
Expand Down
4 changes: 2 additions & 2 deletions src/mtconnect/pipeline/timestamp_extractor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ namespace mtconnect::pipeline {
Now now = DefaultNow)
{
using namespace std;
using namespace date;
using namespace chrono;
using namespace chrono_literals;
using namespace date;
Expand All @@ -103,7 +102,8 @@ namespace mtconnect::pipeline {
if (has_t)
{
istringstream in(timestamp.data());
in >> std::setw(6) >> date::parse("%FT%T", result);
in >> std::setw(6);
date::from_stream(in, "%FT%T", result);
if (!in.good())
{
result = now();
Expand Down
18 changes: 9 additions & 9 deletions src/mtconnect/pipeline/validator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ namespace mtconnect::pipeline {
public:
Validator(const Validator &) = default;
Validator(PipelineContextPtr context)
: Transform("Validator"), m_contract(context->m_contract.get())
: Transform("Validator"), m_contract(context->m_contract.get())
{
m_guard = TypeGuard<observation::Observation>(RUN) || TypeGuard<entity::Entity>(SKIP);
}

/// @brief validate the Event
/// @param entity The Event entity
/// @returns modified entity with quality and deprecated properties
Expand All @@ -51,7 +51,7 @@ namespace mtconnect::pipeline {
using namespace mtconnect::validation::observations;
auto obs = std::dynamic_pointer_cast<Observation>(entity);
auto &value = obs->getValue();

bool valid = true;
auto di = obs->getDataItem();
if (!obs->isUnavailable() && !di->isDataSet())
Expand All @@ -71,7 +71,7 @@ namespace mtconnect::pipeline {
// Check if it has not been introduced yet
if (lit->second.first > 0 && m_contract->getSchemaVersion() < lit->second.first)
valid = false;

// Check if deprecated
if (lit->second.second > 0 && m_contract->getSchemaVersion() >= lit->second.second)
{
Expand All @@ -96,20 +96,20 @@ namespace mtconnect::pipeline {
else if (auto spl = std::dynamic_pointer_cast<observation::Sample>(obs))
{
if (!(spl->hasProperty("quality") || std::holds_alternative<double>(value) ||
std::holds_alternative<int64_t>(value)))
std::holds_alternative<int64_t>(value)))
valid = false;
}
}

if (!valid)
{
obs->setProperty("quality", std::string("INVALID"));
// Log once
auto &id = di->getId();
if (m_logOnce.count(id) < 1)
{
LOG(warning) << "DataItem '" << id << "': Invalid value for '" << obs->getName()
<< "': '" << value << '\'';
LOG(warning) << "DataItem '" << id << "': Invalid value for '" << obs->getName() << "': '"
<< value << '\'';
m_logOnce.insert(id);
}
else
Expand All @@ -121,7 +121,7 @@ namespace mtconnect::pipeline {
{
obs->setProperty("quality", std::string("VALID"));
}

return next(std::move(obs));
}

Expand Down
2 changes: 1 addition & 1 deletion src/mtconnect/printer/xml_printer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ namespace mtconnect::printer {
xmlFreeTextWriter(m_writer);
m_writer = nullptr;
}
return string((char *)m_buf->content, m_buf->use);
return std::string((char *)xmlBufferContent(m_buf), xmlBufferLength(m_buf));
}

protected:
Expand Down
2 changes: 1 addition & 1 deletion src/mtconnect/printer/xml_printer_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ namespace mtconnect::printer {
xmlFreeTextWriter(m_writer);
m_writer = nullptr;
}
return std::string((char *)m_buf->content, m_buf->use);
return std::string((char *)xmlBufferContent(m_buf), xmlBufferLength(m_buf));
}

protected:
Expand Down
2 changes: 1 addition & 1 deletion src/mtconnect/sink/rest_sink/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#include <boost/beast/http/status.hpp>

#include <strstream>
#include <sstream>

#include "mtconnect/entity/entity.hpp"
#include "mtconnect/entity/factory.hpp"
Expand Down
7 changes: 1 addition & 6 deletions src/mtconnect/sink/rest_sink/rest_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1411,12 +1411,7 @@ namespace mtconnect {
Timestamp ts;
if (time)
{
istringstream in(*time);
in >> std::setw(6) >> date::parse("%FT%T", ts);
if (!in.good())
{
ts = chrono::system_clock::now();
}
ts = parseTimestamp(*time);
}
else
{
Expand Down
1 change: 0 additions & 1 deletion src/mtconnect/source/adapter/shdr/shdr_adapter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#pragma once

#include <chrono>
#include <date/tz.h>
#include <optional>
#include <set>
#include <sstream>
Expand Down
5 changes: 0 additions & 5 deletions src/mtconnect/utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include <cstring>
#include <ctime>
#include <date/date.h>
#include <date/tz.h>
#include <list>
#include <map>
#include <mutex>
Expand All @@ -44,8 +43,6 @@
#define _WINSOCKAPI_
#include <windows.h>
#include <winsock2.h>
#define localtime_r(t, tm) localtime_s(tm, t)
#define gmtime_r(t, tm) gmtime_s(tm, t)

#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ull
#endif
Expand Down Expand Up @@ -77,8 +74,6 @@ BOOST_FUSION_ADAPT_STRUCT(mtconnect::url::Url,
m_fragment))

namespace mtconnect {
AGENT_LIB_API void mt_localtime(const time_t *time, struct tm *buf) { localtime_r(time, buf); }

inline string::size_type insertPrefix(string &aPath, string::size_type &aPos,
const string aPrefix)
{
Expand Down
Loading