blob: ceba660bd0d393c31265740e408ad15895b90a8e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/*
* File: fix/parser.hpp
* Purpose: Financial Information Exchange parser in C++
* Author: Amlal El Mahrouss (amlal@nekernel.org)
* Copyright 2025, Amlal El Mahrouss, licensed under the Boost Software License.
*/
#ifndef __OCL_FIX_PARSER
#define __OCL_FIX_PARSER
#include <ocl/fix/detail/config.hpp>
#include <string>
#include <memory>
namespace ocl::fix
{
class visitor;
struct range;
class range_buffer;
/// @brief Buffer+Length structure
using range_ptr_type = range*;
using range_type = range;
using tag_type = std::string;
using value_type = std::string;
struct range final
{
char* bytes_{nullptr};
size_t length_{};
bool is_valid() noexcept
{
return this->bytes_ && this->length_ > 0;
}
explicit operator bool()
{
return this->is_valid();
}
};
/// @brief Convert range to usable string.
/// @note This function assumes that the range is valid and contains ASCII bytes.
inline std::string to_string(range& range) noexcept
{
if (range.length_ < 1)
return std::string{};
return std::string(range.bytes_, range.length_);
}
/// @brief a range object containing the FIX packet values.
class range_buffer final
{
public:
std::size_t magic_len_{};
std::string magic_{};
string_hash_map<value_type> message_{};
static inline const char* begin;
explicit range_buffer() = default;
~range_buffer() = default;
range_buffer& operator=(const range_buffer&) = default;
range_buffer(const range_buffer&) = default;
[[nodiscard("please use the returned value of the tag.")]]
value_type operator[](const tag_type& key)
{
if (key.empty())
return value_type{};
auto it = message_.find(key);
if (it != message_.end())
return it->second;
return value_type{};
}
bool is_valid()
{
constexpr auto magic_tag = "8";
return this->operator[](magic_tag).empty() == false;
}
explicit operator bool()
{
return this->is_valid();
}
};
/// @brief visitor object which returns a fix::range_buffer instance.
class visitor final
{
struct impl;
std::unique_ptr<impl> impl_;
#ifndef OCL_FIX_HAS_IMPL
struct impl
{
};
#endif
public:
visitor();
~visitor();
/// \brief Alias of visit.
range_buffer operator()(const std::string& in);
/// @brief Visits a FIX message and parse it into a range_buffer object.
/// @param in The input FIX message as a string.
/// @warning This function may throw exceptions.
range_buffer visit(const std::string& in);
};
} // namespace ocl::fix
#endif // ifndef __OCL_FIX_PARSER
|