From: g0dil Date: Fri, 3 Jul 2009 09:20:04 +0000 (+0000) Subject: Packets: Add annotations to packet dump X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=76a2b3763bbd8c72fd22e48e5179e63d78a2a60a;p=senf.git Packets: Add annotations to packet dump git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1254 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Packets/Packet.test.cc b/Packets/Packet.test.cc index 18b8fe9..6aecfbe 100644 --- a/Packets/Packet.test.cc +++ b/Packets/Packet.test.cc @@ -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()->type(), diff --git a/Packets/PacketImpl.cc b/Packets/PacketImpl.cc index 647d37f..5b0ad43 100644 --- a/Packets/PacketImpl.cc +++ b/Packets/PacketImpl.cc @@ -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::const_iterator + i (registry().begin()), i_end (registry().end()); + i != i_end; ++i) + (*i)->v_dump(p,os); +} + /////////////////////////////////////////////////////////////////////////// // senf::detail::PacketImpl diff --git a/Packets/PacketImpl.cci b/Packets/PacketImpl.cci index e3c532e..3c6cce0 100644 --- a/Packets/PacketImpl.cci +++ b/Packets/PacketImpl.cci @@ -33,12 +33,22 @@ /////////////////////////////////////////////////////////////////////////// // senf::detail::AnnotationIndexerBase +prefix_ senf::detail::AnnotationIndexerBase::~AnnotationIndexerBase() +{} + prefix_ std::vector & senf::detail::AnnotationIndexerBase::small() { static std::vector smalls; return smalls; } +prefix_ std::vector & +senf::detail::AnnotationIndexerBase::registry() +{ + static std::vector 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? diff --git a/Packets/PacketImpl.cti b/Packets/PacketImpl.cti index 1f2d79a..e3ec1ea 100644 --- a/Packets/PacketImpl.cti +++ b/Packets/PacketImpl.cti @@ -38,6 +38,21 @@ prefix_ senf::detail::AnnotationIndexer::AnnotationIndexer() : index_ (maxAnnotations++) { small().push_back(Small); + registry().push_back(this); +} + +/////////////////////////////////////////////////////////////////////////// +// senf::detail::AnnotationIndexer + + +template +prefix_ void senf::detail::AnnotationIndexer::v_dump(PacketImpl * p, + std::ostream & os) +{ + + os << " " << senf::prettyName(typeid(Annotation)) << ": "; + p->dumpAnnotation(os); + os << "\n"; } template @@ -57,12 +72,27 @@ prefix_ Annotation & senf::detail::GetAnnotation::get(Annotati return static_cast< TAnnotationP* >(e.p)->annotation; } +template +prefix_ void senf::detail::GetAnnotation::dump(AnnotationEntry & e, + std::ostream & os) +{ + if (!e.p) os << "no value"; + else os << get(e); +} + template prefix_ Annotation & senf::detail::GetAnnotation::get(AnnotationEntry & e) { return * static_cast(static_cast(& e.i)); } +template +prefix_ void senf::detail::GetAnnotation::dump(AnnotationEntry & e, + std::ostream & os) +{ + os << get(e); +} + /////////////////////////////////////////////////////////////////////////// // senf::detail::PacketImpl @@ -91,6 +121,13 @@ prefix_ Annotation & senf::detail::PacketImpl::annotation() annotations_[AnnotationIndexer::index()]); } +template +prefix_ void senf::detail::PacketImpl::dumpAnnotation(std::ostream & os) +{ + GetAnnotation::dump( + annotations_[AnnotationIndexer::index()], os); +} + ///////////////////////////////cti.e/////////////////////////////////////// #undef prefix_ diff --git a/Packets/PacketImpl.hh b/Packets/PacketImpl.hh index 32ae5a1..0ad1e77 100644 --- a/Packets/PacketImpl.hh +++ b/Packets/PacketImpl.hh @@ -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 & small(); + static std::vector & registry(); + static void dump(PacketImpl * p, std::ostream & os); }; template @@ -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::value; @@ -112,12 +118,14 @@ namespace detail { struct GetAnnotation { static Annotation & get(AnnotationEntry & e); + static void dump(AnnotationEntry & e, std::ostream & os); }; template struct GetAnnotation { 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 Annotation & annotation(); + void dumpAnnotations(std::ostream & os); + template + void dumpAnnotation(std::ostream & os); /** \brief Internal: Keep PacketImpl instance alive diff --git a/Packets/PacketInterpreter.cc b/Packets/PacketInterpreter.cc index 466ba1f..fcd6783 100644 --- a/Packets/PacketInterpreter.cc +++ b/Packets/PacketInterpreter.cc @@ -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);