This commit is contained in:
Matthias Koefferlein 2024-08-11 15:51:36 +02:00
parent 0f067e1dd8
commit 7357fe50e2
3 changed files with 170 additions and 295 deletions

View File

@ -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<uint32_t *> (&v), true);
}
void ProtocolBufferWriter::write (int tag, double v)
void ProtocolBufferWriterBase::write (int tag, double v)
{
write (tag, *reinterpret_cast<uint64_t *> (&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<uint32_t *> (&v), true);
}
void ProtocolBufferDumper::write (int tag, double v)
{
write (tag, *reinterpret_cast<uint64_t *> (&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 {

View File

@ -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<size_t> 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<size_t> 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<size_t> m_byte_counter_stack;
private:
size_t m_debug_pos;
};

View File

@ -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> 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<Obj> 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<Obj> 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> 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 <class T>
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<Obj> (*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
}