Some refactoring, bug fixes

This commit is contained in:
Matthias Koefferlein 2026-05-03 00:15:47 +02:00
parent fdaa93d234
commit 7f6071db31
9 changed files with 197 additions and 92 deletions

View File

@ -46,45 +46,45 @@ namespace db
// Stream inserters
template<class C>
tl::OutputStream &write_coord (tl::OutputStream &s, C c)
tl::BinaryOutputStream &write_coord (tl::BinaryOutputStream &s, C c)
{
return s << c;
}
inline tl::OutputStream &write_coord (tl::OutputStream &s, db::Coord c)
inline tl::BinaryOutputStream &write_coord (tl::BinaryOutputStream &s, db::Coord c)
{
// NOTE: for compatibility across different builds we use 64 bit coordinates always
return s << (int64_t) c;
}
template<class C>
tl::OutputStream &write_binary (tl::OutputStream &s, const db::point<C> &pt)
tl::BinaryOutputStream &write_binary (tl::BinaryOutputStream &s, const db::point<C> &pt)
{
return write_coord (write_coord (s, pt.x ()), pt.y ());
}
template<class C>
tl::OutputStream &write_binary (tl::OutputStream &s, const db::vector<C> &v)
tl::BinaryOutputStream &write_binary (tl::BinaryOutputStream &s, const db::vector<C> &v)
{
return write_coord (write_coord (s, v.x ()), v.y ());
}
template<class C>
tl::OutputStream &operator<< (tl::OutputStream &s, const db::point<C> &pt)
tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::point<C> &pt)
{
s << (uint16_t) 1; // version
return write_binary (s, pt);
}
template<class C>
tl::OutputStream &operator<< (tl::OutputStream &s, const db::vector<C> &v)
tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::vector<C> &v)
{
s << (uint16_t) 1; // version
return write_binary (s, v);
}
template<class C>
tl::OutputStream &write_binary (tl::OutputStream &s, const db::edge<C> &e)
tl::BinaryOutputStream &write_binary (tl::BinaryOutputStream &s, const db::edge<C> &e)
{
write_binary (s, e.p1 ());
write_binary (s, e.p2 ());
@ -92,14 +92,14 @@ tl::OutputStream &write_binary (tl::OutputStream &s, const db::edge<C> &e)
}
template<class C>
tl::OutputStream &operator<< (tl::OutputStream &s, const db::edge<C> &e)
tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::edge<C> &e)
{
s << (uint16_t) 1; // version
return write_binary (s, e);
}
template<class C>
tl::OutputStream &operator<< (tl::OutputStream &s, const db::box<C> &b)
tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::box<C> &b)
{
s << (uint16_t) 1; // version
write_binary (s, b.p1 ());
@ -108,7 +108,7 @@ tl::OutputStream &operator<< (tl::OutputStream &s, const db::box<C> &b)
}
template<class C>
tl::OutputStream &operator<< (tl::OutputStream &s, const db::edge_pair<C> &ep)
tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::edge_pair<C> &ep)
{
s << (uint16_t) 1; // version
write_binary (s, ep.first ());
@ -117,17 +117,17 @@ tl::OutputStream &operator<< (tl::OutputStream &s, const db::edge_pair<C> &ep)
}
template<class C>
tl::OutputStream &write_binary (tl::OutputStream &s, const db::polygon_contour<C> &c)
tl::BinaryOutputStream &write_binary (tl::BinaryOutputStream &s, const db::polygon_contour<C> &c)
{
s << (uint64_t) c.size ();
for (auto i = c.begin (); i != c.end (); ++i) {
s << *i;
write_binary (s, *i);
}
return s;
}
template<class C>
tl::OutputStream &operator<< (tl::OutputStream &s, const db::polygon<C> &p)
tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::polygon<C> &p)
{
s << (uint16_t) 1; // version
s << (uint64_t) (p.holes () + 1);
@ -138,7 +138,7 @@ tl::OutputStream &operator<< (tl::OutputStream &s, const db::polygon<C> &p)
}
template<class C>
tl::OutputStream &operator<< (tl::OutputStream &s, const db::simple_polygon<C> &p)
tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::simple_polygon<C> &p)
{
// NOTE: the format of polygon and simple polygon are compatible
s << (uint16_t) 1; // version
@ -148,14 +148,14 @@ tl::OutputStream &operator<< (tl::OutputStream &s, const db::simple_polygon<C> &
}
template<class C>
tl::OutputStream &operator<< (tl::OutputStream &s, const db::unit_trans<C> &)
tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::unit_trans<C> &)
{
s << (uint16_t) 1; // version
return s;
}
template<class C>
tl::OutputStream &operator<< (tl::OutputStream &s, const db::disp_trans<C> &t)
tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::disp_trans<C> &t)
{
s << (uint16_t) 1; // version
write_binary (s, t.disp ());
@ -163,7 +163,7 @@ tl::OutputStream &operator<< (tl::OutputStream &s, const db::disp_trans<C> &t)
}
template<class C>
tl::OutputStream &write_binary (tl::OutputStream &s, const db::simple_trans<C> &t)
tl::BinaryOutputStream &write_binary (tl::BinaryOutputStream &s, const db::simple_trans<C> &t)
{
s << (uint16_t) t.rot ();
write_binary (s, t.disp ());
@ -171,22 +171,22 @@ tl::OutputStream &write_binary (tl::OutputStream &s, const db::simple_trans<C> &
}
template<class C>
tl::OutputStream &operator<< (tl::OutputStream &s, const db::simple_trans<C> &t)
tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::simple_trans<C> &t)
{
s << (uint16_t) 1; // version
return write_binary (s, t);
}
template<class C, class D, class R>
tl::OutputStream &operator<< (tl::OutputStream &s, const db::complex_trans<C, D, R> &t)
tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::complex_trans<C, D, R> &t)
{
s << (uint16_t) 1; // version
write_binary (s, t.disp ());
return s << (double) t.msin () << (double) t.mcos () << (double) t.mag ();
return s << (double) t.msin () << (double) t.mcos () << (double) (t.is_mirror () ? -t.mag () : t.mag ());
}
template<class C>
tl::OutputStream &operator<< (tl::OutputStream &s, const db::text<C> &t)
tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::text<C> &t)
{
s << (uint16_t) 1; // version
s << t.string ();
@ -196,7 +196,7 @@ tl::OutputStream &operator<< (tl::OutputStream &s, const db::text<C> &t)
}
template<class C>
tl::OutputStream &operator<< (tl::OutputStream &s, const db::path<C> &p)
tl::BinaryOutputStream &operator<< (tl::BinaryOutputStream &s, const db::path<C> &p)
{
s << (uint16_t) 1; // version
s << (uint64_t) p.points ();
@ -206,7 +206,7 @@ tl::OutputStream &operator<< (tl::OutputStream &s, const db::path<C> &p)
write_coord (s, p.width ());
write_coord (s, p.bgn_ext ());
write_coord (s, p.end_ext ());
write_coord (s, p.round ());
s << p.round ();
return s;
}
@ -333,7 +333,7 @@ tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::edge_pair<C> &e
}
template<class C>
tl::BinaryInputStream &read_binary (tl::BinaryInputStream &s, db::polygon_contour<C> &c)
tl::BinaryInputStream &read_binary (tl::BinaryInputStream &s, db::polygon_contour<C> &c, bool hole)
{
uint64_t n = 0;
s >> n;
@ -346,7 +346,7 @@ tl::BinaryInputStream &read_binary (tl::BinaryInputStream &s, db::polygon_contou
}
// NOTE: not normalization or modification is applied
c.assign (pts.begin (), pts.end (), false, false, false);
c.assign (pts.begin (), pts.end (), hole, false, false, false);
return s;
}
@ -364,10 +364,13 @@ tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::polygon<C> &p)
s >> n;
p = db::polygon<C> ();
if (n > 0) {
p.reserve_holes (n - 1);
}
db::polygon_contour<C> ctr;
for (uint64_t h = 0; h < n; ++h) {
read_binary (s, ctr);
read_binary (s, ctr, h > 0);
if (h == 0) {
p.assign_hull (ctr);
} else {
@ -392,7 +395,7 @@ tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::simple_polygon<
tl_assert (n == (uint64_t) 1);
db::polygon_contour<C> ctr;
read_binary (s, ctr);
read_binary (s, ctr, false);
p.assign_hull (ctr);
return s;
@ -516,7 +519,9 @@ tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::path<C> &p)
}
C width, bgn_ext, end_ext;
s >> width >> bgn_ext >> end_ext;
read_coord (s, width);
read_coord (s, bgn_ext);
read_coord (s, end_ext);
bool round;
s >> round;
@ -533,7 +538,7 @@ std::vector<char> to_bytes (const T &t)
{
tl::OutputMemoryStream osm;
{
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << t;
}
return std::vector<char> (osm.data (), osm.data () + osm.size ());
@ -544,7 +549,7 @@ std::string to_bytes_str (const T &t)
{
tl::OutputMemoryStream osm;
{
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << t;
}
return std::string (osm.data (), osm.size ());

View File

@ -471,7 +471,7 @@ struct edge_defs
"This string can be turned into an edge again by using \\from_bytes\n. "
"\n"
"This method has been added in version 0.30.9.\n"
);
) +
method ("is_parallel?", &C::parallel, gsi::arg ("e"),
"@brief Test for being parallel\n"
"\n"

View File

@ -192,7 +192,7 @@ struct edge_pair_defs
"This string can be turned into an edge pair again by using \\from_bytes\n. "
"\n"
"This method has been added in version 0.30.9.\n"
);
) +
method ("bbox", &C::bbox,
"@brief Gets the bounding box of the edge pair\n"
) +

View File

@ -309,7 +309,7 @@ struct path_defs
"This string can be turned into a path again by using \\from_bytes\n. "
"\n"
"This method has been added in version 0.30.9.\n"
);
) +
method ("simple_polygon", &C::simple_polygon,
"@brief Convert the path to a simple polygon\n"
"The returned polygon is not guaranteed to be non-selfoverlapping. This may happen if the path overlaps "

View File

@ -727,7 +727,7 @@ struct simple_polygon_defs
"This string can be turned into a polygon again by using \\from_bytes\n. "
"\n"
"This method has been added in version 0.30.9.\n"
);
) +
method_ext ("round_corners", &round_corners, gsi::arg ("rinner"), gsi::arg ("router"), gsi::arg ("n"),
"@brief Rounds the corners of the polygon\n"
"\n"
@ -1904,7 +1904,7 @@ struct polygon_defs
"This string can be turned into a polygon again by using \\from_bytes\n. "
"\n"
"This method has been added in version 0.30.9.\n"
);
) +
method_ext ("round_corners", &round_corners, gsi::arg ("rinner"), gsi::arg ("router"), gsi::arg ("n"),
"@brief Rounds the corners of the polygon\n"
"\n"

View File

@ -543,7 +543,7 @@ struct trans_defs
"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"
);
) +
method ("disp", (const vector_type &(C::*) () const) &C::disp,
"@brief Gets to the displacement vector\n"
"\n"
@ -1189,7 +1189,7 @@ struct cplx_trans_defs
"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"
);
) +
method ("disp", (displacement_type (C::*)() const) &C::disp,
"@brief Gets the displacement\n"
) +

