Skip to content

Commit ff27520

Browse files
authored
Merge pull request #561 from mtconnect/555_558_559_deprecated_underscores_and_json_V2_issues
Fixed issues #555, #558, and #559: Fixed issue where camel casing of name with multiple _s caused crash. Fixed order in which validation occurs in the pipeline. Fixed json v1 issue with empty stream.
2 parents 544b6f9 + 7bef848 commit ff27520

File tree

8 files changed

+68
-31
lines changed

8 files changed

+68
-31
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
set(AGENT_VERSION_MAJOR 2)
33
set(AGENT_VERSION_MINOR 5)
44
set(AGENT_VERSION_PATCH 0)
5-
set(AGENT_VERSION_BUILD 10)
5+
set(AGENT_VERSION_BUILD 11)
66
set(AGENT_VERSION_RC "")
77

88
# This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent

conan/mruby/conanfile.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,9 @@ def package_info(self):
195195

196196
buf = io.StringIO()
197197
self.run("{} --cflags".format(ruby), stdout=buf, shell=True)
198-
self.cpp_info.defines = [d[2:] for d in buf.getvalue().split(' ') if d.startswith('/D') or d.startswith('-D')]
199198

200-
self.conf_info.define('mruby', 'ON')
199+
defines = [d[2:] for d in buf.getvalue().split(' ') if d.startswith('/D') or d.startswith('-D')]
200+
self.cpp_info.defines = defines
201201

202202
self.cpp_info.bindirs = ["bin"]
203203
if self.settings.os == 'Windows':

src/mtconnect/entity/data_set.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ namespace mtconnect::entity {
4848
{
4949
return std::holds_alternative<T2>(v1) && std::get<T2>(v1) == v2;
5050
}
51-
51+
5252
/// @brief One entry in a data set. Has necessary interface to be work with maps.
5353
/// @tparam T The type of the underlying variant data
5454
template <typename T>
@@ -109,8 +109,8 @@ namespace mtconnect::entity {
109109
/// @param other the other value to compare against `m_value`
110110
/// @returns `true` if the values are the same
111111
///
112-
/// Compares using the `SameValue` free function in the `data_set` namespace. It must be overloaded
113-
/// for any special types required by the variant type T.
112+
/// Compares using the `SameValue` free function in the `data_set` namespace. It must be
113+
/// overloaded for any special types required by the variant type T.
114114
bool sameValue(const Entry &other) const
115115
{
116116
const auto &ov = other.m_value;

src/mtconnect/printer/json_printer.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,10 @@ namespace mtconnect::printer {
439439
}
440440
else
441441
{
442-
AutoJsonObject streams(writer, "Streams");
442+
if (m_jsonVersion == 1)
443+
AutoJsonArray streams(writer, "Streams");
444+
else
445+
AutoJsonObject streams(writer, "Streams");
443446
}
444447
}
445448
});

