From a1f0197e83f29fd1c559221907b6ed773a0fa244 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Wed, 17 Jan 2024 13:57:02 -0800 Subject: [PATCH] [Yunq] Add parse/serialize for i64 field along with tests. --- lib/yunq/message_view.cpp | 6 ++ lib/yunq/message_view.h | 4 ++ lib/yunq/serialize.cpp | 6 ++ lib/yunq/serialize.h | 5 +- lib/yunq/test/CMakeLists.txt | 4 +- lib/yunq/test/example/example.yunq | 10 ++++ lib/yunq/test/example/example.yunq.cpp | 83 ++++++++++++++++++++++++++ lib/yunq/test/example/example.yunq.h | 60 +++++++++++++++++++ lib/yunq/test/yunq_test.cpp | 11 ++++ 9 files changed, 187 insertions(+), 2 deletions(-) diff --git a/lib/yunq/message_view.cpp b/lib/yunq/message_view.cpp index 960f8c4..4a3b7df 100644 --- a/lib/yunq/message_view.cpp +++ b/lib/yunq/message_view.cpp @@ -29,6 +29,12 @@ glcr::ErrorOr MessageView::ReadField( return buffer_.At(field_offset(field_index)); } +template <> +glcr::ErrorOr MessageView::ReadField( + uint64_t field_index) const { + return buffer_.At(field_offset(field_index)); +} + template <> glcr::ErrorOr MessageView::ReadField( uint64_t field_index) const { diff --git a/lib/yunq/message_view.h b/lib/yunq/message_view.h index 78a11ea..4be5535 100644 --- a/lib/yunq/message_view.h +++ b/lib/yunq/message_view.h @@ -49,6 +49,10 @@ 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; diff --git a/lib/yunq/serialize.cpp b/lib/yunq/serialize.cpp index 188685a..7b7852d 100644 --- a/lib/yunq/serialize.cpp +++ b/lib/yunq/serialize.cpp @@ -20,6 +20,12 @@ void Serializer::WriteField(uint64_t field_index, buffer_.WriteAt(field_offset(field_index), value); } +template <> +void Serializer::WriteField(uint64_t field_index, + const int64_t& value) { + buffer_.WriteAt(field_offset(field_index), value); +} + template <> void Serializer::WriteField(uint64_t field_index, const glcr::String& value) { diff --git a/lib/yunq/serialize.h b/lib/yunq/serialize.h index b19ea4b..b0c84c3 100644 --- a/lib/yunq/serialize.h +++ b/lib/yunq/serialize.h @@ -26,7 +26,6 @@ class Serializer { next_extension_(kHeaderSize + (8 * num_fields)), core_size_(next_extension_), caps_(caps) {} - template void WriteField(uint64_t field_index, const T& value); @@ -65,6 +64,10 @@ template <> void Serializer::WriteField(uint64_t field_index, const uint64_t& value); +template <> +void Serializer::WriteField(uint64_t field_index, + const int64_t& value); + template <> void Serializer::WriteField(uint64_t field_index, const glcr::String& value); diff --git a/lib/yunq/test/CMakeLists.txt b/lib/yunq/test/CMakeLists.txt index c66b271..f05d41c 100644 --- a/lib/yunq/test/CMakeLists.txt +++ b/lib/yunq/test/CMakeLists.txt @@ -36,7 +36,9 @@ set(PYTHON "${CMAKE_SOURCE_DIR}/yunq/venv/bin/python") set(YUNQ "${CMAKE_SOURCE_DIR}/yunq/yunq.py") add_custom_command( - OUTPUT example/example.yunq.cpp + OUTPUT + ${CMAKE_CURRENT_SOURCE_DIR}/example/example.yunq.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/example/example.yunq.h COMMAND ${PYTHON} ${YUNQ} ${CMAKE_CURRENT_SOURCE_DIR}/example/example.yunq DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/example/example.yunq ) diff --git a/lib/yunq/test/example/example.yunq b/lib/yunq/test/example/example.yunq index eaf2a9f..e6a27cd 100644 --- a/lib/yunq/test/example/example.yunq +++ b/lib/yunq/test/example/example.yunq @@ -3,3 +3,13 @@ package ex; message Basic { u64 field; } + +message Types { + u64 unsigned_int; + i64 signed_int; + string str; +} + +message Cap { + capability cap; +} diff --git a/lib/yunq/test/example/example.yunq.cpp b/lib/yunq/test/example/example.yunq.cpp index 7b5733e..745d8fa 100644 --- a/lib/yunq/test/example/example.yunq.cpp +++ b/lib/yunq/test/example/example.yunq.cpp @@ -53,6 +53,89 @@ uint64_t Basic::SerializeInternal(yunq::Serializer& serializer) const { return serializer.size(); } +glcr::Status Types::ParseFromBytes(const yunq::MessageView& message) { + RETURN_ERROR(ParseFromBytesInternal(message)); + return glcr::Status::Ok(); +} + +glcr::Status Types::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) { + RETURN_ERROR(ParseFromBytesInternal(message)); + return glcr::Status::Ok(); +} + +glcr::Status Types::ParseFromBytesInternal(const yunq::MessageView& message) { + RETURN_ERROR(message.CheckHeader()); + // Parse unsigned_int. + ASSIGN_OR_RETURN(unsigned_int_, message.ReadField(0)); + // Parse signed_int. + ASSIGN_OR_RETURN(signed_int_, message.ReadField(1)); + // Parse str. + ASSIGN_OR_RETURN(str_, message.ReadField(2)); + + return glcr::Status::Ok(); +} + +uint64_t Types::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { + yunq::Serializer serializer(bytes, offset, 3); + return SerializeInternal(serializer); +} + +uint64_t Types::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { + yunq::Serializer serializer(bytes, offset, 3, caps); + return SerializeInternal(serializer); +} + +uint64_t Types::SerializeInternal(yunq::Serializer& serializer) const { + // Write unsigned_int. + serializer.WriteField(0, unsigned_int_); + // Write signed_int. + serializer.WriteField(1, signed_int_); + // Write str. + serializer.WriteField(2, str_); + + serializer.WriteHeader(); + + return serializer.size(); +} +glcr::Status Cap::ParseFromBytes(const yunq::MessageView& message) { + RETURN_ERROR(ParseFromBytesInternal(message)); + // Parse cap. + ASSIGN_OR_RETURN(cap_, message.ReadCapability(0)); + return glcr::Status::Ok(); +} + +glcr::Status Cap::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) { + RETURN_ERROR(ParseFromBytesInternal(message)); + // Parse cap. + ASSIGN_OR_RETURN(cap_, message.ReadCapability(0, caps)); + return glcr::Status::Ok(); +} + +glcr::Status Cap::ParseFromBytesInternal(const yunq::MessageView& message) { + RETURN_ERROR(message.CheckHeader()); + // Parse cap. + + return glcr::Status::Ok(); +} + +uint64_t Cap::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { + yunq::Serializer serializer(bytes, offset, 1); + return SerializeInternal(serializer); +} + +uint64_t Cap::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { + yunq::Serializer serializer(bytes, offset, 1, caps); + return SerializeInternal(serializer); +} + +uint64_t Cap::SerializeInternal(yunq::Serializer& serializer) const { + // Write cap. + serializer.WriteCapability(0, cap_); + + serializer.WriteHeader(); + + return serializer.size(); +} } // namepace ex diff --git a/lib/yunq/test/example/example.yunq.h b/lib/yunq/test/example/example.yunq.h index bbaab36..363a3f3 100644 --- a/lib/yunq/test/example/example.yunq.h +++ b/lib/yunq/test/example/example.yunq.h @@ -38,6 +38,66 @@ class Basic { uint64_t SerializeInternal(yunq::Serializer& serializer) const; }; +class Types { + public: + Types() {} + // Delete copy and move until implemented. + Types(const Types&) = delete; + Types(Types&&) = default; + Types& operator=(Types&&) = default; + + [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message); + [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer&); + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; + + const uint64_t& unsigned_int() const { return unsigned_int_; } + uint64_t& mutable_unsigned_int() { return unsigned_int_; } + void set_unsigned_int(const uint64_t& value) { unsigned_int_ = value; } + + const int64_t& signed_int() const { return signed_int_; } + int64_t& mutable_signed_int() { return signed_int_; } + void set_signed_int(const int64_t& value) { signed_int_ = value; } + + const glcr::String& str() const { return str_; } + glcr::String& mutable_str() { return str_; } + void set_str(const glcr::String& value) { str_ = value; } + + private: + uint64_t unsigned_int_; + int64_t signed_int_; + glcr::String str_; + + // Parses everything except for caps. + glcr::Status ParseFromBytesInternal(const yunq::MessageView& message); + + uint64_t SerializeInternal(yunq::Serializer& serializer) const; +}; +class Cap { + public: + Cap() {} + // Delete copy and move until implemented. + Cap(const Cap&) = delete; + Cap(Cap&&) = default; + Cap& operator=(Cap&&) = default; + + [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message); + [[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer&); + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; + + const z_cap_t& cap() const { return cap_; } + z_cap_t& mutable_cap() { return cap_; } + void set_cap(const z_cap_t& value) { cap_ = value; } + + private: + z_cap_t cap_; + + // Parses everything except for caps. + glcr::Status ParseFromBytesInternal(const yunq::MessageView& message); + + uint64_t SerializeInternal(yunq::Serializer& serializer) const; +}; } // namepace ex diff --git a/lib/yunq/test/yunq_test.cpp b/lib/yunq/test/yunq_test.cpp index 126fdef..d2e79a5 100644 --- a/lib/yunq/test/yunq_test.cpp +++ b/lib/yunq/test/yunq_test.cpp @@ -21,3 +21,14 @@ TEST_CASE("Basic serialization", "[yunq]") { REQUIRE(b.field() == 1); } + +TEST_CASE("Types Setter/Getter", "[yunq]") { + ex::Types t; + t.set_unsigned_int(1); + t.set_signed_int(-1); + t.set_str("test"); + + REQUIRE(t.unsigned_int() == 1); + REQUIRE(t.signed_int() == -1); + REQUIRE(t.str() == "test"); +}