mirror of https://github.com/KLayout/klayout.git
WIP: debugging, first tests, basic test case working
This commit is contained in:
parent
64b6512bc1
commit
f6da5e11c6
|
|
@ -21,10 +21,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tlProtocolBuffer.h"
|
#include "tlProtocolBuffer.h"
|
||||||
|
#include "tlLog.h"
|
||||||
|
|
||||||
namespace tl
|
namespace tl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// @@@
|
||||||
|
// Missing: readers should check for proper wire type (i.e. read(int64)->either VARINT or I64, not I32
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
|
|
||||||
ProtocolBufferReader::ProtocolBufferReader (tl::InputStream &input)
|
ProtocolBufferReader::ProtocolBufferReader (tl::InputStream &input)
|
||||||
|
|
@ -284,11 +288,17 @@ ProtocolBufferReader::error (const std::string &msg)
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
|
|
||||||
ProtocolBufferWriter::ProtocolBufferWriter (tl::OutputStream &stream)
|
ProtocolBufferWriter::ProtocolBufferWriter (tl::OutputStream &stream)
|
||||||
: mp_stream (&stream), m_bytes_counted (0)
|
: mp_stream (&stream), m_bytes_counted (0), m_debug (false), m_debug_pos (0)
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProtocolBufferWriter::set_debug (bool f)
|
||||||
|
{
|
||||||
|
m_debug = f;
|
||||||
|
m_debug_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void ProtocolBufferWriter::write (int tag, float v)
|
void ProtocolBufferWriter::write (int tag, float v)
|
||||||
{
|
{
|
||||||
write (tag, *reinterpret_cast<uint32_t *> (&v), true);
|
write (tag, *reinterpret_cast<uint32_t *> (&v), true);
|
||||||
|
|
@ -303,7 +313,7 @@ void ProtocolBufferWriter::write (int tag, uint32_t v, bool fixed)
|
||||||
{
|
{
|
||||||
if (fixed) {
|
if (fixed) {
|
||||||
|
|
||||||
write_varint (pb_varint ((tag << 3) + PB_I32));
|
write_varint (pb_varint ((tag << 3) + PB_I32), true);
|
||||||
|
|
||||||
if (is_counting ()) {
|
if (is_counting ()) {
|
||||||
|
|
||||||
|
|
@ -311,19 +321,25 @@ void ProtocolBufferWriter::write (int tag, uint32_t v, bool fixed)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
auto vv = v;
|
||||||
|
|
||||||
char b[sizeof (v)];
|
char b[sizeof (v)];
|
||||||
for (unsigned int i = 0; i < sizeof (v); ++i) {
|
for (unsigned int i = 0; i < sizeof (v); ++i) {
|
||||||
b[sizeof (v) - 1 - i] = (char) v;
|
b[sizeof (v) - 1 - i] = (char) v;
|
||||||
v >>= 8;
|
v >>= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_debug) {
|
||||||
|
dump (b, sizeof (v), "I32", tl::to_string (vv));
|
||||||
|
}
|
||||||
|
|
||||||
mp_stream->put (b, sizeof (v));
|
mp_stream->put (b, sizeof (v));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
write_varint (pb_varint ((tag << 3) + PB_VARINT));
|
write_varint (pb_varint ((tag << 3) + PB_VARINT), true);
|
||||||
write_varint (pb_varint (v));
|
write_varint (pb_varint (v));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -346,7 +362,7 @@ void ProtocolBufferWriter::write (int tag, uint64_t v, bool fixed)
|
||||||
{
|
{
|
||||||
if (fixed) {
|
if (fixed) {
|
||||||
|
|
||||||
write_varint (pb_varint ((tag << 3) + PB_I64));
|
write_varint (pb_varint ((tag << 3) + PB_I64), true);
|
||||||
|
|
||||||
if (is_counting ()) {
|
if (is_counting ()) {
|
||||||
|
|
||||||
|
|
@ -354,19 +370,25 @@ void ProtocolBufferWriter::write (int tag, uint64_t v, bool fixed)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
auto vv = v;
|
||||||
|
|
||||||
char b[sizeof (v)];
|
char b[sizeof (v)];
|
||||||
for (unsigned int i = 0; i < sizeof (v); ++i) {
|
for (unsigned int i = 0; i < sizeof (v); ++i) {
|
||||||
b[sizeof (v) - 1 - i] = (char) v;
|
b[sizeof (v) - 1 - i] = (char) v;
|
||||||
v >>= 8;
|
v >>= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_debug) {
|
||||||
|
dump (b, sizeof (v), "I64", tl::to_string (vv));
|
||||||
|
}
|
||||||
|
|
||||||
mp_stream->put (b, sizeof (v));
|
mp_stream->put (b, sizeof (v));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
write_varint (pb_varint ((tag << 3) + PB_VARINT));
|
write_varint (pb_varint ((tag << 3) + PB_VARINT), true);
|
||||||
write_varint (pb_varint (v));
|
write_varint (pb_varint (v));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -392,13 +414,21 @@ void ProtocolBufferWriter::write (int tag, bool b)
|
||||||
|
|
||||||
void ProtocolBufferWriter::write (int tag, const std::string &s)
|
void ProtocolBufferWriter::write (int tag, const std::string &s)
|
||||||
{
|
{
|
||||||
write_varint (pb_varint ((tag << 3) + PB_LEN));
|
write_varint (pb_varint ((tag << 3) + PB_LEN), true);
|
||||||
write_varint (s.size ());
|
write_varint (s.size ());
|
||||||
|
|
||||||
if (is_counting ()) {
|
if (is_counting ()) {
|
||||||
|
|
||||||
m_byte_counter_stack.back () += s.size ();
|
m_byte_counter_stack.back () += s.size ();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if (m_debug) {
|
||||||
|
dump (s.c_str (), s.size (), "(string)", s);
|
||||||
|
}
|
||||||
|
|
||||||
mp_stream->put (s.c_str (), s.size ());
|
mp_stream->put (s.c_str (), s.size ());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -411,16 +441,15 @@ void ProtocolBufferWriter::begin_seq (int tag, bool counting)
|
||||||
{
|
{
|
||||||
if (counting) {
|
if (counting) {
|
||||||
|
|
||||||
// header only
|
if (is_counting ()) {
|
||||||
m_byte_counter_stack.push_back (0);
|
write_varint (pb_varint ((tag << 3) + PB_LEN), true);
|
||||||
write_varint (pb_varint ((tag << 3) + PB_LEN));
|
}
|
||||||
|
|
||||||
// body only
|
|
||||||
m_byte_counter_stack.push_back (0);
|
m_byte_counter_stack.push_back (0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
write_varint (pb_varint ((tag << 3) + PB_LEN));
|
write_varint (pb_varint ((tag << 3) + PB_LEN), true);
|
||||||
write_varint (m_bytes_counted);
|
write_varint (m_bytes_counted);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -434,17 +463,15 @@ void ProtocolBufferWriter::end_seq ()
|
||||||
m_byte_counter_stack.pop_back ();
|
m_byte_counter_stack.pop_back ();
|
||||||
|
|
||||||
// just for adding the required bytes
|
// just for adding the required bytes
|
||||||
write_varint (m_bytes_counted);
|
if (is_counting ()) {
|
||||||
|
write_varint (m_bytes_counted);
|
||||||
// now add header bytes
|
}
|
||||||
m_bytes_counted += m_byte_counter_stack.back ();
|
|
||||||
m_byte_counter_stack.pop_back ();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ProtocolBufferWriter::write_varint (pb_varint v)
|
ProtocolBufferWriter::write_varint (pb_varint v, bool id)
|
||||||
{
|
{
|
||||||
if (is_counting ()) {
|
if (is_counting ()) {
|
||||||
|
|
||||||
|
|
@ -461,6 +488,8 @@ ProtocolBufferWriter::write_varint (pb_varint v)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
auto vv = v;
|
||||||
|
|
||||||
char b[16];
|
char b[16];
|
||||||
char *cp = b;
|
char *cp = b;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
@ -473,9 +502,75 @@ ProtocolBufferWriter::write_varint (pb_varint v)
|
||||||
v >>= 7;
|
v >>= 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_debug) {
|
||||||
|
if (id) {
|
||||||
|
unsigned int wt = v & 7;
|
||||||
|
std::string wire_type;
|
||||||
|
if (wt == PB_EGROUP) {
|
||||||
|
wire_type = "EGROUP";
|
||||||
|
} else if (wt == PB_SGROUP) {
|
||||||
|
wire_type = "SGROUP";
|
||||||
|
} else if (wt == PB_VARINT) {
|
||||||
|
wire_type = "VARINT";
|
||||||
|
} else if (wt == PB_I32) {
|
||||||
|
wire_type = "I32";
|
||||||
|
} else if (wt == PB_I64) {
|
||||||
|
wire_type = "I64";
|
||||||
|
} else if (wt == PB_LEN) {
|
||||||
|
wire_type = "LEN";
|
||||||
|
}
|
||||||
|
dump (b, cp - b, "(id)", "#" + tl::to_string (vv >> 3) + " " + wire_type);
|
||||||
|
} else {
|
||||||
|
dump (b, cp - b, "VARINT", tl::to_string (vv));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mp_stream->put (b, cp - b);
|
mp_stream->put (b, cp - b);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ProtocolBufferWriter::dump (const char *cp, size_t n, const std::string &type, const std::string &value)
|
||||||
|
{
|
||||||
|
bool first = true;
|
||||||
|
size_t nn = n;
|
||||||
|
|
||||||
|
while (n > 0) {
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
if (first) {
|
||||||
|
line += tl::sprintf ("%08ld", m_debug_pos);
|
||||||
|
} else {
|
||||||
|
line += " ";
|
||||||
|
}
|
||||||
|
line += " ";
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 8; ++i) {
|
||||||
|
if (n > 0) {
|
||||||
|
line += tl::sprintf ("%02x", (unsigned int) ((unsigned char) *cp));
|
||||||
|
++cp;
|
||||||
|
--n;
|
||||||
|
} else {
|
||||||
|
line += " ";
|
||||||
|
}
|
||||||
|
line += " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
line += " ";
|
||||||
|
line += type;
|
||||||
|
line += " ";
|
||||||
|
line += value;
|
||||||
|
}
|
||||||
|
|
||||||
|
tl::info << line;
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
m_debug_pos += nn;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -259,12 +259,21 @@ public:
|
||||||
*/
|
*/
|
||||||
void end_seq ();
|
void end_seq ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables or disables debug mode
|
||||||
|
* In debug mode, the stream will be dumped in a human readable form
|
||||||
|
*/
|
||||||
|
void set_debug (bool f);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void write_varint (pb_varint v);
|
void write_varint (pb_varint v, bool id = false);
|
||||||
|
void dump (const char *cp, size_t n, const std::string &type, const std::string &value);
|
||||||
|
|
||||||
tl::OutputStream *mp_stream;
|
tl::OutputStream *mp_stream;
|
||||||
size_t m_bytes_counted;
|
size_t m_bytes_counted;
|
||||||
std::vector<size_t> m_byte_counter_stack;
|
std::vector<size_t> m_byte_counter_stack;
|
||||||
|
bool m_debug;
|
||||||
|
size_t m_debug_pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ PBParser::parse_element (const PBElementBase *parent, tl::ProtocolBufferReader &
|
||||||
} else {
|
} else {
|
||||||
new_element->create (parent, *mp_state);
|
new_element->create (parent, *mp_state);
|
||||||
new_element->parse (this, reader);
|
new_element->parse (this, reader);
|
||||||
|
new_element->finish (parent, *mp_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -604,7 +604,9 @@ public:
|
||||||
|
|
||||||
virtual void parse (PBParser *parser, tl::ProtocolBufferReader &reader) const
|
virtual void parse (PBParser *parser, tl::ProtocolBufferReader &reader) const
|
||||||
{
|
{
|
||||||
|
reader.open ();
|
||||||
parser->parse_element (this, reader);
|
parser->parse_element (this, reader);
|
||||||
|
reader.close ();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void write (const PBElementBase * /*parent*/, tl::ProtocolBufferWriter &writer, PBWriterState &objs) const
|
virtual void write (const PBElementBase * /*parent*/, tl::ProtocolBufferWriter &writer, PBWriterState &objs) const
|
||||||
|
|
@ -660,7 +662,7 @@ private:
|
||||||
}
|
}
|
||||||
objs.pop (self_tag);
|
objs.pop (self_tag);
|
||||||
writer.end_seq ();
|
writer.end_seq ();
|
||||||
if (! writer.is_counting ()) {
|
if (writer.is_counting ()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,17 +155,18 @@ struct Child {
|
||||||
struct Root {
|
struct Root {
|
||||||
long m;
|
long m;
|
||||||
unsigned int mi;
|
unsigned int mi;
|
||||||
|
bool b;
|
||||||
std::vector<double> m_subs;
|
std::vector<double> m_subs;
|
||||||
std::vector<int> m_isubs;
|
std::vector<int> m_isubs;
|
||||||
std::vector<Child> m_children;
|
std::vector<Child> m_children;
|
||||||
Child m_child;
|
Child m_child;
|
||||||
|
|
||||||
Root () : m(0), mi(0) { }
|
Root () : m(0), mi(0), b(false) { }
|
||||||
|
|
||||||
bool operator== (const Root &x) const { return m == x.m &&
|
bool operator== (const Root &x) const { return m == x.m &&
|
||||||
mi == x.mi && m_subs == x.m_subs &&
|
mi == x.mi && m_subs == x.m_subs &&
|
||||||
m_isubs == x.m_isubs && m_children == x.m_children
|
m_isubs == x.m_isubs && m_children == x.m_children
|
||||||
&& m_child == x.m_child; }
|
&& m_child == x.m_child && b == x.b; }
|
||||||
|
|
||||||
int get_mi () const { return mi; }
|
int get_mi () const { return mi; }
|
||||||
void set_mi (int i) { mi = i; }
|
void set_mi (int i) { mi = i; }
|
||||||
|
|
@ -204,23 +205,26 @@ struct Root {
|
||||||
const Child &get_child () const { return m_child; }
|
const Child &get_child () const { return m_child; }
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST (100)
|
TEST (100_BasicStruct)
|
||||||
{
|
{
|
||||||
Root root;
|
Root root;
|
||||||
|
|
||||||
|
tl::PBElementList child_struct =
|
||||||
|
tl::pb_make_member (&Child::txt, 1) +
|
||||||
|
tl::pb_make_member (&Child::d, 2) +
|
||||||
|
tl::pb_make_element (&Child::begin_children, &Child::end_children, &Child::add_child, 3, &child_struct);
|
||||||
|
|
||||||
tl::PBStruct<Root> structure (
|
tl::PBStruct<Root> structure (
|
||||||
tl::pb_make_member (&Root::begin_subs, &Root::end_subs, &Root::add_sub, 1) +
|
tl::pb_make_member (&Root::begin_subs, &Root::end_subs, &Root::add_sub, 1) +
|
||||||
tl::pb_make_member (&Root::begin_isubs, &Root::end_isubs, &Root::add_isub, 2) +
|
tl::pb_make_member (&Root::begin_isubs, &Root::end_isubs, &Root::add_isub, 2) +
|
||||||
tl::pb_make_element (&Root::begin_children, &Root::end_children, &Root::add_child, 3,
|
tl::pb_make_element (&Root::begin_children, &Root::end_children, &Root::add_child, 3, &child_struct) +
|
||||||
tl::pb_make_member (&Child::txt, 1) +
|
|
||||||
tl::pb_make_member (&Child::d, 2)
|
|
||||||
) +
|
|
||||||
tl::pb_make_element (&Root::get_child, &Root::set_child, 4,
|
tl::pb_make_element (&Root::get_child, &Root::set_child, 4,
|
||||||
tl::pb_make_member (&Child::txt, 1) +
|
tl::pb_make_member (&Child::txt, 1) +
|
||||||
tl::pb_make_member (&Child::d, 2)
|
tl::pb_make_member (&Child::d, 2)
|
||||||
) +
|
) +
|
||||||
tl::pb_make_member (&Root::m, 5) +
|
tl::pb_make_member (&Root::m, 5) +
|
||||||
tl::pb_make_member (&Root::get_mi, &Root::set_mi, 6)
|
tl::pb_make_member (&Root::get_mi, &Root::set_mi, 6) +
|
||||||
|
tl::pb_make_member (&Root::b, 7)
|
||||||
);
|
);
|
||||||
|
|
||||||
root.add_sub (0.5);
|
root.add_sub (0.5);
|
||||||
|
|
@ -228,6 +232,7 @@ TEST (100)
|
||||||
root.add_isub (420000000);
|
root.add_isub (420000000);
|
||||||
root.m = -1700000;
|
root.m = -1700000;
|
||||||
root.set_mi (21);
|
root.set_mi (21);
|
||||||
|
root.b = true;
|
||||||
|
|
||||||
Child c1;
|
Child c1;
|
||||||
c1.txt = "c1";
|
c1.txt = "c1";
|
||||||
|
|
@ -265,6 +270,7 @@ TEST (100)
|
||||||
{
|
{
|
||||||
tl::OutputStream os (fn);
|
tl::OutputStream os (fn);
|
||||||
tl::ProtocolBufferWriter writer (os);
|
tl::ProtocolBufferWriter writer (os);
|
||||||
|
// For development: writer.set_debug (true);
|
||||||
structure.write (writer, root);
|
structure.write (writer, root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -287,10 +293,11 @@ TEST (100)
|
||||||
EXPECT_EQ (root.m_isubs.size (), size_t (1));
|
EXPECT_EQ (root.m_isubs.size (), size_t (1));
|
||||||
EXPECT_EQ (root.m_isubs [0], 420000000);
|
EXPECT_EQ (root.m_isubs [0], 420000000);
|
||||||
EXPECT_EQ (root.m, -1700000);
|
EXPECT_EQ (root.m, -1700000);
|
||||||
|
EXPECT_EQ (root.b, true);
|
||||||
EXPECT_EQ (root.mi, (unsigned int) 21);
|
EXPECT_EQ (root.mi, (unsigned int) 21);
|
||||||
EXPECT_EQ (root.m_children.size (), size_t (2));
|
EXPECT_EQ (root.m_children.size (), size_t (2));
|
||||||
EXPECT_EQ (root.m_children [0].txt, "c1");
|
EXPECT_EQ (root.m_children [0].txt, "c1");
|
||||||
EXPECT_EQ (root.m_children [1].d, 1.0);
|
EXPECT_EQ (root.m_children [0].d, 1.0);
|
||||||
EXPECT_EQ (root.m_children [1].txt, "c2");
|
EXPECT_EQ (root.m_children [1].txt, "c2");
|
||||||
EXPECT_EQ (root.m_children [1].d, 2.0);
|
EXPECT_EQ (root.m_children [1].d, 2.0);
|
||||||
EXPECT_EQ (root.m_children [1].end_children () - root.m_children [1].begin_children (), 3);
|
EXPECT_EQ (root.m_children [1].end_children () - root.m_children [1].begin_children (), 3);
|
||||||
|
|
@ -322,4 +329,29 @@ TEST (100)
|
||||||
|
|
||||||
EXPECT_EQ (error, "");
|
EXPECT_EQ (error, "");
|
||||||
EXPECT_EQ (root == rsave, true);
|
EXPECT_EQ (root == rsave, true);
|
||||||
|
|
||||||
|
// write empty object
|
||||||
|
out.clear ();
|
||||||
|
root = Root ();
|
||||||
|
|
||||||
|
{
|
||||||
|
tl::OutputStream os (out);
|
||||||
|
tl::ProtocolBufferWriter writer (os);
|
||||||
|
structure.write (writer, root);
|
||||||
|
}
|
||||||
|
|
||||||
|
// and read again.
|
||||||
|
try {
|
||||||
|
error.clear ();
|
||||||
|
tl::InputMemoryStream s2 (out.data (), out.size ());
|
||||||
|
tl::InputStream is (s2);
|
||||||
|
root = Root ();
|
||||||
|
tl::ProtocolBufferReader reader (is);
|
||||||
|
structure.parse (reader, root);
|
||||||
|
} catch (tl::Exception &ex) {
|
||||||
|
error = ex.msg ();
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ (error, "");
|
||||||
|
EXPECT_EQ (root == Root (), true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue