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 "tlLog.h"
|
||||
|
||||
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)
|
||||
|
|
@ -284,11 +288,17 @@ ProtocolBufferReader::error (const std::string &msg)
|
|||
// ----------------------------------------------------------------------------------
|
||||
|
||||
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 ..
|
||||
}
|
||||
|
||||
void ProtocolBufferWriter::set_debug (bool f)
|
||||
{
|
||||
m_debug = f;
|
||||
m_debug_pos = 0;
|
||||
}
|
||||
|
||||
void ProtocolBufferWriter::write (int tag, float v)
|
||||
{
|
||||
write (tag, *reinterpret_cast<uint32_t *> (&v), true);
|
||||
|
|
@ -303,7 +313,7 @@ void ProtocolBufferWriter::write (int tag, uint32_t v, bool fixed)
|
|||
{
|
||||
if (fixed) {
|
||||
|
||||
write_varint (pb_varint ((tag << 3) + PB_I32));
|
||||
write_varint (pb_varint ((tag << 3) + PB_I32), true);
|
||||
|
||||
if (is_counting ()) {
|
||||
|
||||
|
|
@ -311,19 +321,25 @@ void ProtocolBufferWriter::write (int tag, uint32_t v, bool fixed)
|
|||
|
||||
} else {
|
||||
|
||||
auto vv = v;
|
||||
|
||||
char b[sizeof (v)];
|
||||
for (unsigned int i = 0; i < sizeof (v); ++i) {
|
||||
b[sizeof (v) - 1 - i] = (char) v;
|
||||
v >>= 8;
|
||||
}
|
||||
|
||||
if (m_debug) {
|
||||
dump (b, sizeof (v), "I32", tl::to_string (vv));
|
||||
}
|
||||
|
||||
mp_stream->put (b, sizeof (v));
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
write_varint (pb_varint ((tag << 3) + PB_VARINT));
|
||||
write_varint (pb_varint ((tag << 3) + PB_VARINT), true);
|
||||
write_varint (pb_varint (v));
|
||||
|
||||
}
|
||||
|
|
@ -346,7 +362,7 @@ void ProtocolBufferWriter::write (int tag, uint64_t v, bool fixed)
|
|||
{
|
||||
if (fixed) {
|
||||
|
||||
write_varint (pb_varint ((tag << 3) + PB_I64));
|
||||
write_varint (pb_varint ((tag << 3) + PB_I64), true);
|
||||
|
||||
if (is_counting ()) {
|
||||
|
||||
|
|
@ -354,19 +370,25 @@ void ProtocolBufferWriter::write (int tag, uint64_t v, bool fixed)
|
|||
|
||||
} else {
|
||||
|
||||
auto vv = v;
|
||||
|
||||
char b[sizeof (v)];
|
||||
for (unsigned int i = 0; i < sizeof (v); ++i) {
|
||||
b[sizeof (v) - 1 - i] = (char) v;
|
||||
v >>= 8;
|
||||
}
|
||||
|
||||
if (m_debug) {
|
||||
dump (b, sizeof (v), "I64", tl::to_string (vv));
|
||||
}
|
||||
|
||||
mp_stream->put (b, sizeof (v));
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
write_varint (pb_varint ((tag << 3) + PB_VARINT));
|
||||
write_varint (pb_varint ((tag << 3) + PB_VARINT), true);
|
||||
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)
|
||||
{
|
||||
write_varint (pb_varint ((tag << 3) + PB_LEN));
|
||||
write_varint (pb_varint ((tag << 3) + PB_LEN), true);
|
||||
write_varint (s.size ());
|
||||
|
||||
if (is_counting ()) {
|
||||
|
||||
m_byte_counter_stack.back () += s.size ();
|
||||
|
||||
} else {
|
||||
|
||||
if (m_debug) {
|
||||
dump (s.c_str (), s.size (), "(string)", s);
|
||||
}
|
||||
|
||||
mp_stream->put (s.c_str (), s.size ());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -411,16 +441,15 @@ void ProtocolBufferWriter::begin_seq (int tag, bool counting)
|
|||
{
|
||||
if (counting) {
|
||||
|
||||
// header only
|
||||
m_byte_counter_stack.push_back (0);
|
||||
write_varint (pb_varint ((tag << 3) + PB_LEN));
|
||||
if (is_counting ()) {
|
||||
write_varint (pb_varint ((tag << 3) + PB_LEN), true);
|
||||
}
|
||||
|
||||
// body only
|
||||
m_byte_counter_stack.push_back (0);
|
||||
|
||||
} else {
|
||||
|
||||
write_varint (pb_varint ((tag << 3) + PB_LEN));
|
||||
write_varint (pb_varint ((tag << 3) + PB_LEN), true);
|
||||
write_varint (m_bytes_counted);
|
||||
|
||||
}
|
||||
|
|
@ -434,17 +463,15 @@ void ProtocolBufferWriter::end_seq ()
|
|||
m_byte_counter_stack.pop_back ();
|
||||
|
||||
// just for adding the required bytes
|
||||
write_varint (m_bytes_counted);
|
||||
|
||||
// now add header bytes
|
||||
m_bytes_counted += m_byte_counter_stack.back ();
|
||||
m_byte_counter_stack.pop_back ();
|
||||
if (is_counting ()) {
|
||||
write_varint (m_bytes_counted);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProtocolBufferWriter::write_varint (pb_varint v)
|
||||
ProtocolBufferWriter::write_varint (pb_varint v, bool id)
|
||||
{
|
||||
if (is_counting ()) {
|
||||
|
||||
|
|
@ -461,6 +488,8 @@ ProtocolBufferWriter::write_varint (pb_varint v)
|
|||
|
||||
} else {
|
||||
|
||||
auto vv = v;
|
||||
|
||||
char b[16];
|
||||
char *cp = b;
|
||||
while (true) {
|
||||
|
|
@ -473,9 +502,75 @@ ProtocolBufferWriter::write_varint (pb_varint v)
|
|||
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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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 ();
|
||||
|
||||
/**
|
||||
* @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:
|
||||
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;
|
||||
size_t m_bytes_counted;
|
||||
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 {
|
||||
new_element->create (parent, *mp_state);
|
||||
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
|
||||
{
|
||||
reader.open ();
|
||||
parser->parse_element (this, reader);
|
||||
reader.close ();
|
||||
}
|
||||
|
||||
virtual void write (const PBElementBase * /*parent*/, tl::ProtocolBufferWriter &writer, PBWriterState &objs) const
|
||||
|
|
@ -660,7 +662,7 @@ private:
|
|||
}
|
||||
objs.pop (self_tag);
|
||||
writer.end_seq ();
|
||||
if (! writer.is_counting ()) {
|
||||
if (writer.is_counting ()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,17 +155,18 @@ struct Child {
|
|||
struct Root {
|
||||
long m;
|
||||
unsigned int mi;
|
||||
bool b;
|
||||
std::vector<double> m_subs;
|
||||
std::vector<int> m_isubs;
|
||||
std::vector<Child> m_children;
|
||||
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 &&
|
||||
mi == x.mi && m_subs == x.m_subs &&
|
||||
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; }
|
||||
void set_mi (int i) { mi = i; }
|
||||
|
|
@ -204,23 +205,26 @@ struct Root {
|
|||
const Child &get_child () const { return m_child; }
|
||||
};
|
||||
|
||||
TEST (100)
|
||||
TEST (100_BasicStruct)
|
||||
{
|
||||
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::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_element (&Root::begin_children, &Root::end_children, &Root::add_child, 3,
|
||||
tl::pb_make_member (&Child::txt, 1) +
|
||||
tl::pb_make_member (&Child::d, 2)
|
||||
) +
|
||||
tl::pb_make_element (&Root::begin_children, &Root::end_children, &Root::add_child, 3, &child_struct) +
|
||||
tl::pb_make_element (&Root::get_child, &Root::set_child, 4,
|
||||
tl::pb_make_member (&Child::txt, 1) +
|
||||
tl::pb_make_member (&Child::d, 2)
|
||||
) +
|
||||
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);
|
||||
|
|
@ -228,6 +232,7 @@ TEST (100)
|
|||
root.add_isub (420000000);
|
||||
root.m = -1700000;
|
||||
root.set_mi (21);
|
||||
root.b = true;
|
||||
|
||||
Child c1;
|
||||
c1.txt = "c1";
|
||||
|
|
@ -265,6 +270,7 @@ TEST (100)
|
|||
{
|
||||
tl::OutputStream os (fn);
|
||||
tl::ProtocolBufferWriter writer (os);
|
||||
// For development: writer.set_debug (true);
|
||||
structure.write (writer, root);
|
||||
}
|
||||
|
||||
|
|
@ -287,10 +293,11 @@ TEST (100)
|
|||
EXPECT_EQ (root.m_isubs.size (), size_t (1));
|
||||
EXPECT_EQ (root.m_isubs [0], 420000000);
|
||||
EXPECT_EQ (root.m, -1700000);
|
||||
EXPECT_EQ (root.b, true);
|
||||
EXPECT_EQ (root.mi, (unsigned int) 21);
|
||||
EXPECT_EQ (root.m_children.size (), size_t (2));
|
||||
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].d, 2.0);
|
||||
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 (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