View File

@ -1469,7 +1469,39 @@ OutputStream::put_raw (const char *b, size_t n)
}
void
OutputStream::put_native (const char *s, size_t n)
OutputStream::seek (size_t pos)
{
flush ();
if (mp_delegate) {
mp_delegate->seek (pos);
}
m_pos = pos;
}
// ---------------------------------------------------------------
// BinaryOutputStream implementation
BinaryOutputStream::BinaryOutputStream (OutputStreamBase &delegate)
: OutputStream (delegate, false)
{
// .. nothing yet ..
}
BinaryOutputStream::BinaryOutputStream (OutputStreamBase *delegate)
: OutputStream (delegate, false)
{
// .. nothing yet ..
}
BinaryOutputStream::BinaryOutputStream (const std::string &abstract_path, OutputStreamMode om, int keep_backups)
: OutputStream (abstract_path, om, false, keep_backups)
{
// .. nothing yet ..
}
void
BinaryOutputStream::put_native (const char *s, size_t n)
{
// the native format for a string is a length field (uint64_t) and the bytes
// TODO: for now we assume that the memory layout is the same for all platforms
@ -1479,7 +1511,7 @@ OutputStream::put_native (const char *s, size_t n)
}
void
OutputStream::put_native (const std::string &s)
BinaryOutputStream::put_native (const std::string &s)
{
// the native format for a string is a length field (uint64_t) and the bytes
// TODO: for now we assume that the memory layout is the same for all platforms
@ -1489,91 +1521,80 @@ OutputStream::put_native (const std::string &s)
}
void
OutputStream::put_native (double v)
BinaryOutputStream::put_native (double v)
{
// TODO: for now we assume that the memory layout is the same for all platforms
put_raw ((const char *) &v, 8);
}
void
OutputStream::put_native (float v)
BinaryOutputStream::put_native (float v)
{
// TODO: for now we assume that the memory layout is the same for all platforms
put_raw ((const char *) &v, 4);
}
void
OutputStream::put_native (bool v)
BinaryOutputStream::put_native (bool v)
{
char c = v ? 1 : 0;
put_raw (&c, 1);
}
void
OutputStream::put_native (uint8_t v)
BinaryOutputStream::put_native (uint8_t v)
{
put_raw ((const char *) &v, 1);
}
void
OutputStream::put_native (int8_t v)
BinaryOutputStream::put_native (int8_t v)
{
put_raw ((const char *) &v, 1);
}
void
OutputStream::put_native (uint16_t v)
BinaryOutputStream::put_native (uint16_t v)
{
// TODO: for now we assume that the memory layout is the same for all platforms
put_raw ((const char *) &v, 2);
}
void
OutputStream::put_native (int16_t v)
BinaryOutputStream::put_native (int16_t v)
{
// TODO: for now we assume that the memory layout is the same for all platforms
put_raw ((const char *) &v, 2);
}
void
OutputStream::put_native (uint32_t v)
BinaryOutputStream::put_native (uint32_t v)
{
// TODO: for now we assume that the memory layout is the same for all platforms
put_raw ((const char *) &v, 4);
}
void
OutputStream::put_native (int32_t v)
BinaryOutputStream::put_native (int32_t v)
{
// TODO: for now we assume that the memory layout is the same for all platforms
put_raw ((const char *) &v, 4);
}
void
OutputStream::put_native (uint64_t v)
BinaryOutputStream::put_native (uint64_t v)
{
// TODO: for now we assume that the memory layout is the same for all platforms
put_raw ((const char *) &v, 8);
}
void
OutputStream::put_native (int64_t v)
BinaryOutputStream::put_native (int64_t v)
{
// TODO: for now we assume that the memory layout is the same for all platforms
put_raw ((const char *) &v, 8);
}
void
OutputStream::seek (size_t pos)
{
flush ();
if (mp_delegate) {
mp_delegate->seek (pos);
}
m_pos = pos;
}
// ---------------------------------------------------------------
// OutputFileBase implementation

