mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
[wpiutil, ntcore] Add structured data support (#5391)
This adds support for two serialization formats for complex data types: - Protobuf for complex objects with variable length internals that need forward and backward wire compatibility (lower speed, more flexible) - Raw struct (ByteBuffer-style) for fixed-length objects (higher speed, less flexible) Deserialization can be done either by creating a new object (for immutable objects) or overwriting the contents of an existing object (for mutable objects). Implementing classes should provide inner classes that implement the Protobuf or Struct interface (in Java) or specialize the wpi::Protobuf or wpi::Struct struct (in C++). It is possible for classes to implement both. If the class itself does not implement serialization, it's possible for third parties/users to provide an implementation instead. Uses the Google protobuf implementation for C++ and the QuickBuffers alternative protobuf implementation for Java.
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
#include "wpi/Endian.h"
|
||||
#include "wpi/Logger.h"
|
||||
#include "wpi/MathExtras.h"
|
||||
#include "wpi/SmallString.h"
|
||||
#include "wpi/fs.h"
|
||||
#include "wpi/timestamp.h"
|
||||
|
||||
@@ -211,6 +212,33 @@ void DataLog::Resume() {
|
||||
m_paused = false;
|
||||
}
|
||||
|
||||
bool DataLog::HasSchema(std::string_view name) const {
|
||||
std::scoped_lock lock{m_mutex};
|
||||
wpi::SmallString<128> fullName{"/.schema/"};
|
||||
fullName += name;
|
||||
auto it = m_entries.find(fullName);
|
||||
return it != m_entries.end();
|
||||
}
|
||||
|
||||
void DataLog::AddSchema(std::string_view name, std::string_view type,
|
||||
std::span<const uint8_t> schema, int64_t timestamp) {
|
||||
std::scoped_lock lock{m_mutex};
|
||||
wpi::SmallString<128> fullName{"/.schema/"};
|
||||
fullName += name;
|
||||
auto& entryInfo = m_entries[fullName];
|
||||
if (entryInfo.id != 0) {
|
||||
return; // don't add duplicates
|
||||
}
|
||||
int entry = StartImpl(fullName, type, {}, timestamp);
|
||||
|
||||
// inline AppendRaw() without releasing lock
|
||||
if (entry <= 0) {
|
||||
[[unlikely]] return; // should never happen, but check anyway
|
||||
}
|
||||
StartRecord(entry, timestamp, schema.size(), 0);
|
||||
AppendImpl(schema);
|
||||
}
|
||||
|
||||
static void WriteToFile(fs::file_t f, std::span<const uint8_t> data,
|
||||
std::string_view filename, wpi::Logger& msglog) {
|
||||
do {
|
||||
@@ -484,6 +512,11 @@ void DataLog::WriterThreadMain(
|
||||
int DataLog::Start(std::string_view name, std::string_view type,
|
||||
std::string_view metadata, int64_t timestamp) {
|
||||
std::scoped_lock lock{m_mutex};
|
||||
return StartImpl(name, type, metadata, timestamp);
|
||||
}
|
||||
|
||||
int DataLog::StartImpl(std::string_view name, std::string_view type,
|
||||
std::string_view metadata, int64_t timestamp) {
|
||||
auto& entryInfo = m_entries[name];
|
||||
if (entryInfo.id == 0) {
|
||||
entryInfo.id = ++m_lastId;
|
||||
|
||||
Reference in New Issue
Block a user