src/common/packet-history.h
changeset 882 777fcfabc1c8
parent 881 62901fdaeb68
child 883 4d2da35c09b0
equal deleted inserted replaced
881:62901fdaeb68 882:777fcfabc1c8
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
       
     2 /*
       
     3  * Copyright (c) 2006,2007 INRIA
       
     4  * All rights reserved.
       
     5  *
       
     6  * This program is free software; you can redistribute it and/or modify
       
     7  * it under the terms of the GNU General Public License version 2 as
       
     8  * published by the Free Software Foundation;
       
     9  *
       
    10  * This program is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    13  * GNU General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License
       
    16  * along with this program; if not, write to the Free Software
       
    17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    18  *
       
    19  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
       
    20  */
       
    21 #ifndef PACKET_HISTORY_H
       
    22 #define PACKET_HISTORY_H
       
    23 
       
    24 #include <stdint.h>
       
    25 #include <vector>
       
    26 #include "ns3/callback.h"
       
    27 #include "ns3/assert.h"
       
    28 #include "packet-printer.h"
       
    29 
       
    30 namespace ns3 {
       
    31 
       
    32 class Chunk;
       
    33 class Buffer;
       
    34 
       
    35 class PacketHistory {
       
    36 public:
       
    37   static void Enable (void);
       
    38   static void SetOptOne (bool optOne);
       
    39 
       
    40   inline PacketHistory (uint32_t uid, uint32_t size);
       
    41   inline PacketHistory (PacketHistory const &o);
       
    42   inline PacketHistory &operator = (PacketHistory const& o);
       
    43   inline ~PacketHistory ();
       
    44 
       
    45   template <typename T>
       
    46   void AddHeader (T const &header, uint32_t size);
       
    47   template <typename T>
       
    48   void RemoveHeader (T const &header, uint32_t size);
       
    49 
       
    50   template <typename T>
       
    51   void AddTrailer (T const &trailer, uint32_t size);
       
    52   template <typename T>
       
    53   void RemoveTrailer (T const &trailer, uint32_t size);
       
    54 
       
    55   PacketHistory CreateFragment (uint32_t start, uint32_t end) const;
       
    56   void AddAtEnd (PacketHistory const&o);
       
    57   void AddPaddingAtEnd (uint32_t end);
       
    58   void RemoveAtStart (uint32_t start);
       
    59   void RemoveAtEnd (uint32_t end);
       
    60 
       
    61   void PrintDefault (std::ostream &os, Buffer buffer) const;
       
    62   void Print (std::ostream &os, Buffer buffer, PacketPrinter const &printer) const;
       
    63 
       
    64   static void PrintStats (void);
       
    65 
       
    66 private:
       
    67   /**
       
    68      head -(next)-> tail
       
    69        ^             |
       
    70         \---(prev)---|
       
    71    */
       
    72   struct Data {
       
    73     uint16_t m_count;
       
    74     uint16_t m_size;
       
    75     uint16_t m_dirtyEnd;
       
    76     uint8_t m_data[10];
       
    77   };
       
    78   struct SmallItem {
       
    79     uint16_t next;
       
    80     uint16_t prev;
       
    81     uint32_t typeUid;
       
    82     uint32_t size;
       
    83     uint16_t chunkUid;
       
    84   };
       
    85   struct ExtraItem {
       
    86     uint32_t fragmentStart;
       
    87     uint32_t fragmentEnd;
       
    88     uint32_t packetUid;
       
    89   };
       
    90 
       
    91   typedef std::vector<struct Data *> DataFreeList;
       
    92   
       
    93   PacketHistory ();
       
    94   void DoAddHeader (uint32_t uid, uint32_t size);
       
    95   void DoRemoveHeader (uint32_t uid, uint32_t size);
       
    96   void DoAddTrailer (uint32_t uid, uint32_t size);
       
    97   void DoRemoveTrailer (uint32_t uid, uint32_t size);
       
    98 
       
    99   inline uint16_t AddSmall (const PacketHistory::SmallItem *item);
       
   100   uint16_t AddBig (uint32_t head, uint32_t tail,
       
   101                    const PacketHistory::SmallItem *item, 
       
   102                    const PacketHistory::ExtraItem *extraItem);
       
   103   void ReplaceTail (PacketHistory::SmallItem *item, 
       
   104                     PacketHistory::ExtraItem *extraItem,
       
   105                     uint32_t available);
       
   106   inline void UpdateHead (uint16_t written);
       
   107   inline void UpdateTail (uint16_t written);
       
   108   uint32_t GetUleb128Size (uint32_t value) const;
       
   109   uint32_t ReadUleb128 (const uint8_t **pBuffer) const;
       
   110   inline void Append16 (uint16_t value, uint8_t *buffer);
       
   111   inline bool TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end);
       
   112   inline bool TryToAppendFast (uint32_t value, uint8_t **pBuffer, uint8_t *end);
       
   113   inline bool TryToAppend32 (uint32_t value, uint8_t **pBuffer, uint8_t *end);
       
   114   inline bool TryToAppend16 (uint16_t value, uint8_t **pBuffer, uint8_t *end);
       
   115   void AppendValue (uint32_t value, uint8_t *buffer);
       
   116   void AppendValueExtra (uint32_t value, uint8_t *buffer);
       
   117   inline void Reserve (uint32_t n);
       
   118   void ReserveCopy (uint32_t n);
       
   119   uint32_t DoPrint (struct PacketHistory::SmallItem *item, uint32_t current,
       
   120                     Buffer data, uint32_t offset, const PacketPrinter &printer,
       
   121                     std::ostream &os) const;
       
   122   uint32_t GetTotalSize (void) const;
       
   123   uint32_t ReadItems (uint16_t current, 
       
   124                       struct PacketHistory::SmallItem *item,
       
   125                       struct PacketHistory::ExtraItem *extraItem) const;
       
   126 
       
   127 
       
   128   static struct PacketHistory::Data *Create (uint32_t size);
       
   129   static void Recycle (struct PacketHistory::Data *data);
       
   130   static struct PacketHistory::Data *Allocate (uint32_t n);
       
   131   static void Deallocate (struct PacketHistory::Data *data);
       
   132   
       
   133   static DataFreeList m_freeList;
       
   134   static bool m_enable;
       
   135   static uint32_t m_maxSize;
       
   136   static uint16_t m_chunkUid;
       
   137   
       
   138   struct Data *m_data;
       
   139   uint16_t m_head;
       
   140   uint16_t m_tail;
       
   141   uint16_t m_used;
       
   142   uint32_t m_packetUid;
       
   143 };
       
   144 
       
   145 }; // namespace ns3
       
   146 
       
   147 namespace ns3 {
       
   148 
       
   149 template <typename T>
       
   150 void 
       
   151 PacketHistory::AddHeader (T const &header, uint32_t size)
       
   152 {
       
   153   DoAddHeader (PacketPrinter::GetHeaderUid<T> (), size);
       
   154 }
       
   155 
       
   156 template <typename T>
       
   157 void 
       
   158 PacketHistory::RemoveHeader (T const &header, uint32_t size)
       
   159 {
       
   160   DoRemoveHeader (PacketPrinter::GetHeaderUid<T> (), size);
       
   161 }
       
   162 template <typename T>
       
   163 void 
       
   164 PacketHistory::AddTrailer (T const &trailer, uint32_t size)
       
   165 {
       
   166   DoAddTrailer (PacketPrinter::GetTrailerUid<T> (), size);
       
   167 }
       
   168 template <typename T>
       
   169 void 
       
   170 PacketHistory::RemoveTrailer (T const &trailer, uint32_t size)
       
   171 {
       
   172   DoRemoveTrailer (PacketPrinter::GetTrailerUid<T> (), size);
       
   173 }
       
   174 
       
   175 
       
   176 PacketHistory::PacketHistory (uint32_t uid, uint32_t size)
       
   177   : m_data (m_data = PacketHistory::Create (10)),
       
   178     m_head (0xffff),
       
   179     m_tail (0xffff),
       
   180     m_used (0),
       
   181     m_packetUid (uid)
       
   182 {
       
   183   memset (m_data->m_data, 0xff, 4);
       
   184   if (size > 0)
       
   185     {
       
   186       DoAddHeader (0, size);
       
   187     }
       
   188 }
       
   189 PacketHistory::PacketHistory (PacketHistory const &o)
       
   190   : m_data (o.m_data),
       
   191     m_head (o.m_head),
       
   192     m_tail (o.m_tail),
       
   193     m_used (o.m_used),
       
   194     m_packetUid (o.m_packetUid)
       
   195 {
       
   196   NS_ASSERT (m_data != 0);
       
   197   m_data->m_count++;
       
   198 }
       
   199 PacketHistory &
       
   200 PacketHistory::operator = (PacketHistory const& o)
       
   201 {
       
   202   if (m_data == o.m_data) 
       
   203     {
       
   204       // self assignment
       
   205       return *this;
       
   206     }
       
   207   NS_ASSERT (m_data != 0);
       
   208   m_data->m_count--;
       
   209   if (m_data->m_count == 0) 
       
   210     {
       
   211       PacketHistory::Recycle (m_data);
       
   212     }
       
   213   m_data = o.m_data;
       
   214   m_head = o.m_head;
       
   215   m_tail = o.m_tail;
       
   216   m_used = o.m_used;
       
   217   m_packetUid = o.m_packetUid;
       
   218   NS_ASSERT (m_data != 0);
       
   219   m_data->m_count++;
       
   220   return *this;
       
   221 }
       
   222 PacketHistory::~PacketHistory ()
       
   223 {
       
   224   NS_ASSERT (m_data != 0);
       
   225   m_data->m_count--;
       
   226   if (m_data->m_count == 0) 
       
   227     {
       
   228       PacketHistory::Recycle (m_data);
       
   229     }
       
   230 }
       
   231 
       
   232 }; // namespace ns3
       
   233 
       
   234 
       
   235 #endif /* PACKET_HISTORY_H */