View File

@ -1431,11 +1431,7 @@ public:
*/
OutputStream &operator<< (const char *s)
{
if (m_as_text) {
put (s, strlen (s));
} else {
put_native (s, strlen (s));
}
put (s, strlen (s));
return *this;
}
@ -1447,11 +1443,7 @@ public:
*/
OutputStream &operator<< (const std::string &s)
{
if (m_as_text) {
put (s);
} else {
put_native (s);
}
put (s);
return *this;
}
@ -1461,11 +1453,7 @@ public:
template <class T>
OutputStream &operator<< (const T &t)
{
if (m_as_text) {
put (tl::to_string (t));
} else {
put_native (t);
}
put (tl::to_string (t));
return *this;
}
@ -1544,6 +1532,95 @@ private:
size_t m_buffer_capacity, m_buffer_pos;
std::string m_path;
// No copying currently
OutputStream (const OutputStream &);
OutputStream &operator= (const OutputStream &);
};
// ---------------------------------------------------------------------------------
/**
* @brief An output stream specialized on binary representation
*/
class TL_PUBLIC BinaryOutputStream
: public OutputStream
{
public:
/**
* @brief Default constructor
*
* This constructor takes a delegate object.
*/
BinaryOutputStream (OutputStreamBase &delegate);
/**
* @brief Default constructor
*
* This constructor takes a delegate object. The stream will own the delegate.
*/
BinaryOutputStream (OutputStreamBase *delegate);
/**
* @brief Open an output stream with the given path and stream mode
*
* This will automatically create a delegate object and delete it later.
*/
BinaryOutputStream (const std::string &abstract_path, OutputStreamMode om = OM_Auto, int keep_backups = 0);
/**
* @brief << operator: inserts character
*/
OutputStream &operator<< (char s)
{
put (&s, 1);
return *this;
}
/**
* @brief << operator: inserts a character
*/
OutputStream &operator<< (unsigned char s)
{
put ((const char *) &s, 1);
return *this;
}
/**
* @brief << operator: inserts a string
*
* In binary mode, the string is inserted as a length/data
* combination. That matches the extraction in BinaryInputStream.
*/
BinaryOutputStream &operator<< (const char *s)
{
put_native (s, strlen (s));
return *this;
}
/**
* @brief << operator: inserts a string
*
* In binary mode, the string is inserted as a length/data
* combination. That matches the extraction in BinaryInputStream.
*/
BinaryOutputStream &operator<< (const std::string &s)
{
put_native (s);
return *this;
}
/**
* @brief << operator: inserts an object supported by "put_native".
*/
template <class T>
BinaryOutputStream &operator<< (const T &t)
{
put_native (t);
return *this;
}
private:
void put_native (const std::string &s);
void put_native (const char *s, size_t n);
void put_native (double v);
@ -1558,9 +1635,11 @@ private:
void put_native (uint64_t v);
void put_native (int64_t v);
void set_as_text (bool f);
// No copying currently
OutputStream (const OutputStream &);
OutputStream &operator= (const OutputStream &);
BinaryOutputStream (const BinaryOutputStream &);
BinaryOutputStream &operator= (const BinaryOutputStream &);
};
}

