2024-01-11 19:27:57 -08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <glacier/buffer/byte_buffer.h>
|
2024-01-11 19:59:36 -08:00
|
|
|
#include <glacier/buffer/cap_buffer.h>
|
2024-01-11 19:36:24 -08:00
|
|
|
#include <glacier/container/vector.h>
|
2024-01-11 19:27:57 -08:00
|
|
|
#include <glacier/status/error_or.h>
|
2024-01-11 19:51:18 -08:00
|
|
|
#include <glacier/status/status.h>
|
2024-01-11 19:27:57 -08:00
|
|
|
|
2024-01-11 20:36:41 -08:00
|
|
|
#include "yunq/yunq.h"
|
2024-01-11 19:27:57 -08:00
|
|
|
|
2024-01-11 20:36:41 -08:00
|
|
|
namespace yunq {
|
2024-01-11 19:27:57 -08:00
|
|
|
|
|
|
|
class MessageView {
|
|
|
|
public:
|
|
|
|
MessageView(const glcr::ByteBuffer& buffer, uint64_t offset)
|
|
|
|
: buffer_(buffer), offset_(offset) {}
|
|
|
|
|
2024-01-11 19:51:18 -08:00
|
|
|
[[nodiscard]] glcr::Status CheckHeader() const;
|
2024-01-11 22:09:42 -08:00
|
|
|
uint32_t MessageLength() const;
|
2024-01-11 19:51:18 -08:00
|
|
|
|
2024-01-11 19:27:57 -08:00
|
|
|
// TODO: Implement glcr::StatusOr
|
|
|
|
template <typename T>
|
2024-01-11 19:51:18 -08:00
|
|
|
glcr::ErrorOr<T> ReadField(uint64_t field_index) const;
|
2024-01-11 19:27:57 -08:00
|
|
|
|
2024-01-11 19:36:24 -08:00
|
|
|
template <typename T>
|
2024-01-11 19:51:18 -08:00
|
|
|
glcr::ErrorOr<glcr::Vector<T>> ReadRepeated(uint64_t field_index) const;
|
2024-01-11 19:36:24 -08:00
|
|
|
|
2024-01-11 19:59:36 -08:00
|
|
|
glcr::ErrorOr<uint64_t> ReadCapability(uint64_t field_index) const;
|
|
|
|
glcr::ErrorOr<uint64_t> ReadCapability(uint64_t field_index,
|
|
|
|
const glcr::CapBuffer& caps) const;
|
|
|
|
|
2024-01-11 21:32:08 -08:00
|
|
|
template <typename T>
|
|
|
|
glcr::Status ReadMessage(uint64_t field_index, T& message) const;
|
|
|
|
|
2024-01-11 22:09:42 -08:00
|
|
|
template <typename T>
|
|
|
|
glcr::Status ReadRepeatedMessage(uint64_t field_index,
|
|
|
|
glcr::Vector<T>& messages) const;
|
|
|
|
|
2024-01-11 19:27:57 -08:00
|
|
|
private:
|
|
|
|
const glcr::ByteBuffer& buffer_;
|
|
|
|
uint64_t offset_;
|
|
|
|
|
2024-01-11 19:51:18 -08:00
|
|
|
uint64_t field_offset(uint64_t field_index) const {
|
2024-01-11 19:27:57 -08:00
|
|
|
return offset_ + kHeaderSize + (8 * field_index);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
2024-01-11 19:51:18 -08:00
|
|
|
glcr::ErrorOr<uint64_t> MessageView::ReadField<uint64_t>(
|
|
|
|
uint64_t field_index) const;
|
2024-01-11 19:27:57 -08:00
|
|
|
|
2024-01-17 13:57:02 -08:00
|
|
|
template <>
|
|
|
|
glcr::ErrorOr<int64_t> MessageView::ReadField<int64_t>(
|
|
|
|
uint64_t field_index) const;
|
|
|
|
|
2024-01-11 19:27:57 -08:00
|
|
|
template <>
|
|
|
|
glcr::ErrorOr<glcr::String> MessageView::ReadField<glcr::String>(
|
2024-01-11 19:51:18 -08:00
|
|
|
uint64_t field_index) const;
|
2024-01-11 19:27:57 -08:00
|
|
|
|
2024-01-11 19:36:24 -08:00
|
|
|
template <>
|
|
|
|
glcr::ErrorOr<glcr::Vector<uint64_t>> MessageView::ReadRepeated<uint64_t>(
|
2024-01-11 19:51:18 -08:00
|
|
|
uint64_t field_index) const;
|
2024-01-11 19:36:24 -08:00
|
|
|
|
2024-01-11 21:32:08 -08:00
|
|
|
template <typename T>
|
|
|
|
glcr::Status MessageView::ReadMessage(uint64_t field_index, T& message) const {
|
|
|
|
ExtensionPointer ptr =
|
|
|
|
buffer_.At<ExtensionPointer>(field_offset(field_index));
|
|
|
|
|
|
|
|
MessageView subview(buffer_, offset_ + ptr.offset);
|
|
|
|
return message.ParseFromBytes(subview);
|
|
|
|
}
|
|
|
|
|
2024-01-11 22:09:42 -08:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2024-01-11 19:27:57 -08:00
|
|
|
} // namespace yunq
|