src/mtconnect/source/adapter/adapter_pipeline.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,15 @@ namespace mtconnect {
144144
if (IsOptionSet(m_options, configuration::CorrectTimestamps))
145145
next = next->bind(make_shared<CorrectTimestamp>(m_context));
146146

147-
// Validate Values
148-
if (IsOptionSet(m_options, configuration::Validation))
149-
next = next->bind(make_shared<Validator>(m_context));
150-
151147
// Filter dups, by delta, and by period
152148
next = next->bind(make_shared<DuplicateFilter>(m_context));
153149
next = next->bind(make_shared<DeltaFilter>(m_context));
154150
next = next->bind(make_shared<PeriodFilter>(m_context, m_strand));
155151

152+
// Validate Values
153+
if (IsOptionSet(m_options, configuration::Validation))
154+
next = next->bind(make_shared<Validator>(m_context));
155+
156156
// Deliver
157157
std::optional<string> obsMetrics;
158158
obsMetrics = m_identity + "_observation_update_rate";

src/mtconnect/utilities.hpp

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -685,25 +685,27 @@ namespace mtconnect {
685685
///
686686
/// @param[in,out] start starting iterator
687687
/// @param[in,out] end ending iterator
688-
inline void capitalize(std::string::iterator start, std::string::iterator end)
688+
inline void capitalize(std::ostringstream &camel, std::string::const_iterator start,
689+
std::string::const_iterator end)
689690
{
690691
using namespace std;
691692

692693
// Exceptions to the rule
693-
const static std::unordered_map<std::string, std::string> exceptions = {
694+
const static std::unordered_map<std::string_view, std::string_view> exceptions = {
694695
{"AC", "AC"}, {"DC", "DC"}, {"PH", "PH"},
695696
{"IP", "IP"}, {"URI", "URI"}, {"MTCONNECT", "MTConnect"}};
696697

697-
const auto &w = exceptions.find(std::string(start, end));
698+
std::string_view s(&*start, distance(start, end));
699+
const auto &w = exceptions.find(s);
700+
ostream_iterator<char> out(camel);
698701
if (w != exceptions.end())
699702
{
700-
copy(w->second.begin(), w->second.end(), start);
703+
copy(w->second.begin(), w->second.end(), out);
701704
}
702705
else
703706
{
704-
*start = ::toupper(*start);
705-
start++;
706-
transform(start, end, start, ::tolower);
707+
camel << static_cast<char>(::toupper(*start));
708+
transform(start + 1, end, out, ::tolower);
707709
}
708710
}
709711

@@ -721,34 +723,33 @@ namespace mtconnect {
721723
if (type.empty())
722724
return "";
723725

724-
string camel;
726+
ostringstream camel;
727+
728+
auto start = type.begin();
729+
decltype(start) end;
730+
725731
auto colon = type.find(':');
726732

727733
if (colon != string::npos)
728734
{
729735
prefix = type.substr(0ul, colon);
730-
camel = type.substr(colon + 1ul);
736+
start += colon + 1;
731737
}
732-
else
733-
camel = type;
734-
735-
auto start = camel.begin();
736-
decltype(start) end;
737738

738739
bool done;
739740
do
740741
{
741-
end = find(start, camel.end(), '_');
742-
capitalize(start, end);
743-
done = end == camel.end();
742+
end = find(start, type.end(), '_');
743+
if (start != end)
744+
capitalize(camel, start, end);
745+
done = end == type.end();
744746
if (!done)
745747
{
746-
camel.erase(end);
747-
start = end;
748+
start = end + 1;
748749
}
749750
} while (!done);
750751

751-
return camel;
752+
return camel.str();
752753
}
753754

754755
/// @brief parse a string timestamp to a `Timestamp`

test_package/data_item_test.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,14 @@ TEST_F(DataItemTest, GetCamel)
163163
ASSERT_EQ((string) "CamelCase", pascalize("CAMEL_CASE", prefix));
164164
ASSERT_EQ((string) "ABCc", pascalize("A_B_CC", prefix));
165165

166+
ASSERT_EQ((string) "ThreeHumpCamelCase", pascalize("THREE_HUMP_CAMEL_CASE", prefix));
167+
166168
prefix.reset();
167169
ASSERT_EQ((string) "CamelCase", pascalize("x:CAMEL_CASE", prefix));
168170
ASSERT_EQ((string) "x", *prefix);
171+
prefix.reset();
172+
ASSERT_EQ((string) "MySillyTag", pascalize("y:MY__SILLY_TAG", prefix));
173+
ASSERT_EQ((string) "y", *prefix);
169174
}
170175

171176
TEST_F(DataItemTest, Condition) { ASSERT_EQ(DataItem::CONDITION, m_dataItemC->getCategory()); }

test_package/json_printer_stream_test.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,34 @@ TEST_F(JsonPrinterStreamTest, DeviceStream)
173173
stream.at("/uuid"_json_pointer).get<string>());
174174
}
175175

176+
TEST_F(JsonPrinterStreamTest, should_use_array_for_empty_version_1_stream)
177+
{
178+
Checkpoint checkpoint;
179+
ObservationList list;
180+
checkpoint.getObservations(list);
181+
auto doc = m_printer->printSample(123, 131072, 10254805, 10123733, 10123800, list);
182+
183+
auto jdoc = json::parse(doc);
184+
json stream = jdoc.at("/MTConnectStreams/Streams"_json_pointer);
185+
ASSERT_TRUE(stream.is_array());
186+
ASSERT_EQ(0, stream.size());
187+
}
188+
189+
TEST_F(JsonPrinterStreamTest, should_use_object_for_empty_version_2_stream)
190+
{
191+
m_printer = std::make_unique<printer::JsonPrinter>(2, true);
192+
193+
Checkpoint checkpoint;
194+
ObservationList list;
195+
checkpoint.getObservations(list);
196+
auto doc = m_printer->printSample(123, 131072, 10254805, 10123733, 10123800, list);
197+
198+
auto jdoc = json::parse(doc);
199+
json stream = jdoc.at("/MTConnectStreams/Streams"_json_pointer);
200+
ASSERT_TRUE(stream.is_object());
201+
ASSERT_EQ(0, stream.size());
202+
}
203+
176204
TEST_F(JsonPrinterStreamTest, DeviceStream_version_2_one_device)
177205
{
178206
m_printer = std::make_unique<printer::JsonPrinter>(2, true);

0 commit comments

Comments
 (0)