Skip to content
Snippets Groups Projects
Commit d5068cf5 authored by g0dil's avatar g0dil
Browse files

Packets: Add annotations to packet dump

parent e8fe8333
No related branches found
No related tags found
No related merge requests found
...@@ -90,8 +90,8 @@ namespace { ...@@ -90,8 +90,8 @@ namespace {
using mixin::init; using mixin::init;
static void dump(packet p, std::ostream & os) { static void dump(packet p, std::ostream & os) {
os << "BarPacket:\n" os << "BarPacket:\n"
<< "type: " << p->type() << "\n" << " type: " << p->type() << "\n"
<< "length: " << p->length() << "\n"; << " length: " << p->length() << "\n";
} }
static void finalize(packet p) { static void finalize(packet p) {
if (p.next(senf::nothrow)) if (p.next(senf::nothrow))
...@@ -113,25 +113,41 @@ namespace { ...@@ -113,25 +113,41 @@ namespace {
struct IntAnnotation { struct IntAnnotation {
unsigned value; unsigned value;
}; };
std::ostream & operator<<(std::ostream & os, IntAnnotation const & v)
{ os << v.value; return os; }
struct LargeAnnotation { struct LargeAnnotation {
char value[32]; char value[32];
}; };
std::ostream & operator<<(std::ostream & os, LargeAnnotation const & v)
{ os << v.value; return os; }
struct ComplexAnnotation : senf::ComplexAnnotation struct ComplexAnnotation : senf::ComplexAnnotation
{ {
ComplexAnnotation() : s(), i() {}
std::string s; std::string s;
int i; int i;
}; };
std::ostream & operator<<(std::ostream & os, ComplexAnnotation const & v)
{ os << "('" << v.s << "' " << v.i << ')'; return os; }
struct ComplexEmptyAnnotation : senf::ComplexAnnotation struct ComplexEmptyAnnotation : senf::ComplexAnnotation
{}; {};
std::ostream & operator<<(std::ostream & os, ComplexEmptyAnnotation const & v)
{ os << "(empty)"; return os; }
struct InvalidAnnotation struct InvalidAnnotation
{ {
std::string value; std::string value;
}; };
std::ostream & operator<<(std::ostream & os, InvalidAnnotation const & v)
{ os << v.value; return os; }
} }
BOOST_AUTO_UNIT_TEST(packet) BOOST_AUTO_UNIT_TEST(packet)
...@@ -180,7 +196,13 @@ BOOST_AUTO_UNIT_TEST(packet) ...@@ -180,7 +196,13 @@ BOOST_AUTO_UNIT_TEST(packet)
std::stringstream s; std::stringstream s;
packet.dump(s); packet.dump(s);
BOOST_CHECK_EQUAL( s.str(), "BarPacket:\ntype: 0\nlength: 0\n" ); BOOST_CHECK_EQUAL( s.str(),
"Annotations:\n"
" (anonymous namespace)::ComplexAnnotation: no value\n"
" (anonymous namespace)::IntAnnotation: 0\n"
"BarPacket:\n"
" type: 0\n"
" length: 0\n" );
packet.finalizeAll(); packet.finalizeAll();
BOOST_CHECK_EQUAL( packet.last().as<BarPacket>()->type(), BOOST_CHECK_EQUAL( packet.last().as<BarPacket>()->type(),
......
...@@ -33,8 +33,19 @@ ...@@ -33,8 +33,19 @@
#define prefix_ #define prefix_
///////////////////////////////cc.p//////////////////////////////////////// ///////////////////////////////cc.p////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::detail::AnnotationIndexerBase
unsigned senf::detail::AnnotationIndexerBase::maxAnnotations (0); unsigned senf::detail::AnnotationIndexerBase::maxAnnotations (0);
prefix_ void senf::detail::AnnotationIndexerBase::dump(PacketImpl * p, std::ostream & os)
{
for(std::vector<AnnotationIndexerBase*>::const_iterator
i (registry().begin()), i_end (registry().end());
i != i_end; ++i)
(*i)->v_dump(p,os);
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// senf::detail::PacketImpl // senf::detail::PacketImpl
......
...@@ -33,12 +33,22 @@ ...@@ -33,12 +33,22 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// senf::detail::AnnotationIndexerBase // senf::detail::AnnotationIndexerBase
prefix_ senf::detail::AnnotationIndexerBase::~AnnotationIndexerBase()
{}
prefix_ std::vector<bool> & senf::detail::AnnotationIndexerBase::small() prefix_ std::vector<bool> & senf::detail::AnnotationIndexerBase::small()
{ {
static std::vector<bool> smalls; static std::vector<bool> smalls;
return smalls; return smalls;
} }
prefix_ std::vector<senf::detail::AnnotationIndexerBase*> &
senf::detail::AnnotationIndexerBase::registry()
{
static std::vector<AnnotationIndexerBase*> reg;
return reg;
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// senf::detail::AnnotationP // senf::detail::AnnotationP
...@@ -186,6 +196,11 @@ prefix_ senf::detail::PacketImpl::size_type senf::detail::PacketImpl::capacity() ...@@ -186,6 +196,11 @@ prefix_ senf::detail::PacketImpl::size_type senf::detail::PacketImpl::capacity()
return data_.capacity(); return data_.capacity();
} }
prefix_ void senf::detail::PacketImpl::dumpAnnotations(std::ostream & os)
{
AnnotationIndexerBase::dump(this, os);
}
// This function has a problem being inlined. Somehow, often when calling this, the size of the // This function has a problem being inlined. Somehow, often when calling this, the size of the
// resulting inlined code would be huge? // resulting inlined code would be huge?
......
...@@ -38,6 +38,21 @@ prefix_ senf::detail::AnnotationIndexer<Annotation>::AnnotationIndexer() ...@@ -38,6 +38,21 @@ prefix_ senf::detail::AnnotationIndexer<Annotation>::AnnotationIndexer()
: index_ (maxAnnotations++) : index_ (maxAnnotations++)
{ {
small().push_back(Small); small().push_back(Small);
registry().push_back(this);
}
///////////////////////////////////////////////////////////////////////////
// senf::detail::AnnotationIndexer<Annotation>
template <class Annotation>
prefix_ void senf::detail::AnnotationIndexer<Annotation>::v_dump(PacketImpl * p,
std::ostream & os)
{
os << " " << senf::prettyName(typeid(Annotation)) << ": ";
p->dumpAnnotation<Annotation>(os);
os << "\n";
} }
template <class Annotation> template <class Annotation>
...@@ -57,12 +72,27 @@ prefix_ Annotation & senf::detail::GetAnnotation<Annotation,Small>::get(Annotati ...@@ -57,12 +72,27 @@ prefix_ Annotation & senf::detail::GetAnnotation<Annotation,Small>::get(Annotati
return static_cast< TAnnotationP<Annotation>* >(e.p)->annotation; return static_cast< TAnnotationP<Annotation>* >(e.p)->annotation;
} }
template <class Annotation, bool Small>
prefix_ void senf::detail::GetAnnotation<Annotation,Small>::dump(AnnotationEntry & e,
std::ostream & os)
{
if (!e.p) os << "no value";
else os << get(e);
}
template <class Annotation> template <class Annotation>
prefix_ Annotation & senf::detail::GetAnnotation<Annotation, true>::get(AnnotationEntry & e) prefix_ Annotation & senf::detail::GetAnnotation<Annotation, true>::get(AnnotationEntry & e)
{ {
return * static_cast<Annotation*>(static_cast<void*>(& e.i)); return * static_cast<Annotation*>(static_cast<void*>(& e.i));
} }
template <class Annotation>
prefix_ void senf::detail::GetAnnotation<Annotation, true>::dump(AnnotationEntry & e,
std::ostream & os)
{
os << get(e);
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// senf::detail::PacketImpl // senf::detail::PacketImpl
...@@ -91,6 +121,13 @@ prefix_ Annotation & senf::detail::PacketImpl::annotation() ...@@ -91,6 +121,13 @@ prefix_ Annotation & senf::detail::PacketImpl::annotation()
annotations_[AnnotationIndexer<Annotation>::index()]); annotations_[AnnotationIndexer<Annotation>::index()]);
} }
template <class Annotation>
prefix_ void senf::detail::PacketImpl::dumpAnnotation(std::ostream & os)
{
GetAnnotation<Annotation>::dump(
annotations_[AnnotationIndexer<Annotation>::index()], os);
}
///////////////////////////////cti.e/////////////////////////////////////// ///////////////////////////////cti.e///////////////////////////////////////
#undef prefix_ #undef prefix_
......
...@@ -82,8 +82,13 @@ namespace detail { ...@@ -82,8 +82,13 @@ namespace detail {
struct AnnotationIndexerBase struct AnnotationIndexerBase
{ {
virtual ~AnnotationIndexerBase();
virtual void v_dump(PacketImpl * p, std::ostream & os) = 0;
static unsigned maxAnnotations; static unsigned maxAnnotations;
static std::vector<bool> & small(); static std::vector<bool> & small();
static std::vector<AnnotationIndexerBase*> & registry();
static void dump(PacketImpl * p, std::ostream & os);
}; };
template <class Annotation> template <class Annotation>
...@@ -92,6 +97,7 @@ namespace detail { ...@@ -92,6 +97,7 @@ namespace detail {
public AnnotationIndexerBase public AnnotationIndexerBase
{ {
AnnotationIndexer(); AnnotationIndexer();
virtual void v_dump(PacketImpl * p, std::ostream & os);
unsigned index_; unsigned index_;
static unsigned index(); static unsigned index();
static bool const Complex = boost::is_base_of<ComplexAnnotation, Annotation>::value; static bool const Complex = boost::is_base_of<ComplexAnnotation, Annotation>::value;
...@@ -112,12 +118,14 @@ namespace detail { ...@@ -112,12 +118,14 @@ namespace detail {
struct GetAnnotation struct GetAnnotation
{ {
static Annotation & get(AnnotationEntry & e); static Annotation & get(AnnotationEntry & e);
static void dump(AnnotationEntry & e, std::ostream & os);
}; };
template <class Annotation> template <class Annotation>
struct GetAnnotation<Annotation, true> struct GetAnnotation<Annotation, true>
{ {
static Annotation & get(AnnotationEntry & e); static Annotation & get(AnnotationEntry & e);
static void dump(AnnotationEntry & e, std::ostream & os);
}; };
/** \brief Internal: Packet data storage /** \brief Internal: Packet data storage
...@@ -191,6 +199,9 @@ namespace detail { ...@@ -191,6 +199,9 @@ namespace detail {
// Annotations // Annotations
template <class Annotation> template <class Annotation>
Annotation & annotation(); Annotation & annotation();
void dumpAnnotations(std::ostream & os);
template <class Annotation>
void dumpAnnotation(std::ostream & os);
/** \brief Internal: Keep PacketImpl instance alive /** \brief Internal: Keep PacketImpl instance alive
......
...@@ -74,6 +74,10 @@ prefix_ senf::PacketInterpreterBase::ptr senf::PacketInterpreterBase::append(ptr ...@@ -74,6 +74,10 @@ prefix_ senf::PacketInterpreterBase::ptr senf::PacketInterpreterBase::append(ptr
prefix_ void senf::PacketInterpreterBase::dump(std::ostream & os) prefix_ void senf::PacketInterpreterBase::dump(std::ostream & os)
{ {
if (detail::AnnotationIndexerBase::maxAnnotations > 0) {
os << "Annotations:\n";
impl().dumpAnnotations(os);
}
v_dump(os); v_dump(os);
for (ptr i (next()); i; i = i->next()) for (ptr i (next()); i; i = i->next())
i->v_dump(os); i->v_dump(os);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment