#pragma once #include #include #include #include #include #include "yunq/yunq.h" namespace yunq { class MessageView { public: MessageView(const glcr::ByteBuffer& buffer, uint64_t offset) : buffer_(buffer), offset_(offset) {} [[nodiscard]] glcr::Status CheckHeader() const; uint32_t MessageLength() const; // TODO: Implement glcr::StatusOr template glcr::ErrorOr ReadField(uint64_t field_index) const; template glcr::ErrorOr> ReadRepeated(uint64_t field_index) const; glcr::ErrorOr ReadCapability(uint64_t field_index) const; glcr::ErrorOr ReadCapability(uint64_t field_index, const glcr::CapBuffer& caps) const; template glcr::Status ReadMessage(uint64_t field_index, T& message) const; template glcr::Status ReadRepeatedMessage(uint64_t field_index, glcr::Vector& messages) const; private: const glcr::ByteBuffer& buffer_; uint64_t offset_; uint64_t field_offset(uint64_t field_index) const { return offset_ + kHeaderSize + (8 * field_index); } }; template <> glcr::ErrorOr MessageView::ReadField( uint64_t field_index) const; template <> glcr::ErrorOr MessageView::ReadField( uint64_t field_index) const; template <> glcr::ErrorOr MessageView::ReadField( uint64_t field_index) const; template <> glcr::ErrorOr> MessageView::ReadRepeated( uint64_t field_index) const; template glcr::Status MessageView::ReadMessage(uint64_t field_index, T& message) const { ExtensionPointer ptr = buffer_.At(field_offset(field_index)); MessageView subview(buffer_, offset_ + ptr.offset); return message.ParseFromBytes(subview); } template glcr::Status MessageView::ReadRepeatedMessage(uint64_t field_index, glcr::Vector& messages) const { ExtensionPointer ptr = buffer_.At(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