1+ #pragma once
2+
3+ #include " flowKey.hpp"
4+ #include " flowRecord.hpp"
5+ #include " ipAddress.hpp"
6+ #include " processPluginBuilder.hpp"
7+
8+ #include < cstddef>
9+ #include < memory>
10+ #include < mutex>
11+ #include < thread>
12+ #include < type_traits>
13+ #include < vector>
14+
15+ namespace ipxp {
16+
17+ static std::size_t calculatePluginTableSize (const std::vector<ProcessPluginEntry>& plugins) noexcept
18+ {
19+ return sizeof (FlowRecordPluginTable) + ((plugins.size () - 1 ) * sizeof (PluginLayoutItem));
20+ }
21+
22+ class FlowRecordBuilder {
23+ public:
24+ FlowRecordBuilder (
25+ const std::vector<ProcessPluginEntry>& plugins,
26+ const FlowKeyLayout& flowKeyLayout)
27+ : m_processPluginEntries(plugins)
28+ , m_flowKeyLayout(flowKeyLayout)
29+ {
30+ prepareLayout ();
31+ }
32+
33+ std::size_t getTotalBufferSize () const { return m_totalBufferSize; }
34+ std::size_t getMaxAlignment () const { return m_maxAlignment; }
35+ FlowRecordLayout getLayout () const { return m_layout; }
36+
37+ void printLayoutInfo () const
38+ {
39+ std::cout << " FlowKey:\n " ;
40+ std::cout << " Size: " << m_flowKeyLayout.size << " bytes\n " ;
41+ std::cout << " Alignment: " << m_flowKeyLayout.alignment << " bytes\n " ;
42+ std::cout << " Offset: " << m_layout.flowKeyOffset << " \n\n " ;
43+
44+ std::cout << " Plugin Table:\n " ;
45+ std::cout << " Offset: " << m_layout.pluginTableOffset << " \n " ;
46+ std::cout << " Size: " << calculatePluginTableSize (m_processPluginEntries)
47+ << " bytes\n " ;
48+ std::cout << " Count: " << m_processPluginEntries.size () << " \n\n " ;
49+
50+ std::cout << " Plugins (" << m_processPluginEntries.size () << " ):\n " ;
51+ for (std::size_t i = 0 ; i < m_pluginLayouts.size (); ++i) {
52+ const auto & layout = m_pluginLayouts[i];
53+ if (layout.offset == std::numeric_limits<std::size_t >::max ()) {
54+ std::cout << " Plugin " << i << " : disabled\n " ;
55+ } else {
56+ const auto & pluginEntry = m_processPluginEntries[i];
57+ std::cout << " Plugin " << i << " : " << pluginEntry.name << " \n " ; // přidáno jméno
58+ std::cout << " Offset: " << layout.offset << " \n " ;
59+ std::cout << " Context Size: " << pluginEntry.contextSize << " bytes\n " ;
60+ std::cout << " Context Alignment: " << pluginEntry.contextAlignment
61+ << " bytes\n " ;
62+ }
63+ }
64+
65+ std::cout << " \n Total FlowRecord size: " << m_totalBufferSize << " bytes\n " ;
66+ std::cout << " Max alignment: " << m_maxAlignment << " bytes\n " ;
67+ }
68+
69+ FlowRecordUniquePtr build ()
70+ {
71+ // Alokace zarovnané paměti
72+ void * rawMem = ::operator new (m_totalBufferSize, std::align_val_t (m_maxAlignment));
73+
74+ // Konstrukce FlowRecord přímo v alokované paměti (placement new)
75+ FlowRecord* recordPtr
76+ = std::construct_at (static_cast <FlowRecord*>(rawMem), m_pluginsAvailable);
77+
78+ recordPtr->m_layout = m_layout;
79+
80+ // Inicializace pluginové tabulky
81+ FlowRecordPluginTable* pluginTable = reinterpret_cast <FlowRecordPluginTable*>(
82+ reinterpret_cast <std::byte*>(rawMem) + m_layout.pluginTableOffset );
83+ pluginTable->pluginCount = m_pluginLayouts.size ();
84+ for (std::size_t i = 0 ; i < m_pluginLayouts.size (); ++i) {
85+ pluginTable->pluginDataLayouts [i] = m_pluginLayouts[i];
86+ }
87+
88+ return FlowRecordUniquePtr (recordPtr, FlowRecordDeleter {m_maxAlignment});
89+ }
90+
91+ private:
92+ void prepareLayout ()
93+ {
94+ constexpr std::size_t baseSize = sizeof (FlowRecord);
95+ m_maxAlignment = alignof (FlowRecord);
96+
97+ std::size_t flowKeyOffset = alignUp (baseSize, m_flowKeyLayout.alignment );
98+
99+ std::size_t pluginTableOffset
100+ = alignUp (flowKeyOffset + m_flowKeyLayout.size , alignof (FlowRecordPluginTable));
101+
102+ std::size_t pluginTableSize = calculatePluginTableSize (m_processPluginEntries);
103+
104+ std::size_t currentOffset = pluginTableOffset + pluginTableSize;
105+
106+ m_maxAlignment = std::max (m_maxAlignment, m_flowKeyLayout.alignment );
107+ m_maxAlignment = std::max (m_maxAlignment, alignof (FlowRecordPluginTable));
108+
109+ m_pluginLayouts.clear ();
110+ m_pluginsAvailable.reset ();
111+
112+ for (std::size_t pluginID = 0 ; pluginID < m_processPluginEntries.size (); ++pluginID) {
113+ const auto & pluginEntry = m_processPluginEntries[pluginID];
114+ if (!pluginEntry.enabled ) {
115+ m_pluginLayouts.push_back ({std::numeric_limits<std::size_t >::max ()});
116+ continue ;
117+ }
118+
119+ std::size_t alignment = pluginEntry.contextAlignment ;
120+ if (alignment > 1 ) {
121+ std::size_t mod = currentOffset % alignment;
122+ if (mod != 0 ) {
123+ currentOffset += alignment - mod;
124+ }
125+ }
126+
127+ m_pluginLayouts.push_back ({currentOffset});
128+ m_pluginsAvailable.set (pluginID);
129+
130+ currentOffset += pluginEntry.contextSize ;
131+ m_maxAlignment = std::max (m_maxAlignment, alignment);
132+ }
133+
134+ m_totalBufferSize = currentOffset;
135+
136+ m_layout.flowKeyOffset = flowKeyOffset;
137+ m_layout.pluginTableOffset = pluginTableOffset;
138+ }
139+
140+ static std::size_t alignUp (std::size_t value, std::size_t alignment)
141+ {
142+ return (value + alignment - 1 ) & ~(alignment - 1 );
143+ }
144+
145+ private:
146+ std::vector<ProcessPluginEntry> m_processPluginEntries;
147+ FlowKeyLayout m_flowKeyLayout;
148+
149+ std::vector<PluginLayoutItem> m_pluginLayouts;
150+ PluginsBitset m_pluginsAvailable = {};
151+
152+ std::size_t m_totalBufferSize = 0 ;
153+ std::size_t m_maxAlignment = 0 ;
154+ FlowRecordLayout m_layout;
155+ };
156+
157+ } // namespace ipxp
0 commit comments