From 77fb74e0727ca9f13f963dfa1a3e02b866dbbb95 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 3 May 2026 18:10:00 +0200 Subject: [PATCH] Supporting to_bytes and from_bytes also for the ..WithProperties types --- src/db/db/dbBinarySerialize.h | 45 ++++++++++++++++++++++++++ src/db/db/gsiDeclDbPropertiesSupport.h | 28 ++++++++++++++++ testdata/ruby/dbBoxTest.rb | 14 ++++++++ testdata/ruby/dbPolygonTest.rb | 18 +++++++++++ 4 files changed, 105 insertions(+) diff --git a/src/db/db/dbBinarySerialize.h b/src/db/db/dbBinarySerialize.h index 8482558e0..2898420ef 100644 --- a/src/db/db/dbBinarySerialize.h +++ b/src/db/db/dbBinarySerialize.h @@ -35,6 +35,7 @@ #include "dbPath.h" #include "dbTrans.h" #include "dbText.h" +#include "dbObjectWithProperties.h" #include "tlBinaryStream.h" #include "tlException.h" @@ -210,6 +211,23 @@ tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::path return s; } +template +tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::object_with_properties &o) +{ + s << (uint16_t) 1; // version + + s << (const T &) o; + + const auto &ps = db::properties (o.properties_id ()); + + s << (uint64_t) ps.size (); + for (auto i = ps.begin (); i != ps.end (); ++i) { + s << db::property_name (i->first) << db::property_value (i->second); + } + + return s; +} + // ----------------------------------------------------------------------------------------- // Stream extractors @@ -530,6 +548,33 @@ tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::path &p) return s; } +template +tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::object_with_properties &o) +{ + uint16_t fmt = 0; + s >> fmt; + if (fmt > 1) { + throw FutureBinarySerializationFormatException (); + } + + s >> (T &) o; + + uint64_t n = 0; + s >> n; + + db::PropertiesSet ps; + + while (n-- > 0) { + tl::Variant name, value; + s >> name >> value; + ps.insert (name, value); + } + + o.properties_id (db::properties_id (ps)); + + return s; +} + // ----------------------------------------------------------------------------------------- // Converters of objects to a binary string diff --git a/src/db/db/gsiDeclDbPropertiesSupport.h b/src/db/db/gsiDeclDbPropertiesSupport.h index cb7930772..2dbf2d1ae 100644 --- a/src/db/db/gsiDeclDbPropertiesSupport.h +++ b/src/db/db/gsiDeclDbPropertiesSupport.h @@ -27,12 +27,27 @@ #include "tlTypeTraits.h" #include "dbPropertiesRepository.h" #include "dbObjectWithProperties.h" +#include "dbBinarySerialize.h" #include "dbTrans.h" #include "dbEdge.h" namespace gsi { +template +static T *from_bytes (const std::vector &s) +{ + std::unique_ptr t (new T ()); + db::from_bytes (s, *t); + return t.release (); +} + +template +static std::vector to_bytes (const T *t) +{ + return db::to_bytes (*t); +} + template static void delete_property_meth_impl (T *s, const tl::Variant &key) { @@ -253,6 +268,19 @@ static gsi::Methods properties_support_methods () gsi::method ("to_s", (std::string (T::*) () const) &T::to_string, "@brief Returns a string representing the object\n" ) + + gsi::constructor ("from_bytes", &from_bytes, gsi::arg ("s"), + "@brief Creates an object from a binary serialization\n" + "Creates the object from a binary representation (as returned by \\to_bytes)\n" + "\n" + "This method has been added in version 0.30.9.\n" + ) + + gsi::method_ext ("to_bytes", &to_bytes, + "@brief Returns a binary string representing this object\n" + "\n" + "This string can be turned into an object again by using \\from_bytes\n. " + "\n" + "This method has been added in version 0.30.9.\n" + ) + gsi::method_ext ("properties", &get_properties_meth_impl, "@brief Gets the user properties\n" "This method is a convenience method that gets the properties of the shape as a single hash.\n" diff --git a/testdata/ruby/dbBoxTest.rb b/testdata/ruby/dbBoxTest.rb index 5c440098a..40c11e141 100644 --- a/testdata/ruby/dbBoxTest.rb +++ b/testdata/ruby/dbBoxTest.rb @@ -552,6 +552,20 @@ class DBBox_TestClass < TestBase assert_equal(s.to_s, "(0,0;100,200) props={}") assert_equal(s.property(1), nil) + # binary serialization + + s = RBA::BoxWithProperties::new(RBA::Box::new(0, 0, 100, 200), {}) + assert_equal(RBA::BoxWithProperties::from_bytes(s.to_bytes).to_s, s.to_s) + + s = RBA::BoxWithProperties::new(RBA::Box::new(0, 0, 100, 200), { 1 => "one", "key" => 17 }) + assert_equal(RBA::BoxWithProperties::from_bytes(s.to_bytes).to_s, s.to_s) + + s = RBA::DBoxWithProperties::new(RBA::DBox::new(0, 0, 100, 200), {}) + assert_equal(RBA::DBoxWithProperties::from_bytes(s.to_bytes).to_s, s.to_s) + + s = RBA::DBoxWithProperties::new(RBA::DBox::new(0, 0, 100, 200), { 1 => "one", "key" => 17 }) + assert_equal(RBA::DBoxWithProperties::from_bytes(s.to_bytes).to_s, s.to_s) + end end diff --git a/testdata/ruby/dbPolygonTest.rb b/testdata/ruby/dbPolygonTest.rb index 4749f832c..422e32a49 100644 --- a/testdata/ruby/dbPolygonTest.rb +++ b/testdata/ruby/dbPolygonTest.rb @@ -990,6 +990,24 @@ class DBPolygon_TestClass < TestBase assert_equal(s.class.to_s, "RBA::DSimplePolygonWithProperties") assert_equal(s.downcast.class.to_s, "RBA::DSimplePolygon") + # binary serialization + s = RBA::PolygonWithProperties::new(RBA::Box::new(0, 0, 100, 200), {}) + assert_equal(RBA::PolygonWithProperties::from_bytes(s.to_bytes).to_s, s.to_s) + s = RBA::PolygonWithProperties::new(RBA::Box::new(0, 0, 100, 200), { 1 => "one", "key" => 17 }) + assert_equal(RBA::PolygonWithProperties::from_bytes(s.to_bytes).to_s, s.to_s) + s = RBA::DPolygonWithProperties::new(RBA::DBox::new(0, 0, 100, 200), {}) + assert_equal(RBA::DPolygonWithProperties::from_bytes(s.to_bytes).to_s, s.to_s) + s = RBA::DPolygonWithProperties::new(RBA::DBox::new(0, 0, 100, 200), { 1 => "one", "key" => 17 }) + assert_equal(RBA::DPolygonWithProperties::from_bytes(s.to_bytes).to_s, s.to_s) + s = RBA::SimplePolygonWithProperties::new(RBA::Box::new(0, 0, 100, 200), {}) + assert_equal(RBA::SimplePolygonWithProperties::from_bytes(s.to_bytes).to_s, s.to_s) + s = RBA::SimplePolygonWithProperties::new(RBA::Box::new(0, 0, 100, 200), { 1 => "one", "key" => 17 }) + assert_equal(RBA::SimplePolygonWithProperties::from_bytes(s.to_bytes).to_s, s.to_s) + s = RBA::DSimplePolygonWithProperties::new(RBA::DBox::new(0, 0, 100, 200), {}) + assert_equal(RBA::DSimplePolygonWithProperties::from_bytes(s.to_bytes).to_s, s.to_s) + s = RBA::DSimplePolygonWithProperties::new(RBA::DBox::new(0, 0, 100, 200), { 1 => "one", "key" => 17 }) + assert_equal(RBA::DSimplePolygonWithProperties::from_bytes(s.to_bytes).to_s, s.to_s) + end def test_triangulation