diff --git a/src/tl/tl/tlProtocolBuffer.cc b/src/tl/tl/tlProtocolBuffer.cc index 1f676e574..279512474 100644 --- a/src/tl/tl/tlProtocolBuffer.cc +++ b/src/tl/tl/tlProtocolBuffer.cc @@ -36,6 +36,7 @@ ProtocolBufferReader::ProtocolBufferReader (tl::InputStream &input) int ProtocolBufferReader::read_tag () { + m_type = PB_VARINT; uint32_t value = 0; read (value); m_type = PBWireType (value & 7); @@ -102,9 +103,9 @@ ProtocolBufferReader::read (std::string &s) } void -ProtocolBufferReader::read (uint32_t &ui32, bool fixed) +ProtocolBufferReader::read (uint32_t &ui32) { - if (! fixed) { + if (m_type != PB_I32) { pb_varint ui64 = read_varint (); if (ui64 > std::numeric_limits::max ()) { @@ -125,12 +126,12 @@ ProtocolBufferReader::read (uint32_t &ui32, bool fixed) } void -ProtocolBufferReader::read (int32_t &i32, bool fixed) +ProtocolBufferReader::read (int32_t &i32) { uint32_t ui32; - read (ui32, fixed); + read (ui32); - if (! fixed) { + if (m_type != PB_I32) { if (ui32 & 1) { i32 = -(int32_t (ui32 >> 1) + 1); } else { @@ -142,9 +143,9 @@ ProtocolBufferReader::read (int32_t &i32, bool fixed) } void -ProtocolBufferReader::read (uint64_t &ui64, bool fixed) +ProtocolBufferReader::read (uint64_t &ui64) { - if (! fixed) { + if (m_type != PB_I64) { ui64 = read_varint (); @@ -160,12 +161,12 @@ ProtocolBufferReader::read (uint64_t &ui64, bool fixed) } void -ProtocolBufferReader::read (int64_t &i64, bool fixed) +ProtocolBufferReader::read (int64_t &i64) { uint64_t ui64; - read (ui64, fixed); + read (ui64); - if (! fixed) { + if (m_type != PB_I64) { if (ui64 & 1) { i64 = -(int64_t (ui64 >> 1) + 1); } else { @@ -241,6 +242,7 @@ pb_varint ProtocolBufferReader::read_varint () { pb_varint v = 0; + unsigned int s = 0; while (true) { const char *cp = get (1); @@ -250,8 +252,8 @@ ProtocolBufferReader::read_varint () if ((v & 0xfe00000000000000l) != 0) { error (tl::to_string (tr ("64 bit integer overflow"))); } - v <<= 7; - v |= (unsigned char) (*cp & 0x7f); + v |= (pb_varint ((unsigned char) (*cp & 0x7f)) << s); + s += 7; if ((*cp & 0x80) == 0) { break; } @@ -289,12 +291,12 @@ ProtocolBufferWriter::ProtocolBufferWriter (tl::OutputStream &stream) void ProtocolBufferWriter::write (int tag, float v) { - write (tag, *reinterpret_cast (&v)); + write (tag, *reinterpret_cast (&v), true); } void ProtocolBufferWriter::write (int tag, double v) { - write (tag, *reinterpret_cast (&v)); + write (tag, *reinterpret_cast (&v), true); } void ProtocolBufferWriter::write (int tag, uint32_t v, bool fixed) @@ -335,7 +337,7 @@ void ProtocolBufferWriter::write (int tag, int32_t v, bool fixed) if (v < 0) { write (tag, ((uint32_t (-v) - 1) << 1) + 1, false); } else { - write (tag, uint32_t (v), false); + write (tag, uint32_t (v) << 1, false); } } } @@ -378,7 +380,7 @@ void ProtocolBufferWriter::write (int tag, int64_t v, bool fixed) if (v < 0) { write (tag, ((uint64_t (-v) - 1) << 1) + 1, false); } else { - write (tag, uint64_t (v), false); + write (tag, uint64_t (v) << 1, false); } } } @@ -471,7 +473,7 @@ ProtocolBufferWriter::write_varint (pb_varint v) v >>= 7; } - m_byte_counter_stack.back () += (cp - b); + mp_stream->put (b, cp - b); } } diff --git a/src/tl/tl/tlProtocolBuffer.h b/src/tl/tl/tlProtocolBuffer.h index 011f3b7a7..fdb7f7d1b 100644 --- a/src/tl/tl/tlProtocolBuffer.h +++ b/src/tl/tl/tlProtocolBuffer.h @@ -147,25 +147,25 @@ public: * @brief Reads a uint32_t value from the current message * Throws a reader error if the current tag's value is not compatible with a uint32_t. */ - void read (uint32_t &ui32, bool fixed = false); + void read (uint32_t &ui32); /** * @brief Reads a int32_t value from the current message * Throws a reader error if the current tag's value is not compatible with a int32_t. */ - void read (int32_t &i32, bool fixed = false); + void read (int32_t &i32); /** * @brief Reads a uint64_t value from the current message * Throws a reader error if the current tag's value is not compatible with a uint64_t. */ - void read (uint64_t &ui64, bool fixed = false); + void read (uint64_t &ui64); /** * @brief Reads a int64_t value from the current message * Throws a reader error if the current tag's value is not compatible with a int64_t. */ - void read (int64_t &i64, bool fixed = false); + void read (int64_t &i64); /** * @brief Reads a boolean value from the current message diff --git a/src/tl/tl/tlProtocolBufferStruct.cc b/src/tl/tl/tlProtocolBufferStruct.cc index 2d074e305..b41f1b459 100644 --- a/src/tl/tl/tlProtocolBufferStruct.cc +++ b/src/tl/tl/tlProtocolBufferStruct.cc @@ -26,6 +26,9 @@ namespace tl { + // -------------------------------------------------------------------- +// PBParser implementation + PBParser::PBParser () { // .. nothing yet .. @@ -70,4 +73,56 @@ PBParser::parse_element (const PBElementBase *parent, tl::ProtocolBufferReader & } } +// -------------------------------------------------------------------- +// PBElementProxy implementation + +PBElementProxy::PBElementProxy (const PBElementProxy &d) + : mp_ptr (d.mp_ptr->clone ()) +{ + // .. nothing yet .. +} + +PBElementProxy::PBElementProxy (const PBElementBase &d) + : mp_ptr (d.clone ()) +{ + // .. nothing yet .. +} + +PBElementProxy::PBElementProxy (PBElementBase *d) + : mp_ptr (d) +{ + // .. nothing yet .. +} + +PBElementProxy::~PBElementProxy () +{ + delete mp_ptr; + mp_ptr = 0; +} + +// -------------------------------------------------------------------- +// PBReaderState implementation + +PBReaderState::PBReaderState () +{ + // .. nothing yet .. +} + +PBReaderState::~PBReaderState () +{ + for (std::vector ::const_iterator o = m_objects.begin (); o != m_objects.end (); ++o) { + (*o)->release (); + delete *o; + } + m_objects.clear (); +} + +// -------------------------------------------------------------------- +// PBWriterState implementation + +PBWriterState::PBWriterState () +{ + // .. nothing yet .. +} + } diff --git a/src/tl/unit_tests/tlProtocolBufferTests.cc b/src/tl/unit_tests/tlProtocolBufferTests.cc index de172ae48..d5ae4db05 100644 --- a/src/tl/unit_tests/tlProtocolBufferTests.cc +++ b/src/tl/unit_tests/tlProtocolBufferTests.cc @@ -27,6 +27,116 @@ #include #include +// @@@ +// Missing: all kind of variants (uint8_t, ...), float + +// Basic tests of reader and writer +TEST (1_BasicTypes) +{ + tl::OutputMemoryStream out; + + { + tl::OutputStream os (out); + tl::ProtocolBufferWriter writer (os); + writer.write (1, std::string ("xyz_abc")); + writer.write (2, float (1.5)); + writer.write (3, double (2.5)); + writer.write (4, true); + writer.write (5, int32_t (-100000)); + writer.write (6, int32_t (100000)); + writer.write (7, uint32_t (200000)); + writer.write (8, int64_t (-10000000000)); + writer.write (9, int64_t (10000000000)); + writer.write (10, uint64_t (20000000000)); + writer.write (11, int32_t (-100000), true); + writer.write (12, int32_t (100000), true); + writer.write (13, uint32_t (200000), true); + writer.write (14, int64_t (-10000000000), true); + writer.write (15, int64_t (10000000000), true); + writer.write (16, uint64_t (20000000000), true); + } + + { + tl::InputMemoryStream s2 (out.data (), out.size ()); + tl::InputStream is (s2); + tl::ProtocolBufferReader reader (is); + + std::string s; + bool b; + float f; + double d; + uint32_t ui32; + int32_t i32; + uint64_t ui64; + int64_t i64; + + EXPECT_EQ (reader.read_tag (), 1); + s = ""; + reader.read (s); + EXPECT_EQ (s, "xyz_abc"); + EXPECT_EQ (reader.read_tag (), 2); + f = 0; + reader.read (f); + EXPECT_EQ (f, 1.5); + EXPECT_EQ (reader.read_tag (), 3); + d = 0; + reader.read (d); + EXPECT_EQ (d, 2.5); + EXPECT_EQ (reader.read_tag (), 4); + b = false; + reader.read (b); + EXPECT_EQ (b, true); + EXPECT_EQ (reader.read_tag (), 5); + i32 = 0; + reader.read (i32); + EXPECT_EQ (i32, -100000); + EXPECT_EQ (reader.read_tag (), 6); + i32 = 0; + reader.read (i32); + EXPECT_EQ (i32, 100000); + EXPECT_EQ (reader.read_tag (), 7); + ui32 = 0; + reader.read (ui32); + EXPECT_EQ (ui32, 200000u); + EXPECT_EQ (reader.read_tag (), 8); + i64 = 0; + reader.read (i64); + EXPECT_EQ (i64, -10000000000); + EXPECT_EQ (reader.read_tag (), 9); + i64 = 0; + reader.read (i64); + EXPECT_EQ (i64, 10000000000); + EXPECT_EQ (reader.read_tag (), 10); + ui64 = 0; + reader.read (ui64); + EXPECT_EQ (ui64, 20000000000u); + EXPECT_EQ (reader.read_tag (), 11); + i32 = 0; + reader.read (i32); + EXPECT_EQ (i32, -100000); + EXPECT_EQ (reader.read_tag (), 12); + i32 = 0; + reader.read (i32); + EXPECT_EQ (i32, 100000); + EXPECT_EQ (reader.read_tag (), 13); + ui32 = 0; + reader.read (ui32); + EXPECT_EQ (ui32, 200000u); + EXPECT_EQ (reader.read_tag (), 14); + i64 = 0; + reader.read (i64); + EXPECT_EQ (i64, -10000000000); + EXPECT_EQ (reader.read_tag (), 15); + i64 = 0; + reader.read (i64); + EXPECT_EQ (i64, 10000000000); + EXPECT_EQ (reader.read_tag (), 16); + ui64 = 0; + reader.read (ui64); + EXPECT_EQ (ui64, 20000000000u); + EXPECT_EQ (reader.at_end (), true); + } +} struct Child { Child () : txt (""), d(-1), live(true) { } @@ -94,7 +204,7 @@ struct Root { const Child &get_child () const { return m_child; } }; -TEST (1) +TEST (100) { Root root; @@ -115,8 +225,9 @@ TEST (1) root.add_sub (0.5); root.add_sub (7.5); - root.add_isub (42); - root.add_isub (1700000000); + root.add_isub (420000000); + root.m = -1700000; + root.set_mi (21); Child c1; c1.txt = "c1"; @@ -144,6 +255,11 @@ TEST (1) root.add_child (c2); + Child sc; + sc.txt = "single"; + sc.d = 4.2e6; + root.set_child (sc); + std::string fn = tl::combine_path (tl::testtmp (), "pb_test.pb"); { @@ -152,6 +268,8 @@ TEST (1) structure.write (writer, root); } + root = Root (); + std::string error; try { tl::InputStream is (fn); @@ -164,19 +282,20 @@ TEST (1) // TODO: adjust EXPECT_EQ (error, ""); EXPECT_EQ (root.m_subs.size (), size_t (2)); - EXPECT_EQ (root.m_subs [0], 1.0); - EXPECT_EQ (root.m_subs [1], -2.5); + EXPECT_EQ (root.m_subs [0], 0.5); + EXPECT_EQ (root.m_subs [1], 7.5); EXPECT_EQ (root.m_isubs.size (), size_t (1)); - EXPECT_EQ (root.m_isubs [0], -100); - EXPECT_EQ (root.m, 10); + EXPECT_EQ (root.m_isubs [0], 420000000); + EXPECT_EQ (root.m, -1700000); EXPECT_EQ (root.mi, (unsigned int) 21); EXPECT_EQ (root.m_children.size (), size_t (2)); - EXPECT_EQ (root.m_children [0].txt, " Text "); - EXPECT_EQ (fabs (root.m_children [0].d - 0.001) < 1e-12, true); - EXPECT_EQ (root.m_children [1].txt, "T2"); - EXPECT_EQ (root.m_children [1].d, -1.0); - EXPECT_EQ (root.m_child.txt, "Single child"); - EXPECT_EQ (root.m_child.d, -1.0); + EXPECT_EQ (root.m_children [0].txt, "c1"); + EXPECT_EQ (root.m_children [1].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); + EXPECT_EQ (root.m_child.txt, "single"); + EXPECT_EQ (root.m_child.d, 4.2e6); // write .. tl::OutputMemoryStream out;