Supporting to_bytes and from_bytes also for the ..WithProperties types

This commit is contained in:
Matthias Koefferlein 2026-05-03 18:10:00 +02:00
parent 1de28f2d6b
commit 77fb74e072
4 changed files with 105 additions and 0 deletions

View File

@ -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<C>
return s;
}
template<class T>
tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::object_with_properties<T> &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<C> &p)
return s;
}
template<class T>
tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::object_with_properties<T> &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

View File

@ -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 <class T>
static T *from_bytes (const std::vector<char> &s)
{
std::unique_ptr<T> t (new T ());
db::from_bytes (s, *t);
return t.release ();
}
template <class T>
static std::vector<char> to_bytes (const T *t)
{
return db::to_bytes (*t);
}
template <class T>
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<T>, 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<T>,
"@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<T>,
"@brief Gets the user properties\n"
"This method is a convenience method that gets the properties of the shape as a single hash.\n"

View File

@ -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

View File

@ -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