# HG changeset patch # User Mathieu Lacage # Date 1198577355 -3600 # Node ID ebe61d20a7aec680ce1471b0ae35b93b088923ab # Parent 2a729c1b2e68bfeebff78ebd4783113c22a99f00 fix bug 98 diff -r 2a729c1b2e68 -r ebe61d20a7ae src/core/array-trace-resolver.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/array-trace-resolver.cc Tue Dec 25 11:09:15 2007 +0100 @@ -0,0 +1,287 @@ +#include "array-trace-resolver.h" + + +namespace ns3 { + +ArrayTraceResolverMatcher::ArrayTraceResolverMatcher (std::string element) + : m_element (element) +{} +bool +ArrayTraceResolverMatcher::Matches (uint32_t i) const +{ + if (m_element == "*") + { + return true; + } + std::string::size_type tmp; + tmp = m_element.find ("|"); + if (tmp != std::string::npos) + { + std::string left = m_element.substr (0, tmp-0); + std::string right = m_element.substr (tmp+1, m_element.size () - (tmp + 1)); + ArrayTraceResolverMatcher matcher = ArrayTraceResolverMatcher (left); + if (matcher.Matches (i)) + { + return true; + } + matcher = ArrayTraceResolverMatcher (right); + if (matcher.Matches (i)) + { + return true; + } + return false; + } + std::string::size_type leftBracket = m_element.find ("["); + std::string::size_type rightBracket = m_element.find ("]"); + std::string::size_type dash = m_element.find ("-"); + if (leftBracket == 0 && rightBracket == m_element.size () - 1 && + dash > leftBracket && dash < rightBracket) + { + std::string lowerBound = m_element.substr (leftBracket + 1, dash - (leftBracket + 1)); + std::string upperBound = m_element.substr (dash + 1, rightBracket - (dash + 1)); + uint32_t min; + uint32_t max; + if (StringToUint32 (lowerBound, &min) && + StringToUint32 (upperBound, &max) && + i >= min && i <= max) + { + return true; + } + else + { + return false; + } + } + uint32_t value; + if (StringToUint32 (m_element, &value) && + i == value) + { + return true; + } + return false; +} + +bool +ArrayTraceResolverMatcher::StringToUint32 (std::string str, uint32_t *value) const +{ + std::istringstream iss; + iss.str (str); + iss >> (*value); + return !iss.bad () && !iss.fail (); +} + +}//namespace ns3 + + +#ifdef RUN_SELF_TESTS + +#include +#include "test.h" +#include "object.h" +#include "array-trace-resolver.h" +#include "callback-trace-source.h" +#include "composite-trace-resolver.h" + +namespace ns3 { + +class ObjectTraceTesterIndex : public TraceContextElement +{ +public: + ObjectTraceTesterIndex (); + ObjectTraceTesterIndex (uint32_t index); + void Print (std::ostream &os); + static uint16_t GetUid (void); + uint32_t Get (void) const; + std::string GetTypeName (void) const; +private: + uint32_t m_index; +}; + + +ObjectTraceTesterIndex::ObjectTraceTesterIndex () + : m_index (0) +{} +ObjectTraceTesterIndex::ObjectTraceTesterIndex (uint32_t index) + : m_index (index) +{} +void +ObjectTraceTesterIndex::Print (std::ostream &os) +{ + os << "nodeid=" << m_index; +} +uint16_t +ObjectTraceTesterIndex::GetUid (void) +{ + static uint16_t uid = AllocateUid ("ObjectTraceTesterIndex"); + return uid; +} +uint32_t +ObjectTraceTesterIndex::Get (void) const +{ + return m_index; +} +std::string +ObjectTraceTesterIndex::GetTypeName (void) const +{ + return "ns3::ObjectTraceTesterIndex"; +} + + +class ObjectTraceTester : public Object +{ +public: + void Do (uint32_t i); +protected: + virtual Ptr GetTraceResolver (void) const; +private: + CallbackTraceSource m_test; +}; + +void +ObjectTraceTester::Do (uint32_t i) +{ + m_test (i); +} + +Ptr +ObjectTraceTester::GetTraceResolver (void) const +{ + Ptr resolver = Create (); + resolver->AddSource ("test", + TraceDoc ("Test"), + m_test); + resolver->SetParentResolver (Object::GetTraceResolver ()); + return resolver; +} + +class ArrayTraceResolverTest : public Test +{ +public: + ArrayTraceResolverTest (); + virtual bool RunTests (void); +private: + bool RunOne (uint32_t n, std::string str, + uint32_t nExpected, ...); + void OneItem (const TraceContext &context, + uint32_t i); + + typedef std::vector Got; + Got m_got; +}; + +ArrayTraceResolverTest::ArrayTraceResolverTest () + : Test ("ArrayTraceResolver") +{} +bool +ArrayTraceResolverTest::RunOne (uint32_t n, std::string str, + uint32_t nExpected, ...) +{ + bool result = true; + std::vector expected; + va_list ap; + va_start (ap, nExpected); + for (uint32_t k = 0; k < nExpected; k++) + { + uint32_t v = va_arg (ap, uint32_t); + expected.push_back (v); + } + va_end (ap); + std::sort (expected.begin (), expected.end ()); + std::sort (m_got.begin (), m_got.end ()); + + std::vector > vec; + for (uint32_t i = 0; i < n; i++) + { + vec.push_back (Create ()); + } + ArrayTraceResolver resolver; + resolver.SetIterators (vec.begin (), vec.end ()); + + TraceContext context; + resolver.Connect (str, MakeCallback (&ArrayTraceResolverTest::OneItem, this), context); + uint32_t l = 0; + for (std::vector >::const_iterator j = vec.begin (); j != vec.end (); j++) + { + (*j)->Do (l); + l++; + } + NS_TEST_ASSERT_EQUAL (m_got.size (), expected.size ()); + for (uint32_t m = 0; m < expected.size (); m++) + { + NS_TEST_ASSERT_EQUAL (m_got[m], expected[m]); + } + m_got.clear (); + resolver.Disconnect (str, MakeCallback (&ArrayTraceResolverTest::OneItem, this)); + for (std::vector >::const_iterator j = vec.begin (); j != vec.end (); j++) + { + (*j)->Do (l); + l++; + } + NS_TEST_ASSERT_EQUAL (m_got.size (), 0); + m_got.clear (); + + return result; +} +void +ArrayTraceResolverTest::OneItem (const TraceContext &context, + uint32_t i) +{ + ObjectTraceTesterIndex index; + bool found = context.GetElement (index); + if (!found) + { + return; + } + if (index.Get () != i) + { + return; + } + m_got.push_back (i); +} + +bool +ArrayTraceResolverTest::RunTests (void) +{ + bool result = true; + + NS_TEST_ASSERT (RunOne (0, "/*/test", 0)); + NS_TEST_ASSERT (RunOne (1, "/*/test", 1, 0)); + NS_TEST_ASSERT (RunOne (1, "/0/test", 1, 0)); + NS_TEST_ASSERT (RunOne (1, "/[0-0]/test", 1, 0)); + NS_TEST_ASSERT (RunOne (1, "/0|0/test", 1, 0)); + NS_TEST_ASSERT (RunOne (2, "/*/test", 2, 0, 1)); + NS_TEST_ASSERT (RunOne (2, "/0|1/test", 2, 0, 1)); + NS_TEST_ASSERT (RunOne (2, "/1/test", 1, 1)); + NS_TEST_ASSERT (RunOne (2, "/|1|/test", 1, 1)); + NS_TEST_ASSERT (RunOne (2, "/0/test", 1, 0)); + NS_TEST_ASSERT (RunOne (2, "/0|/test", 1, 0)); + NS_TEST_ASSERT (RunOne (2, "/|0/test", 1, 0)); + NS_TEST_ASSERT (RunOne (2, "/[0-1]/test", 2, 0, 1)); + NS_TEST_ASSERT (RunOne (2, "/[0-0]/test", 1, 0)); + NS_TEST_ASSERT (RunOne (2, "/[1-1]/test", 1, 1)); + NS_TEST_ASSERT (RunOne (2, "/0|[1-1]/test", 2, 0, 1)); + NS_TEST_ASSERT (RunOne (3, "/1|0/test", 2, 0, 1)); + NS_TEST_ASSERT (RunOne (3, "/2|0/test", 2, 0, 2)); + NS_TEST_ASSERT (RunOne (3, "/2|1/test", 2, 1, 2)); + NS_TEST_ASSERT (RunOne (3, "/[0-1]/test", 2, 0, 1)); + NS_TEST_ASSERT (RunOne (3, "/[1-2]/test", 2, 1, 2)); + NS_TEST_ASSERT (RunOne (3, "/[0-2]/test", 3, 0, 1, 2)); + NS_TEST_ASSERT (RunOne (3, "/[1-2]|0/test", 3, 0, 1, 2)); + NS_TEST_ASSERT (RunOne (3, "/[1-1]|0|[2-2]/test", 3, 0, 1, 2)); + NS_TEST_ASSERT (RunOne (3, "/[1-2]||/test", 2, 1, 2)); + NS_TEST_ASSERT (RunOne (3, "/[1-2]||/test", 2, 2, 1)); + NS_TEST_ASSERT (RunOne (3, "/||||/test", 0)); + NS_TEST_ASSERT (RunOne (20, "/[5-10]|[2-3]|[15-17]/test", 11, 2, 3, 5, 6, 7, 8, 9, 10, 15, 16, 17)); + NS_TEST_ASSERT (RunOne (3, "/[1-2]|[0-1]/test", 3, 0, 1, 2)); + + return result; +} + + + +static ArrayTraceResolverTest g_arrayTraceResolverTest; + + +} // namespace ns3 + +#endif /* RUN_SELF_TESTS */ diff -r 2a729c1b2e68 -r ebe61d20a7ae src/core/array-trace-resolver.h --- a/src/core/array-trace-resolver.h Sat Dec 22 18:46:43 2007 +0000 +++ b/src/core/array-trace-resolver.h Tue Dec 25 11:09:15 2007 +0100 @@ -23,6 +23,7 @@ #include #include +#include #include "callback.h" #include "trace-resolver.h" #include "object.h" @@ -78,6 +79,17 @@ }; IteratorBase *m_iter; }; + +class ArrayTraceResolverMatcher +{ +public: + ArrayTraceResolverMatcher (std::string element); + bool Matches (uint32_t i) const; + bool StringToUint32 (std::string str, uint32_t *value) const; +private: + std::string m_element; +}; + }//namespace ns3 @@ -133,19 +145,20 @@ } std::string id = GetElement (path); std::string subpath = GetSubpath (path); - if (id == "*") - { - uint32_t j = 0; - for (m_iter->Rewind (); m_iter->HasNext (); m_iter->Next ()) - { - TraceContext tmp = context; - INDEX index = j; - tmp.AddElement (index); - Ptr obj = m_iter->Get (); - obj->GetTraceResolver ()->Connect (subpath, cb, tmp); - j++; - } - } + ArrayTraceResolverMatcher matcher = ArrayTraceResolverMatcher (id); + uint32_t i = 0; + for (m_iter->Rewind (); m_iter->HasNext (); m_iter->Next ()) + { + if (matcher.Matches (i)) + { + TraceContext tmp = context; + INDEX index = i; + tmp.AddElement (index); + Ptr obj = m_iter->Get (); + obj->GetTraceResolver ()->Connect (subpath, cb, tmp); + } + i++; + } } template void @@ -157,14 +170,17 @@ } std::string id = GetElement (path); std::string subpath = GetSubpath (path); - if (id == "*") - { - for (m_iter->Rewind (); m_iter->HasNext (); m_iter->Next ()) - { - Ptr obj = m_iter->Get (); - obj->TraceDisconnect (subpath, cb); - } - } + ArrayTraceResolverMatcher matcher = ArrayTraceResolverMatcher (id); + uint32_t i = 0; + for (m_iter->Rewind (); m_iter->HasNext (); m_iter->Next ()) + { + if (matcher.Matches (i)) + { + Ptr obj = m_iter->Get (); + obj->TraceDisconnect (subpath, cb); + } + i++; + } } template void diff -r 2a729c1b2e68 -r ebe61d20a7ae src/core/wscript --- a/src/core/wscript Sat Dec 22 18:46:43 2007 +0000 +++ b/src/core/wscript Tue Dec 25 11:09:15 2007 +0100 @@ -51,6 +51,7 @@ 'trace-doc.cc', 'trace-source.cc', 'type-traits-test.cc', + 'array-trace-resolver.cc', ] if sys.platform == 'win32':