6#include "../packet/packet.hpp"
8#include "libxr_mem.hpp"
13 : topic_map_([](const uint32_t& a, const uint32_t& b) {
return (a > b) - (a < b); }),
14 queue_(1, buffer_length)
16 ASSERT(buffer_length > PACK_BASE_SIZE);
17 parse_buff_.size_ = buffer_length;
24 ASSERT(topic !=
nullptr);
25 ASSERT(topic->
data_.payload_size != 0);
26 ASSERT(topic->
data_.payload_alignment != 0);
29 ASSERT(topic->
data_.payload_size + PACK_BASE_SIZE <= parse_buff_.size_);
32 topic_map_.Insert(*node, topic->
key);
37 return ParseDataRaw(data,
false,
false);
42 return ParseDataRaw(data,
true, in_isr);
45size_t Topic::Server::ParseDataRaw(
ConstRawData data,
bool from_callback,
bool in_isr)
49 (void)queue_.PushBatchBytes(data.
addr_, data.
size_);
53 if (status_ == Status::WAIT_START && !SyncToPacketStart())
58 if (status_ == Status::WAIT_TOPIC && !ReadHeader())
63 if (status_ == Status::WAIT_DATA_CRC)
65 switch (ReadPayload(from_callback, in_isr))
67 case ParseResult::NEED_MORE:
69 case ParseResult::DROPPED:
71 case ParseResult::DELIVERED:
79bool Topic::Server::SyncToPacketStart()
81 auto queue_size = queue_.Size();
82 for (uint32_t i = 0; i < queue_size; i++)
85 queue_.PeekBytes(&prefix);
86 if (prefix == PACKET_PREFIX)
88 status_ = Status::WAIT_TOPIC;
97bool Topic::Server::ReadHeader()
99 if (queue_.Size() <
sizeof(PackedDataHeader))
104 queue_.PopBatchBytes(parse_buff_.addr_,
sizeof(PackedDataHeader));
105 if (!
CRC8::Verify(parse_buff_.addr_,
sizeof(PackedDataHeader)))
111 auto* header =
reinterpret_cast<PackedDataHeader*
>(parse_buff_.addr_);
112 if (header->version != PACKET_VERSION)
118 auto* node = topic_map_.Search<
TopicHandle>(header->topic_name_crc32);
125 data_len_ = header->GetDataLen();
126 current_timestamp_ = header->GetTimestamp();
127 current_topic_ = *node;
128 const auto target_size = current_topic_->data_.payload_size;
130 if (target_size + PACK_BASE_SIZE > parse_buff_.size_)
136 if (data_len_ + PACK_BASE_SIZE > queue_.length_)
142 status_ = Status::WAIT_DATA_CRC;
146Topic::Server::ParseResult Topic::Server::ReadPayload(
bool from_callback,
bool in_isr)
148 if (queue_.Size() < data_len_ +
sizeof(uint8_t))
150 return ParseResult::NEED_MORE;
154 reinterpret_cast<uint8_t*
>(parse_buff_.addr_) +
sizeof(PackedDataHeader);
155 queue_.PopBatchBytes(payload_addr, data_len_ +
sizeof(uint8_t));
158 data_len_ +
sizeof(PackedDataHeader) +
sizeof(uint8_t)))
161 return ParseResult::DROPPED;
164 const auto target_size = current_topic_->data_.payload_size;
165 void* publish_addr = payload_addr;
166 if (
reinterpret_cast<uintptr_t
>(payload_addr) %
167 current_topic_->data_.payload_alignment !=
170 publish_addr = parse_buff_.addr_;
171 if (data_len_ >= target_size)
181 auto topic =
Topic(current_topic_);
184 topic.PublishBytesFromServerCallback(publish_addr, target_size, current_timestamp_,
189 topic.PublishBytesFromServer(publish_addr, target_size, current_timestamp_);
193 return ParseResult::DELIVERED;
196void Topic::Server::ResetParser()
198 status_ = Status::WAIT_START;
200 current_topic_ =
nullptr;
static bool Verify(const void *raw, size_t len)
验证数据的 CRC8 校验码 / Verifies the CRC8 checksum of the given data
只读原始数据视图 / Immutable raw data view
size_t size_
数据字节数 / Data size in bytes
const void * addr_
数据起始地址 / Data start address
static void FastMove(void *dst, const void *src, size_t size)
内存搬移 / Memory move
微秒时间戳 / Microsecond timestamp
Key key
节点键值 / Key associated with the node.
红黑树的泛型数据节点,继承自 BaseNode Generic data node for Red-Black Tree, inheriting from BaseNode.
Data data_
存储的数据 / Stored data.
红黑树实现,支持泛型键和值,并提供线程安全操作 Red-Black Tree implementation supporting generic keys and values with thread-...
void Register(TopicHandle topic)
注册一个可接收 packet 的 topic / Register one topic that may receive parsed packets
size_t ParseData(ConstRawData data)
在普通上下文里喂入一批新字节 / Feed one new byte batch in normal context
size_t ParseDataFromCallback(ConstRawData data, bool in_isr)
在回调/ISR 路径里喂入一批新字节 / Feed one new byte batch in callback/ISR path
Server(size_t buffer_length)
构造 parser 并分配内部暂存队列 / Construct the parser and allocate its internal staging queue
RBTree< uint32_t >::Node< Block > * TopicHandle
指向一个 topic 运行时状态块的句柄 / Handle pointing to one topic runtime state block
Topic()
构造一个空 topic 视图 / Construct one empty topic view
LibXR 命名空间 / LibXR namespace.
constexpr size_t CACHE_LINE_SIZE
兼容旧代码的缓存行别名 / Backward-compatible cache-line alias for existing code