[Yunq] Add support for repeated nested fields
This commit is contained in:
parent
05f2403dc2
commit
9c860dd6a4
14 changed files with 207 additions and 61 deletions
|
|
@ -19,6 +19,10 @@ glcr::Status MessageView::CheckHeader() const {
|
|||
return glcr::Status::Ok();
|
||||
}
|
||||
|
||||
uint32_t MessageView::MessageLength() const {
|
||||
return buffer_.At<uint32_t>(offset_ + 8);
|
||||
}
|
||||
|
||||
template <>
|
||||
glcr::ErrorOr<uint64_t> MessageView::ReadField<uint64_t>(
|
||||
uint64_t field_index) const {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ class MessageView {
|
|||
: buffer_(buffer), offset_(offset) {}
|
||||
|
||||
[[nodiscard]] glcr::Status CheckHeader() const;
|
||||
uint32_t MessageLength() const;
|
||||
|
||||
// TODO: Implement glcr::StatusOr
|
||||
template <typename T>
|
||||
|
|
@ -31,6 +32,10 @@ class MessageView {
|
|||
template <typename T>
|
||||
glcr::Status ReadMessage(uint64_t field_index, T& message) const;
|
||||
|
||||
template <typename T>
|
||||
glcr::Status ReadRepeatedMessage(uint64_t field_index,
|
||||
glcr::Vector<T>& messages) const;
|
||||
|
||||
private:
|
||||
const glcr::ByteBuffer& buffer_;
|
||||
uint64_t offset_;
|
||||
|
|
@ -61,4 +66,22 @@ glcr::Status MessageView::ReadMessage(uint64_t field_index, T& message) const {
|
|||
return message.ParseFromBytes(subview);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
glcr::Status MessageView::ReadRepeatedMessage(uint64_t field_index,
|
||||
glcr::Vector<T>& messages) const {
|
||||
ExtensionPointer ptr =
|
||||
buffer_.At<ExtensionPointer>(field_offset(field_index));
|
||||
|
||||
uint64_t ext_offset = ptr.offset;
|
||||
|
||||
while (ext_offset < ptr.offset + ptr.length) {
|
||||
MessageView subview(buffer_, offset_ + ext_offset);
|
||||
messages.EmplaceBack();
|
||||
RETURN_ERROR(messages.PeekBack().ParseFromBytes(subview));
|
||||
ext_offset += subview.MessageLength();
|
||||
}
|
||||
|
||||
return glcr::Status::Ok();
|
||||
}
|
||||
|
||||
} // namespace yunq
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ class Serializer {
|
|||
template <typename T>
|
||||
void WriteMessage(uint64_t field_index, const T& value);
|
||||
|
||||
template <typename T>
|
||||
void WriteRepeatedMessage(uint64_t field_index, const glcr::Vector<T>& value);
|
||||
|
||||
void WriteHeader();
|
||||
|
||||
uint64_t size() const { return next_extension_; }
|
||||
|
|
@ -90,4 +93,32 @@ void Serializer::WriteMessage(uint64_t field_index, const T& value) {
|
|||
buffer_.WriteAt<ExtensionPointer>(field_offset(field_index), ptr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Serializer::WriteRepeatedMessage(uint64_t field_index,
|
||||
const glcr::Vector<T>& value) {
|
||||
uint64_t next_offset = next_extension_;
|
||||
uint64_t length = 0;
|
||||
|
||||
for (T& message : value) {
|
||||
uint64_t msg_length = 0;
|
||||
if (caps_) {
|
||||
msg_length = message.SerializeToBytes(buffer_, offset_ + next_offset,
|
||||
caps_.value().get());
|
||||
} else {
|
||||
msg_length = message.SerializeToBytes(buffer_, offset_ + next_offset);
|
||||
}
|
||||
length += msg_length;
|
||||
next_offset += msg_length;
|
||||
}
|
||||
|
||||
ExtensionPointer ptr{
|
||||
.offset = (uint32_t)next_extension_,
|
||||
.length = (uint32_t)length,
|
||||
};
|
||||
|
||||
next_extension_ += length;
|
||||
|
||||
buffer_.WriteAt<ExtensionPointer>(field_offset(field_index), ptr);
|
||||
}
|
||||
|
||||
} // namespace yunq
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue