dfx 0.1.0
Linux-based dynamic dataflow executor
Loading...
Searching...
No Matches
Framer.hpp
1// SPDX-FileCopyrightText: 2026 Vincent Leroy
2// SPDX-License-Identifier: MIT
3//
4// This file is part of dfx.
5//
6// Licensed under the MIT License. See the LICENSE file in the project root
7// for full license information.
8
9#pragma once
10
11// Standard includes
12#include <array>
13#include <chrono>
14#include <cstdint>
15#include <ctime>
16#include <mutex>
17#include <optional>
18#include <span>
19#include <sys/socket.h>
20#include <unordered_map>
21#include <vector>
22
23// Project includes
24#include <dfx-utilities/CompilerSupport.hpp>
25
26/*
27 * 0 1 2 3
28 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
29 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
30 * | Magic (0x5348) | Version | Flags |
31 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32 * | Reserved | Frame size |
33 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 * | Message ID (UID) |
35 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 * | Offset |
37 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38 * | Total Payload size |
39 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40 * | Header + Payload CRC32C |
41 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 */
43
45{
46class Framer
47{
48public:
49 static constexpr uint16_t frameMagic = 0x5348; // "SH"
50 static constexpr uint8_t currentVersion = 1;
51
52 enum Flag : uint8_t
53 {
54 None = 0x00,
55 };
56
57 struct DFX_PACKED Header
58 {
59 uint16_t magic = frameMagic;
60 uint8_t version = currentVersion;
61 Flag flags = None;
62 uint16_t reserved = 0;
63 uint16_t frameSize = 0;
64 uint32_t messageId = 0;
65 uint32_t offset = 0;
66 uint32_t totalPayloadSize = 0;
67 uint32_t crc32c = 0;
68 };
69
70 static_assert(sizeof(Header) % 4 == 0);
71
72 struct Frame
73 {
74 Header header;
75 std::span<uint8_t const> payload;
76
77 std::array<iovec, 2> toIovec() const noexcept;
78 };
79
80private:
81 struct ReassemblyBuffer
82 {
83 std::vector<uint8_t> data;
84 uint32_t totalPayloadSize;
85 uint32_t payloadSizeReceived;
86 timespec lastUpdatedAt;
87 };
88
89public:
90 static std::vector<Frame> frameAll(uint32_t payloadId,
91 std::span<uint8_t const> payload,
92 size_t maxFrameSize);
93
94 static Frame frameNext(uint32_t payloadId,
95 std::span<uint8_t const> fullPayload,
96 size_t maxFrameSize,
97 size_t & offset);
98
99 static constexpr std::size_t maxFrameSize() noexcept { return std::numeric_limits<decltype(Header::frameSize)>::max(); }
100
101public:
102 std::optional<std::vector<uint8_t>> push(std::span<uint8_t const> frame, timespec const & time);
103 void gc(std::chrono::milliseconds maxAge);
104
105 bool hasPendingData() const noexcept { return !_pending.empty(); }
106
107private:
108 std::mutex _mutex;
109 std::unordered_map<uint32_t, ReassemblyBuffer> _pending;
110};
111} // !namespace dfx::Core::details
Definition Framer.hpp:47
Definition Framer.hpp:45
Definition Framer.hpp:73
Definition Framer.hpp:58