View File

@ -642,7 +642,7 @@ std::string s2string (tl::OutputMemoryStream &osm)
TEST(BinaryStreams1)
{
tl::OutputMemoryStream osm;
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << (double) 0.17;
@ -662,7 +662,7 @@ TEST(BinaryStreams1)
TEST(BinaryStreams2)
{
tl::OutputMemoryStream osm;
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << (float) 0.17;
@ -682,7 +682,7 @@ TEST(BinaryStreams2)
TEST(BinaryStreams3)
{
tl::OutputMemoryStream osm;
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << std::string ("ABC");
@ -702,7 +702,7 @@ TEST(BinaryStreams3)
TEST(BinaryStreams4)
{
tl::OutputMemoryStream osm;
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << "ABC";
@ -722,7 +722,7 @@ TEST(BinaryStreams4)
TEST(BinaryStreams5)
{
tl::OutputMemoryStream osm;
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << uint8_t (17);
@ -742,7 +742,7 @@ TEST(BinaryStreams5)
TEST(BinaryStreams6)
{
tl::OutputMemoryStream osm;
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << int8_t (17);
@ -762,7 +762,7 @@ TEST(BinaryStreams6)
TEST(BinaryStreams7)
{
tl::OutputMemoryStream osm;
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << uint16_t (1742);
@ -782,7 +782,7 @@ TEST(BinaryStreams7)
TEST(BinaryStreams8)
{
tl::OutputMemoryStream osm;
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << int16_t (1742);
@ -802,7 +802,7 @@ TEST(BinaryStreams8)
TEST(BinaryStreams9)
{
tl::OutputMemoryStream osm;
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << uint32_t (17420000);
@ -822,7 +822,7 @@ TEST(BinaryStreams9)
TEST(BinaryStreams10)
{
tl::OutputMemoryStream osm;
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << int32_t (17420000);
@ -842,7 +842,7 @@ TEST(BinaryStreams10)
TEST(BinaryStreams11)
{
tl::OutputMemoryStream osm;
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << uint64_t (174200000000l);
@ -862,7 +862,7 @@ TEST(BinaryStreams11)
TEST(BinaryStreams12)
{
tl::OutputMemoryStream osm;
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << int64_t (174200000000l);
@ -882,7 +882,7 @@ TEST(BinaryStreams12)
TEST(BinaryStreams13)
{
tl::OutputMemoryStream osm;
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << true;
os << false;
@ -904,7 +904,7 @@ TEST(BinaryStreams13)
TEST(BinaryStreamsCombined)
{
tl::OutputMemoryStream osm;
tl::OutputStream os (osm, false /*binary*/);
tl::BinaryOutputStream os (osm);
os << "ABC" << 17.0 << "XUV" << (int32_t) 42;