src/common/mtag-list.cc
changeset 3041 a624276a897b
parent 3040 e11e106c7c19
child 3042 d0a9677d5452
equal deleted inserted replaced
3040:e11e106c7c19 3041:a624276a897b
     1 #include "mtag-list.h"
       
     2 
       
     3 namespace ns3 {
       
     4 
       
     5 TagList::Iterator::Item::Item (TagBuffer buf_)
       
     6     : buf (buf_)
       
     7 {}
       
     8 
       
     9 bool 
       
    10 TagList::Iterator::HasNext (void) const
       
    11 {
       
    12   return m_current < m_end;
       
    13 }
       
    14 struct TagList::Iterator::Item 
       
    15 TagList::Iterator::Next (void)
       
    16 {
       
    17   NS_ASSERT (HasNext ());
       
    18   struct Item item = Item (TagBuffer (m_current, m_end));
       
    19   item.tid.SetUid (item.buf.ReadU32 ());
       
    20   item.size = item.buf.ReadU32 ();
       
    21   item.start = item.buf.ReadU32 ();
       
    22   item.end = item.buf.ReadU32 ();
       
    23   item.start = std::max (item.start, m_offsetStart);
       
    24   item.end = std::min (item.end, m_offsetEnd);
       
    25   m_current += 4 + 4 + 4 + 4 + item.size;
       
    26   item.buf.TrimAtEnd (m_end - m_current);
       
    27   PrepareForNext ();
       
    28   return item;
       
    29 }
       
    30 void
       
    31 TagList::Iterator::PrepareForNext (void)
       
    32 {
       
    33   while (m_current < m_end)
       
    34     {
       
    35       struct Item item = Item (TagBuffer (m_current, m_end));
       
    36       item.tid.SetUid (item.buf.ReadU32 ());
       
    37       item.size = item.buf.ReadU32 ();
       
    38       item.start = item.buf.ReadU32 ();
       
    39       item.end = item.buf.ReadU32 ();
       
    40       if (item.start > m_offsetEnd || item.end < m_offsetStart)
       
    41 	{
       
    42 	  m_current += 4 + 4 + 4 + 4 + item.size;
       
    43 	}
       
    44       else
       
    45 	{
       
    46 	  break;
       
    47 	}
       
    48     }
       
    49 }
       
    50 TagList::Iterator::Iterator (uint8_t *start, uint8_t *end, uint32_t offsetStart, uint32_t offsetEnd)
       
    51   : m_current (start),
       
    52     m_end (end),
       
    53     m_offsetStart (offsetStart),
       
    54     m_offsetEnd (offsetEnd)
       
    55 {
       
    56   PrepareForNext ();
       
    57 }
       
    58 
       
    59 uint32_t 
       
    60 TagList::Iterator::GetOffsetStart (void) const
       
    61 {
       
    62   return m_offsetStart;
       
    63 }
       
    64 
       
    65 
       
    66 TagList::TagList ()
       
    67   : m_buffer (0),
       
    68     m_size (0)
       
    69 {}
       
    70 TagList::TagList (const TagList &o)
       
    71   : m_size (o.m_size)
       
    72 {
       
    73   m_buffer = new uint8_t [o.m_size] ();
       
    74   memcpy (m_buffer, o.m_buffer, o.m_size);
       
    75 }
       
    76 TagList &
       
    77 TagList::operator = (const TagList &o)
       
    78 {
       
    79   delete [] m_buffer;
       
    80   m_buffer = new uint8_t [o.m_size] ();
       
    81   memcpy (m_buffer, o.m_buffer, m_size);
       
    82   m_size = o.m_size;
       
    83   return *this;
       
    84 }
       
    85 TagList::~TagList ()
       
    86 {
       
    87   delete [] m_buffer;
       
    88   m_buffer = 0;
       
    89   m_size = 0;
       
    90 }
       
    91 
       
    92 TagBuffer
       
    93 TagList::Add (TypeId tid, uint32_t bufferSize, uint32_t start, uint32_t end)
       
    94 {
       
    95   uint32_t newSize = m_size + bufferSize + 4 + 4 + 4 + 4;
       
    96   uint8_t *newBuffer = new uint8_t [newSize] ();
       
    97   memcpy (newBuffer, m_buffer, m_size);
       
    98   TagBuffer tag = TagBuffer (newBuffer + m_size, newBuffer + newSize);
       
    99   tag.WriteU32 (tid.GetUid ());
       
   100   tag.WriteU32 (bufferSize);
       
   101   tag.WriteU32 (start);
       
   102   tag.WriteU32 (end);
       
   103   delete [] m_buffer;
       
   104   m_buffer = newBuffer;
       
   105   m_size = newSize;
       
   106   return tag;
       
   107 }
       
   108 
       
   109 void 
       
   110 TagList::Add (const TagList &o)
       
   111 {
       
   112   TagList::Iterator i = o.Begin (0, 0xffffffff);
       
   113   while (i.HasNext ())
       
   114     {
       
   115       TagList::Iterator::Item item = i.Next ();
       
   116       TagBuffer buf = Add (item.tid, item.size, item.start, item.end);
       
   117       buf.CopyFrom (item.buf);
       
   118     }
       
   119 }
       
   120 
       
   121 void 
       
   122 TagList::Remove (const Iterator &i)
       
   123 {
       
   124   // XXX: more complex to implement.
       
   125 }
       
   126 
       
   127 void 
       
   128 TagList::RemoveAll (void)
       
   129 {
       
   130   delete [] m_buffer;
       
   131   m_buffer = 0;
       
   132   m_size = 0;  
       
   133 }
       
   134 
       
   135 TagList::Iterator 
       
   136 TagList::Begin (uint32_t offsetStart, uint32_t offsetEnd) const
       
   137 {
       
   138   return Iterator (m_buffer, m_buffer + m_size, offsetStart, offsetEnd);
       
   139 }
       
   140 
       
   141 bool 
       
   142 TagList::IsDirtyAtEnd (uint32_t appendOffset)
       
   143 {
       
   144   TagList::Iterator i = Begin (0, 0xffffffff);
       
   145   while (i.HasNext ())
       
   146     {
       
   147       TagList::Iterator::Item item = i.Next ();
       
   148       if (item.end > appendOffset)
       
   149 	{
       
   150 	  return true;
       
   151 	}
       
   152     }
       
   153   return false;
       
   154 }
       
   155 
       
   156 bool 
       
   157 TagList::IsDirtyAtStart (uint32_t prependOffset)
       
   158 {
       
   159   TagList::Iterator i = Begin (0, 0xffffffff);
       
   160   while (i.HasNext ())
       
   161     {
       
   162       TagList::Iterator::Item item = i.Next ();
       
   163       if (item.start < prependOffset)
       
   164 	{
       
   165 	  return true;
       
   166 	}
       
   167     }
       
   168   return false;
       
   169 }
       
   170 
       
   171 void 
       
   172 TagList::AddAtEnd (int32_t adjustment, uint32_t appendOffset)
       
   173 {
       
   174   if (adjustment == 0 && !IsDirtyAtEnd (appendOffset))
       
   175     {
       
   176       return;
       
   177     }
       
   178   TagList list;
       
   179   TagList::Iterator i = Begin (0, 0xffffffff);
       
   180   while (i.HasNext ())
       
   181     {
       
   182       TagList::Iterator::Item item = i.Next ();
       
   183       item.start += adjustment;
       
   184       item.end += adjustment;
       
   185 
       
   186       if (item.start > appendOffset)
       
   187 	{
       
   188 	  continue;
       
   189 	}
       
   190       else if (item.start < appendOffset && item.end > appendOffset)
       
   191 	{
       
   192 	  item.end = appendOffset;
       
   193 	}
       
   194       else
       
   195 	{
       
   196 	  // nothing to do.
       
   197 	}
       
   198       TagBuffer buf = list.Add (item.tid, item.size, item.start, item.end);
       
   199       buf.CopyFrom (item.buf);
       
   200     }
       
   201   *this = list;  
       
   202 }
       
   203 
       
   204 void 
       
   205 TagList::AddAtStart (int32_t adjustment, uint32_t prependOffset)
       
   206 {
       
   207   if (adjustment == 0 && !IsDirtyAtStart (prependOffset))
       
   208     {
       
   209       return;
       
   210     }
       
   211   TagList list;
       
   212   TagList::Iterator i = Begin (0, 0xffffffff);
       
   213   while (i.HasNext ())
       
   214     {
       
   215       TagList::Iterator::Item item = i.Next ();
       
   216       item.start += adjustment;
       
   217       item.end += adjustment;
       
   218 
       
   219       if (item.end < prependOffset)
       
   220 	{
       
   221 	  continue;
       
   222 	}
       
   223       else if (item.end > prependOffset && item.start < prependOffset)
       
   224 	{
       
   225 	  item.start = prependOffset;
       
   226 	}
       
   227       else
       
   228 	{
       
   229 	  // nothing to do.
       
   230 	}
       
   231       TagBuffer buf = list.Add (item.tid, item.size, item.start, item.end);
       
   232       buf.CopyFrom (item.buf);
       
   233     }
       
   234   *this = list;    
       
   235 }
       
   236 
       
   237 } // namespace ns3