1.1 --- a/src/common/tag-list.cc Thu Apr 24 16:06:33 2008 -0700
1.2 +++ b/src/common/tag-list.cc Tue May 06 14:18:05 2008 -0700
1.3 @@ -64,45 +64,68 @@
1.4
1.5
1.6 TagList::TagList ()
1.7 - : m_buffer (0),
1.8 - m_size (0)
1.9 + : m_used (0),
1.10 + m_data (0)
1.11 {}
1.12 TagList::TagList (const TagList &o)
1.13 - : m_size (o.m_size)
1.14 + : m_used (o.m_used),
1.15 + m_data (o.m_data)
1.16 {
1.17 - m_buffer = new uint8_t [o.m_size] ();
1.18 - memcpy (m_buffer, o.m_buffer, o.m_size);
1.19 + if (m_data != 0)
1.20 + {
1.21 + m_data->count++;
1.22 + }
1.23 }
1.24 TagList &
1.25 TagList::operator = (const TagList &o)
1.26 {
1.27 - delete [] m_buffer;
1.28 - m_buffer = new uint8_t [o.m_size] ();
1.29 - memcpy (m_buffer, o.m_buffer, m_size);
1.30 - m_size = o.m_size;
1.31 + if (this == &o)
1.32 + {
1.33 + return *this;
1.34 + }
1.35 +
1.36 + Deallocate (m_data);
1.37 + m_data = o.m_data;
1.38 + m_used = o.m_used;
1.39 + if (m_data != 0)
1.40 + {
1.41 + m_data->count++;
1.42 + }
1.43 return *this;
1.44 }
1.45 TagList::~TagList ()
1.46 {
1.47 - delete [] m_buffer;
1.48 - m_buffer = 0;
1.49 - m_size = 0;
1.50 + Deallocate (m_data);
1.51 + m_data = 0;
1.52 + m_used = 0;
1.53 }
1.54
1.55 TagBuffer
1.56 TagList::Add (TypeId tid, uint32_t bufferSize, uint32_t start, uint32_t end)
1.57 {
1.58 - uint32_t newSize = m_size + bufferSize + 4 + 4 + 4 + 4;
1.59 - uint8_t *newBuffer = new uint8_t [newSize] ();
1.60 - memcpy (newBuffer, m_buffer, m_size);
1.61 - TagBuffer tag = TagBuffer (newBuffer + m_size, newBuffer + newSize);
1.62 + uint32_t spaceNeeded = m_used + bufferSize + 4 + 4 + 4 + 4;
1.63 + NS_ASSERT (m_used <= spaceNeeded);
1.64 + if (m_data == 0)
1.65 + {
1.66 + m_data = Allocate (spaceNeeded);
1.67 + m_used = 0;
1.68 + }
1.69 + else if (m_data->size < spaceNeeded ||
1.70 + (m_data->count != 1 && m_data->dirty != m_used))
1.71 + {
1.72 + struct TagList::Data *newData = Allocate (spaceNeeded);
1.73 + memcpy (&newData->data, &m_data->data, m_used);
1.74 + Deallocate (m_data);
1.75 + m_data = newData;
1.76 + }
1.77 + TagBuffer tag = TagBuffer (&m_data->data[m_used],
1.78 + &m_data->data[spaceNeeded]);
1.79 tag.WriteU32 (tid.GetUid ());
1.80 tag.WriteU32 (bufferSize);
1.81 tag.WriteU32 (start);
1.82 tag.WriteU32 (end);
1.83 - delete [] m_buffer;
1.84 - m_buffer = newBuffer;
1.85 - m_size = newSize;
1.86 + m_used = spaceNeeded;
1.87 + m_data->dirty = m_used;
1.88 return tag;
1.89 }
1.90
1.91 @@ -127,15 +150,22 @@
1.92 void
1.93 TagList::RemoveAll (void)
1.94 {
1.95 - delete [] m_buffer;
1.96 - m_buffer = 0;
1.97 - m_size = 0;
1.98 + Deallocate (m_data);
1.99 + m_data = 0;
1.100 + m_used = 0;
1.101 }
1.102
1.103 TagList::Iterator
1.104 TagList::Begin (uint32_t offsetStart, uint32_t offsetEnd) const
1.105 {
1.106 - return Iterator (m_buffer, m_buffer + m_size, offsetStart, offsetEnd);
1.107 + if (m_data == 0)
1.108 + {
1.109 + return Iterator (0, 0, offsetStart, offsetEnd);
1.110 + }
1.111 + else
1.112 + {
1.113 + return Iterator (m_data->data, &m_data->data[m_used], offsetStart, offsetEnd);
1.114 + }
1.115 }
1.116
1.117 bool
1.118 @@ -234,4 +264,32 @@
1.119 *this = list;
1.120 }
1.121
1.122 +
1.123 +struct TagList::Data *
1.124 +TagList::Allocate (uint32_t size)
1.125 +{
1.126 + uint8_t *buffer = new uint8_t [size + sizeof (struct TagList::Data) - 4];
1.127 + struct Data *data = (struct Data *)buffer;
1.128 + data->count = 1;
1.129 + data->size = size;
1.130 + data->dirty = 0;
1.131 + return data;
1.132 +}
1.133 +
1.134 +void
1.135 +TagList::Deallocate (struct Data *data)
1.136 +{
1.137 + if (data == 0)
1.138 + {
1.139 + return;
1.140 + }
1.141 + data->count--;
1.142 + if (data->count == 0)
1.143 + {
1.144 + uint8_t *buffer = (uint8_t *)data;
1.145 + delete [] buffer;
1.146 + }
1.147 +}
1.148 +
1.149 +
1.150 } // namespace ns3
2.1 --- a/src/common/tag-list.h Thu Apr 24 16:06:33 2008 -0700
2.2 +++ b/src/common/tag-list.h Tue May 06 14:18:05 2008 -0700
2.3 @@ -58,8 +58,18 @@
2.4 private:
2.5 bool IsDirtyAtEnd (uint32_t appendOffset);
2.6 bool IsDirtyAtStart (uint32_t prependOffset);
2.7 - uint8_t *m_buffer;
2.8 - uint32_t m_size;
2.9 +
2.10 + struct Data {
2.11 + uint32_t size;
2.12 + uint32_t count;
2.13 + uint32_t dirty;
2.14 + uint8_t data[4];
2.15 + };
2.16 + struct TagList::Data *Allocate (uint32_t size);
2.17 + void Deallocate (struct Data *data);
2.18 +
2.19 + uint16_t m_used;
2.20 + struct Data *m_data;
2.21 };
2.22
2.23 } // namespace ns3