[Yunq] Move serialization to yunq library.

This commit is contained in:
Drew Galbraith 2024-01-11 20:36:41 -08:00
parent 0135d8d844
commit 7ec4f696a8
9 changed files with 316 additions and 486 deletions

View file

@ -6,23 +6,10 @@
#include <glacier/status/error_or.h>
#include <glacier/status/status.h>
#include "yunq/yunq.h"
namespace yunq {
const uint64_t kHeaderSize = 24; // 4x uint32, 1x uint64
struct MessageHeader {
uint32_t ident;
uint32_t core_length;
uint32_t length;
uint32_t crc32;
uint64_t options;
} __attribute__((packed));
struct ExtensionPointer {
uint32_t offset;
uint32_t length;
};
class MessageView {
public:
MessageView(const glcr::ByteBuffer& buffer, uint64_t offset)

View file

@ -7,12 +7,38 @@ const uint64_t kIdentByte = 0x33441122;
} // namespace
void WriteHeader(glcr::ByteBuffer& bytes, uint64_t offset, uint32_t core_size,
uint32_t extension_size) {
bytes.WriteAt<uint32_t>(offset + 0, kIdentByte);
bytes.WriteAt<uint32_t>(offset + 4, core_size);
bytes.WriteAt<uint32_t>(offset + 8, extension_size);
bytes.WriteAt<uint32_t>(offset + 12, 0); // TODO: Calculate CRC32.
void Serializer::WriteHeader() {
buffer_.WriteAt<uint32_t>(offset_ + 0, kIdentByte);
buffer_.WriteAt<uint32_t>(offset_ + 4, core_size_);
buffer_.WriteAt<uint32_t>(offset_ + 8, next_extension_);
buffer_.WriteAt<uint32_t>(offset_ + 12, 0); // TODO: Calculate CRC32.
}
template <>
void Serializer::WriteField<glcr::String>(uint64_t field_index,
const glcr::String& value) {
ExtensionPointer ptr{
.offset = (uint32_t)next_extension_,
// FIXME: Check downcast of str length.
.length = (uint32_t)value.length(),
};
buffer_.WriteStringAt(offset_ + next_extension_, value);
next_extension_ += ptr.length;
buffer_.WriteAt<ExtensionPointer>(field_offset(field_index), ptr);
}
void Serializer::WriteCapability(uint64_t field_index, uint64_t value) {
if (caps_) {
buffer_.WriteAt<uint64_t>(field_offset(field_index), next_cap_);
caps_.value().get().WriteAt(next_cap_++, value);
} else {
WriteField<uint64_t>(field_index, value);
}
}
void Serializer::WriteRepeatedCapability(uint64_t field_index,
const glcr::Vector<uint64_t>& value) {}
} // namespace yunq

View file

@ -1,11 +1,84 @@
#pragma once
#include <glacier/buffer/byte_buffer.h>
#include <glacier/buffer/cap_buffer.h>
#include <glacier/container/optional.h>
#include <glacier/container/vector.h>
#include <glacier/memory/reference.h>
#include <glacier/status/status.h>
#include "yunq/yunq.h"
namespace yunq {
void WriteHeader(glcr::ByteBuffer& bytes, uint64_t offset, uint32_t core_size,
uint32_t extension_size);
class Serializer {
public:
Serializer(glcr::ByteBuffer& bytes, uint64_t offset, uint64_t num_fields)
: buffer_(bytes),
offset_(offset),
next_extension_(kHeaderSize + (8 * num_fields)),
core_size_(next_extension_),
caps_() {}
Serializer(glcr::ByteBuffer& bytes, uint64_t offset, uint64_t num_fields,
glcr::CapBuffer& caps)
: buffer_(bytes),
offset_(offset),
next_extension_(kHeaderSize + (8 * num_fields)),
core_size_(next_extension_),
caps_(caps) {}
template <typename T>
void WriteField(uint64_t field_index, const T& value);
template <typename T>
void WriteRepeated(uint64_t field_index, const glcr::Vector<T>& value);
void WriteCapability(uint64_t field_index, uint64_t value);
void WriteRepeatedCapability(uint64_t field_index,
const glcr::Vector<uint64_t>& value);
void WriteHeader();
uint64_t size() const { return next_extension_; }
private:
glcr::ByteBuffer& buffer_;
uint64_t offset_;
uint64_t next_extension_;
uint64_t core_size_;
uint64_t next_cap_ = 0;
glcr::Optional<glcr::Ref<glcr::CapBuffer>> caps_;
uint64_t field_offset(uint64_t field_index) const {
return offset_ + kHeaderSize + (8 * field_index);
}
};
template <typename T>
void Serializer::WriteField(uint64_t field_index, const T& value) {
buffer_.WriteAt<T>(field_offset(field_index), value);
}
template <>
void Serializer::WriteField<glcr::String>(uint64_t field_index,
const glcr::String& value);
template <typename T>
void Serializer::WriteRepeated(uint64_t field_index,
const glcr::Vector<T>& value) {
ExtensionPointer ptr{
.offset = (uint32_t)next_extension_,
.length = (uint32_t)(value.size() * sizeof(T)),
};
next_extension_ += ptr.length;
buffer_.WriteAt<ExtensionPointer>(field_offset(field_index), ptr);
for (uint64_t i = 0; i < value.size(); i++) {
uint32_t ext_offset = offset_ + ptr.offset + (i * sizeof(T));
buffer_.WriteAt<T>(ext_offset, value.at(i));
}
}
} // namespace yunq

22
lib/yunq/yunq.h Normal file
View file

@ -0,0 +1,22 @@
#pragma once
#include <stdint.h>
namespace yunq {
struct MessageHeader {
uint32_t ident;
uint32_t core_length;
uint32_t length;
uint32_t crc32;
uint64_t options;
} __attribute__((packed));
const uint64_t kHeaderSize = 24; // 4x uint32, 1x uint64
struct ExtensionPointer {
uint32_t offset;
uint32_t length;
};
} // namespace yunq