From 7357fe50e2aa2d109a5b25d91a80af8ad04c2694 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 11 Aug 2024 15:51:36 +0200 Subject: [PATCH] WIP --- src/tl/tl/tlProtocolBuffer.cc | 306 +++++++++++------------------ src/tl/tl/tlProtocolBuffer.h | 119 ++++------- src/tl/tl/tlProtocolBufferStruct.h | 40 ++-- 3 files changed, 170 insertions(+), 295 deletions(-) diff --git a/src/tl/tl/tlProtocolBuffer.cc b/src/tl/tl/tlProtocolBuffer.cc index 0099fdf39..a6a62dab1 100644 --- a/src/tl/tl/tlProtocolBuffer.cc +++ b/src/tl/tl/tlProtocolBuffer.cc @@ -360,45 +360,28 @@ inline size_t varint_encode (char *b, pb_varint v) // ---------------------------------------------------------------------------------- -ProtocolBufferWriter::ProtocolBufferWriter (tl::OutputStream &stream) - : mp_stream (&stream), m_bytes_counted (0) +ProtocolBufferWriterBase::ProtocolBufferWriterBase () + : m_bytes_counted (0) { // .. nothing yet .. } -void ProtocolBufferWriter::write (int tag, float v) +ProtocolBufferWriterBase::~ProtocolBufferWriterBase () +{ + // .. nothing yet .. +} + +void ProtocolBufferWriterBase::write (int tag, float v) { write (tag, *reinterpret_cast (&v), true); } -void ProtocolBufferWriter::write (int tag, double v) +void ProtocolBufferWriterBase::write (int tag, double v) { write (tag, *reinterpret_cast (&v), true); } -void ProtocolBufferWriter::write (int tag, uint32_t v, bool fixed) -{ - if (fixed) { - - write_varint (pb_varint ((tag << 3) + PB_I32), true); - - if (is_counting ()) { - m_byte_counter_stack.back () += sizeof (v); - } else { - char b[sizeof (v)]; - little_endian_encode (b, v); - mp_stream->put (b, sizeof (v)); - } - - } else { - - write_varint (pb_varint ((tag << 3) + PB_VARINT), true); - write_varint (pb_varint (v)); - - } -} - -void ProtocolBufferWriter::write (int tag, int32_t v, bool fixed) +void ProtocolBufferWriterBase::write (int tag, int32_t v, bool fixed) { if (fixed) { write (tag, uint32_t (v), true); @@ -407,29 +390,7 @@ void ProtocolBufferWriter::write (int tag, int32_t v, bool fixed) } } -void ProtocolBufferWriter::write (int tag, uint64_t v, bool fixed) -{ - if (fixed) { - - write_varint (pb_varint ((tag << 3) + PB_I64), true); - - if (is_counting ()) { - m_byte_counter_stack.back () += sizeof (v); - } else { - char b[sizeof (v)]; - little_endian_encode (b, v); - mp_stream->put (b, sizeof (v)); - } - - } else { - - write_varint (pb_varint ((tag << 3) + PB_VARINT), true); - write_varint (pb_varint (v)); - - } -} - -void ProtocolBufferWriter::write (int tag, int64_t v, bool fixed) +void ProtocolBufferWriterBase::write (int tag, int64_t v, bool fixed) { if (fixed) { write (tag, uint64_t (v), true); @@ -438,29 +399,46 @@ void ProtocolBufferWriter::write (int tag, int64_t v, bool fixed) } } -void ProtocolBufferWriter::write (int tag, bool b) +void ProtocolBufferWriterBase::write (int tag, bool b) { write (tag, uint32_t (b ? 1 : 0)); } -void ProtocolBufferWriter::write (int tag, const std::string &s) +void ProtocolBufferWriterBase::write (int tag, uint32_t v, bool fixed) { - write_varint (pb_varint ((tag << 3) + PB_LEN), true); - write_varint (s.size ()); - - if (is_counting ()) { - m_byte_counter_stack.back () += s.size (); + if (fixed) { + write_varint (pb_varint ((tag << 3) + PB_I32), true); + write_fixed (v); } else { - mp_stream->put (s.c_str (), s.size ()); + write_varint (pb_varint ((tag << 3) + PB_VARINT), true); + write_varint (pb_varint (v), false); } } -bool ProtocolBufferWriter::is_counting () const +void ProtocolBufferWriterBase::write (int tag, uint64_t v, bool fixed) +{ + if (fixed) { + write_varint (pb_varint ((tag << 3) + PB_I64), true); + write_fixed (v); + } else { + write_varint (pb_varint ((tag << 3) + PB_VARINT), true); + write_varint (pb_varint (v), false); + } +} + +void ProtocolBufferWriterBase::write (int tag, const std::string &s) +{ + write_varint (pb_varint ((tag << 3) + PB_LEN), true); + write_varint (s.size (), false); + write_bytes (s); +} + +bool ProtocolBufferWriterBase::is_counting () const { return ! m_byte_counter_stack.empty (); } -void ProtocolBufferWriter::begin_seq (int tag, bool counting) +void ProtocolBufferWriterBase::begin_seq (int tag, bool counting) { if (counting) { @@ -473,12 +451,12 @@ void ProtocolBufferWriter::begin_seq (int tag, bool counting) } else { write_varint (pb_varint ((tag << 3) + PB_LEN), true); - write_varint (m_bytes_counted); + write_varint (m_bytes_counted, false); } } -void ProtocolBufferWriter::end_seq () +void ProtocolBufferWriterBase::end_seq () { if (is_counting ()) { @@ -488,164 +466,104 @@ void ProtocolBufferWriter::end_seq () // just for adding the required bytes if (is_counting ()) { m_byte_counter_stack.back () += m_bytes_counted; - write_varint (m_bytes_counted); + write_varint (m_bytes_counted, false); } } } +void ProtocolBufferWriterBase::add_bytes (size_t n) +{ + tl_assert (! m_byte_counter_stack.empty ()); + m_byte_counter_stack.back () += n; +} + +// ---------------------------------------------------------------------------------- + +ProtocolBufferWriter::ProtocolBufferWriter (tl::OutputStream &stream) + : mp_stream (&stream) +{ + // .. nothing yet .. +} + +void ProtocolBufferWriter::write_fixed (uint32_t v) +{ + if (is_counting ()) { + add_bytes (sizeof (v)); + } else { + char b[sizeof (v)]; + little_endian_encode (b, v); + mp_stream->put (b, sizeof (v)); + } +} + +void ProtocolBufferWriter::write_fixed (uint64_t v) +{ + if (is_counting ()) { + add_bytes (sizeof (v)); + } else { + char b[sizeof (v)]; + little_endian_encode (b, v); + mp_stream->put (b, sizeof (v)); + } +} + +void ProtocolBufferWriter::write_bytes (const std::string &s) +{ + if (is_counting ()) { + add_bytes (s.size ()); + } else { + mp_stream->put (s.c_str (), s.size ()); + } +} + void ProtocolBufferWriter::write_varint (pb_varint v, bool /*id*/) { if (is_counting ()) { - - m_byte_counter_stack.back () += count_varint_bytes (v); - + add_bytes (count_varint_bytes (v)); } else { - char b [max_varint_bytes]; size_t n = varint_encode (b, v); mp_stream->put (b, n); - } } // ---------------------------------------------------------------------------------- ProtocolBufferDumper::ProtocolBufferDumper () - : m_bytes_counted (0), m_debug_pos (0) + : m_debug_pos (0) { // .. nothing yet .. } -void ProtocolBufferDumper::write (int tag, float v) +void ProtocolBufferDumper::write_fixed (uint32_t v) { - write (tag, *reinterpret_cast (&v), true); -} - -void ProtocolBufferDumper::write (int tag, double v) -{ - write (tag, *reinterpret_cast (&v), true); -} - -void ProtocolBufferDumper::write (int tag, uint32_t v, bool fixed) -{ - if (fixed) { - - write_varint (pb_varint ((tag << 3) + PB_I32), true); - - if (is_counting ()) { - m_byte_counter_stack.back () += sizeof (v); - } else { - char b[sizeof (v)]; - little_endian_encode (b, v); - dump (b, sizeof (v), "I32", tl::to_string (v)); - } - - } else { - - write_varint (pb_varint ((tag << 3) + PB_VARINT), true); - write_varint (pb_varint (v)); - - } -} - -void ProtocolBufferDumper::write (int tag, int32_t v, bool fixed) -{ - if (fixed) { - write (tag, uint32_t (v), true); - } else { - write (tag, zigzag_encode (v), false); - } -} - -void ProtocolBufferDumper::write (int tag, uint64_t v, bool fixed) -{ - if (fixed) { - - write_varint (pb_varint ((tag << 3) + PB_I64), true); - - if (is_counting ()) { - m_byte_counter_stack.back () += sizeof (v); - } else { - char b[sizeof (v)]; - little_endian_encode (b, v); - dump (b, sizeof (v), "I64", tl::to_string (v)); - } - - } else { - - write_varint (pb_varint ((tag << 3) + PB_VARINT), true); - write_varint (pb_varint (v)); - - } -} - -void ProtocolBufferDumper::write (int tag, int64_t v, bool fixed) -{ - if (fixed) { - write (tag, uint64_t (v), true); - } else { - write (tag, zigzag_encode (v), false); - } -} - -void ProtocolBufferDumper::write (int tag, bool b) -{ - write (tag, uint32_t (b ? 1 : 0)); -} - -void ProtocolBufferDumper::write (int tag, const std::string &s) -{ - write_varint (pb_varint ((tag << 3) + PB_LEN), true); - write_varint (s.size ()); - if (is_counting ()) { - - m_byte_counter_stack.back () += s.size (); - + add_bytes (sizeof (v)); } else { + char b[sizeof (v)]; + little_endian_encode (b, v); + dump (b, sizeof (v), "I32", tl::to_string (v)); + } +} +void ProtocolBufferDumper::write_fixed (uint64_t v) +{ + if (is_counting ()) { + add_bytes (sizeof (v)); + } else { + char b[sizeof (v)]; + little_endian_encode (b, v); + dump (b, sizeof (v), "I64", tl::to_string (v)); + } +} + +void ProtocolBufferDumper::write_bytes (const std::string &s) +{ + if (is_counting ()) { + add_bytes (s.size ()); + } else { dump (s.c_str (), s.size (), "(string)", s); - - } -} - -bool ProtocolBufferDumper::is_counting () const -{ - return ! m_byte_counter_stack.empty (); -} - -void ProtocolBufferDumper::begin_seq (int tag, bool counting) -{ - if (counting) { - - if (is_counting ()) { - write_varint (pb_varint ((tag << 3) + PB_LEN), true); - } - - m_byte_counter_stack.push_back (0); - - } else { - - write_varint (pb_varint ((tag << 3) + PB_LEN), true); - write_varint (m_bytes_counted); - - } -} - -void ProtocolBufferDumper::end_seq () -{ - if (is_counting ()) { - - m_bytes_counted = m_byte_counter_stack.back (); - m_byte_counter_stack.pop_back (); - - // just for adding the required bytes - if (is_counting ()) { - m_byte_counter_stack.back () += m_bytes_counted; - write_varint (m_bytes_counted); - } - } } @@ -654,7 +572,7 @@ ProtocolBufferDumper::write_varint (pb_varint v, bool id) { if (is_counting ()) { - m_byte_counter_stack.back () += count_varint_bytes (v); + add_bytes (count_varint_bytes (v)); } else { diff --git a/src/tl/tl/tlProtocolBuffer.h b/src/tl/tl/tlProtocolBuffer.h index 61acf4b04..0d7d8b4d6 100644 --- a/src/tl/tl/tlProtocolBuffer.h +++ b/src/tl/tl/tlProtocolBuffer.h @@ -319,45 +319,52 @@ public: /** * @brief Constructor */ - ProtocolBufferWriterBase () - { - // .. nothing yet .. - } + ProtocolBufferWriterBase (); /** * @brief Destructor */ - virtual ~ProtocolBufferWriterBase () - { - // .. nothing yet .. - } + virtual ~ProtocolBufferWriterBase (); /** - * @brief Writes a scalar tag with the given value + * @brief Writes a scalar element with the given value and tag */ - virtual void write (int tag, float v) = 0; - virtual void write (int tag, double v) = 0; - virtual void write (int tag, uint32_t v, bool fixed = false) = 0; - virtual void write (int tag, int32_t v, bool fixed = false) = 0; - virtual void write (int tag, uint64_t v, bool fixed = false) = 0; - virtual void write (int tag, int64_t v, bool fixed = false) = 0; - virtual void write (int tag, bool b) = 0; - virtual void write (int tag, const std::string &s) = 0; + + // implicit types + void write (int tag, float v); + void write (int tag, double v); + void write (int tag, int32_t v, bool fixed = false); + void write (int tag, int64_t v, bool fixed = false); + void write (int tag, uint32_t v, bool fixed = false); + void write (int tag, uint64_t v, bool fixed = false); + void write (int tag, bool b); + void write (int tag, const std::string &s); /** * @brief Returns true if the writer is in counting mode */ - virtual bool is_counting () const = 0; + bool is_counting () const; /** * @brief Initiates a new sequence. See class documentation for details. */ - virtual void begin_seq (int tag, bool counting) = 0; + void begin_seq (int tag, bool counting); /** * @brief Ends a sequence. See class documentation for details. */ - virtual void end_seq () = 0; + void end_seq (); + +protected: + virtual void write_bytes (const std::string &s) = 0; + virtual void write_fixed (uint32_t v) = 0; + virtual void write_fixed (uint64_t v) = 0; + virtual void write_varint (pb_varint v, bool id) = 0; + void add_bytes (size_t n); + +private: + size_t m_bytes_counted; + std::vector m_byte_counter_stack; }; /** @@ -376,39 +383,14 @@ public: */ ProtocolBufferWriter (tl::OutputStream &stream); - /** - * @brief Writes a scalar tag with the given value - */ - void write (int tag, float v); - void write (int tag, double v); - void write (int tag, uint32_t v, bool fixed = false); - void write (int tag, int32_t v, bool fixed = false); - void write (int tag, uint64_t v, bool fixed = false); - void write (int tag, int64_t v, bool fixed = false); - void write (int tag, bool b); - void write (int tag, const std::string &s); - - /** - * @brief Returns true if the writer is in counting mode - */ - bool is_counting () const; - - /** - * @brief Initiates a new sequence. See class documentation for details. - */ - void begin_seq (int tag, bool counting); - - /** - * @brief Ends a sequence. See class documentation for details. - */ - void end_seq (); +protected: + virtual void write_bytes (const std::string &s); + virtual void write_fixed (uint32_t v); + virtual void write_fixed (uint64_t v); + virtual void write_varint (pb_varint v, bool id = false); private: - void write_varint (pb_varint v, bool id = false); - tl::OutputStream *mp_stream; - size_t m_bytes_counted; - std::vector m_byte_counter_stack; }; /** @@ -426,39 +408,14 @@ public: */ ProtocolBufferDumper (); - /** - * @brief Writes a scalar tag with the given value - */ - void write (int tag, float v); - void write (int tag, double v); - void write (int tag, uint32_t v, bool fixed = false); - void write (int tag, int32_t v, bool fixed = false); - void write (int tag, uint64_t v, bool fixed = false); - void write (int tag, int64_t v, bool fixed = false); - void write (int tag, bool b); - void write (int tag, const std::string &s); - - /** - * @brief Returns true if the writer is in counting mode - */ - bool is_counting () const; - - /** - * @brief Initiates a new sequence. See class documentation for details. - */ - void begin_seq (int tag, bool counting); - - /** - * @brief Ends a sequence. See class documentation for details. - */ - void end_seq (); - -private: - void write_varint (pb_varint v, bool id = false); +protected: + virtual void write_bytes (const std::string &s); + virtual void write_fixed (uint32_t v); + virtual void write_fixed (uint64_t v); + virtual 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); - size_t m_bytes_counted; - std::vector m_byte_counter_stack; +private: size_t m_debug_pos; }; diff --git a/src/tl/tl/tlProtocolBufferStruct.h b/src/tl/tl/tlProtocolBufferStruct.h index 560cd89f9..68fd22e7e 100644 --- a/src/tl/tl/tlProtocolBufferStruct.h +++ b/src/tl/tl/tlProtocolBufferStruct.h @@ -520,7 +520,7 @@ public: virtual void parse (PBParser *, tl::ProtocolBufferReaderBase &) const = 0; virtual void finish (const PBElementBase *parent, PBReaderState &objs) const = 0; - virtual void write (const PBElementBase *, tl::ProtocolBufferWriter &, PBWriterState &) const { } + virtual void write (const PBElementBase *, tl::ProtocolBufferWriterBase &, PBWriterState &) const { } int tag () const { @@ -609,7 +609,7 @@ public: reader.close (); } - virtual void write (const PBElementBase * /*parent*/, tl::ProtocolBufferWriter &writer, PBWriterState &objs) const + virtual void write (const PBElementBase * /*parent*/, tl::ProtocolBufferWriterBase &writer, PBWriterState &objs) const { PBObjTag parent_tag; @@ -632,7 +632,7 @@ private: Write m_w; // this write helper is used if the reader delivers an object by value - void write_obj (Obj obj, int tag, tl::ProtocolBufferWriter &writer, tl::pass_by_value_tag, PBWriterState &objs) const + void write_obj (Obj obj, int tag, tl::ProtocolBufferWriterBase &writer, tl::pass_by_value_tag, PBWriterState &objs) const { PBObjTag self_tag; @@ -650,7 +650,7 @@ private: } } - void write_obj (const Obj &obj, int tag, tl::ProtocolBufferWriter &writer, tl::pass_by_ref_tag, PBWriterState &objs) const + void write_obj (const Obj &obj, int tag, tl::ProtocolBufferWriterBase &writer, tl::pass_by_ref_tag, PBWriterState &objs) const { PBObjTag self_tag; @@ -781,7 +781,7 @@ public: value_obj.pop (tag); } - virtual void write (const PBElementBase * /*parent*/, tl::ProtocolBufferWriter &writer, PBWriterState &objs) const + virtual void write (const PBElementBase * /*parent*/, tl::ProtocolBufferWriterBase &writer, PBWriterState &objs) const { PBObjTag parent_tag; Read r (m_r); @@ -798,68 +798,68 @@ private: Converter m_c; // write incarnations - void write (tl::ProtocolBufferWriter &writer, int tag, float v) const + void write (tl::ProtocolBufferWriterBase &writer, int tag, float v) const { writer.write (tag, v); } - void write (tl::ProtocolBufferWriter &writer, int tag, double v) const + void write (tl::ProtocolBufferWriterBase &writer, int tag, double v) const { writer.write (tag, v); } - void write (tl::ProtocolBufferWriter &writer, int tag, uint8_t v) const + void write (tl::ProtocolBufferWriterBase &writer, int tag, uint8_t v) const { writer.write (tag, (uint32_t) v); } - void write (tl::ProtocolBufferWriter &writer, int tag, int8_t v) const + void write (tl::ProtocolBufferWriterBase &writer, int tag, int8_t v) const { writer.write (tag, (int32_t) v); } - void write (tl::ProtocolBufferWriter &writer, int tag, uint16_t v) const + void write (tl::ProtocolBufferWriterBase &writer, int tag, uint16_t v) const { writer.write (tag, (uint32_t) v); } - void write (tl::ProtocolBufferWriter &writer, int tag, int16_t v) const + void write (tl::ProtocolBufferWriterBase &writer, int tag, int16_t v) const { writer.write (tag, (int32_t) v); } - void write (tl::ProtocolBufferWriter &writer, int tag, uint32_t v) const + void write (tl::ProtocolBufferWriterBase &writer, int tag, uint32_t v) const { writer.write (tag, v); } - void write (tl::ProtocolBufferWriter &writer, int tag, int32_t v) const + void write (tl::ProtocolBufferWriterBase &writer, int tag, int32_t v) const { writer.write (tag, v); } - void write (tl::ProtocolBufferWriter &writer, int tag, uint64_t v) const + void write (tl::ProtocolBufferWriterBase &writer, int tag, uint64_t v) const { writer.write (tag, v); } - void write (tl::ProtocolBufferWriter &writer, int tag, int64_t v) const + void write (tl::ProtocolBufferWriterBase &writer, int tag, int64_t v) const { writer.write (tag, v); } - void write (tl::ProtocolBufferWriter &writer, int tag, bool v) const + void write (tl::ProtocolBufferWriterBase &writer, int tag, bool v) const { writer.write (tag, v); } - void write (tl::ProtocolBufferWriter &writer, int tag, const std::string &v) const + void write (tl::ProtocolBufferWriterBase &writer, int tag, const std::string &v) const { writer.write (tag, v); } template - void write (tl::ProtocolBufferWriter &writer, int tag, const T &v) const + void write (tl::ProtocolBufferWriterBase &writer, int tag, const T &v) const { writer.write (tag, m_c.to_string (v)); } @@ -982,7 +982,7 @@ public: return new PBStruct (*this); } - void write (tl::ProtocolBufferWriter &writer, const Obj &root) const + void write (tl::ProtocolBufferWriterBase &writer, const Obj &root) const { PBWriterState writer_state; writer_state.push (& root); @@ -1006,7 +1006,7 @@ public: } private: - virtual void write (const PBElementBase*, tl::ProtocolBufferWriter &, PBWriterState &) const + virtual void write (const PBElementBase*, tl::ProtocolBufferWriterBase &, PBWriterState &) const { // disable base class implementation }