00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "packet.h"
00021 #include "ns3/assert.h"
00022 #include "ns3/log.h"
00023
00024 NS_LOG_COMPONENT_DEFINE ("Packet");
00025
00026 namespace ns3 {
00027
00028 uint32_t Packet::m_globalUid = 0;
00029
00030 TypeId
00031 TagIterator::Item::GetTypeId (void) const
00032 {
00033 return m_tid;
00034 }
00035 uint32_t
00036 TagIterator::Item::GetStart (void) const
00037 {
00038 return m_start;
00039 }
00040 uint32_t
00041 TagIterator::Item::GetEnd (void) const
00042 {
00043 return m_end;
00044 }
00045 void
00046 TagIterator::Item::GetTag (Tag &tag) const
00047 {
00048 if (tag.GetInstanceTypeId () != GetTypeId ())
00049 {
00050 NS_FATAL_ERROR ("The tag you provided is not of the right type.");
00051 }
00052 tag.Deserialize (m_buffer);
00053 }
00054 TagIterator::Item::Item (TypeId tid, uint32_t start, uint32_t end, TagBuffer buffer)
00055 : m_tid (tid),
00056 m_start (start),
00057 m_end (end),
00058 m_buffer (buffer)
00059 {}
00060 bool
00061 TagIterator::HasNext (void) const
00062 {
00063 return m_current.HasNext ();
00064 }
00065 TagIterator::Item
00066 TagIterator::Next (void)
00067 {
00068 TagList::Iterator::Item i = m_current.Next ();
00069 return TagIterator::Item (i.tid,
00070 i.start-m_current.GetOffsetStart (),
00071 i.end-m_current.GetOffsetStart (),
00072 i.buf);
00073 }
00074 TagIterator::TagIterator (TagList::Iterator i)
00075 : m_current (i)
00076 {}
00077
00078
00079 void
00080 Packet::Ref (void) const
00081 {
00082 m_refCount++;
00083 }
00084 void
00085 Packet::Unref (void) const
00086 {
00087 m_refCount--;
00088 if (m_refCount == 0)
00089 {
00090 delete this;
00091 }
00092 }
00093
00094 Ptr<Packet>
00095 Packet::Copy (void) const
00096 {
00097
00098
00099
00100 return Ptr<Packet> (new Packet (*this), false);
00101 }
00102
00103 Packet::Packet ()
00104 : m_buffer (),
00105 m_tagList (),
00106 m_metadata (m_globalUid, 0),
00107 m_refCount (1)
00108 {
00109 m_globalUid++;
00110 }
00111
00112 Packet::Packet (const Packet &o)
00113 : m_buffer (o.m_buffer),
00114 m_tagList (o.m_tagList),
00115 m_metadata (o.m_metadata),
00116 m_refCount (1)
00117 {}
00118
00119 Packet &
00120 Packet::operator = (const Packet &o)
00121 {
00122 if (this == &o)
00123 {
00124 return *this;
00125 }
00126 m_buffer = o.m_buffer;
00127 m_tagList = o.m_tagList;
00128 m_metadata = o.m_metadata;
00129 return *this;
00130 }
00131
00132 Packet::Packet (uint32_t size)
00133 : m_buffer (size),
00134 m_tagList (),
00135 m_metadata (m_globalUid, size),
00136 m_refCount (1)
00137 {
00138 m_globalUid++;
00139 }
00140 Packet::Packet (uint8_t const*buffer, uint32_t size)
00141 : m_buffer (),
00142 m_tagList (),
00143 m_metadata (m_globalUid, size),
00144 m_refCount (1)
00145 {
00146 m_globalUid++;
00147 m_buffer.AddAtStart (size);
00148 Buffer::Iterator i = m_buffer.Begin ();
00149 i.Write (buffer, size);
00150 }
00151
00152 Packet::Packet (const Buffer &buffer, const TagList &tagList, const PacketMetadata &metadata)
00153 : m_buffer (buffer),
00154 m_tagList (tagList),
00155 m_metadata (metadata),
00156 m_refCount (1)
00157 {}
00158
00159 Ptr<Packet>
00160 Packet::CreateFragment (uint32_t start, uint32_t length) const
00161 {
00162 NS_LOG_FUNCTION (this << start << length);
00163 Buffer buffer = m_buffer.CreateFragment (start, length);
00164 NS_ASSERT (m_buffer.GetSize () >= start + length);
00165 uint32_t end = m_buffer.GetSize () - (start + length);
00166 PacketMetadata metadata = m_metadata.CreateFragment (start, end);
00167
00168
00169 return Ptr<Packet> (new Packet (buffer, m_tagList, metadata), false);
00170 }
00171
00172 uint32_t
00173 Packet::GetSize (void) const
00174 {
00175 return m_buffer.GetSize ();
00176 }
00177
00178 void
00179 Packet::AddHeader (const Header &header)
00180 {
00181 NS_LOG_FUNCTION (this << &header);
00182 uint32_t size = header.GetSerializedSize ();
00183 uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
00184 bool resized = m_buffer.AddAtStart (size);
00185 if (resized)
00186 {
00187 m_tagList.AddAtStart (m_buffer.GetCurrentStartOffset () + size - orgStart,
00188 m_buffer.GetCurrentStartOffset () + size);
00189 }
00190 header.Serialize (m_buffer.Begin ());
00191 m_metadata.AddHeader (header, size);
00192 }
00193 uint32_t
00194 Packet::RemoveHeader (Header &header)
00195 {
00196 NS_LOG_FUNCTION (this << &header);
00197 uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
00198 m_buffer.RemoveAtStart (deserialized);
00199 m_metadata.RemoveHeader (header, deserialized);
00200 return deserialized;
00201 }
00202 uint32_t
00203 Packet::PeekHeader (Header &header) const
00204 {
00205 NS_LOG_FUNCTION (this << &header);
00206 uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
00207 return deserialized;
00208 }
00209 void
00210 Packet::AddTrailer (const Trailer &trailer)
00211 {
00212 NS_LOG_FUNCTION (this << &trailer);
00213 uint32_t size = trailer.GetSerializedSize ();
00214 uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
00215 bool resized = m_buffer.AddAtEnd (size);
00216 if (resized)
00217 {
00218 m_tagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - orgStart,
00219 m_buffer.GetCurrentEndOffset () - size);
00220 }
00221 Buffer::Iterator end = m_buffer.End ();
00222 trailer.Serialize (end);
00223 m_metadata.AddTrailer (trailer, size);
00224 }
00225 uint32_t
00226 Packet::RemoveTrailer (Trailer &trailer)
00227 {
00228 NS_LOG_FUNCTION (this << &trailer);
00229 uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
00230 m_buffer.RemoveAtEnd (deserialized);
00231 m_metadata.RemoveTrailer (trailer, deserialized);
00232 return deserialized;
00233 }
00234 uint32_t
00235 Packet::PeekTrailer (Trailer &trailer)
00236 {
00237 NS_LOG_FUNCTION (this << &trailer);
00238 uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
00239 return deserialized;
00240 }
00241
00242 void
00243 Packet::AddAtEnd (Ptr<const Packet> packet)
00244 {
00245 NS_LOG_FUNCTION (this << packet);
00246 uint32_t aStart = m_buffer.GetCurrentStartOffset ();
00247 uint32_t bEnd = packet->m_buffer.GetCurrentEndOffset ();
00248 m_buffer.AddAtEnd (packet->m_buffer);
00249 uint32_t appendPrependOffset = m_buffer.GetCurrentEndOffset () - packet->m_buffer.GetSize ();
00250 m_tagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - aStart,
00251 appendPrependOffset);
00252 TagList copy = packet->m_tagList;
00253 copy.AddAtStart (m_buffer.GetCurrentEndOffset () - bEnd,
00254 appendPrependOffset);
00255 m_tagList.Add (copy);
00256 m_metadata.AddAtEnd (packet->m_metadata);
00257 }
00258 void
00259 Packet::AddPaddingAtEnd (uint32_t size)
00260 {
00261 NS_LOG_FUNCTION (this << size);
00262 uint32_t orgEnd = m_buffer.GetCurrentEndOffset ();
00263 bool resized = m_buffer.AddAtEnd (size);
00264 if (resized)
00265 {
00266 m_tagList.AddAtEnd (m_buffer.GetCurrentEndOffset () - orgEnd,
00267 m_buffer.GetCurrentEndOffset () - size);
00268 }
00269 m_metadata.AddPaddingAtEnd (size);
00270 }
00271 void
00272 Packet::RemoveAtEnd (uint32_t size)
00273 {
00274 NS_LOG_FUNCTION (this << size);
00275 m_buffer.RemoveAtEnd (size);
00276 m_metadata.RemoveAtEnd (size);
00277 }
00278 void
00279 Packet::RemoveAtStart (uint32_t size)
00280 {
00281 NS_LOG_FUNCTION (this << size);
00282 m_buffer.RemoveAtStart (size);
00283 m_metadata.RemoveAtStart (size);
00284 }
00285
00286 void
00287 Packet::RemoveAllTags (void)
00288 {
00289 NS_LOG_FUNCTION (this);
00290 m_tagList.RemoveAll ();
00291 }
00292
00293 uint8_t const *
00294 Packet::PeekData (void) const
00295 {
00296 return m_buffer.PeekData ();
00297 }
00298
00299 uint32_t
00300 Packet::CopyData (uint8_t *buffer, uint32_t size) const
00301 {
00302 Buffer::Iterator i = m_buffer.Begin ();
00303 uint32_t cur = 0;
00304 while (!i.IsEnd () && cur < size)
00305 {
00306 buffer[cur] = i.ReadU8 ();
00307 cur++;
00308 }
00309 return cur;
00310 }
00311
00312 uint32_t
00313 Packet::GetUid (void) const
00314 {
00315 return m_metadata.GetUid ();
00316 }
00317
00318 void
00319 Packet::PrintTags (std::ostream &os) const
00320 {
00321 TagIterator i = GetTagIterator ();
00322 while (i.HasNext ())
00323 {
00324 TagIterator::Item item = i.Next ();
00325 os << item.GetTypeId ().GetName () << " [" << item.GetStart () << "-" << item.GetEnd () << "]";
00326 Callback<ObjectBase *> constructor = item.GetTypeId ().GetConstructor ();
00327 if (constructor.IsNull ())
00328 {
00329 if (i.HasNext ())
00330 {
00331 os << " ";
00332 }
00333 continue;
00334 }
00335 Tag *tag = dynamic_cast<Tag *> (constructor ());
00336 NS_ASSERT (tag != 0);
00337 os << " ";
00338 item.GetTag (*tag);
00339 tag->Print (os);
00340 if (i.HasNext ())
00341 {
00342 os << " ";
00343 }
00344 delete tag;
00345 }
00346 }
00347
00348 void
00349 Packet::Print (std::ostream &os) const
00350 {
00351 PacketMetadata::ItemIterator i = m_metadata.BeginItem (m_buffer);
00352 while (i.HasNext ())
00353 {
00354 PacketMetadata::Item item = i.Next ();
00355 if (item.isFragment)
00356 {
00357 switch (item.type) {
00358 case PacketMetadata::Item::PAYLOAD:
00359 os << "Payload";
00360 break;
00361 case PacketMetadata::Item::HEADER:
00362 case PacketMetadata::Item::TRAILER:
00363 os << item.tid.GetName ();
00364 break;
00365 }
00366 os << " Fragment [" << item.currentTrimedFromStart<<":"
00367 << (item.currentTrimedFromStart + item.currentSize) << "]";
00368 }
00369 else
00370 {
00371 switch (item.type) {
00372 case PacketMetadata::Item::PAYLOAD:
00373 os << "Payload (size=" << item.currentSize << ")";
00374 break;
00375 case PacketMetadata::Item::HEADER:
00376 case PacketMetadata::Item::TRAILER:
00377 os << item.tid.GetName () << " (";
00378 {
00379 NS_ASSERT (item.tid.HasConstructor ());
00380 Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
00381 NS_ASSERT (!constructor.IsNull ());
00382 ObjectBase *instance = constructor ();
00383 NS_ASSERT (instance != 0);
00384 Chunk *chunk = dynamic_cast<Chunk *> (instance);
00385 NS_ASSERT (chunk != 0);
00386 chunk->Deserialize (item.current);
00387 chunk->Print (os);
00388 delete chunk;
00389 }
00390 os << ")";
00391 break;
00392 }
00393 }
00394 if (i.HasNext ())
00395 {
00396 os << " ";
00397 }
00398 }
00399 #if 0
00400
00401
00402
00403
00404 PacketMetadata::ItemIterator i = m_metadata.BeginItem (m_buffer);
00405 while (i.HasNext ())
00406 {
00407 PacketMetadata::Item item = i.Next ();
00408 if (item.isFragment)
00409 {
00410 switch (item.type) {
00411 case PacketMetadata::Item::PAYLOAD:
00412 os << "Payload";
00413 break;
00414 case PacketMetadata::Item::HEADER:
00415 case PacketMetadata::Item::TRAILER:
00416 os << item.tid.GetName ();
00417 break;
00418 }
00419 os << " Fragment [" << item.currentTrimedFromStart<<":"
00420 << (item.currentTrimedFromStart + item.currentSize) << "]";
00421 }
00422 else
00423 {
00424 switch (item.type) {
00425 case PacketMetadata::Item::PAYLOAD:
00426 os << "Payload (size=" << item.currentSize << ")";
00427 break;
00428 case PacketMetadata::Item::HEADER:
00429 case PacketMetadata::Item::TRAILER:
00430 os << item.tid.GetName () << "(";
00431 {
00432 NS_ASSERT (item.tid.HasConstructor ());
00433 Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
00434 NS_ASSERT (constructor.IsNull ());
00435 ObjectBase *instance = constructor ();
00436 NS_ASSERT (instance != 0);
00437 Chunk *chunk = dynamic_cast<Chunk *> (instance);
00438 NS_ASSERT (chunk != 0);
00439 chunk->Deserialize (item.current);
00440 for (uint32_t j = 0; j < item.tid.GetAttributeN (); j++)
00441 {
00442 std::string attrName = item.tid.GetAttributeName (j);
00443 std::string value;
00444 bool ok = chunk->GetAttribute (attrName, value);
00445 NS_ASSERT (ok);
00446 os << attrName << "=" << value;
00447 if ((j + 1) < item.tid.GetAttributeN ())
00448 {
00449 os << ",";
00450 }
00451 }
00452 }
00453 os << ")";
00454 break;
00455 }
00456 }
00457 if (i.HasNext ())
00458 {
00459 os << " ";
00460 }
00461 }
00462 #endif
00463 }
00464
00465 PacketMetadata::ItemIterator
00466 Packet::BeginItem (void) const
00467 {
00468 return m_metadata.BeginItem (m_buffer);
00469 }
00470
00471 void
00472 Packet::EnableMetadata (void)
00473 {
00474 NS_LOG_FUNCTION_NOARGS ();
00475 EnableChecking ();
00476 }
00477
00478 void
00479 Packet::EnablePrinting (void)
00480 {
00481 NS_LOG_FUNCTION_NOARGS ();
00482 PacketMetadata::Enable ();
00483 }
00484
00485 void
00486 Packet::EnableChecking (void)
00487 {
00488 NS_LOG_FUNCTION_NOARGS ();
00489 PacketMetadata::EnableChecking ();
00490 }
00491
00492 Buffer
00493 Packet::Serialize (void) const
00494 {
00495 NS_LOG_FUNCTION (this);
00496 Buffer buffer;
00497 uint32_t reserve;
00498
00499
00500 reserve = m_metadata.GetSerializedSize ();
00501 buffer.AddAtStart (reserve);
00502 m_metadata.Serialize (buffer.Begin (), reserve);
00503
00504
00505
00506
00507
00508
00509
00510
00511 Buffer tmp = m_buffer.CreateFullCopy ();
00512 tmp.AddAtEnd (buffer);
00513
00514
00515 tmp.AddAtStart (4);
00516 tmp.Begin ().WriteU32 (m_buffer.GetSize ());
00517
00518 return tmp;
00519 }
00520 void
00521 Packet::Deserialize (Buffer buffer)
00522 {
00523 NS_LOG_FUNCTION (this);
00524 Buffer buf = buffer;
00525
00526 uint32_t packetSize = buf.Begin ().ReadU32 ();
00527 buf.RemoveAtStart (4);
00528
00529
00530 buf.RemoveAtEnd (buf.GetSize () - packetSize);
00531 m_buffer = buf;
00532 buffer.RemoveAtStart (4 + packetSize);
00533
00534
00535
00536
00537
00538
00539
00540
00541 uint32_t metadataDeserialized =
00542 m_metadata.Deserialize (buffer.Begin ());
00543 buffer.RemoveAtStart (metadataDeserialized);
00544 }
00545
00546 void
00547 Packet::AddTag (const Tag &tag) const
00548 {
00549 NS_LOG_FUNCTION (this << &tag);
00550 TagList *list = const_cast<TagList *> (&m_tagList);
00551 TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (),
00552 m_buffer.GetCurrentStartOffset (),
00553 m_buffer.GetCurrentEndOffset ());
00554 tag.Serialize (buffer);
00555 }
00556 TagIterator
00557 Packet::GetTagIterator (void) const
00558 {
00559 return TagIterator (m_tagList.Begin (m_buffer.GetCurrentStartOffset (), m_buffer.GetCurrentEndOffset ()));
00560 }
00561
00562 bool
00563 Packet::FindFirstMatchingTag (Tag &tag) const
00564 {
00565 TypeId tid = tag.GetInstanceTypeId ();
00566 TagIterator i = GetTagIterator ();
00567 while (i.HasNext ())
00568 {
00569 TagIterator::Item item = i.Next ();
00570 if (tid == item.GetTypeId ())
00571 {
00572 item.GetTag (tag);
00573 return true;
00574 }
00575 }
00576 return false;
00577 }
00578
00579 std::ostream& operator<< (std::ostream& os, const Packet &packet)
00580 {
00581 packet.Print (os);
00582 return os;
00583 }
00584
00585
00586 }
00587
00588
00589
00590 #ifdef RUN_SELF_TESTS
00591
00592 #include "ns3/test.h"
00593 #include <string>
00594 #include <stdarg.h>
00595
00596 using namespace ns3;
00597
00598 namespace {
00599
00600 class ATestTagBase : public Tag
00601 {
00602 public:
00603 ATestTagBase () : m_error (false) {}
00604 bool m_error;
00605 };
00606
00607 template <int N>
00608 class ATestTag : public ATestTagBase
00609 {
00610 public:
00611 static TypeId GetTypeId (void) {
00612 std::ostringstream oss;
00613 oss << "anon::ATestTag<" << N << ">";
00614 static TypeId tid = TypeId (oss.str ().c_str ())
00615 .SetParent<Tag> ()
00616 .AddConstructor<ATestTag<N> > ()
00617 .HideFromDocumentation ()
00618 ;
00619 return tid;
00620 }
00621 virtual TypeId GetInstanceTypeId (void) const {
00622 return GetTypeId ();
00623 }
00624 virtual uint32_t GetSerializedSize (void) const {
00625 return N;
00626 }
00627 virtual void Serialize (TagBuffer buf) const {
00628 for (uint32_t i = 0; i < N; ++i)
00629 {
00630 buf.WriteU8 (N);
00631 }
00632 }
00633 virtual void Deserialize (TagBuffer buf) {
00634 for (uint32_t i = 0; i < N; ++i)
00635 {
00636 uint8_t v = buf.ReadU8 ();
00637 if (v != N)
00638 {
00639 m_error = true;
00640 }
00641 }
00642 }
00643 virtual void Print (std::ostream &os) const {
00644 os << N;
00645 }
00646 ATestTag ()
00647 : ATestTagBase () {}
00648 };
00649
00650 class ATestHeaderBase : public Header
00651 {
00652 public:
00653 ATestHeaderBase () : Header (), m_error (false) {}
00654 bool m_error;
00655 };
00656
00657 template <int N>
00658 class ATestHeader : public ATestHeaderBase
00659 {
00660 public:
00661 static TypeId GetTypeId (void) {
00662 std::ostringstream oss;
00663 oss << "anon::ATestHeader<" << N << ">";
00664 static TypeId tid = TypeId (oss.str ().c_str ())
00665 .SetParent<Header> ()
00666 .AddConstructor<ATestHeader<N> > ()
00667 .HideFromDocumentation ()
00668 ;
00669 return tid;
00670 }
00671 virtual TypeId GetInstanceTypeId (void) const {
00672 return GetTypeId ();
00673 }
00674 virtual uint32_t GetSerializedSize (void) const {
00675 return N;
00676 }
00677 virtual void Serialize (Buffer::Iterator iter) const {
00678 for (uint32_t i = 0; i < N; ++i)
00679 {
00680 iter.WriteU8 (N);
00681 }
00682 }
00683 virtual uint32_t Deserialize (Buffer::Iterator iter) {
00684 for (uint32_t i = 0; i < N; ++i)
00685 {
00686 uint8_t v = iter.ReadU8 ();
00687 if (v != N)
00688 {
00689 m_error = true;
00690 }
00691 }
00692 return N;
00693 }
00694 virtual void Print (std::ostream &os) const {
00695 }
00696 ATestHeader ()
00697 : ATestHeaderBase () {}
00698
00699 };
00700
00701 class ATestTrailerBase : public Trailer
00702 {
00703 public:
00704 ATestTrailerBase () : Trailer (), m_error (false) {}
00705 bool m_error;
00706 };
00707
00708 template <int N>
00709 class ATestTrailer : public ATestTrailerBase
00710 {
00711 public:
00712 static TypeId GetTypeId (void) {
00713 std::ostringstream oss;
00714 oss << "anon::ATestTrailer<" << N << ">";
00715 static TypeId tid = TypeId (oss.str ().c_str ())
00716 .SetParent<Header> ()
00717 .AddConstructor<ATestTrailer<N> > ()
00718 .HideFromDocumentation ()
00719 ;
00720 return tid;
00721 }
00722 virtual TypeId GetInstanceTypeId (void) const {
00723 return GetTypeId ();
00724 }
00725 virtual uint32_t GetSerializedSize (void) const {
00726 return N;
00727 }
00728 virtual void Serialize (Buffer::Iterator iter) const {
00729 iter.Prev (N);
00730 for (uint32_t i = 0; i < N; ++i)
00731 {
00732 iter.WriteU8 (N);
00733 }
00734 }
00735 virtual uint32_t Deserialize (Buffer::Iterator iter) {
00736 iter.Prev (N);
00737 for (uint32_t i = 0; i < N; ++i)
00738 {
00739 uint8_t v = iter.ReadU8 ();
00740 if (v != N)
00741 {
00742 m_error = true;
00743 }
00744 }
00745 return N;
00746 }
00747 virtual void Print (std::ostream &os) const {
00748 }
00749 ATestTrailer ()
00750 : ATestTrailerBase () {}
00751
00752 };
00753
00754
00755 struct Expected
00756 {
00757 Expected (uint32_t n_, uint32_t start_, uint32_t end_)
00758 : n (n_), start (start_), end (end_) {}
00759
00760 uint32_t n;
00761 uint32_t start;
00762 uint32_t end;
00763 };
00764
00765 }
00766
00767
00768 #define E(a,b,c) a,b,c
00769
00770 #define CHECK(p, n, ...) \
00771 NS_TEST_ASSERT (DoCheck (p, __FILE__, __LINE__, n, __VA_ARGS__))
00772
00773 namespace ns3 {
00774
00775
00776 class PacketTest: public Test
00777 {
00778 public:
00779 PacketTest ();
00780 virtual bool RunTests (void);
00781 private:
00782 bool DoCheck (Ptr<const Packet> p, const char *file, int line, uint32_t n, ...);
00783 };
00784
00785
00786 PacketTest::PacketTest ()
00787 : Test ("Packet") {}
00788
00789 bool
00790 PacketTest::DoCheck (Ptr<const Packet> p, const char *file, int line, uint32_t n, ...)
00791 {
00792 bool result = true;
00793 std::vector<struct Expected> expected;
00794 va_list ap;
00795 va_start (ap, n);
00796 for (uint32_t k = 0; k < n; ++k)
00797 {
00798 uint32_t N = va_arg (ap, uint32_t);
00799 uint32_t start = va_arg (ap, uint32_t);
00800 uint32_t end = va_arg (ap, uint32_t);
00801 expected.push_back (Expected (N, start, end));
00802 }
00803 va_end (ap);
00804
00805 TagIterator i = p->GetTagIterator ();
00806 uint32_t j = 0;
00807 while (i.HasNext () && j < expected.size ())
00808 {
00809 TagIterator::Item item = i.Next ();
00810 struct Expected e = expected[j];
00811 std::ostringstream oss;
00812 oss << "anon::ATestTag<" << e.n << ">";
00813 NS_TEST_ASSERT_EQUAL_FILELINE (item.GetTypeId ().GetName (), oss.str (), file, line);
00814 NS_TEST_ASSERT_EQUAL_FILELINE (item.GetStart (), e.start, file, line);
00815 NS_TEST_ASSERT_EQUAL_FILELINE (item.GetEnd (), e.end, file, line);
00816 ATestTagBase *tag = dynamic_cast<ATestTagBase *> (item.GetTypeId ().GetConstructor () ());
00817 NS_TEST_ASSERT (tag != 0);
00818 item.GetTag (*tag);
00819 NS_TEST_ASSERT (!tag->m_error);
00820 delete tag;
00821 j++;
00822 }
00823 NS_TEST_ASSERT (!i.HasNext ());
00824 NS_TEST_ASSERT_EQUAL (j, expected.size ());
00825 return result;
00826 }
00827
00828 bool
00829 PacketTest::RunTests (void)
00830 {
00831 bool result = true;
00832
00833 Ptr<Packet> pkt1 = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello"), 5);
00834 Ptr<Packet> pkt2 = Create<Packet> (reinterpret_cast<const uint8_t*> (" world"), 6);
00835 Ptr<Packet> packet = Create<Packet> ();
00836 packet->AddAtEnd (pkt1);
00837 packet->AddAtEnd (pkt2);
00838
00839 NS_TEST_ASSERT_EQUAL (packet->GetSize (), 11);
00840
00841 std::string msg = std::string (reinterpret_cast<const char *>(packet->PeekData ()),
00842 packet->GetSize ());
00843 NS_TEST_ASSERT_EQUAL (msg, "hello world");
00844
00845
00846 Ptr<const Packet> p = Create<Packet> (1000);
00847
00848 p->AddTag (ATestTag<1> ());
00849 CHECK (p, 1, E (1, 0, 1000));
00850 Ptr<const Packet> copy = p->Copy ();
00851 CHECK (copy, 1, E (1, 0, 1000));
00852
00853 p->AddTag (ATestTag<2> ());
00854 CHECK (p, 2, E (1, 0, 1000), E(2, 0, 1000));
00855 CHECK (copy, 1, E (1, 0, 1000));
00856
00857 {
00858 Packet c0 = *copy;
00859 Packet c1 = *copy;
00860 c0 = c1;
00861 CHECK (&c0, 1, E (1, 0, 1000));
00862 CHECK (&c1, 1, E (1, 0, 1000));
00863 CHECK (copy, 1, E (1, 0, 1000));
00864 c0.AddTag (ATestTag<10> ());
00865 CHECK (&c0, 2, E (1, 0, 1000), E (10, 0, 1000));
00866 CHECK (&c1, 1, E (1, 0, 1000));
00867 CHECK (copy, 1, E (1, 0, 1000));
00868 }
00869
00870 Ptr<Packet> frag0 = p->CreateFragment (0, 10);
00871 Ptr<Packet> frag1 = p->CreateFragment (10, 90);
00872 Ptr<const Packet> frag2 = p->CreateFragment (100, 900);
00873 frag0->AddTag (ATestTag<3> ());
00874 CHECK (frag0, 3, E (1, 0, 10), E(2, 0, 10), E (3, 0, 10));
00875 frag1->AddTag (ATestTag<4> ());
00876 CHECK (frag1, 3, E (1, 0, 90), E(2, 0, 90), E (4, 0, 90));
00877 frag2->AddTag (ATestTag<5> ());
00878 CHECK (frag2, 3, E (1, 0, 900), E(2, 0, 900), E (5, 0, 900));
00879
00880 frag1->AddAtEnd (frag2);
00881 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));
00882
00883 CHECK (frag0, 3, E (1, 0, 10), E(2, 0, 10), E (3, 0, 10));
00884 frag0->AddAtEnd (frag1);
00885 CHECK (frag0, 9,
00886 E (1, 0, 10), E(2, 0, 10), E (3, 0, 10),
00887 E (1, 10, 100), E(2, 10, 100), E (4, 10, 100),
00888 E (1, 100, 1000), E(2, 100, 1000), E (5, 100, 1000));
00889
00890
00891
00892 frag0 = Create<Packet> (1000);
00893 frag0->AddHeader (ATestHeader<10> ());
00894 frag0 = 0;
00895
00896 p = Create<Packet> (1000);
00897 p->AddTag (ATestTag<20> ());
00898 CHECK (p, 1, E (20, 0, 1000));
00899 frag0 = p->CreateFragment (10, 90);
00900 CHECK (p, 1, E (20, 0, 1000));
00901 CHECK (frag0, 1, E (20, 0, 90));
00902 p = 0;
00903 frag0->AddHeader (ATestHeader<10> ());
00904 CHECK (frag0, 1, E (20, 10, 100));
00905
00906 {
00907 Ptr<Packet> tmp = Create<Packet> (100);
00908 tmp->AddTag (ATestTag<20> ());
00909 CHECK (tmp, 1, E (20, 0, 100));
00910 tmp->AddHeader (ATestHeader<10> ());
00911 CHECK (tmp, 1, E (20, 10, 110));
00912 ATestHeader<10> h;
00913 tmp->RemoveHeader (h);
00914 CHECK (tmp, 1, E (20, 0, 100));
00915 tmp->AddHeader (ATestHeader<10> ());
00916 CHECK (tmp, 1, E (20, 10, 110));
00917
00918 tmp = Create<Packet> (100);
00919 tmp->AddTag (ATestTag<20> ());
00920 CHECK (tmp, 1, E (20, 0, 100));
00921 tmp->AddTrailer (ATestTrailer<10> ());
00922 CHECK (tmp, 1, E (20, 0, 100));
00923 ATestTrailer<10> t;
00924 tmp->RemoveTrailer (t);
00925 CHECK (tmp, 1, E (20, 0, 100));
00926 tmp->AddTrailer (ATestTrailer<10> ());
00927 CHECK (tmp, 1, E (20, 0, 100));
00928
00929 }
00930
00931 {
00932 Ptr<Packet> tmp = Create<Packet> (0);
00933 tmp->AddHeader (ATestHeader<156> ());
00934 tmp->AddTag (ATestTag<20> ());
00935 CHECK (tmp, 1, E (20, 0, 156));
00936 tmp->RemoveAtStart (120);
00937 CHECK (tmp, 1, E (20, 0, 36));
00938 Ptr<Packet> a = Create<Packet> (0);
00939 a->AddAtEnd (tmp);
00940 CHECK (a, 1, E (20, 0, 36));
00941 }
00942
00943 {
00944 Ptr<Packet> tmp = Create<Packet> (0);
00945 tmp->AddTag (ATestTag<20> ());
00946 CHECK (tmp, 0, E (20, 0, 0));
00947 }
00948 {
00949 Ptr<Packet> tmp = Create<Packet> (1000);
00950 tmp->AddTag (ATestTag<20> ());
00951 CHECK (tmp, 1, E (20, 0, 1000));
00952 tmp->RemoveAtStart (1000);
00953 CHECK (tmp, 0, E (0,0,0));
00954 Ptr<Packet> a = Create<Packet> (10);
00955 a->AddTag (ATestTag<10> ());
00956 CHECK (a, 1, E (10, 0, 10));
00957 tmp->AddAtEnd (a);
00958 CHECK (tmp, 1, E (10, 0, 10));
00959 }
00960
00961
00962 return result;
00963 }
00964
00965
00966 static PacketTest g_packetTest;
00967
00968 };
00969
00970 #endif