Skip to content

Commit 07eb1df

Browse files
committed
ADD: Always set code when upgrading SystemMsg
1 parent 766fe82 commit 07eb1df

File tree

4 files changed

+78
-3
lines changed

4 files changed

+78
-3
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Changelog
22

3-
## 0.43.1 - TBD
3+
## 0.44.0 - TBD
4+
5+
### Enhancements
6+
- Added logic to set `code` when upgrading version 1 `SystemMsg` to newer versions
47

58
### Bug fixes
69
- Added missing `<cstddef>` include to `constants.hpp` (credit: @ognian-)

src/v1.cpp

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#include "databento/v1.hpp"
22

33
#include <algorithm> // copy
4+
#include <cstddef> // size_t
45
#include <cstdint>
5-
#include <limits> // numeric_limits
6+
#include <cstring> // strlen, strncmp
7+
#include <limits> // numeric_limits
68

79
#include "databento/enums.hpp"
810
#include "databento/pretty.hpp" // Px
@@ -239,8 +241,35 @@ v2::SystemMsg SystemMsg::ToV2() const {
239241
RecordHeader{sizeof(v2::SystemMsg) / RecordHeader::kLengthMultiplier,
240242
RType::System, hd.publisher_id, hd.instrument_id, hd.ts_event},
241243
{},
242-
IsHeartbeat() ? SystemCode::Heartbeat : SystemCode::Unset};
244+
SystemCode::Unset};
243245
std::copy(msg.begin(), msg.end(), ret.msg.begin());
246+
// No standardized strnlen
247+
const auto null_it = std::find(msg.begin(), msg.end(), '\0');
248+
if (null_it != msg.end()) {
249+
constexpr auto kEndOfInterval = "End of interval for ";
250+
constexpr auto kSubAckStart = "Subscription request ";
251+
constexpr auto kSubAckEnd = " succeeded";
252+
constexpr auto kSlowReader = "Warning: slow reading";
253+
constexpr auto kFinishedStart = "Finished ";
254+
constexpr auto kFinishedEnd = " replay";
255+
256+
const auto msg_len = static_cast<std::size_t>(null_it - msg.begin());
257+
if (IsHeartbeat()) {
258+
ret.code = SystemCode::Heartbeat;
259+
} else if (std::strncmp(Msg(), kEndOfInterval, std::strlen(kEndOfInterval)) == 0) {
260+
ret.code = SystemCode::EndOfInterval;
261+
} else if (std::strncmp(Msg(), kSubAckStart, std::strlen(kSubAckStart)) == 0 &&
262+
std::strncmp(&Msg()[msg_len - std::strlen(kSubAckEnd)], kSubAckEnd,
263+
std::strlen(kSubAckEnd)) == 0) {
264+
ret.code = SystemCode::SubscriptionAck;
265+
} else if (std::strncmp(Msg(), kSlowReader, std::strlen(kSlowReader)) == 0) {
266+
ret.code = SystemCode::SlowReaderWarning;
267+
} else if (std::strncmp(Msg(), kFinishedStart, std::strlen(kFinishedStart)) == 0 &&
268+
std::strncmp(&Msg()[msg_len - std::strlen(kFinishedEnd)], kFinishedEnd,
269+
std::strlen(kFinishedEnd)) == 0) {
270+
ret.code = SystemCode::ReplayCompleted;
271+
}
272+
}
244273
return ret;
245274
}
246275

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ set(
5252
src/symbol_map_tests.cpp
5353
src/symbology_tests.cpp
5454
src/tcp_client_tests.cpp
55+
src/v1_tests.cpp
5556
src/zstd_stream_tests.cpp
5657
)
5758
add_executable(${PROJECT_NAME} ${test_headers} ${test_sources})

tests/src/v1_tests.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include <gtest/gtest.h>
2+
3+
#include <cstring> // strcpy
4+
5+
#include "databento/enums.hpp"
6+
#include "databento/record.hpp"
7+
#include "databento/v1.hpp"
8+
9+
namespace databento::v1::tests {
10+
TEST(V1Tests, TestSystemMsgCodeUpgrade) {
11+
v1::SystemMsg target{
12+
RecordHeader{sizeof(v1::SystemMsg) / RecordHeader::kLengthMultiplier,
13+
RType::System,
14+
0,
15+
0,
16+
{}}};
17+
std::strcpy(target.msg.data(), "Heartbeat");
18+
const auto res1 = target.ToV2();
19+
EXPECT_EQ(res1.code, SystemCode::Heartbeat);
20+
21+
target.msg = {};
22+
std::strcpy(target.msg.data(), "End of interval for bbo-1s");
23+
const auto res2 = target.ToV2();
24+
EXPECT_EQ(res2.code, SystemCode::EndOfInterval);
25+
26+
target.msg = {};
27+
std::strcpy(target.msg.data(), "Subscription request 5 for mbo data succeeded");
28+
const auto res3 = target.ToV2();
29+
EXPECT_EQ(res3.code, SystemCode::SubscriptionAck);
30+
31+
target.msg = {};
32+
std::strcpy(target.msg.data(),
33+
"Warning: slow reading, not keeping pace with cbbo-1s data");
34+
const auto res4 = target.ToV2();
35+
EXPECT_EQ(res4.code, SystemCode::SlowReaderWarning);
36+
37+
target.msg = {};
38+
std::strcpy(target.msg.data(), "Finished ohlcv-1s replay");
39+
const auto res5 = target.ToV2();
40+
EXPECT_EQ(res5.code, SystemCode::ReplayCompleted);
41+
}
42+
} // namespace databento::v1::tests

0 commit comments

Comments
 (0)