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 {
using mixin::init;
static void dump(packet p, std::ostream & os) {
os << "BarPacket:\n"
<< "type: " << p->type() << "\n"
<< "length: " << p->length() << "\n";
<< " type: " << p->type() << "\n"
<< " length: " << p->length() << "\n";
}
static void finalize(packet p) {
if (p.next(senf::nothrow))
......@@ -113,25 +113,41 @@ namespace {
struct IntAnnotation {
unsigned value;
};
std::ostream & operator<<(std::ostream & os, IntAnnotation const & v)
{ os << v.value; return os; }
struct LargeAnnotation {
char value[32];
};
std::ostream & operator<<(std::ostream & os, LargeAnnotation const & v)
{ os << v.value; return os; }
struct ComplexAnnotation : senf::ComplexAnnotation
{
ComplexAnnotation() : s(), i() {}
std::string s;
int i;
};
std::ostream & operator<<(std::ostream & os, ComplexAnnotation const & v)
{ os << "('" << v.s << "' " << v.i << ')'; return os; }
struct ComplexEmptyAnnotation : senf::ComplexAnnotation
{};
std::ostream & operator<<(std::ostream & os, ComplexEmptyAnnotation const & v)
{ os << "(empty)"; return os; }
struct InvalidAnnotation
{
std::string value;
};
std::ostream & operator<<(std::ostream & os, InvalidAnnotation const & v)
{ os << v.value; return os; }
}
BOOST_AUTO_UNIT_TEST(packet)
......@@ -180,7 +196,13 @@ BOOST_AUTO_UNIT_TEST(packet)
std::stringstream 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();
BOOST_CHECK_EQUAL( packet.last().as<BarPacket>()->type(),
......
......@@ -33,8 +33,19 @@
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::detail::AnnotationIndexerBase
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
......
......@@ -33,12 +33,22 @@
///////////////////////////////////////////////////////////////////////////
// senf::detail::AnnotationIndexerBase
prefix_ senf::detail::AnnotationIndexerBase::~AnnotationIndexerBase()
{}
prefix_ std::vector<bool> & senf::detail::AnnotationIndexerBase::small()
{
static std::vector<bool> smalls;
return smalls;
}
prefix_ std::vector<senf::detail::AnnotationIndexerBase*> &
senf::detail::AnnotationIndexerBase::registry()
{
static std::vector<AnnotationIndexerBase*> reg;
return reg;
}
///////////////////////////////////////////////////////////////////////////
// senf::detail::AnnotationP
......@@ -186,6 +196,11 @@ prefix_ senf::detail::PacketImpl::size_type senf::detail::PacketImpl::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
// resulting inlined code would be huge?
......
......@@ -38,6 +38,21 @@ prefix_ senf::detail::AnnotationIndexer<Annotation>::AnnotationIndexer()
: index_ (maxAnnotations++)
{
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>
......@@ -57,12 +72,27 @@ prefix_ Annotation & senf::detail::GetAnnotation<Annotation,Small>::get(Annotati
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>
prefix_ Annotation & senf::detail::GetAnnotation<Annotation, true>::get(AnnotationEntry & e)
{
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
......@@ -91,6 +121,13 @@ prefix_ Annotation & senf::detail::PacketImpl::annotation()
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///////////////////////////////////////
#undef prefix_
......
......@@ -82,8 +82,13 @@ namespace detail {
struct AnnotationIndexerBase
{
virtual ~AnnotationIndexerBase();
virtual void v_dump(PacketImpl * p, std::ostream & os) = 0;
static unsigned maxAnnotations;
static std::vector<bool> & small();
static std::vector<AnnotationIndexerBase*> & registry();
static void dump(PacketImpl * p, std::ostream & os);
};
template <class Annotation>
......@@ -92,6 +97,7 @@ namespace detail {
public AnnotationIndexerBase
{
AnnotationIndexer();
virtual void v_dump(PacketImpl * p, std::ostream & os);
unsigned index_;
static unsigned index();
static bool const Complex = boost::is_base_of<ComplexAnnotation, Annotation>::value;
......@@ -112,12 +118,14 @@ namespace detail {
struct GetAnnotation
{
static Annotation & get(AnnotationEntry & e);
static void dump(AnnotationEntry & e, std::ostream & os);
};
template <class Annotation>
struct GetAnnotation<Annotation, true>
{
static Annotation & get(AnnotationEntry & e);
static void dump(AnnotationEntry & e, std::ostream & os);
};
/** \brief Internal: Packet data storage
......@@ -191,6 +199,9 @@ namespace detail {
// Annotations
template <class Annotation>
Annotation & annotation();
void dumpAnnotations(std::ostream & os);
template <class Annotation>
void dumpAnnotation(std::ostream & os);
/** \brief Internal: Keep PacketImpl instance alive
......
......@@ -74,6 +74,10 @@ prefix_ senf::PacketInterpreterBase::ptr senf::PacketInterpreterBase::append(ptr
prefix_ void senf::PacketInterpreterBase::dump(std::ostream & os)
{
if (detail::AnnotationIndexerBase::maxAnnotations > 0) {
os << "Annotations:\n";
impl().dumpAnnotations(os);
}
v_dump(os);
for (ptr i (next()); i; i = i->next())
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