replace RefCountBase with SimpleRefCount<> to avoid duplicate refcounting implementations.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
3 * Copyright (c) 2005,2006 INRIA
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
21 #include "ns3/assert.h"
27 NS_LOG_COMPONENT_DEFINE ("Packet");
31 uint32_t Packet::m_globalUid = 0;
34 ByteTagIterator::Item::GetTypeId (void) const
39 ByteTagIterator::Item::GetStart (void) const
44 ByteTagIterator::Item::GetEnd (void) const
49 ByteTagIterator::Item::GetTag (Tag &tag) const
51 if (tag.GetInstanceTypeId () != GetTypeId ())
53 NS_FATAL_ERROR ("The tag you provided is not of the right type.");
55 tag.Deserialize (m_buffer);
57 ByteTagIterator::Item::Item (TypeId tid, uint32_t start, uint32_t end, TagBuffer buffer)
64 ByteTagIterator::HasNext (void) const
66 return m_current.HasNext ();
69 ByteTagIterator::Next (void)
71 ByteTagList::Iterator::Item i = m_current.Next ();
72 return ByteTagIterator::Item (i.tid,
73 i.start-m_current.GetOffsetStart (),
74 i.end-m_current.GetOffsetStart (),
77 ByteTagIterator::ByteTagIterator (ByteTagList::Iterator i)
82 PacketTagIterator::PacketTagIterator (const struct PacketTagList::TagData *head)
86 PacketTagIterator::HasNext (void) const
88 return m_current != 0;
90 PacketTagIterator::Item
91 PacketTagIterator::Next (void)
93 NS_ASSERT (HasNext ());
94 const struct PacketTagList::TagData *prev = m_current;
95 m_current = m_current->next;
96 return PacketTagIterator::Item (prev);
99 PacketTagIterator::Item::Item (const struct PacketTagList::TagData *data)
103 PacketTagIterator::Item::GetTypeId (void) const
108 PacketTagIterator::Item::GetTag (Tag &tag) const
110 NS_ASSERT (tag.GetInstanceTypeId () == m_data->tid);
111 tag.Deserialize (TagBuffer ((uint8_t*)m_data->data, (uint8_t*)m_data->data+PACKET_TAG_MAX_SIZE));
116 Packet::Copy (void) const
118 // we need to invoke the copy constructor directly
119 // rather than calling Create because the copy constructor
121 return Ptr<Packet> (new Packet (*this), false);
128 m_metadata (m_globalUid, 0),
134 Packet::Packet (const Packet &o)
135 : m_buffer (o.m_buffer),
136 m_byteTagList (o.m_byteTagList),
137 m_packetTagList (o.m_packetTagList),
138 m_metadata (o.m_metadata)
140 o.m_nixVector ? m_nixVector = o.m_nixVector->Copy ()
145 Packet::operator = (const Packet &o)
151 m_buffer = o.m_buffer;
152 m_byteTagList = o.m_byteTagList;
153 m_packetTagList = o.m_packetTagList;
154 m_metadata = o.m_metadata;
155 o.m_nixVector ? m_nixVector = o.m_nixVector->Copy ()
160 Packet::Packet (uint32_t size)
164 m_metadata (m_globalUid, size),
169 Packet::Packet (uint8_t const*buffer, uint32_t size)
173 m_metadata (m_globalUid, size),
177 m_buffer.AddAtStart (size);
178 Buffer::Iterator i = m_buffer.Begin ();
179 i.Write (buffer, size);
182 Packet::Packet (const Buffer &buffer, const ByteTagList &byteTagList,
183 const PacketTagList &packetTagList, const PacketMetadata &metadata)
185 m_byteTagList (byteTagList),
186 m_packetTagList (packetTagList),
187 m_metadata (metadata),
192 Packet::CreateFragment (uint32_t start, uint32_t length) const
194 NS_LOG_FUNCTION (this << start << length);
195 Buffer buffer = m_buffer.CreateFragment (start, length);
196 NS_ASSERT (m_buffer.GetSize () >= start + length);
197 uint32_t end = m_buffer.GetSize () - (start + length);
198 PacketMetadata metadata = m_metadata.CreateFragment (start, end);
199 // again, call the constructor directly rather than
200 // through Create because it is private.
201 return Ptr<Packet> (new Packet (buffer, m_byteTagList, m_packetTagList, metadata), false);
205 Packet::SetNixVector (Ptr<NixVector> nixVector)
207 m_nixVector = nixVector;
211 Packet::GetNixVector (void) const
217 Packet::GetSize (void) const
219 return m_buffer.GetSize ();
223 Packet::AddHeader (const Header &header)
225 uint32_t size = header.GetSerializedSize ();
226 NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << size);
227 uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
228 bool resized = m_buffer.AddAtStart (size);
231 m_byteTagList.AddAtStart (m_buffer.GetCurrentStartOffset () + size - orgStart,
232 m_buffer.GetCurrentStartOffset () + size);
234 header.Serialize (m_buffer.Begin ());
235 m_metadata.AddHeader (header, size);
238 Packet::RemoveHeader (Header &header)
240 uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
241 NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
242 m_buffer.RemoveAtStart (deserialized);
243 m_metadata.RemoveHeader (header, deserialized);
247 Packet::PeekHeader (Header &header) const
249 uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
250 NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
254 Packet::AddTrailer (const Trailer &trailer)
256 uint32_t size = trailer.GetSerializedSize ();
257 NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << size);
258 uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
259 bool resized = m_buffer.AddAtEnd (size);
262 m_byteTagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - orgStart,
263 m_buffer.GetCurrentEndOffset () - size);
265 Buffer::Iterator end = m_buffer.End ();
266 trailer.Serialize (end);
267 m_metadata.AddTrailer (trailer, size);
270 Packet::RemoveTrailer (Trailer &trailer)
272 uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
273 NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << deserialized);
274 m_buffer.RemoveAtEnd (deserialized);
275 m_metadata.RemoveTrailer (trailer, deserialized);
279 Packet::PeekTrailer (Trailer &trailer)
281 uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
282 NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << deserialized);
287 Packet::AddAtEnd (Ptr<const Packet> packet)
289 NS_LOG_FUNCTION (this << packet << packet->GetSize ());
290 uint32_t aStart = m_buffer.GetCurrentStartOffset ();
291 uint32_t bEnd = packet->m_buffer.GetCurrentEndOffset ();
292 m_buffer.AddAtEnd (packet->m_buffer);
293 uint32_t appendPrependOffset = m_buffer.GetCurrentEndOffset () - packet->m_buffer.GetSize ();
294 m_byteTagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - aStart,
295 appendPrependOffset);
296 ByteTagList copy = packet->m_byteTagList;
297 copy.AddAtStart (m_buffer.GetCurrentEndOffset () - bEnd,
298 appendPrependOffset);
299 m_byteTagList.Add (copy);
300 m_metadata.AddAtEnd (packet->m_metadata);
303 Packet::AddPaddingAtEnd (uint32_t size)
305 NS_LOG_FUNCTION (this << size);
306 uint32_t orgEnd = m_buffer.GetCurrentEndOffset ();
307 bool resized = m_buffer.AddAtEnd (size);
310 m_byteTagList.AddAtEnd (m_buffer.GetCurrentEndOffset () - orgEnd,
311 m_buffer.GetCurrentEndOffset () - size);
313 m_metadata.AddPaddingAtEnd (size);
316 Packet::RemoveAtEnd (uint32_t size)
318 NS_LOG_FUNCTION (this << size);
319 m_buffer.RemoveAtEnd (size);
320 m_metadata.RemoveAtEnd (size);
323 Packet::RemoveAtStart (uint32_t size)
325 NS_LOG_FUNCTION (this << size);
326 m_buffer.RemoveAtStart (size);
327 m_metadata.RemoveAtStart (size);
331 Packet::RemoveAllByteTags (void)
333 NS_LOG_FUNCTION (this);
334 m_byteTagList.RemoveAll ();
338 Packet::PeekData (void) const
340 NS_LOG_FUNCTION (this);
341 uint32_t oldStart = m_buffer.GetCurrentStartOffset ();
342 uint8_t const * data = m_buffer.PeekData ();
343 uint32_t newStart = m_buffer.GetCurrentStartOffset ();
345 // Update tag offsets if buffer offsets were changed
346 const_cast<ByteTagList &>(m_byteTagList).AddAtStart (newStart - oldStart, newStart);
351 Packet::CopyData (uint8_t *buffer, uint32_t size) const
353 Buffer::Iterator i = m_buffer.Begin ();
355 while (!i.IsEnd () && cur < size)
357 buffer[cur] = i.ReadU8 ();
364 Packet::CopyData(std::ostream *os, uint32_t size) const
366 return m_buffer.CopyData (os, size);
370 Packet::GetUid (void) const
372 return m_metadata.GetUid ();
376 Packet::PrintByteTags (std::ostream &os) const
378 ByteTagIterator i = GetByteTagIterator ();
381 ByteTagIterator::Item item = i.Next ();
382 os << item.GetTypeId ().GetName () << " [" << item.GetStart () << "-" << item.GetEnd () << "]";
383 Callback<ObjectBase *> constructor = item.GetTypeId ().GetConstructor ();
384 if (constructor.IsNull ())
392 Tag *tag = dynamic_cast<Tag *> (constructor ());
393 NS_ASSERT (tag != 0);
406 Packet::Print (std::ostream &os) const
408 PacketMetadata::ItemIterator i = m_metadata.BeginItem (m_buffer);
411 PacketMetadata::Item item = i.Next ();
415 case PacketMetadata::Item::PAYLOAD:
418 case PacketMetadata::Item::HEADER:
419 case PacketMetadata::Item::TRAILER:
420 os << item.tid.GetName ();
423 os << " Fragment [" << item.currentTrimedFromStart<<":"
424 << (item.currentTrimedFromStart + item.currentSize) << "]";
429 case PacketMetadata::Item::PAYLOAD:
430 os << "Payload (size=" << item.currentSize << ")";
432 case PacketMetadata::Item::HEADER:
433 case PacketMetadata::Item::TRAILER:
434 os << item.tid.GetName () << " (";
436 NS_ASSERT (item.tid.HasConstructor ());
437 Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
438 NS_ASSERT (!constructor.IsNull ());
439 ObjectBase *instance = constructor ();
440 NS_ASSERT (instance != 0);
441 Chunk *chunk = dynamic_cast<Chunk *> (instance);
442 NS_ASSERT (chunk != 0);
443 chunk->Deserialize (item.current);
457 // The code below will work only if headers and trailers
458 // define the right attributes which is not the case for
459 // now. So, as a temporary measure, we use the
460 // headers' and trailers' Print method as shown above.
461 PacketMetadata::ItemIterator i = m_metadata.BeginItem (m_buffer);
464 PacketMetadata::Item item = i.Next ();
468 case PacketMetadata::Item::PAYLOAD:
471 case PacketMetadata::Item::HEADER:
472 case PacketMetadata::Item::TRAILER:
473 os << item.tid.GetName ();
476 os << " Fragment [" << item.currentTrimedFromStart<<":"
477 << (item.currentTrimedFromStart + item.currentSize) << "]";
482 case PacketMetadata::Item::PAYLOAD:
483 os << "Payload (size=" << item.currentSize << ")";
485 case PacketMetadata::Item::HEADER:
486 case PacketMetadata::Item::TRAILER:
487 os << item.tid.GetName () << "(";
489 NS_ASSERT (item.tid.HasConstructor ());
490 Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
491 NS_ASSERT (constructor.IsNull ());
492 ObjectBase *instance = constructor ();
493 NS_ASSERT (instance != 0);
494 Chunk *chunk = dynamic_cast<Chunk *> (instance);
495 NS_ASSERT (chunk != 0);
496 chunk->Deserialize (item.current);
497 for (uint32_t j = 0; j < item.tid.GetAttributeN (); j++)
499 std::string attrName = item.tid.GetAttributeName (j);
501 bool ok = chunk->GetAttribute (attrName, value);
503 os << attrName << "=" << value;
504 if ((j + 1) < item.tid.GetAttributeN ())
522 PacketMetadata::ItemIterator
523 Packet::BeginItem (void) const
525 return m_metadata.BeginItem (m_buffer);
529 Packet::EnablePrinting (void)
531 NS_LOG_FUNCTION_NOARGS ();
532 PacketMetadata::Enable ();
536 Packet::EnableChecking (void)
538 NS_LOG_FUNCTION_NOARGS ();
539 PacketMetadata::EnableChecking ();
543 Packet::Serialize (void) const
545 NS_LOG_FUNCTION (this);
550 reserve = m_metadata.GetSerializedSize ();
551 buffer.AddAtStart (reserve);
552 m_metadata.Serialize (buffer.Begin (), reserve);
556 //reserve = m_tags.GetSerializedSize ();
557 //buffer.AddAtStart (reserve);
558 //m_tags.Serialize (buffer.Begin (), reserve);
560 // aggregate byte buffer, metadata, and tags
561 Buffer tmp = m_buffer.CreateFullCopy ();
562 tmp.AddAtEnd (buffer);
564 // write byte buffer size.
566 tmp.Begin ().WriteU32 (m_buffer.GetSize ());
571 Packet::Deserialize (Buffer buffer)
573 NS_LOG_FUNCTION (this);
576 uint32_t packetSize = buf.Begin ().ReadU32 ();
577 buf.RemoveAtStart (4);
580 buf.RemoveAtEnd (buf.GetSize () - packetSize);
582 buffer.RemoveAtStart (4 + packetSize);
587 //uint32_t tagsDeserialized = m_tags.Deserialize (buffer.Begin ());
588 //buffer.RemoveAtStart (tagsDeserialized);
591 uint32_t metadataDeserialized =
592 m_metadata.Deserialize (buffer.Begin ());
593 buffer.RemoveAtStart (metadataDeserialized);
597 Packet::AddByteTag (const Tag &tag) const
599 NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
600 ByteTagList *list = const_cast<ByteTagList *> (&m_byteTagList);
601 TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (),
602 m_buffer.GetCurrentStartOffset (),
603 m_buffer.GetCurrentEndOffset ());
604 tag.Serialize (buffer);
607 Packet::GetByteTagIterator (void) const
609 return ByteTagIterator (m_byteTagList.Begin (m_buffer.GetCurrentStartOffset (), m_buffer.GetCurrentEndOffset ()));
613 Packet::FindFirstMatchingByteTag (Tag &tag) const
615 TypeId tid = tag.GetInstanceTypeId ();
616 ByteTagIterator i = GetByteTagIterator ();
619 ByteTagIterator::Item item = i.Next ();
620 if (tid == item.GetTypeId ())
630 Packet::AddPacketTag (const Tag &tag) const
632 NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
633 m_packetTagList.Add (tag);
636 Packet::RemovePacketTag (Tag &tag)
638 NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
639 bool found = m_packetTagList.Remove (tag);
643 Packet::PeekPacketTag (Tag &tag) const
645 bool found = m_packetTagList.Peek (tag);
649 Packet::RemoveAllPacketTags (void)
651 NS_LOG_FUNCTION (this);
652 m_packetTagList.RemoveAll ();
656 Packet::PrintPacketTags (std::ostream &os) const
658 PacketTagIterator i = GetPacketTagIterator ();
661 PacketTagIterator::Item item = i.Next ();
662 NS_ASSERT (item.GetTypeId ().HasConstructor ());
663 Callback<ObjectBase *> constructor = item.GetTypeId ().GetConstructor ();
664 NS_ASSERT (!constructor.IsNull ());
665 ObjectBase *instance = constructor ();
666 Tag *tag = dynamic_cast<Tag *> (instance);
667 NS_ASSERT (tag != 0);
679 Packet::GetPacketTagIterator (void) const
681 return PacketTagIterator (m_packetTagList.Head ());
684 std::ostream& operator<< (std::ostream& os, const Packet &packet)
690 //-----------------------------------------------------------------------------
692 //-----------------------------------------------------------------------------
695 class ATestTagBase : public Tag
698 ATestTagBase () : m_error (false) {}
703 class ATestTag : public ATestTagBase
706 static TypeId GetTypeId (void) {
707 std::ostringstream oss;
708 oss << "anon::ATestTag<" << N << ">";
709 static TypeId tid = TypeId (oss.str ().c_str ())
711 .AddConstructor<ATestTag<N> > ()
712 .HideFromDocumentation ()
716 virtual TypeId GetInstanceTypeId (void) const {
719 virtual uint32_t GetSerializedSize (void) const {
722 virtual void Serialize (TagBuffer buf) const {
723 for (uint32_t i = 0; i < N; ++i)
728 virtual void Deserialize (TagBuffer buf) {
729 for (uint32_t i = 0; i < N; ++i)
731 uint8_t v = buf.ReadU8 ();
738 virtual void Print (std::ostream &os) const {
745 class ATestHeaderBase : public Header
748 ATestHeaderBase () : Header (), m_error (false) {}
753 class ATestHeader : public ATestHeaderBase
756 static TypeId GetTypeId (void) {
757 std::ostringstream oss;
758 oss << "anon::ATestHeader<" << N << ">";
759 static TypeId tid = TypeId (oss.str ().c_str ())
760 .SetParent<Header> ()
761 .AddConstructor<ATestHeader<N> > ()
762 .HideFromDocumentation ()
766 virtual TypeId GetInstanceTypeId (void) const {
769 virtual uint32_t GetSerializedSize (void) const {
772 virtual void Serialize (Buffer::Iterator iter) const {
773 for (uint32_t i = 0; i < N; ++i)
778 virtual uint32_t Deserialize (Buffer::Iterator iter) {
779 for (uint32_t i = 0; i < N; ++i)
781 uint8_t v = iter.ReadU8 ();
789 virtual void Print (std::ostream &os) const {
792 : ATestHeaderBase () {}
796 class ATestTrailerBase : public Trailer
799 ATestTrailerBase () : Trailer (), m_error (false) {}
804 class ATestTrailer : public ATestTrailerBase
807 static TypeId GetTypeId (void) {
808 std::ostringstream oss;
809 oss << "anon::ATestTrailer<" << N << ">";
810 static TypeId tid = TypeId (oss.str ().c_str ())
811 .SetParent<Header> ()
812 .AddConstructor<ATestTrailer<N> > ()
813 .HideFromDocumentation ()
817 virtual TypeId GetInstanceTypeId (void) const {
820 virtual uint32_t GetSerializedSize (void) const {
823 virtual void Serialize (Buffer::Iterator iter) const {
825 for (uint32_t i = 0; i < N; ++i)
830 virtual uint32_t Deserialize (Buffer::Iterator iter) {
832 for (uint32_t i = 0; i < N; ++i)
834 uint8_t v = iter.ReadU8 ();
842 virtual void Print (std::ostream &os) const {
845 : ATestTrailerBase () {}
852 Expected (uint32_t n_, uint32_t start_, uint32_t end_)
853 : n (n_), start (start_), end (end_) {}
862 // tag name, start, end
863 #define E(a,b,c) a,b,c
865 #define CHECK(p, n, ...) \
866 DoCheck (p, __FILE__, __LINE__, n, __VA_ARGS__)
868 class PacketTest: public TestCase
872 virtual bool DoRun (void);
874 void DoCheck (Ptr<const Packet> p, const char *file, int line, uint32_t n, ...);
878 PacketTest::PacketTest ()
879 : TestCase ("Packet") {}
882 PacketTest::DoCheck (Ptr<const Packet> p, const char *file, int line, uint32_t n, ...)
884 std::vector<struct Expected> expected;
887 for (uint32_t k = 0; k < n; ++k)
889 uint32_t N = va_arg (ap, uint32_t);
890 uint32_t start = va_arg (ap, uint32_t);
891 uint32_t end = va_arg (ap, uint32_t);
892 expected.push_back (Expected (N, start, end));
896 ByteTagIterator i = p->GetByteTagIterator ();
898 while (i.HasNext () && j < expected.size ())
900 ByteTagIterator::Item item = i.Next ();
901 struct Expected e = expected[j];
902 std::ostringstream oss;
903 oss << "anon::ATestTag<" << e.n << ">";
904 NS_TEST_EXPECT_MSG_EQ_INTERNAL (item.GetTypeId ().GetName (), oss.str (), "trivial", file, line);
905 NS_TEST_EXPECT_MSG_EQ_INTERNAL (item.GetStart (), e.start, "trivial", file, line);
906 NS_TEST_EXPECT_MSG_EQ_INTERNAL (item.GetEnd (), e.end, "trivial", file, line);
907 ATestTagBase *tag = dynamic_cast<ATestTagBase *> (item.GetTypeId ().GetConstructor () ());
908 NS_TEST_EXPECT_MSG_NE (tag, 0, "trivial");
910 NS_TEST_EXPECT_MSG_EQ (tag->m_error, false, "trivial");
914 NS_TEST_EXPECT_MSG_EQ (i.HasNext (), false, "Nothing left");
915 NS_TEST_EXPECT_MSG_EQ (j, expected.size (), "Size match");
919 PacketTest::DoRun (void)
921 Ptr<Packet> pkt1 = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello"), 5);
922 Ptr<Packet> pkt2 = Create<Packet> (reinterpret_cast<const uint8_t*> (" world"), 6);
923 Ptr<Packet> packet = Create<Packet> ();
924 packet->AddAtEnd (pkt1);
925 packet->AddAtEnd (pkt2);
927 NS_TEST_EXPECT_MSG_EQ (packet->GetSize (), 11, "trivial");
929 std::string msg = std::string (reinterpret_cast<const char *>(packet->PeekData ()),
931 NS_TEST_EXPECT_MSG_EQ (msg, "hello world", "trivial");
934 Ptr<const Packet> p = Create<Packet> (1000);
936 p->AddByteTag (ATestTag<1> ());
937 CHECK (p, 1, E (1, 0, 1000));
938 Ptr<const Packet> copy = p->Copy ();
939 CHECK (copy, 1, E (1, 0, 1000));
941 p->AddByteTag (ATestTag<2> ());
942 CHECK (p, 2, E (1, 0, 1000), E(2, 0, 1000));
943 CHECK (copy, 1, E (1, 0, 1000));
949 CHECK (&c0, 1, E (1, 0, 1000));
950 CHECK (&c1, 1, E (1, 0, 1000));
951 CHECK (copy, 1, E (1, 0, 1000));
952 c0.AddByteTag (ATestTag<10> ());
953 CHECK (&c0, 2, E (1, 0, 1000), E (10, 0, 1000));
954 CHECK (&c1, 1, E (1, 0, 1000));
955 CHECK (copy, 1, E (1, 0, 1000));
958 Ptr<Packet> frag0 = p->CreateFragment (0, 10);
959 Ptr<Packet> frag1 = p->CreateFragment (10, 90);
960 Ptr<const Packet> frag2 = p->CreateFragment (100, 900);
961 frag0->AddByteTag (ATestTag<3> ());
962 CHECK (frag0, 3, E (1, 0, 10), E(2, 0, 10), E (3, 0, 10));
963 frag1->AddByteTag (ATestTag<4> ());
964 CHECK (frag1, 3, E (1, 0, 90), E(2, 0, 90), E (4, 0, 90));
965 frag2->AddByteTag (ATestTag<5> ());
966 CHECK (frag2, 3, E (1, 0, 900), E(2, 0, 900), E (5, 0, 900));
968 frag1->AddAtEnd (frag2);
969 CHECK (frag1, 6, E (1, 0, 90), E(2, 0, 90), E (4, 0, 90), E (1, 90, 990), E(2, 90, 990), E (5, 90, 990));
971 CHECK (frag0, 3, E (1, 0, 10), E(2, 0, 10), E (3, 0, 10));
972 frag0->AddAtEnd (frag1);
974 E (1, 0, 10), E(2, 0, 10), E (3, 0, 10),
975 E (1, 10, 100), E(2, 10, 100), E (4, 10, 100),
976 E (1, 100, 1000), E(2, 100, 1000), E (5, 100, 1000));
979 // force caching a buffer of the right size.
980 frag0 = Create<Packet> (1000);
981 frag0->AddHeader (ATestHeader<10> ());
984 p = Create<Packet> (1000);
985 p->AddByteTag (ATestTag<20> ());
986 CHECK (p, 1, E (20, 0, 1000));
987 frag0 = p->CreateFragment (10, 90);
988 CHECK (p, 1, E (20, 0, 1000));
989 CHECK (frag0, 1, E (20, 0, 90));
991 frag0->AddHeader (ATestHeader<10> ());
992 CHECK (frag0, 1, E (20, 10, 100));
995 Ptr<Packet> tmp = Create<Packet> (100);
996 tmp->AddByteTag (ATestTag<20> ());
997 CHECK (tmp, 1, E (20, 0, 100));
998 tmp->AddHeader (ATestHeader<10> ());
999 CHECK (tmp, 1, E (20, 10, 110));
1001 tmp->RemoveHeader (h);
1002 CHECK (tmp, 1, E (20, 0, 100));
1003 tmp->AddHeader (ATestHeader<10> ());
1004 CHECK (tmp, 1, E (20, 10, 110));
1006 tmp = Create<Packet> (100);
1007 tmp->AddByteTag (ATestTag<20> ());
1008 CHECK (tmp, 1, E (20, 0, 100));
1009 tmp->AddTrailer (ATestTrailer<10> ());
1010 CHECK (tmp, 1, E (20, 0, 100));
1012 tmp->RemoveTrailer (t);
1013 CHECK (tmp, 1, E (20, 0, 100));
1014 tmp->AddTrailer (ATestTrailer<10> ());
1015 CHECK (tmp, 1, E (20, 0, 100));
1020 Ptr<Packet> tmp = Create<Packet> (0);
1021 tmp->AddHeader (ATestHeader<156> ());
1022 tmp->AddByteTag (ATestTag<20> ());
1023 CHECK (tmp, 1, E (20, 0, 156));
1024 tmp->RemoveAtStart (120);
1025 CHECK (tmp, 1, E (20, 0, 36));
1026 Ptr<Packet> a = Create<Packet> (0);
1028 CHECK (a, 1, E (20, 0, 36));
1032 Ptr<Packet> tmp = Create<Packet> (0);
1033 tmp->AddByteTag (ATestTag<20> ());
1034 CHECK (tmp, 0, E (20, 0, 0));
1037 Ptr<Packet> tmp = Create<Packet> (1000);
1038 tmp->AddByteTag (ATestTag<20> ());
1039 CHECK (tmp, 1, E (20, 0, 1000));
1040 tmp->RemoveAtStart (1000);
1041 CHECK (tmp, 0, E (0,0,0));
1042 Ptr<Packet> a = Create<Packet> (10);
1043 a->AddByteTag (ATestTag<10> ());
1044 CHECK (a, 1, E (10, 0, 10));
1046 CHECK (tmp, 1, E (10, 0, 10));
1053 NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (a), true, "trivial");
1056 NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (b), true, "trivial");
1057 NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (a), true, "trivial");
1059 NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (b), true, "trivial");
1060 NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (a), true, "trivial");
1062 NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (c), false, "trivial");
1063 copy.AddPacketTag (c);
1064 NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (c), true, "trivial");
1065 NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (b), true, "trivial");
1066 NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (a), true, "trivial");
1067 NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (c), false, "trivial");
1068 copy.RemovePacketTag (b);
1069 NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (b), false, "trivial");
1070 NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (b), true, "trivial");
1071 p.RemovePacketTag (a);
1072 NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (a), false, "trivial");
1073 NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (a), true, "trivial");
1074 NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (c), false, "trivial");
1075 NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (c), true, "trivial");
1076 p.RemoveAllPacketTags ();
1077 NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (b), false, "trivial");
1082 Ptr<Packet> tmp = Create<Packet> (1000);
1083 tmp->AddByteTag (ATestTag<20> ());
1084 CHECK (tmp, 1, E (20, 0, 1000));
1085 tmp->AddHeader (ATestHeader<2> ());
1086 CHECK (tmp, 1, E (20, 2, 1002));
1087 tmp->RemoveAtStart (1);
1088 CHECK (tmp, 1, E (20, 1, 1001));
1090 CHECK (tmp, 1, E (20, 1, 1001));
1093 return GetErrorStatus ();
1095 //-----------------------------------------------------------------------------
1096 class PacketTestSuite : public TestSuite
1102 PacketTestSuite::PacketTestSuite ()
1103 : TestSuite ("packet", UNIT)
1105 AddTestCase (new PacketTest);
1108 PacketTestSuite g_packetTestSuite;