21 #include "ns3/assert.h"
26 #define LOG_INTERNAL_STATE(y) \
27 NS_LOG_LOGIC (y << "start="<<m_start<<", end="<<m_end<<", zero start="<<m_zeroAreaStart<< \
28 ", zero end="<<m_zeroAreaEnd<<", count="<<m_data->m_count<<", size="<<m_data->m_size<< \
29 ", dirty start="<<m_data->m_dirtyStart<<", dirty end="<<m_data->m_dirtyEnd)
38 memset (buffer, 0, size);
50 #ifdef BUFFER_FREE_LIST
68 #define MAGIC_DESTROYED (~(long) 0)
69 #define IS_UNINITIALIZED(x) (x == (Buffer::FreeList*)0)
70 #define IS_DESTROYED(x) (x == (Buffer::FreeList*)MAGIC_DESTROYED)
71 #define IS_INITIALIZED(x) (!IS_UNINITIALIZED (x) && !IS_DESTROYED (x))
72 #define DESTROYED ((Buffer::FreeList*)MAGIC_DESTROYED)
73 #define UNINITIALIZED ((Buffer::FreeList*)0)
74 uint32_t Buffer::g_maxSize = 0;
75 Buffer::FreeList *Buffer::g_freeList = 0;
76 struct Buffer::LocalStaticDestructor Buffer::g_localStaticDestructor;
78 Buffer::LocalStaticDestructor::~LocalStaticDestructor(void)
81 if (IS_INITIALIZED (g_freeList))
83 for (Buffer::FreeList::iterator i = g_freeList->begin ();
84 i != g_freeList->end (); i++)
86 Buffer::Deallocate (*i);
89 g_freeList = DESTROYED;
94 Buffer::Recycle (
struct Buffer::Data *data)
98 NS_ASSERT (!IS_UNINITIALIZED (g_freeList));
99 g_maxSize = std::max (g_maxSize, data->m_size);
101 if (data->m_size < g_maxSize ||
102 IS_DESTROYED (g_freeList) ||
103 g_freeList->size () > 1000)
105 Buffer::Deallocate (data);
110 g_freeList->push_back (data);
115 Buffer::Create (uint32_t dataSize)
119 if (IS_UNINITIALIZED (g_freeList))
121 g_freeList =
new Buffer::FreeList ();
123 else if (IS_INITIALIZED (g_freeList))
125 while (!g_freeList->empty ())
127 struct Buffer::Data *data = g_freeList->back ();
128 g_freeList->pop_back ();
129 if (data->m_size >= dataSize)
134 Buffer::Deallocate (data);
137 struct Buffer::Data *data = Buffer::Allocate (dataSize);
143 Buffer::Recycle (
struct Buffer::Data *data)
151 Buffer::Create (uint32_t size)
154 return Allocate (size);
158 struct Buffer::Data *
159 Buffer::Allocate (uint32_t reqSize)
167 uint32_t size = reqSize - 1 +
sizeof (
struct Buffer::Data);
168 uint8_t *b =
new uint8_t [size];
169 struct Buffer::Data *data =
reinterpret_cast<struct Buffer::Data*
>(b);
170 data->m_size = reqSize;
176 Buffer::Deallocate (
struct Buffer::Data *data)
180 uint8_t *buf =
reinterpret_cast<uint8_t *
> (data);
190 Buffer::Buffer (uint32_t dataSize)
193 Initialize (dataSize);
196 Buffer::Buffer (uint32_t dataSize,
bool initialize)
199 if (initialize ==
true)
201 Initialize (dataSize);
206 Buffer::CheckInternalState (
void)
const
215 m_start <= m_zeroAreaStart &&
216 m_zeroAreaStart <= m_zeroAreaEnd &&
217 m_zeroAreaEnd <= m_end;
219 m_start >= m_data->m_dirtyStart &&
220 m_end <= m_data->m_dirtyEnd;
221 bool internalSizeOk = m_end - (m_zeroAreaEnd - m_zeroAreaStart) <= m_data->m_size &&
222 m_start <= m_data->m_size &&
223 m_zeroAreaStart <= m_data->m_size;
225 bool ok = m_data->m_count > 0 && offsetsOk && dirtyOk && internalSizeOk;
228 LOG_INTERNAL_STATE (
"check " <<
this <<
229 ", " << (offsetsOk ?
"true" :
"false") <<
230 ", " << (dirtyOk ?
"true" :
"false") <<
231 ", " << (internalSizeOk ?
"true" :
"false") <<
" ");
240 Buffer::Initialize (uint32_t zeroSize)
243 m_data = Buffer::Create (0);
245 m_maxZeroAreaStart = m_start;
246 m_zeroAreaStart = m_start;
247 m_zeroAreaEnd = m_zeroAreaStart + zeroSize;
248 m_end = m_zeroAreaEnd;
249 m_data->m_dirtyStart = m_start;
250 m_data->m_dirtyEnd = m_end;
255 Buffer::operator = (Buffer
const&o)
258 if (m_data != o.m_data)
262 if (m_data->m_count == 0)
270 m_maxZeroAreaStart = o.m_maxZeroAreaStart;
271 m_zeroAreaStart = o.m_zeroAreaStart;
272 m_zeroAreaEnd = o.m_zeroAreaEnd;
285 if (m_data->m_count == 0)
292 Buffer::GetInternalSize (
void)
const
295 return m_zeroAreaStart - m_start + m_end - m_zeroAreaEnd;
298 Buffer::GetInternalEnd (
void)
const
301 return m_end - (m_zeroAreaEnd - m_zeroAreaStart);
310 bool isDirty = m_data->m_count > 1 && m_start > m_data->m_dirtyStart;
311 if (m_start >= start && !isDirty)
318 NS_ASSERT (m_data->m_count == 1 || m_start == m_data->m_dirtyStart);
320 dirty = m_start > m_data->m_dirtyStart;
322 m_data->m_dirtyStart = m_start;
326 uint32_t newSize = GetInternalSize () + start;
327 struct Buffer::Data *newData = Buffer::Create (newSize);
328 memcpy (newData->m_data + start, m_data->m_data + m_start, GetInternalSize ());
330 if (m_data->m_count == 0)
332 Buffer::Recycle (m_data);
336 int32_t delta = start - m_start;
338 m_zeroAreaStart += delta;
339 m_zeroAreaEnd += delta;
344 m_data->m_dirtyStart = m_start;
345 m_data->m_dirtyEnd = m_end;
350 m_maxZeroAreaStart = std::max (m_maxZeroAreaStart, m_zeroAreaStart);
351 LOG_INTERNAL_STATE (
"add start=" << start <<
", ");
361 bool isDirty = m_data->m_count > 1 && m_end < m_data->m_dirtyEnd;
362 if (GetInternalEnd () + end <= m_data->m_size && !isDirty)
369 NS_ASSERT (m_data->m_count == 1 || m_end == m_data->m_dirtyEnd);
372 m_data->m_dirtyEnd = m_end;
374 dirty = m_end < m_data->m_dirtyEnd;
379 uint32_t newSize = GetInternalSize () + end;
380 struct Buffer::Data *newData = Buffer::Create (newSize);
381 memcpy (newData->m_data, m_data->m_data + m_start, GetInternalSize ());
383 if (m_data->m_count == 0)
385 Buffer::Recycle (m_data);
389 int32_t delta = -m_start;
390 m_zeroAreaStart += delta;
391 m_zeroAreaEnd += delta;
397 m_data->m_dirtyStart = m_start;
398 m_data->m_dirtyEnd = m_end;
403 m_maxZeroAreaStart = std::max (m_maxZeroAreaStart, m_zeroAreaStart);
404 LOG_INTERNAL_STATE (
"add end=" << end <<
", ");
414 if (m_data->m_count == 1 &&
415 m_end == m_zeroAreaEnd &&
416 m_end == m_data->m_dirtyEnd &&
417 o.m_start == o.m_zeroAreaStart &&
418 o.m_zeroAreaEnd - o.m_zeroAreaStart > 0)
425 uint32_t zeroSize = o.m_zeroAreaEnd - o.m_zeroAreaStart;
426 m_zeroAreaEnd += zeroSize;
427 m_end = m_zeroAreaEnd;
428 m_data->m_dirtyEnd = m_zeroAreaEnd;
429 uint32_t endData = o.m_end - o.m_zeroAreaEnd;
440 Buffer dst = CreateFullCopy ();
441 Buffer src = o.CreateFullCopy ();
456 uint32_t newStart = m_start + start;
457 if (newStart <= m_zeroAreaStart)
463 else if (newStart <= m_zeroAreaEnd)
467 uint32_t delta = newStart - m_zeroAreaStart;
468 m_start = m_zeroAreaStart;
469 m_zeroAreaEnd -= delta;
472 else if (newStart <= m_end)
478 uint32_t zeroSize = m_zeroAreaEnd - m_zeroAreaStart;
479 m_start = newStart - zeroSize;
481 m_zeroAreaStart = m_start;
482 m_zeroAreaEnd = m_start;
487 m_end -= m_zeroAreaEnd - m_zeroAreaStart;
489 m_zeroAreaEnd = m_end;
490 m_zeroAreaStart = m_end;
492 m_maxZeroAreaStart = std::max (m_maxZeroAreaStart, m_zeroAreaStart);
493 LOG_INTERNAL_STATE (
"rem start=" << start <<
", ");
501 uint32_t newEnd = m_end - std::min (end, m_end - m_start);
502 if (newEnd > m_zeroAreaEnd)
507 else if (newEnd > m_zeroAreaStart)
511 m_zeroAreaEnd = newEnd;
513 else if (newEnd > m_start)
517 m_zeroAreaEnd = newEnd;
518 m_zeroAreaStart = newEnd;
524 m_zeroAreaEnd = m_start;
525 m_zeroAreaStart = m_start;
527 m_maxZeroAreaStart = std::max (m_maxZeroAreaStart, m_zeroAreaStart);
528 LOG_INTERNAL_STATE (
"rem end=" << end <<
", ");
545 Buffer::CreateFullCopy (
void)
const
549 if (m_zeroAreaEnd - m_zeroAreaStart != 0)
552 tmp.
AddAtStart (m_zeroAreaEnd - m_zeroAreaStart);
553 tmp.
Begin ().
WriteU8 (0, m_zeroAreaEnd - m_zeroAreaStart);
554 uint32_t dataStart = m_zeroAreaStart - m_start;
556 tmp.
Begin ().
Write (m_data->m_data+m_start, dataStart);
557 uint32_t dataEnd = m_end - m_zeroAreaEnd;
561 i.
Write (m_data->m_data+m_zeroAreaStart,dataEnd);
573 uint32_t dataStart = (m_zeroAreaStart - m_start + 3) & (~0x3);
574 uint32_t dataEnd = (m_end - m_zeroAreaEnd + 3) & (~0x3);
580 uint32_t sz =
sizeof (uint32_t)
593 uint32_t* p =
reinterpret_cast<uint32_t *
> (buffer);
597 if (size + 4 <= maxSize)
600 *p++ = m_zeroAreaEnd - m_zeroAreaStart;
608 uint32_t dataStartLength = m_zeroAreaStart - m_start;
609 if (size + 4 <= maxSize)
612 *p++ = dataStartLength;
620 if (size + ((dataStartLength + 3) & (~3)) <= maxSize)
622 size += (dataStartLength + 3) & (~3);
623 memcpy (p, m_data->m_data + m_start, dataStartLength);
624 p += (((dataStartLength + 3) & (~3))/4);
632 uint32_t dataEndLength = m_end - m_zeroAreaEnd;
633 if (size + 4 <= maxSize)
636 *p++ = dataEndLength;
644 if (size + ((dataEndLength + 3) & (~3)) <= maxSize)
646 size += (dataEndLength + 3) & (~3);
647 memcpy (p, m_data->m_data+m_zeroAreaStart,dataEndLength);
648 p += (((dataEndLength + 3) & (~3))/4);
663 const uint32_t* p =
reinterpret_cast<const uint32_t *
> (buffer);
664 uint32_t sizeCheck = size-4;
667 uint32_t zeroDataLength = *p++;
671 Initialize (zeroDataLength);
675 uint32_t dataStartLength = *p++;
679 NS_ASSERT (sizeCheck >= dataStartLength);
680 Begin ().
Write (reinterpret_cast<uint8_t *> (const_cast<uint32_t *> (p)), dataStartLength);
681 p += (((dataStartLength+3)&(~3))/4);
682 sizeCheck -= ((dataStartLength+3)&(~3));
686 uint32_t dataEndLength = *p++;
692 tmp.
Prev (dataEndLength);
693 tmp.
Write (reinterpret_cast<uint8_t *> (const_cast<uint32_t *> (p)), dataEndLength);
694 p += (((dataEndLength+3)&(~3))/4);
695 sizeCheck -= ((dataEndLength+3)&(~3));
700 return (sizeCheck != 0) ? 0 : 1;
704 Buffer::GetCurrentStartOffset (
void)
const
710 Buffer::GetCurrentEndOffset (
void)
const
718 Buffer::TransformIntoRealBuffer (
void)
const
722 Buffer tmp = CreateFullCopy ();
723 *
const_cast<Buffer *
> (
this) = tmp;
733 TransformIntoRealBuffer ();
735 return m_data->m_data + m_start;
744 uint32_t tmpsize = std::min (m_zeroAreaStart-m_start, size);
745 os->write ((
const char*)(m_data->m_data + m_start), tmpsize);
748 size -= m_zeroAreaStart-m_start;
749 tmpsize = std::min (m_zeroAreaEnd - m_zeroAreaStart, size);
750 uint32_t left = tmpsize;
753 uint32_t toWrite = std::min (left, g_zeroes.size);
754 os->write (g_zeroes.buffer, toWrite);
760 tmpsize = std::min (m_end - m_zeroAreaEnd, size);
761 os->write ((
const char*)(m_data->m_data + m_zeroAreaStart), tmpsize);
771 uint32_t originalSize = size;
774 uint32_t tmpsize = std::min (m_zeroAreaStart-m_start, size);
775 memcpy (buffer, (
const char*)(m_data->m_data + m_start), tmpsize);
780 tmpsize = std::min (m_zeroAreaEnd - m_zeroAreaStart, size);
781 uint32_t left = tmpsize;
784 uint32_t toWrite = std::min (left, g_zeroes.size);
785 memcpy (buffer, g_zeroes.buffer, toWrite);
792 tmpsize = std::min (m_end - m_zeroAreaEnd, size);
793 memcpy (buffer, (
const char*)(m_data->m_data + m_zeroAreaStart), tmpsize);
798 return originalSize - size;
811 int32_t diff = m_current - o.m_current;
826 return m_current == m_dataEnd;
832 return m_current == m_dataStart;
836 Buffer::Iterator::CheckNoZero (uint32_t start, uint32_t end)
const
840 for (uint32_t i = start; i < end; i++)
850 Buffer::Iterator::Check (uint32_t i)
const
853 return i >= m_dataStart &&
854 !(i >= m_zeroStart && i < m_zeroEnd) &&
864 NS_ASSERT (start.m_current <= end.m_current);
865 NS_ASSERT (start.m_zeroStart == end.m_zeroStart);
866 NS_ASSERT (start.m_zeroEnd == end.m_zeroEnd);
868 uint32_t size = end.m_current - start.m_current;
870 GetWriteErrorMessage ());
871 if (start.m_current <= start.m_zeroStart)
873 uint32_t toCopy = std::min (size, start.m_zeroStart - start.m_current);
874 memcpy (&m_data[m_current], &start.m_data[start.m_current], toCopy);
875 start.m_current += toCopy;
879 if (start.m_current <= start.m_zeroEnd)
881 uint32_t toCopy = std::min (size, start.m_zeroEnd - start.m_current);
882 memset (&m_data[m_current], 0, toCopy);
883 start.m_current += toCopy;
887 uint32_t toCopy = std::min (size, start.m_dataEnd - start.m_current);
888 uint8_t *from = &start.m_data[start.m_current - (start.m_zeroEnd-start.m_zeroStart)];
889 uint8_t *to = &m_data[m_current];
890 memcpy (to, from, toCopy);
898 WriteU8 (data & 0xff);
900 WriteU8 (data & 0xff);
906 WriteU8 (data & 0xff);
908 WriteU8 (data & 0xff);
910 WriteU8 (data & 0xff);
912 WriteU8 (data & 0xff);
918 WriteU8 (data & 0xff);
920 WriteU8 (data & 0xff);
922 WriteU8 (data & 0xff);
924 WriteU8 (data & 0xff);
926 WriteU8 (data & 0xff);
928 WriteU8 (data & 0xff);
930 WriteU8 (data & 0xff);
932 WriteU8 (data & 0xff);
938 WriteU8 ((data >> 0) & 0xff);
939 WriteU8 ((data >> 8) & 0xff);
945 WriteU8 ((data >> 0) & 0xff);
946 WriteU8 ((data >> 8) & 0xff);
947 WriteU8 ((data >> 16) & 0xff);
948 WriteU8 ((data >> 24) & 0xff);
954 WriteU8 ((data >> 0) & 0xff);
955 WriteU8 ((data >> 8) & 0xff);
956 WriteU8 ((data >> 16) & 0xff);
957 WriteU8 ((data >> 24) & 0xff);
958 WriteU8 ((data >> 32) & 0xff);
959 WriteU8 ((data >> 40) & 0xff);
960 WriteU8 ((data >> 48) & 0xff);
961 WriteU8 ((data >> 56) & 0xff);
968 WriteU8 ((data >> 56) & 0xff);
969 WriteU8 ((data >> 48) & 0xff);
970 WriteU8 ((data >> 40) & 0xff);
971 WriteU8 ((data >> 32) & 0xff);
972 WriteU8 ((data >> 24) & 0xff);
973 WriteU8 ((data >> 16) & 0xff);
974 WriteU8 ((data >> 8) & 0xff);
975 WriteU8 ((data >> 0) & 0xff);
982 GetWriteErrorMessage ());
984 if (m_current <= m_zeroStart)
986 to = &m_data[m_current];
990 to = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
992 memcpy (to, buffer, size);
1000 uint8_t byte0 = ReadU8 ();
1001 uint8_t byte1 = ReadU8 ();
1002 uint8_t byte2 = ReadU8 ();
1003 uint8_t byte3 = ReadU8 ();
1004 uint32_t data = byte3;
1017 uint8_t byte0 = ReadU8 ();
1018 uint8_t byte1 = ReadU8 ();
1019 uint8_t byte2 = ReadU8 ();
1020 uint8_t byte3 = ReadU8 ();
1021 uint8_t byte4 = ReadU8 ();
1022 uint8_t byte5 = ReadU8 ();
1023 uint8_t byte6 = ReadU8 ();
1024 uint8_t byte7 = ReadU8 ();
1025 uint64_t data = byte7;
1044 Buffer::Iterator::SlowReadNtohU16 (
void)
1047 uint16_t retval = 0;
1048 retval |= ReadU8 ();
1050 retval |= ReadU8 ();
1054 Buffer::Iterator::SlowReadNtohU32 (
void)
1057 uint32_t retval = 0;
1058 retval |= ReadU8 ();
1060 retval |= ReadU8 ();
1062 retval |= ReadU8 ();
1064 retval |= ReadU8 ();
1071 uint64_t retval = 0;
1072 retval |= ReadU8 ();
1074 retval |= ReadU8 ();
1076 retval |= ReadU8 ();
1078 retval |= ReadU8 ();
1080 retval |= ReadU8 ();
1082 retval |= ReadU8 ();
1084 retval |= ReadU8 ();
1086 retval |= ReadU8 ();
1093 uint8_t byte0 = ReadU8 ();
1094 uint8_t byte1 = ReadU8 ();
1095 uint16_t data = byte1;
1104 uint8_t byte0 = ReadU8 ();
1105 uint8_t byte1 = ReadU8 ();
1106 uint8_t byte2 = ReadU8 ();
1107 uint8_t byte3 = ReadU8 ();
1108 uint32_t data = byte3;
1121 uint8_t byte0 = ReadU8 ();
1122 uint8_t byte1 = ReadU8 ();
1123 uint8_t byte2 = ReadU8 ();
1124 uint8_t byte3 = ReadU8 ();
1125 uint8_t byte4 = ReadU8 ();
1126 uint8_t byte5 = ReadU8 ();
1127 uint8_t byte6 = ReadU8 ();
1128 uint8_t byte7 = ReadU8 ();
1129 uint64_t data = byte7;
1151 for (uint32_t i = 0; i < size; i++)
1153 buffer[i] = ReadU8 ();
1161 return CalculateIpChecksum (size, 0);
1169 uint32_t sum = initialChecksum;
1171 for (
int j = 0; j < size/2; j++)
1178 sum = (sum & 0xffff) + (sum >> 16);
1186 return m_dataEnd - m_dataStart;
1191 Buffer::Iterator::GetReadErrorMessage (
void)
const
1194 std::string str =
"You have attempted to read beyond the bounds of the "
1195 "available buffer space. This usually indicates that a "
1196 "Header::Deserialize or Trailer::Deserialize method "
1197 "is trying to read data which was not written by "
1198 "a Header::Serialize or Trailer::Serialize method. "
1199 "In short: check the code of your Serialize and Deserialize "
1204 Buffer::Iterator::GetWriteErrorMessage (
void)
const
1208 if (m_current < m_dataStart)
1210 str =
"You have attempted to write before the start of the available "
1211 "buffer space. This usually indicates that Trailer::GetSerializedSize "
1212 "returned a size which is too small compared to what Trailer::Serialize "
1213 "is actually using.";
1215 else if (m_current >= m_dataEnd)
1217 str =
"You have attempted to write after the end of the available "
1218 "buffer space. This usually indicates that Header::GetSerializedSize "
1219 "returned a size which is too small compared to what Header::Serialize "
1220 "is actually using.";
1224 NS_ASSERT (m_current >= m_zeroStart && m_current < m_zeroEnd);
1225 str =
"You have attempted to write inside the payload area of the "
1226 "buffer. This usually indicates that your Serialize method uses more "
1227 "buffer space than what your GetSerialized method returned.";
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
void WriteHtonU64(uint64_t data)
#define NS_LOG_FUNCTION(parameters)
void RemoveAtEnd(uint32_t end)
void RemoveAtStart(uint32_t start)
automatically resized byte buffer
uint64_t ReadNtohU64(void)
#define NS_ASSERT(condition)
#define NS_LOG_COMPONENT_DEFINE(name)
uint32_t GetSerializedSize(void) const
uint32_t GetDistanceFrom(Iterator const &o) const
iterator in a Buffer instance
uint32_t Deserialize(const uint8_t *buffer, uint32_t size)
void WriteU16(uint16_t data)
Buffer::Iterator End(void) const
uint8_t const * PeekData(void) const
void WriteU64(uint64_t data)
void CopyData(std::ostream *os, uint32_t size) const
Buffer::Iterator Begin(void) const
void Read(uint8_t *buffer, uint32_t size)
uint32_t GetSize(void) const
Buffer CreateFragment(uint32_t start, uint32_t length) const
bool AddAtEnd(uint32_t end)
void WriteHtolsbU16(uint16_t data)
#define NS_ASSERT_MSG(condition, message)
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
void WriteU8(uint8_t data)
void WriteHtolsbU64(uint64_t data)
static uint32_t g_recommendedStart
void Write(uint8_t const *buffer, uint32_t size)
uint16_t ReadLsbtohU16(void)
bool AddAtStart(uint32_t start)
uint64_t ReadLsbtohU64(void)
void WriteU32(uint32_t data)
uint32_t GetSize(void) const
uint32_t ReadLsbtohU32(void)
void WriteHtolsbU32(uint32_t data)