diff --git a/src/db/db/db.pro b/src/db/db/db.pro index bcae249bf..d316c1c60 100644 --- a/src/db/db/db.pro +++ b/src/db/db/db.pro @@ -8,6 +8,7 @@ DEFINES += MAKE_DB_LIBRARY SOURCES = \ dbArray.cc \ + dbBinarySerialize.cc \ dbBox.cc \ dbBoxConvert.cc \ dbBoxScanner.cc \ @@ -248,6 +249,7 @@ SOURCES = \ HEADERS = \ dbArray.h \ + dbBinarySerialize.h \ dbBoxConvert.h \ dbBox.h \ dbBoxScanner.h \ diff --git a/src/db/db/dbBinarySerialize.cc b/src/db/db/dbBinarySerialize.cc new file mode 100644 index 000000000..ea92b8ac4 --- /dev/null +++ b/src/db/db/dbBinarySerialize.cc @@ -0,0 +1,31 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2026 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#include "dbBinarySerialize.h" + +namespace db +{ + + // .. nothing yet .. + +} diff --git a/src/db/db/dbBinarySerialize.h b/src/db/db/dbBinarySerialize.h new file mode 100644 index 000000000..93c55505c --- /dev/null +++ b/src/db/db/dbBinarySerialize.h @@ -0,0 +1,573 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2026 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#ifndef HDR_dbBinarySerialize +#define HDR_dbBinarySerialize + +#include "dbCommon.h" + +#include "dbPoint.h" +#include "dbVector.h" +#include "dbEdge.h" +#include "dbEdgePair.h" +#include "dbPolygon.h" +#include "dbBox.h" +#include "dbPath.h" +#include "dbTrans.h" +#include "dbText.h" + +#include "tlStream.h" +#include "tlException.h" + +namespace db +{ + +// ----------------------------------------------------------------------------------------- +// Stream inserters + +template +tl::OutputStream &write_coord (tl::OutputStream &s, C c) +{ + return s << c; +} + +inline tl::OutputStream &write_coord (tl::OutputStream &s, db::Coord c) +{ + // NOTE: for compatibility across different builds we use 64 bit coordinates always + return s << (int64_t) c; +} + +template +tl::OutputStream &write_binary (tl::OutputStream &s, const db::point &pt) +{ + return write_coord (write_coord (s, pt.x ()), pt.y ()); +} + +template +tl::OutputStream &write_binary (tl::OutputStream &s, const db::vector &v) +{ + return write_coord (write_coord (s, v.x ()), v.y ()); +} + +template +tl::OutputStream &operator<< (tl::OutputStream &s, const db::point &pt) +{ + s << (uint16_t) 1; // version + return write_binary (s, pt); +} + +template +tl::OutputStream &operator<< (tl::OutputStream &s, const db::vector &v) +{ + s << (uint16_t) 1; // version + return write_binary (s, v); +} + +template +tl::OutputStream &write_binary (tl::OutputStream &s, const db::edge &e) +{ + write_binary (s, e.p1 ()); + write_binary (s, e.p2 ()); + return s; +} + +template +tl::OutputStream &operator<< (tl::OutputStream &s, const db::edge &e) +{ + s << (uint16_t) 1; // version + return write_binary (s, e); +} + +template +tl::OutputStream &operator<< (tl::OutputStream &s, const db::box &b) +{ + s << (uint16_t) 1; // version + write_binary (s, b.p1 ()); + write_binary (s, b.p2 ()); + return s; +} + +template +tl::OutputStream &operator<< (tl::OutputStream &s, const db::edge_pair &ep) +{ + s << (uint16_t) 1; // version + write_binary (s, ep.first ()); + write_binary (s, ep.second ()); + return s; +} + +template +tl::OutputStream &write_binary (tl::OutputStream &s, const db::polygon_contour &c) +{ + s << (uint64_t) c.size (); + for (auto i = c.begin (); i != c.end (); ++i) { + s << *i; + } + return s; +} + +template +tl::OutputStream &operator<< (tl::OutputStream &s, const db::polygon &p) +{ + s << (uint16_t) 1; // version + s << (uint64_t) (p.holes () + 1); + for (size_t h = 0; h < p.holes () + 1; ++h) { + write_binary (s, p.contour (h)); + } + return s; +} + +template +tl::OutputStream &operator<< (tl::OutputStream &s, const db::simple_polygon &p) +{ + // NOTE: the format of polygon and simple polygon are compatible + s << (uint16_t) 1; // version + s << (uint64_t) 1; // number of contours + write_binary (s, p.hull ()); + return s; +} + +template +tl::OutputStream &operator<< (tl::OutputStream &s, const db::unit_trans &) +{ + s << (uint16_t) 1; // version + return s; +} + +template +tl::OutputStream &operator<< (tl::OutputStream &s, const db::disp_trans &t) +{ + s << (uint16_t) 1; // version + write_binary (s, t.disp ()); + return s; +} + +template +tl::OutputStream &write_binary (tl::OutputStream &s, const db::simple_trans &t) +{ + s << (uint16_t) t.rot (); + write_binary (s, t.disp ()); + return s; +} + +template +tl::OutputStream &operator<< (tl::OutputStream &s, const db::simple_trans &t) +{ + s << (uint16_t) 1; // version + return write_binary (s, t); +} + +template +tl::OutputStream &operator<< (tl::OutputStream &s, const db::complex_trans &t) +{ + s << (uint16_t) 1; // version + write_binary (s, t.disp ()); + return s << (double) t.msin () << (double) t.mcos () << (double) t.mag (); +} + +template +tl::OutputStream &operator<< (tl::OutputStream &s, const db::text &t) +{ + s << (uint16_t) 1; // version + s << t.string (); + write_binary (s, t.trans ()); + write_coord (s, t.size ()); + return s << (int32_t) t.font () << (int32_t) t.halign () << (int32_t) t.valign (); +} + +template +tl::OutputStream &operator<< (tl::OutputStream &s, const db::path &p) +{ + s << (uint16_t) 1; // version + s << (uint64_t) p.points (); + for (auto i = p.begin (); i != p.end (); ++i) { + write_binary (s, *i); + } + write_coord (s, p.width ()); + write_coord (s, p.bgn_ext ()); + write_coord (s, p.end_ext ()); + write_coord (s, p.round ()); + return s; +} + +// ----------------------------------------------------------------------------------------- +// Stream extractors + +class FutureBinarySerializationFormatException + : public tl::Exception +{ +public: + FutureBinarySerializationFormatException () + : tl::Exception (tl::to_string (tr ("Binary serialization format version is too new for this build"))) + { } +}; + +template +tl::BinaryInputStream &read_coord (tl::BinaryInputStream &s, C &c) +{ + return s >> c; +} + +inline tl::BinaryInputStream &read_coord (tl::BinaryInputStream &s, db::Coord &c) +{ + // NOTE: for compatibility across different builds we use 64 bit coordinates always + int64_t cc = 0; + s >> cc; + c = cc; + return s; +} + +template +tl::BinaryInputStream &read_binary (tl::BinaryInputStream &s, db::point &pt) +{ + C x = 0, y = 0; + read_coord (s, x); + read_coord (s, y); + pt = db::point (x, y); + return s; +} + +template +tl::BinaryInputStream &read_binary (tl::BinaryInputStream &s, db::vector &v) +{ + C x = 0, y = 0; + read_coord (s, x); + read_coord (s, y); + v = db::vector (x, y); + return s; +} + +template +tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::point &pt) +{ + uint16_t fmt = 0; + s >> fmt; + if (fmt > 1) { + throw FutureBinarySerializationFormatException (); + } + return read_binary (s, pt); +} + +template +tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::vector &v) +{ + uint16_t fmt = 0; + s >> fmt; + if (fmt > 1) { + throw FutureBinarySerializationFormatException (); + } + return read_binary (s, v); +} + +template +tl::BinaryInputStream &read_binary (tl::BinaryInputStream &s, db::edge &v) +{ + db::point p1, p2; + read_binary (s, p1); + read_binary (s, p2); + v = db::edge (p1, p2); + return s; +} + +template +tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::edge &e) +{ + uint16_t fmt = 0; + s >> fmt; + if (fmt > 1) { + throw FutureBinarySerializationFormatException (); + } + return read_binary (s, e); +} + +template +tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::box &b) +{ + uint16_t fmt = 0; + s >> fmt; + if (fmt > 1) { + throw FutureBinarySerializationFormatException (); + } + + db::point p1, p2; + read_binary (s, p1); + read_binary (s, p2); + b = db::box (p1, p2); + return s; +} + +template +tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::edge_pair &ep) +{ + uint16_t fmt = 0; + s >> fmt; + if (fmt > 1) { + throw FutureBinarySerializationFormatException (); + } + + db::edge e1, e2; + read_binary (s, e1); + read_binary (s, e2); + ep = db::edge_pair (e1, e2); + return s; +} + +template +tl::BinaryInputStream &read_binary (tl::BinaryInputStream &s, db::polygon_contour &c) +{ + uint64_t n = 0; + s >> n; + + std::vector > pts; + pts.reserve (n); + while (n-- > 0) { + pts.push_back (db::point ()); + read_binary (s, pts.back ()); + } + + // NOTE: not normalization or modification is applied + c.assign (pts.begin (), pts.end (), false, false, false); + + return s; +} + +template +tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::polygon &p) +{ + uint16_t fmt = 0; + s >> fmt; + if (fmt > 1) { + throw FutureBinarySerializationFormatException (); + } + + uint64_t n = 0; + s >> n; + + p = db::polygon (); + + db::polygon_contour ctr; + for (uint64_t h = 0; h < n; ++h) { + read_binary (s, ctr); + if (h == 0) { + p.assign_hull (ctr); + } else { + p.insert_hole (ctr); + } + } + + return s; +} + +template +tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::simple_polygon &p) +{ + uint16_t fmt = 0; + s >> fmt; + if (fmt > 1) { + throw FutureBinarySerializationFormatException (); + } + + uint64_t n = 0; + s >> n; + tl_assert (n == (uint64_t) 1); + + db::polygon_contour ctr; + read_binary (s, ctr); + p.assign_hull (ctr); + + return s; +} + +template +tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::unit_trans &) +{ + uint16_t fmt = 0; + s >> fmt; + if (fmt > 1) { + throw FutureBinarySerializationFormatException (); + } + + return s; +} + +template +tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::disp_trans &t) +{ + uint16_t fmt = 0; + s >> fmt; + if (fmt > 1) { + throw FutureBinarySerializationFormatException (); + } + + db::vector d; + read_binary (s, d); + t = db::disp_trans (d); + + return s; +} + +template +tl::BinaryInputStream &read_binary (tl::BinaryInputStream &s, db::simple_trans &t) +{ + uint16_t r = 0; + s >> r; + + db::vector d; + read_binary (s, d); + + t = db::simple_trans (r, d); + return s; +} + +template +tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::simple_trans &t) +{ + uint16_t fmt = 0; + s >> fmt; + if (fmt > 1) { + throw FutureBinarySerializationFormatException (); + } + + return read_binary (s, t); +} + +template +tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::complex_trans &t) +{ + uint16_t fmt = 0; + s >> fmt; + if (fmt > 1) { + throw FutureBinarySerializationFormatException (); + } + + db::vector d; + read_binary (s, d); + + double asin, acos, mag; + s >> asin >> acos >> mag; + + t = db::complex_trans (d, asin, acos, mag); + + return s; +} + +template +tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::text &t) +{ + uint16_t fmt = 0; + s >> fmt; + if (fmt > 1) { + throw FutureBinarySerializationFormatException (); + } + + std::string txt; + s >> txt; + + db::simple_trans tr; + read_binary (s, tr); + + C size; + read_coord (s, size); + + int32_t font, halign, valign; + s >> font >> halign >> valign; + + t = db::text (txt, tr, size, db::Font (font), db::HAlign (halign), db::VAlign (valign)); + return s; +} + +template +tl::BinaryInputStream &operator>> (tl::BinaryInputStream &s, db::path &p) +{ + uint16_t fmt = 0; + s >> fmt; + if (fmt > 1) { + throw FutureBinarySerializationFormatException (); + } + + uint64_t n = 0; + s >> n; + + std::vector > pts; + pts.reserve (n); + while (n-- > 0) { + pts.push_back (db::point ()); + read_binary (s, pts.back ()); + } + + C width, bgn_ext, end_ext; + s >> width >> bgn_ext >> end_ext; + + bool round; + s >> round; + + p = db::path (pts.begin (), pts.end (), width, bgn_ext, end_ext, round); + return s; +} + +// ----------------------------------------------------------------------------------------- +// Converters of objects to a binary string + +template +std::vector to_bytes (const T &t) +{ + tl::OutputMemoryStream osm; + { + tl::OutputStream os (osm, false /*binary*/); + os << t; + } + return std::vector (osm.data (), osm.data () + osm.size ()); +} + +template +std::string to_bytes_str (const T &t) +{ + tl::OutputMemoryStream osm; + { + tl::OutputStream os (osm, false /*binary*/); + os << t; + } + return std::string (osm.data (), osm.size ()); +} + +template +void from_bytes (const char *data, size_t n, T &t) +{ + tl::InputMemoryStream ism (data, n); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + bis >> t; +} + +template +void from_bytes (const std::vector &s, T &t) +{ + tl::InputMemoryStream ism (s.begin ().operator-> (), s.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + bis >> t; +} + +} + +#endif diff --git a/src/db/db/dbTrans.h b/src/db/db/dbTrans.h index 9c93a54bc..cf50a7cb4 100644 --- a/src/db/db/dbTrans.h +++ b/src/db/db/dbTrans.h @@ -1625,6 +1625,17 @@ public: m_mag = s.is_mirror () ? -1.0 : 1.0; } + /** + * @brief Native constructor + * + * This constructor creates the objects from the native parameters (max, acos, asin and displacement) + */ + complex_trans (const vector &disp, R asin, R acos, R mag) + : m_u (disp), m_sin (asin), m_cos (acos), m_mag (mag) + { + // .. nothing yet .. + } + /** * @brief Migration constructor from a simple transformation to a complex transformation * diff --git a/src/db/db/gsiDeclDbBox.cc b/src/db/db/gsiDeclDbBox.cc index 80e3bdfbb..f5572fa16 100644 --- a/src/db/db/gsiDeclDbBox.cc +++ b/src/db/db/gsiDeclDbBox.cc @@ -26,6 +26,7 @@ #include "dbPoint.h" #include "dbBox.h" #include "dbHash.h" +#include "dbBinarySerialize.h" namespace gsi { @@ -50,6 +51,18 @@ struct box_defs return c.release (); } + static C *from_bytes (const std::vector &s) + { + std::unique_ptr c (new C ()); + db::from_bytes (s, *c); + return c.release (); + } + + static std::vector to_bytes (const C *c) + { + return db::to_bytes (*c); + } + static C world () { return C::world (); @@ -533,6 +546,19 @@ struct box_defs "If a DBU is given, the output units will be micrometers.\n" "\n" "The DBU argument has been added in version 0.27.6.\n" + ) + + constructor ("from_bytes", &from_bytes, gsi::arg ("s"), + "@brief Creates a box 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" + ) + + method_ext ("to_bytes", &to_bytes, + "@brief Returns a binary string representing this box\n" + "\n" + "This string can be turned into a box again by using \\from_bytes\n. " + "\n" + "This method has been added in version 0.30.9.\n" ); } }; diff --git a/src/db/db/gsiDeclDbEdge.cc b/src/db/db/gsiDeclDbEdge.cc index c7b348f69..5b25f4073 100644 --- a/src/db/db/gsiDeclDbEdge.cc +++ b/src/db/db/gsiDeclDbEdge.cc @@ -26,6 +26,7 @@ #include "dbPoint.h" #include "dbEdge.h" #include "dbHash.h" +#include "dbBinarySerialize.h" namespace gsi { @@ -53,6 +54,18 @@ struct edge_defs return c.release (); } + static C *from_bytes (const std::vector &s) + { + std::unique_ptr c (new C ()); + db::from_bytes (s, *c); + return c.release (); + } + + static std::vector to_bytes (const C *c) + { + return db::to_bytes (*c); + } + static C *new_v () { return new C (); @@ -446,6 +459,19 @@ struct edge_defs "\n" "The DBU argument has been added in version 0.27.6.\n" ) + + constructor ("from_bytes", &from_bytes, gsi::arg ("s"), + "@brief Creates an edge 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" + ) + + method_ext ("to_bytes", &to_bytes, + "@brief Returns a binary string representing this edge\n" + "\n" + "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" diff --git a/src/db/db/gsiDeclDbEdgePair.cc b/src/db/db/gsiDeclDbEdgePair.cc index 2d9e7a86c..c1953db26 100644 --- a/src/db/db/gsiDeclDbEdgePair.cc +++ b/src/db/db/gsiDeclDbEdgePair.cc @@ -26,6 +26,7 @@ #include "dbEdgePair.h" #include "dbHash.h" +#include "dbBinarySerialize.h" namespace gsi { @@ -50,6 +51,18 @@ struct edge_pair_defs return c.release (); } + static C *from_bytes (const std::vector &s) + { + std::unique_ptr c (new C ()); + db::from_bytes (s, *c); + return c.release (); + } + + static std::vector to_bytes (const C *c) + { + return db::to_bytes (*c); + } + static C *new_v () { return new C (); @@ -167,6 +180,19 @@ struct edge_pair_defs "\n" "The DBU argument has been added in version 0.27.6.\n" ) + + constructor ("from_bytes", &from_bytes, gsi::arg ("s"), + "@brief Creates an edge pair 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" + ) + + method_ext ("to_bytes", &to_bytes, + "@brief Returns a binary string representing this edge pair\n" + "\n" + "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" ) + diff --git a/src/db/db/gsiDeclDbPath.cc b/src/db/db/gsiDeclDbPath.cc index b2b6dae33..8cef53f97 100644 --- a/src/db/db/gsiDeclDbPath.cc +++ b/src/db/db/gsiDeclDbPath.cc @@ -26,6 +26,7 @@ #include "dbPoint.h" #include "dbPath.h" #include "dbHash.h" +#include "dbBinarySerialize.h" namespace gsi { @@ -59,6 +60,18 @@ struct path_defs return c.release (); } + static C *from_bytes (const std::vector &s) + { + std::unique_ptr c (new C ()); + db::from_bytes (s, *c); + return c.release (); + } + + static std::vector to_bytes (const C *c) + { + return db::to_bytes (*c); + } + static C *new_v () { return new C (); @@ -284,6 +297,19 @@ struct path_defs method ("to_s", (std::string (C::*) () const) &C::to_string, "@brief Convert to a string\n" ) + + constructor ("from_bytes", &from_bytes, gsi::arg ("s"), + "@brief Creates a path 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" + ) + + method_ext ("to_bytes", &to_bytes, + "@brief Returns a binary string representing this path\n" + "\n" + "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 " diff --git a/src/db/db/gsiDeclDbPoint.cc b/src/db/db/gsiDeclDbPoint.cc index 80b65c4b1..de391726c 100644 --- a/src/db/db/gsiDeclDbPoint.cc +++ b/src/db/db/gsiDeclDbPoint.cc @@ -25,6 +25,7 @@ #include "dbPoint.h" #include "dbBox.h" #include "dbHash.h" +#include "dbBinarySerialize.h" namespace gsi { @@ -46,6 +47,18 @@ struct point_defs return c.release (); } + static C *from_bytes (const std::vector &s) + { + std::unique_ptr c (new C ()); + db::from_bytes (s, *c); + return c.release (); + } + + static std::vector to_bytes (const C *c) + { + return db::to_bytes (*c); + } + static C *new_v () { return new C (); @@ -320,6 +333,19 @@ struct point_defs "If a DBU is given, the output units will be micrometers.\n" "\n" "The DBU argument has been added in version 0.27.6.\n" + ) + + constructor ("from_bytes", &from_bytes, gsi::arg ("s"), + "@brief Creates a point 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" + ) + + method_ext ("to_bytes", &to_bytes, + "@brief Returns a binary string representing this point\n" + "\n" + "This string can be turned into a point again by using \\from_bytes\n. " + "\n" + "This method has been added in version 0.30.9.\n" ); } diff --git a/src/db/db/gsiDeclDbPolygon.cc b/src/db/db/gsiDeclDbPolygon.cc index 41b6b205a..be2023eb4 100644 --- a/src/db/db/gsiDeclDbPolygon.cc +++ b/src/db/db/gsiDeclDbPolygon.cc @@ -30,6 +30,7 @@ #include "dbHash.h" #include "dbPLCTriangulation.h" #include "dbPLCConvexDecomposition.h" +#include "dbBinarySerialize.h" namespace gsi { @@ -307,6 +308,18 @@ struct simple_polygon_defs return c.release (); } + static C *from_bytes (const std::vector &s) + { + std::unique_ptr c (new C ()); + db::from_bytes (s, *c); + return c.release (); + } + + static std::vector to_bytes (const C *c) + { + return db::to_bytes (*c); + } + static C *new_v () { return new C; @@ -702,6 +715,19 @@ struct simple_polygon_defs method ("to_s", (std::string (C::*) () const) &C::to_string, "@brief Returns a string representing the polygon\n" ) + + constructor ("from_bytes", &from_bytes, gsi::arg ("s"), + "@brief Creates a polygon 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" + ) + + method_ext ("to_bytes", &to_bytes, + "@brief Returns a binary string representing this polygon\n" + "\n" + "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" @@ -1298,6 +1324,18 @@ struct polygon_defs return c.release (); } + static C *from_bytes (const std::vector &s) + { + std::unique_ptr c (new C ()); + db::from_bytes (s, *c); + return c.release (); + } + + static std::vector to_bytes (const C *c) + { + return db::to_bytes (*c); + } + static C *new_v () { return new C; @@ -1854,6 +1892,19 @@ struct polygon_defs method ("to_s", (std::string (C::*) () const) &C::to_string, "@brief Returns a string representing the polygon\n" ) + + constructor ("from_bytes", &from_bytes, gsi::arg ("s"), + "@brief Creates a polygon 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" + ) + + method_ext ("to_bytes", &to_bytes, + "@brief Returns a binary string representing this polygon\n" + "\n" + "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" diff --git a/src/db/db/gsiDeclDbText.cc b/src/db/db/gsiDeclDbText.cc index 118e7474c..7f88d763e 100644 --- a/src/db/db/gsiDeclDbText.cc +++ b/src/db/db/gsiDeclDbText.cc @@ -27,6 +27,7 @@ #include "dbPoint.h" #include "dbText.h" #include "dbHash.h" +#include "dbBinarySerialize.h" namespace gsi { @@ -52,6 +53,18 @@ struct text_defs return c.release (); } + static C *from_bytes (const std::vector &s) + { + std::unique_ptr c (new C ()); + db::from_bytes (s, *c); + return c.release (); + } + + static std::vector to_bytes (const C *c) + { + return db::to_bytes (*c); + } + static C *new_v () { return new C (); @@ -397,6 +410,19 @@ struct text_defs "If a DBU is given, the output units will be micrometers.\n" "\n" "The DBU argument has been added in version 0.27.6.\n" + ) + + constructor ("from_bytes", &from_bytes, gsi::arg ("s"), + "@brief Creates a text 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" + ) + + method_ext ("to_bytes", &to_bytes, + "@brief Returns a binary string representing this text object\n" + "\n" + "This string can be turned into a text object again by using \\from_bytes\n. " + "\n" + "This method has been added in version 0.30.9.\n" ); } }; diff --git a/src/db/db/gsiDeclDbTrans.cc b/src/db/db/gsiDeclDbTrans.cc index 917fa60fe..213fdd512 100644 --- a/src/db/db/gsiDeclDbTrans.cc +++ b/src/db/db/gsiDeclDbTrans.cc @@ -29,6 +29,7 @@ #include "dbPath.h" #include "dbText.h" #include "dbHash.h" +#include "dbBinarySerialize.h" namespace gsi { @@ -98,6 +99,18 @@ struct trans_defs return c.release (); } + static C *from_bytes (const std::vector &s) + { + std::unique_ptr c (new C ()); + db::from_bytes (s, *c); + return c.release (); + } + + static std::vector to_bytes (const C *c) + { + return db::to_bytes (*c); + } + static C *new_v () { return new C (); @@ -518,6 +531,19 @@ struct trans_defs "\n" "The DBU argument has been added in version 0.27.6.\n" ) + + 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" + ) + + 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" + ); method ("disp", (const vector_type &(C::*) () const) &C::disp, "@brief Gets to the displacement vector\n" "\n" @@ -736,6 +762,18 @@ struct cplx_trans_defs return c.release (); } + static C *from_bytes (const std::vector &s) + { + std::unique_ptr c (new C ()); + db::from_bytes (s, *c); + return c.release (); + } + + static std::vector to_bytes (const C *c) + { + return db::to_bytes (*c); + } + static C *new_v () { return new C (); @@ -1139,6 +1177,19 @@ struct cplx_trans_defs "\n" "The lazy and DBU arguments have been added in version 0.27.6.\n" ) + + 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" + ) + + 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" + ); method ("disp", (displacement_type (C::*)() const) &C::disp, "@brief Gets the displacement\n" ) + diff --git a/src/db/db/gsiDeclDbVector.cc b/src/db/db/gsiDeclDbVector.cc index 6946f5ac8..25b22fd4d 100644 --- a/src/db/db/gsiDeclDbVector.cc +++ b/src/db/db/gsiDeclDbVector.cc @@ -25,6 +25,7 @@ #include "dbVector.h" #include "dbPoint.h" #include "dbHash.h" +#include "dbBinarySerialize.h" namespace gsi { @@ -45,6 +46,18 @@ struct vector_defs return c.release (); } + static C *from_bytes (const std::vector &s) + { + std::unique_ptr c (new C ()); + db::from_bytes (s, *c); + return c.release (); + } + + static std::vector to_bytes (const C *c) + { + return db::to_bytes (*c); + } + static C *new_v () { return new C (); @@ -275,6 +288,19 @@ struct vector_defs "If a DBU is given, the output units will be micrometers.\n" "\n" "The DBU argument has been added in version 0.27.6.\n" + ) + + constructor ("from_bytes", &from_bytes, gsi::arg ("s"), + "@brief Creates a vector 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" + ) + + method_ext ("to_bytes", &to_bytes, + "@brief Returns a binary string representing this vector\n" + "\n" + "This string can be turned into a vector again by using \\from_bytes\n. " + "\n" + "This method has been added in version 0.30.9.\n" ); } diff --git a/src/laybasic/laybasic/layBitmap.cc b/src/laybasic/laybasic/layBitmap.cc index c17ffda7e..d919bd0b2 100644 --- a/src/laybasic/laybasic/layBitmap.cc +++ b/src/laybasic/laybasic/layBitmap.cc @@ -298,7 +298,7 @@ Bitmap::fill_pattern (int y, int x, const uint32_t *pp, unsigned int stride, uns uint32_t p = *pp; int x1 = x + s * 32; - if (x1 <= -32 || x1 >= m_width) { + if (x1 <= -32 || x1 >= (int)m_width) { continue; } else if (x1 < 0) { p >>= (unsigned int)-x1; diff --git a/src/tl/tl/tlBinaryStream.cc b/src/tl/tl/tlBinaryStream.cc new file mode 100644 index 000000000..e69de29bb diff --git a/src/tl/tl/tlBinaryStream.h b/src/tl/tl/tlBinaryStream.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/tl/tl/tlStream.cc b/src/tl/tl/tlStream.cc index 4e52db055..214e5914a 100644 --- a/src/tl/tl/tlStream.cc +++ b/src/tl/tl/tlStream.cc @@ -133,6 +133,15 @@ public: { } }; +class UnexpectedEndOfFileException + : public tl::Exception +{ +public: + UnexpectedEndOfFileException (const std::string &f) + : tl::Exception (tl::to_string (tr ("Unexpected end of file: %s")), f) + { } +}; + // --------------------------------------------------------------- class ZLibFilePrivate @@ -920,6 +929,183 @@ TextInputStream::reset () } } +// --------------------------------------------------------------- + +BinaryInputStream::BinaryInputStream (InputStream &stream) + : m_stream (stream) +{ + // .. nothing yet .. +} + +void +BinaryInputStream::reset () +{ + m_stream.reset (); +} + +BinaryInputStream & +BinaryInputStream::operator>> (std::string &v) +{ + uint64_t l = 0; + *this >> l; + + v.clear (); + v.reserve (l); + + size_t chunk_size = 1024, n = l; + while (n > 0) { + size_t chunk_len = std::min (n, chunk_size); + const char *chunk_data = m_stream.get (chunk_len); + if (! chunk_data) { + throw UnexpectedEndOfFileException (source ()); + } + v.append (chunk_data, chunk_len); + n -= chunk_len; + } + + return *this; +} + +BinaryInputStream & +BinaryInputStream::operator>> (double &v) +{ + const char *chunk_data = m_stream.get (8); + if (! chunk_data) { + throw UnexpectedEndOfFileException (source ()); + } + // TODO: for now, we assume that file and memory layout are identical on all platforms + v = *reinterpret_cast (chunk_data); + + return *this; +} + +BinaryInputStream & +BinaryInputStream::operator>> (float &v) +{ + const char *chunk_data = m_stream.get (4); + if (! chunk_data) { + throw UnexpectedEndOfFileException (source ()); + } + // TODO: for now, we assume that file and memory layout are identical on all platforms + v = *reinterpret_cast (chunk_data); + + return *this; +} + +BinaryInputStream & +BinaryInputStream::operator>> (bool &v) +{ + const char *chunk_data = m_stream.get (1); + if (! chunk_data) { + throw UnexpectedEndOfFileException (source ()); + } + v = *chunk_data != 0; + + return *this; +} + +BinaryInputStream & +BinaryInputStream::operator>> (uint8_t &v) +{ + const char *chunk_data = m_stream.get (1); + if (! chunk_data) { + throw UnexpectedEndOfFileException (source ()); + } + v = (uint8_t) *chunk_data; + + return *this; +} + +BinaryInputStream & +BinaryInputStream::operator>> (int8_t &v) +{ + const char *chunk_data = m_stream.get (1); + if (! chunk_data) { + throw UnexpectedEndOfFileException (source ()); + } + v = (int8_t) *chunk_data; + + return *this; +} + +BinaryInputStream & +BinaryInputStream::operator>> (uint16_t &v) +{ + const char *chunk_data = m_stream.get (2); + if (! chunk_data) { + throw UnexpectedEndOfFileException (source ()); + } + // TODO: for now, we assume that file and memory layout are identical on all platforms + v = *reinterpret_cast (chunk_data); + + return *this; +} + +BinaryInputStream & +BinaryInputStream::operator>> (int16_t &v) +{ + const char *chunk_data = m_stream.get (2); + if (! chunk_data) { + throw UnexpectedEndOfFileException (source ()); + } + // TODO: for now, we assume that file and memory layout are identical on all platforms + v = *reinterpret_cast (chunk_data); + + return *this; +} + +BinaryInputStream & +BinaryInputStream::operator>> (uint32_t &v) +{ + const char *chunk_data = m_stream.get (4); + if (! chunk_data) { + throw UnexpectedEndOfFileException (source ()); + } + // TODO: for now, we assume that file and memory layout are identical on all platforms + v = *reinterpret_cast (chunk_data); + + return *this; +} + +BinaryInputStream & +BinaryInputStream::operator>> (int32_t &v) +{ + const char *chunk_data = m_stream.get (4); + if (! chunk_data) { + throw UnexpectedEndOfFileException (source ()); + } + // TODO: for now, we assume that file and memory layout are identical on all platforms + v = *reinterpret_cast (chunk_data); + + return *this; +} + +BinaryInputStream & +BinaryInputStream::operator>> (uint64_t &v) +{ + const char *chunk_data = m_stream.get (8); + if (! chunk_data) { + throw UnexpectedEndOfFileException (source ()); + } + // TODO: for now, we assume that file and memory layout are identical on all platforms + v = *reinterpret_cast (chunk_data); + + return *this; +} + +BinaryInputStream & +BinaryInputStream::operator>> (int64_t &v) +{ + const char *chunk_data = m_stream.get (8); + if (! chunk_data) { + throw UnexpectedEndOfFileException (source ()); + } + // TODO: for now, we assume that file and memory layout are identical on all platforms + v = *reinterpret_cast (chunk_data); + + return *this; +} + // --------------------------------------------------------------- // InputFile implementation @@ -1282,6 +1468,101 @@ OutputStream::put_raw (const char *b, size_t n) } } +void +OutputStream::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 + uint64_t len = uint64_t (n); + put_raw ((const char *) &len, 8); + put_raw (s, n); +} + +void +OutputStream::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 + uint64_t len = uint64_t (s.size ()); + put_raw ((const char *) &len, 8); + put_raw (s.c_str (), s.size ()); +} + +void +OutputStream::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) +{ + // 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) +{ + char c = v ? 1 : 0; + put_raw (&c, 1); +} + +void +OutputStream::put_native (uint8_t v) +{ + put_raw ((const char *) &v, 1); +} + +void +OutputStream::put_native (int8_t v) +{ + put_raw ((const char *) &v, 1); +} + +void +OutputStream::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) +{ + // 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) +{ + // 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) +{ + // 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) +{ + // 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) +{ + // 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) { diff --git a/src/tl/tl/tlStream.h b/src/tl/tl/tlStream.h index 70fac833c..05285de14 100644 --- a/src/tl/tl/tlStream.h +++ b/src/tl/tl/tlStream.h @@ -730,7 +730,7 @@ public: } /** - * @brief Get a single line (presumably UTF8 encoded) + * @brief Gets a single line (presumably UTF8 encoded) */ const std::string &get_line (); @@ -747,7 +747,7 @@ public: std::string read_all (size_t max_count); /** - * @brief Get a single character + * @brief Gets a single character */ char get_char (); @@ -757,14 +757,14 @@ public: char peek_char (); /** - * @brief Skip blanks, newlines etc. + * @brief Skips blanks, newlines etc. * * Returns the following character without getting it. */ char skip (); /** - * @brief Get the source specification + * @brief Gets the source specification */ std::string source () const { @@ -772,7 +772,7 @@ public: } /** - * @brief Get the current line number + * @brief Gets the current line number */ size_t line_number () { @@ -780,7 +780,7 @@ public: } /** - * @brief Return false, if no more characters can be obtained + * @brief Returns false, if no more characters can be obtained */ bool at_end () const { @@ -788,7 +788,7 @@ public: } /** - * @brief Reset to the initial position + * @brief Resets to the initial position */ void reset (); @@ -805,6 +805,69 @@ private: // --------------------------------------------------------------------------------- +/** + * @brief A binary input stream + * + * This class is put in front of a InputStream to retrieve binary primitives from the stream. + * The binary format corresponds to binary mode of OutputStream. + */ +class TL_PUBLIC BinaryInputStream +{ +public: + /** + * @brief Default constructor + * + * This constructor takes a delegate object. + */ + BinaryInputStream (InputStream &stream); + + /** + * @brief Gets the raw stream + */ + InputStream &raw_stream () + { + return m_stream; + } + + /** + * @brief Get the source specification + */ + std::string source () const + { + return m_stream.source (); + } + + /** + * @brief Gets a value of a specific type + */ + BinaryInputStream &operator>> (std::string &v); + BinaryInputStream &operator>> (double &v); + BinaryInputStream &operator>> (float &v); + BinaryInputStream &operator>> (bool &v); + BinaryInputStream &operator>> (uint8_t &v); + BinaryInputStream &operator>> (int8_t &v); + BinaryInputStream &operator>> (uint16_t &v); + BinaryInputStream &operator>> (int16_t &v); + BinaryInputStream &operator>> (uint32_t &v); + BinaryInputStream &operator>> (int32_t &v); + BinaryInputStream &operator>> (uint64_t &v); + BinaryInputStream &operator>> (int64_t &v); + + /** + * @brief Resets to the initial position + */ + void reset (); + +private: + InputStream &m_stream; + + // no copying + BinaryInputStream (const BinaryInputStream &); + BinaryInputStream &operator= (const BinaryInputStream &); +}; + +// --------------------------------------------------------------------------------- + /** * @brief The output stream delegate base class * @@ -880,9 +943,9 @@ public: /** * @brief Create a string writer */ - OutputMemoryStream () + OutputMemoryStream (size_t initial_alloc = 65536) { - m_buffer.reserve (65336); + m_buffer.reserve (initial_alloc); } /** @@ -1312,13 +1375,20 @@ public: void close (); /** - * @brief This is the outer write method to call + * @brief Puts a string into the stream * - * This implementation writes data through the - * protected write call. + * In text mode, this handles line separator conversion. + * In binary mode, this method is equivalent to "put_raw". */ void put (const char *b, size_t n); + /** + * @brief Puts the raw bytes into the stream + * + * This method bypasses the line feed translation. + */ + void put_raw (const char *b, size_t n); + /** * @brief Puts a C string (UTF-8) to the output */ @@ -1336,7 +1406,7 @@ public: } /** - * @brief << operator + * @brief << operator: inserts character */ OutputStream &operator<< (char s) { @@ -1345,7 +1415,7 @@ public: } /** - * @brief << operator + * @brief << operator: inserts a character */ OutputStream &operator<< (unsigned char s) { @@ -1354,30 +1424,48 @@ public: } /** - * @brief << operator + * @brief << operator: inserts a string + * + * In binary mode, the string is inserted as a length/data + * combination. That matches the extraction in BinaryInputStream. */ OutputStream &operator<< (const char *s) { - put (s); + if (m_as_text) { + put (s, strlen (s)); + } else { + put_native (s, strlen (s)); + } return *this; } /** - * @brief << operator + * @brief << operator: inserts a string + * + * In binary mode, the string is inserted as a length/data + * combination. That matches the extraction in BinaryInputStream. */ OutputStream &operator<< (const std::string &s) { - put (s); + if (m_as_text) { + put (s); + } else { + put_native (s); + } return *this; } /** - * @brief << operator + * @brief << operator: inserts an object supported by "put_native". */ template OutputStream &operator<< (const T &t) { - put (tl::to_string (t)); + if (m_as_text) { + put (tl::to_string (t)); + } else { + put_native (t); + } return *this; } @@ -1456,7 +1544,19 @@ private: size_t m_buffer_capacity, m_buffer_pos; std::string m_path; - void put_raw (const char *b, size_t n); + void put_native (const std::string &s); + void put_native (const char *s, size_t n); + void put_native (double v); + void put_native (float v); + void put_native (bool v); + void put_native (uint8_t v); + void put_native (int8_t v); + void put_native (uint16_t v); + void put_native (int16_t v); + void put_native (uint32_t v); + void put_native (int32_t v); + void put_native (uint64_t v); + void put_native (int64_t v); // No copying currently OutputStream (const OutputStream &); diff --git a/src/tl/unit_tests/tlStreamTests.cc b/src/tl/unit_tests/tlStreamTests.cc index 4396a102f..490814a7a 100644 --- a/src/tl/unit_tests/tlStreamTests.cc +++ b/src/tl/unit_tests/tlStreamTests.cc @@ -66,7 +66,7 @@ TEST(OutputPipe1) { tl::OutputPipe pipe ("cat >" + tf); tl::OutputStream str (pipe); - str << "Hello, world!"; + str.put ("Hello, world!"); } { @@ -82,7 +82,7 @@ TEST(TextOutputStream) { tl::OutputStream os (fn, tl::OutputStream::OM_Auto, false); - os << "Hello, world!\nWith another line\n\r\r\nseparated by a LFCR and CRLF."; + os.put ("Hello, world!\nWith another line\n\r\r\nseparated by a LFCR and CRLF."); } { @@ -140,7 +140,7 @@ TEST(TextInputStream) { tl::OutputStream os (fn, tl::OutputStream::OM_Auto, false); - os << "Hello, world!\nWith another line\n\r\r\nseparated by a LFCR and CRLF."; + os.put ("Hello, world!\nWith another line\n\r\r\nseparated by a LFCR and CRLF."); } { @@ -242,7 +242,7 @@ TEST(SafeOutput) { tl::OutputStream os (tp); - os << "blabla\n"; + os.put ("blabla\n"); } EXPECT_EQ (tl::file_exists (tp + ".~backup"), false); @@ -252,7 +252,7 @@ TEST(SafeOutput) tl::OutputStream os (tp); EXPECT_EQ (tl::file_exists (tp + ".~backup"), true); EXPECT_EQ (tl::file_exists (tp), true); - os << "Hello, world!\n"; + os.put ("Hello, world!\n"); } EXPECT_EQ (tl::file_exists (tp + ".~backup"), false); @@ -268,7 +268,7 @@ TEST(SafeOutput) tl::OutputStream os (broken); EXPECT_EQ (tl::file_exists (tp + ".~backup"), true); EXPECT_EQ (tl::file_exists (tp), true); - os << "Hi!\n"; + os.put ("Hi!\n"); os.flush (); // raises the exception EXPECT_EQ (true, false); } catch (...) { @@ -291,7 +291,7 @@ TEST(SafeOutput) tl::OutputStream os (broken); EXPECT_EQ (tl::file_exists (tp + ".~backup"), true); EXPECT_EQ (tl::file_exists (tp), true); - os << "Hi!\n"; + os.put ("Hi!\n"); os.flush (); // raises the exception EXPECT_EQ (true, false); } catch (...) { @@ -323,7 +323,7 @@ TEST(SafeOutput2) { tl::OutputStream os (tp); - os << "blabla\n"; + os.put ("blabla\n"); } EXPECT_EQ (tl::file_exists (tp + ".~backup"), false); @@ -333,7 +333,7 @@ TEST(SafeOutput2) tl::OutputStream os (tp); EXPECT_EQ (tl::file_exists (tp + ".~backup"), true); EXPECT_EQ (tl::file_exists (tp), true); - os << "Hello, world!\n"; + os.put ("Hello, world!\n"); } EXPECT_EQ (tl::file_exists (tp + ".~backup"), false); @@ -358,7 +358,7 @@ TEST(Backups) { tl::OutputStream os (tp, tl::OutputStream::OM_Auto, false, 2); - os << "1\n"; + os.put ("1\n"); } EXPECT_EQ (tl::file_exists (tp + ".~backup"), false); @@ -376,7 +376,7 @@ TEST(Backups) tl::OutputStream os (tp, tl::OutputStream::OM_Auto, false, 2); EXPECT_EQ (tl::file_exists (tp + ".~backup"), true); EXPECT_EQ (tl::file_exists (tp), true); - os << "2\n"; + os.put ("2\n"); } EXPECT_EQ (tl::file_exists (tp + ".~backup"), false); @@ -399,7 +399,7 @@ TEST(Backups) tl::OutputStream os (tp, tl::OutputStream::OM_Auto, false, 2); EXPECT_EQ (tl::file_exists (tp + ".~backup"), true); EXPECT_EQ (tl::file_exists (tp), true); - os << "3\n"; + os.put ("3\n"); } EXPECT_EQ (tl::file_exists (tp + ".~backup"), false); @@ -427,7 +427,7 @@ TEST(Backups) tl::OutputStream os (tp, tl::OutputStream::OM_Auto, false, 2); EXPECT_EQ (tl::file_exists (tp + ".~backup"), true); EXPECT_EQ (tl::file_exists (tp), true); - os << "4\n"; + os.put ("4\n"); } EXPECT_EQ (tl::file_exists (tp + ".~backup"), false); @@ -456,7 +456,7 @@ TEST(Backups) tl::OutputStream os (broken); EXPECT_EQ (tl::file_exists (tp + ".~backup"), true); EXPECT_EQ (tl::file_exists (tp), true); - os << "5!\n"; + os.put ("5!\n"); os.flush (); // raises the exception EXPECT_EQ (true, false); } catch (...) { @@ -624,3 +624,304 @@ TEST(MatchFormat) EXPECT_EQ (tl::match_filename_to_format ("abc.TEXT", "Text files (*.txt *.TXT)"), false); EXPECT_EQ (tl::match_filename_to_format ("abc.TEXT", "Text files (*)"), true); } + +std::string s2string (tl::OutputMemoryStream &osm) +{ + std::string res; + size_t n = osm.size (); + const char *d = osm.data (); + for (size_t i = 0; i < n; ++i, ++d) { + if (i > 0) { + res += ","; + } + res += tl::sprintf ("0x%02x", int ((unsigned char) *d)); + } + return res; +} + +TEST(BinaryStreams1) +{ + tl::OutputMemoryStream osm; + tl::OutputStream os (osm, false /*binary*/); + + os << (double) 0.17; + + os.flush (); + EXPECT_EQ (s2string (osm), "0xc3,0xf5,0x28,0x5c,0x8f,0xc2,0xc5,0x3f"); + + tl::InputMemoryStream ism (osm.data (), osm.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + + double x = 0.0; + bis >> x; + + EXPECT_EQ (tl::to_string (x), "0.17"); +} + +TEST(BinaryStreams2) +{ + tl::OutputMemoryStream osm; + tl::OutputStream os (osm, false /*binary*/); + + os << (float) 0.17; + + os.flush (); + EXPECT_EQ (s2string (osm), "0x7b,0x14,0x2e,0x3e"); + + tl::InputMemoryStream ism (osm.data (), osm.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + + float x = 0.0; + bis >> x; + + EXPECT_EQ (tl::to_string (x), "0.17"); +} + +TEST(BinaryStreams3) +{ + tl::OutputMemoryStream osm; + tl::OutputStream os (osm, false /*binary*/); + + os << std::string ("ABC"); + + os.flush (); + EXPECT_EQ (s2string (osm), "0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x42,0x43"); + + tl::InputMemoryStream ism (osm.data (), osm.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + + std::string x; + bis >> x; + + EXPECT_EQ (x, "ABC"); +} + +TEST(BinaryStreams4) +{ + tl::OutputMemoryStream osm; + tl::OutputStream os (osm, false /*binary*/); + + os << "ABC"; + + os.flush (); + EXPECT_EQ (s2string (osm), "0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x42,0x43"); + + tl::InputMemoryStream ism (osm.data (), osm.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + + std::string x; + bis >> x; + + EXPECT_EQ (x, "ABC"); +} + +TEST(BinaryStreams5) +{ + tl::OutputMemoryStream osm; + tl::OutputStream os (osm, false /*binary*/); + + os << uint8_t (17); + + os.flush (); + EXPECT_EQ (s2string (osm), "0x11"); + + tl::InputMemoryStream ism (osm.data (), osm.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + + uint8_t x; + bis >> x; + + EXPECT_EQ (x, 17); +} + +TEST(BinaryStreams6) +{ + tl::OutputMemoryStream osm; + tl::OutputStream os (osm, false /*binary*/); + + os << int8_t (17); + + os.flush (); + EXPECT_EQ (s2string (osm), "0x11"); + + tl::InputMemoryStream ism (osm.data (), osm.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + + int8_t x; + bis >> x; + + EXPECT_EQ (x, 17); +} + +TEST(BinaryStreams7) +{ + tl::OutputMemoryStream osm; + tl::OutputStream os (osm, false /*binary*/); + + os << uint16_t (1742); + + os.flush (); + EXPECT_EQ (s2string (osm), "0xce,0x06"); + + tl::InputMemoryStream ism (osm.data (), osm.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + + uint16_t x; + bis >> x; + + EXPECT_EQ (x, 1742); +} + +TEST(BinaryStreams8) +{ + tl::OutputMemoryStream osm; + tl::OutputStream os (osm, false /*binary*/); + + os << int16_t (1742); + + os.flush (); + EXPECT_EQ (s2string (osm), "0xce,0x06"); + + tl::InputMemoryStream ism (osm.data (), osm.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + + int16_t x; + bis >> x; + + EXPECT_EQ (x, 1742); +} + +TEST(BinaryStreams9) +{ + tl::OutputMemoryStream osm; + tl::OutputStream os (osm, false /*binary*/); + + os << uint32_t (17420000); + + os.flush (); + EXPECT_EQ (s2string (osm), "0xe0,0xce,0x09,0x01"); + + tl::InputMemoryStream ism (osm.data (), osm.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + + uint32_t x; + bis >> x; + + EXPECT_EQ (x, 17420000u); +} + +TEST(BinaryStreams10) +{ + tl::OutputMemoryStream osm; + tl::OutputStream os (osm, false /*binary*/); + + os << int32_t (17420000); + + os.flush (); + EXPECT_EQ (s2string (osm), "0xe0,0xce,0x09,0x01"); + + tl::InputMemoryStream ism (osm.data (), osm.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + + int32_t x; + bis >> x; + + EXPECT_EQ (x, 17420000); +} + +TEST(BinaryStreams11) +{ + tl::OutputMemoryStream osm; + tl::OutputStream os (osm, false /*binary*/); + + os << uint64_t (174200000000l); + + os.flush (); + EXPECT_EQ (s2string (osm), "0x00,0x0e,0x21,0x8f,0x28,0x00,0x00,0x00"); + + tl::InputMemoryStream ism (osm.data (), osm.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + + uint64_t x; + bis >> x; + + EXPECT_EQ (x, 174200000000lu); +} + +TEST(BinaryStreams12) +{ + tl::OutputMemoryStream osm; + tl::OutputStream os (osm, false /*binary*/); + + os << int64_t (174200000000l); + + os.flush (); + EXPECT_EQ (s2string (osm), "0x00,0x0e,0x21,0x8f,0x28,0x00,0x00,0x00"); + + tl::InputMemoryStream ism (osm.data (), osm.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + + int64_t x; + bis >> x; + + EXPECT_EQ (x, 174200000000l); +} + +TEST(BinaryStreams13) +{ + tl::OutputMemoryStream osm; + tl::OutputStream os (osm, false /*binary*/); + + os << true; + os << false; + + os.flush (); + EXPECT_EQ (s2string (osm), "0x01,0x00"); + + tl::InputMemoryStream ism (osm.data (), osm.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + + bool x = false, y = false; + bis >> x >> y; + + EXPECT_EQ (x, true); + EXPECT_EQ (y, false); +} + +TEST(BinaryStreamsCombined) +{ + tl::OutputMemoryStream osm; + tl::OutputStream os (osm, false /*binary*/); + + os << "ABC" << 17.0 << "XUV" << (int32_t) 42; + + os.flush (); + + tl::InputMemoryStream ism (osm.data (), osm.size ()); + tl::InputStream is (ism); + tl::BinaryInputStream bis (is); + + std::string a, c; + double b = 0.0; + int32_t d = 0; + + bis >> a >> b >> c >> d; + + EXPECT_EQ (a, "ABC"); + EXPECT_EQ (b, 17.0); + EXPECT_EQ (c, "XUV"); + EXPECT_EQ (d, 42); +} diff --git a/testdata/ruby/dbBoxTest.rb b/testdata/ruby/dbBoxTest.rb index 537c8c047..5c440098a 100644 --- a/testdata/ruby/dbBoxTest.rb +++ b/testdata/ruby/dbBoxTest.rb @@ -41,6 +41,7 @@ class DBBox_TestClass < TestBase a = RBA::DBox::new( -10, 21, 11, 17 ) assert_equal( a.to_s, "(-10,17;11,21)" ) assert_equal( RBA::DBox::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::DBox::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( (a*0.5).to_s, "(-5,8.5;5.5,10.5)" ) b = a @@ -263,6 +264,7 @@ class DBBox_TestClass < TestBase a = RBA::Box::new( -10, 21, 11, 17 ) assert_equal( a.to_s, "(-10,17;11,21)" ) assert_equal( RBA::Box::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::Box::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( (a*2).to_s, "(-20,34;22,42)" ) b = a diff --git a/testdata/ruby/dbEdgePairTest.rb b/testdata/ruby/dbEdgePairTest.rb index 2a02a05ad..bfcfbe5b4 100644 --- a/testdata/ruby/dbEdgePairTest.rb +++ b/testdata/ruby/dbEdgePairTest.rb @@ -40,6 +40,9 @@ class DBEdgePair_TestClass < TestBase assert_equal(ep.to_s, "(0,0;10,20)/(-10,0;-10,30)") assert_equal(ep.bbox.to_s, "(-10,0;10,30)") + assert_equal(RBA::EdgePair::from_s(ep.to_s).to_s, ep.to_s) + assert_equal(RBA::EdgePair::from_bytes(ep.to_bytes).to_s, ep.to_s) + assert_equal(RBA::EdgePair::new(ep.first, ep.second).to_s, "(0,0;10,20)/(-10,0;-10,30)") ep2 = RBA::EdgePair::new @@ -91,6 +94,9 @@ class DBEdgePair_TestClass < TestBase assert_equal(ep.to_s, "(0,0;10,20)/(-10,0;-10,30)") assert_equal(ep.bbox.to_s, "(-10,0;10,30)") + assert_equal(RBA::DEdgePair::from_s(ep.to_s).to_s, ep.to_s) + assert_equal(RBA::DEdgePair::from_bytes(ep.to_bytes).to_s, ep.to_s) + assert_equal(RBA::DEdgePair::new(ep.first, ep.second).to_s, "(0,0;10,20)/(-10,0;-10,30)") ep2 = RBA::DEdgePair::new diff --git a/testdata/ruby/dbEdgeTest.rb b/testdata/ruby/dbEdgeTest.rb index 09623dce3..3e6c8271c 100644 --- a/testdata/ruby/dbEdgeTest.rb +++ b/testdata/ruby/dbEdgeTest.rb @@ -36,6 +36,7 @@ class DBEdge_TestClass < TestBase a = RBA::DEdge::new( -1, 2, 15, -7 ) assert_equal( a.to_s, "(-1,2;15,-7)" ) assert_equal( RBA::DEdge::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::DEdge::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( (a*0.5).to_s, "(-0.5,1;7.5,-3.5)" ) d = RBA::Edge::new( a ) assert_equal( d.to_s, "(-1,2;15,-7)" ) @@ -156,6 +157,7 @@ class DBEdge_TestClass < TestBase a = RBA::Edge::new( RBA::Point::new( -1, 2 ), RBA::Point::new( 15, -7 ) ) assert_equal( a.to_s, "(-1,2;15,-7)" ) assert_equal( RBA::Edge::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::Edge::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( (a*2).to_s, "(-2,4;30,-14)" ) d = RBA::DEdge::new( a ) assert_equal( d.to_s, "(-1,2;15,-7)" ) diff --git a/testdata/ruby/dbPathTest.rb b/testdata/ruby/dbPathTest.rb index 199d808b2..f3bd55e97 100644 --- a/testdata/ruby/dbPathTest.rb +++ b/testdata/ruby/dbPathTest.rb @@ -33,6 +33,7 @@ class DBPath_TestClass < TestBase assert_equal( a.area.to_s, "0.0" ) assert_equal( a.length.to_s, "0.0" ) assert_equal( RBA::DPath::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::DPath::from_bytes(a.to_bytes).to_s, a.to_s ) b = a.dup a = RBA::DPath::new( [ RBA::DPoint::new( 0, 1 ), RBA::DPoint::new( 1, 5 ) ], 2.5 ) @@ -40,6 +41,7 @@ class DBPath_TestClass < TestBase assert_equal( "%.3f" % a.area, "10.308" ) assert_equal( "%.3f" % a.length, "4.123" ) assert_equal( RBA::DPath::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::DPath::from_bytes(a.to_bytes).to_s, a.to_s ) c = a.dup assert_equal( a == b, false ) @@ -55,6 +57,7 @@ class DBPath_TestClass < TestBase a = RBA::DPath::new( [ RBA::DPoint::new( 0, 1 ), RBA::DPoint::new( 1, 5 ) ], 2.5, -0.5, 1.5 ) assert_equal( a.to_s, "(0,1;1,5) w=2.5 bx=-0.5 ex=1.5 r=false" ) assert_equal( RBA::DPath::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::DPath::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( "%.3f" % a.length, "5.123" ) assert_equal( RBA::Path::new(a).to_s, "(0,1;1,5) w=3 bx=-1 ex=2 r=false" ) @@ -122,6 +125,7 @@ class DBPath_TestClass < TestBase assert_equal( a.area.to_f.to_s, "0.0" ) assert_equal( a.length.to_s, "0" ) assert_equal( RBA::Path::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::Path::from_bytes(a.to_bytes).to_s, a.to_s ) b = a.dup a = RBA::Path::new( [ RBA::Point::new( 0, 10 ), RBA::Point::new( 10, 50 ) ], 25 ) @@ -129,6 +133,7 @@ class DBPath_TestClass < TestBase assert_equal( a.area.to_f.to_s, "1025.0" ) assert_equal( a.length.to_s, "41" ) assert_equal( RBA::Path::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::Path::from_bytes(a.to_bytes).to_s, a.to_s ) c = a.dup assert_equal( a == b, false ) @@ -144,6 +149,7 @@ class DBPath_TestClass < TestBase assert_equal( a.to_s, "(0,10;10,50) w=25 bx=-5 ex=15 r=false" ) assert_equal( a.length.to_s, "51" ) assert_equal( RBA::Path::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::Path::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( RBA::DPath::new(a).to_s, "(0,10;10,50) w=25 bx=-5 ex=15 r=false" ) a.bgn_ext = 5 diff --git a/testdata/ruby/dbPointTest.rb b/testdata/ruby/dbPointTest.rb index 2aeea8a61..030475706 100644 --- a/testdata/ruby/dbPointTest.rb +++ b/testdata/ruby/dbPointTest.rb @@ -34,6 +34,7 @@ class DBPoint_TestClass < TestBase assert_equal( a.to_s, "1,-17" ) assert_equal( RBA::DPoint::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::DPoint::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( (-a).to_s, "-1,17" ) assert_equal( b.to_s, "0,0" ) assert_equal( c.to_s, "5,11" ) @@ -84,6 +85,7 @@ class DBPoint_TestClass < TestBase assert_equal( a.to_s, "1,-17" ) assert_equal( RBA::Point::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::Point::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( (-a).to_s, "-1,17" ) assert_equal( b.to_s, "0,0" ) assert_equal( c.to_s, "5,11" ) diff --git a/testdata/ruby/dbPolygonTest.rb b/testdata/ruby/dbPolygonTest.rb index e3ed29a83..4749f832c 100644 --- a/testdata/ruby/dbPolygonTest.rb +++ b/testdata/ruby/dbPolygonTest.rb @@ -31,6 +31,7 @@ class DBPolygon_TestClass < TestBase a = RBA::DPolygon::new assert_equal( a.to_s, "()" ) assert_equal( RBA::DPolygon::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::DPolygon::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( a.is_box?, false ) assert_equal( a.is_empty?, true ) assert_equal( a.is_rectilinear?, false ) @@ -41,6 +42,7 @@ class DBPolygon_TestClass < TestBase assert_equal( a.to_s, "(0,1;1,5;5,5)" ) assert_equal( (a * 2).to_s, "(0,2;2,10;10,10)" ) assert_equal( RBA::DPolygon::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::DPolygon::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( a.is_box?, false ) assert_equal( a.num_points_hull, 3 ) assert_equal( a.is_empty?, false ) @@ -101,6 +103,7 @@ class DBPolygon_TestClass < TestBase a.insert_hole( [ RBA::DPoint::new( 1, 2 ), RBA::DPoint::new( 2, 2 ), RBA::DPoint::new( 2, 6 ) ] ) assert_equal( a.to_s, "(0,1;1,5;1,1/1,2;2,2;2,6)" ) assert_equal( RBA::DPolygon::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::DPolygon::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( a.area, 0 ) assert_equal( a.num_points_hole(0), 3 ) assert_equal( a.holes, 1 ) @@ -172,6 +175,7 @@ class DBPolygon_TestClass < TestBase a = RBA::Polygon::new assert_equal( a.to_s, "()" ) assert_equal( RBA::Polygon::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::Polygon::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( a.is_box?, false ) b = a.dup @@ -179,6 +183,7 @@ class DBPolygon_TestClass < TestBase assert_equal( a.to_s, "(0,1;1,5;5,5)" ) assert_equal( (a * 2).to_s, "(0,2;2,10;10,10)" ) assert_equal( RBA::Polygon::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::Polygon::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( a.num_points_hull, 3 ) c = a.dup @@ -226,6 +231,7 @@ class DBPolygon_TestClass < TestBase a.insert_hole( [ RBA::Point::new( 1, 2 ), RBA::Point::new( 2, 2 ), RBA::Point::new( 2, 6 ) ] ) assert_equal( a.to_s, "(0,1;1,5;1,1/1,2;2,2;2,6)" ) assert_equal( RBA::Polygon::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::Polygon::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( a.area, 0 ) assert_equal( a.num_points_hole(0), 3 ) assert_equal( a.holes, 1 ) diff --git a/testdata/ruby/dbTextTest.rb b/testdata/ruby/dbTextTest.rb index ac4ca0c38..a05494ecd 100644 --- a/testdata/ruby/dbTextTest.rb +++ b/testdata/ruby/dbTextTest.rb @@ -30,10 +30,12 @@ class DBText_TestClass < TestBase a = RBA::DText::new( "hallo", 10.0, -15.0 ) assert_equal( RBA::DText::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::DText::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( a.to_s, "('hallo',r0 10,-15)" ) a = RBA::DText::new( RBA::Text::new( "itext", RBA::Trans::new( RBA::Trans::R270, RBA::Point::new( 100, -150 )))) assert_equal( RBA::DText::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::DText::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( a.to_s, "('itext',r270 100,-150)" ) a = RBA::DText::new @@ -124,6 +126,7 @@ class DBText_TestClass < TestBase a = RBA::Text::new( "hallo", 10, -15 ) assert_equal( RBA::Text::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::Text::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( a.to_s, "('hallo',r0 10,-15)" ) a = RBA::Text::new( RBA::DText::new( "dtext", RBA::DTrans::new( RBA::DTrans::R270, RBA::DPoint::new( 100.0, -150.0 )))) @@ -136,6 +139,7 @@ class DBText_TestClass < TestBase a = RBA::Text::new( "hallo", RBA::Trans::new( RBA::Trans::R90, RBA::Point::new( 10, -15 ))) assert_equal( a.to_s, "('hallo',r90 10,-15)" ) assert_equal( RBA::Text::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::Text::from_bytes(a.to_bytes).to_s, a.to_s ) c = a.dup assert_equal( a == b, false ) diff --git a/testdata/ruby/dbTransTest.rb b/testdata/ruby/dbTransTest.rb index 71bc4d780..8385ddd9b 100644 --- a/testdata/ruby/dbTransTest.rb +++ b/testdata/ruby/dbTransTest.rb @@ -38,6 +38,7 @@ class DBTrans_TestClass < TestBase assert_equal( a.to_s, "r0 0,0" ) assert_equal( RBA::DTrans::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::DTrans::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( b.to_s, "m135 17,5" ) assert_equal( c.to_s, "m135 17,5" ) assert_equal( d.to_s, "r0 17,5" ) @@ -47,6 +48,7 @@ class DBTrans_TestClass < TestBase assert_equal( RBA::DTrans::new( RBA::Trans::M135, RBA::DPoint::new( 1.2, 0.25 )).to_itype(0.001).to_s, "m135 1200,250" ) assert_equal( RBA::Trans::new( RBA::Trans::M135, RBA::Point::new( 1200, 250 )).to_dtype(0.001).to_s, "m135 1.2,0.25" ) assert_equal( RBA::DTrans::from_s(f.to_s).to_s, f.to_s ) + assert_equal( RBA::DTrans::from_bytes(f.to_bytes).to_s, f.to_s ) assert_equal( b.trans( RBA::DPoint::new( 1, 0 )).to_s, "17,4" ) @@ -139,6 +141,7 @@ class DBTrans_TestClass < TestBase assert_equal( i.to_s, "m135 *0.5 2.5,8.5" ) assert_equal( RBA::DCplxTrans::from_s(i.to_s).to_s, i.to_s ) + assert_equal( RBA::DCplxTrans::from_bytes(i.to_bytes).to_s, i.to_s ) assert_equal( i * mb == u, true ) assert_equal( mb * i == u, true ) @@ -244,6 +247,7 @@ class DBTrans_TestClass < TestBase assert_equal( a.to_s, "r0 0,0" ) assert_equal( RBA::Trans::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::Trans::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( b.to_s, "m135 17,5" ) assert_equal( c.to_s, "m135 17,5" ) assert_equal( d.to_s, "r0 17,5" ) @@ -251,6 +255,7 @@ class DBTrans_TestClass < TestBase assert_equal( e2.to_s, "m135 0,0" ) assert_equal( f.to_s, "m135 17,5" ) assert_equal( RBA::Trans::from_s(f.to_s).to_s, f.to_s ) + assert_equal( RBA::Trans::from_bytes(f.to_bytes).to_s, f.to_s ) assert_equal( b.trans( RBA::Point::new( 1, 0 )).to_s, "17,4" ) @@ -340,6 +345,7 @@ class DBTrans_TestClass < TestBase c = RBA::CplxTrans::new( 5, -7 ) assert_equal( c.to_s, "r0 *1 5,-7" ) assert_equal( RBA::CplxTrans::from_s(c.to_s).to_s, c.to_s ) + assert_equal( RBA::CplxTrans::from_bytes(c.to_bytes).to_s, c.to_s ) c = RBA::CplxTrans::new( RBA::CplxTrans::M135 ) assert_equal( c.to_s, "m135 *1 0,0" ) @@ -367,6 +373,7 @@ class DBTrans_TestClass < TestBase c = RBA::CplxTrans::new( 0.75, 45, true, 2.5, -12.5 ) assert_equal( c.to_s, "m22.5 *0.75 2.5,-12.5" ) assert_equal( RBA::CplxTrans::from_s(c.to_s).to_s, c.to_s ) + assert_equal( RBA::CplxTrans::from_bytes(c.to_bytes).to_s, c.to_s ) c = RBA::CplxTrans::new( 0.75, 45, true, RBA::DPoint::new( 2.5, -12.5 ) ) assert_equal( c.to_s, "m22.5 *0.75 2.5,-12.5" ) assert_equal( c.is_unity?, false ) @@ -436,6 +443,7 @@ class DBTrans_TestClass < TestBase assert_equal( m.to_s, "r0 *1.1 0,0" ) assert_equal( RBA::DCplxTrans::from_s(m.to_s).to_s, m.to_s ) + assert_equal( RBA::DCplxTrans::from_bytes(m.to_bytes).to_s, m.to_s ) assert_equal( m.trans( RBA::Point::new( 5, -7 )).to_s, "5.5,-7.7" ) im = RBA::ICplxTrans::new( a, 0.5 ) @@ -443,6 +451,7 @@ class DBTrans_TestClass < TestBase assert_equal( im.to_s, "r0 *0.5 0,0" ) assert_equal( RBA::ICplxTrans::from_s(im.to_s).to_s, im.to_s ) + assert_equal( RBA::ICplxTrans::from_bytes(im.to_bytes).to_s, im.to_s ) assert_equal( im.trans( RBA::Point::new( 5, -7 )).to_s, "3,-4" ) im = RBA::ICplxTrans::new(m) diff --git a/testdata/ruby/dbVectorTest.rb b/testdata/ruby/dbVectorTest.rb index d279cb2bc..34bce3627 100644 --- a/testdata/ruby/dbVectorTest.rb +++ b/testdata/ruby/dbVectorTest.rb @@ -34,6 +34,7 @@ class DBVector_TestClass < TestBase assert_equal( a.to_s, "1,-17" ) assert_equal( RBA::DVector::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::DVector::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( (-a).to_s, "-1,17" ) assert_equal( b.to_s, "0,0" ) assert_equal( c.to_s, "5,11" ) @@ -88,6 +89,7 @@ class DBVector_TestClass < TestBase assert_equal( a.to_s, "1,-17" ) assert_equal( RBA::Vector::from_s(a.to_s).to_s, a.to_s ) + assert_equal( RBA::Vector::from_bytes(a.to_bytes).to_s, a.to_s ) assert_equal( (-a).to_s, "-1,17" ) assert_equal( b.to_s, "0,0" ) assert_equal( c.to_s, "5,11" )