[Yunq] Move serialization to yunq library.
This commit is contained in:
parent
0135d8d844
commit
7ec4f696a8
9 changed files with 316 additions and 486 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
22
lib/yunq/yunq.h
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue