A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
buffer.h
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006,2007 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #ifndef BUFFER_H
21 #define BUFFER_H
22 
23 #include <stdint.h>
24 #include <vector>
25 #include <ostream>
26 #include "ns3/assert.h"
27 
28 #define BUFFER_FREE_LIST 1
29 
30 namespace ns3 {
31 
92 class Buffer
93 {
94 public:
98  class Iterator
99  {
100 public:
101  inline Iterator ();
105  inline void Next (void);
109  inline void Prev (void);
113  inline void Next (uint32_t delta);
117  inline void Prev (uint32_t delta);
126  uint32_t GetDistanceFrom (Iterator const &o) const;
127 
132  bool IsEnd (void) const;
137  bool IsStart (void) const;
138 
145  inline void WriteU8 (uint8_t data);
153  inline void WriteU8 (uint8_t data, uint32_t len);
163  void WriteU16 (uint16_t data);
173  void WriteU32 (uint32_t data);
183  void WriteU64 (uint64_t data);
191  void WriteHtolsbU16 (uint16_t data);
199  void WriteHtolsbU32 (uint32_t data);
207  void WriteHtolsbU64 (uint64_t data);
215  inline void WriteHtonU16 (uint16_t data);
223  inline void WriteHtonU32 (uint32_t data);
231  void WriteHtonU64 (uint64_t data);
239  void Write (uint8_t const*buffer, uint32_t size);
251  void Write (Iterator start, Iterator end);
252 
258  inline uint8_t PeekU8 (void);
259 
266  inline uint8_t ReadU8 (void);
274  inline uint16_t ReadU16 (void);
282  uint32_t ReadU32 (void);
290  uint64_t ReadU64 (void);
298  inline uint16_t ReadNtohU16 (void);
306  inline uint32_t ReadNtohU32 (void);
314  uint64_t ReadNtohU64 (void);
322  uint16_t ReadLsbtohU16 (void);
330  uint32_t ReadLsbtohU32 (void);
338  uint64_t ReadLsbtohU64 (void);
347  void Read (uint8_t *buffer, uint32_t size);
348 
357  inline void Read (Iterator start, uint32_t size);
358 
364  uint16_t CalculateIpChecksum (uint16_t size);
365 
372  uint16_t CalculateIpChecksum (uint16_t size, uint32_t initialChecksum);
373 
377  uint32_t GetSize (void) const;
378 
379 private:
380  friend class Buffer;
386  inline Iterator (Buffer const*buffer);
393  inline Iterator (Buffer const*buffer, bool dummy);
399  inline void Construct (const Buffer *buffer);
407  bool CheckNoZero (uint32_t start, uint32_t end) const;
414  bool Check (uint32_t i) const;
424  uint16_t SlowReadNtohU16 (void);
434  uint32_t SlowReadNtohU32 (void);
439  std::string GetReadErrorMessage (void) const;
447  std::string GetWriteErrorMessage (void) const;
448 
453  uint32_t m_zeroStart;
458  uint32_t m_zeroEnd;
463  uint32_t m_dataStart;
468  uint32_t m_dataEnd;
473  uint32_t m_current;
478  uint8_t *m_data;
479  };
480 
484  inline uint32_t GetSize (void) const;
485 
495  uint8_t const*PeekData (void) const;
496 
507  bool AddAtStart (uint32_t start);
518  bool AddAtEnd (uint32_t end);
519 
527  void AddAtEnd (const Buffer &o);
535  void RemoveAtStart (uint32_t start);
543  void RemoveAtEnd (uint32_t end);
544 
552  Buffer CreateFragment (uint32_t start, uint32_t length) const;
553 
558  inline Buffer::Iterator Begin (void) const;
563  inline Buffer::Iterator End (void) const;
564 
571  Buffer CreateFullCopy (void) const;
572 
577  uint32_t GetSerializedSize (void) const;
578 
589  uint32_t Serialize (uint8_t* buffer, uint32_t maxSize) const;
590 
599  uint32_t Deserialize (const uint8_t* buffer, uint32_t size);
600 
605  int32_t GetCurrentStartOffset (void) const;
610  int32_t GetCurrentEndOffset (void) const;
611 
618  void CopyData (std::ostream *os, uint32_t size) const;
619 
627  uint32_t CopyData (uint8_t *buffer, uint32_t size) const;
628 
633  inline Buffer (Buffer const &o);
639  Buffer &operator = (Buffer const &o);
640  Buffer ();
648  Buffer (uint32_t dataSize);
658  Buffer (uint32_t dataSize, bool initialize);
659  ~Buffer ();
660 private:
675  struct Data
676  {
681  uint32_t m_count;
685  uint32_t m_size;
690  uint32_t m_dirtyStart;
695  uint32_t m_dirtyEnd;
700  uint8_t m_data[1];
701  };
702 
706  void TransformIntoRealBuffer (void) const;
714  bool CheckInternalState (void) const;
715 
721  void Initialize (uint32_t zeroSize);
722 
728  uint32_t GetInternalSize (void) const;
729 
734  uint32_t GetInternalEnd (void) const;
735 
740  static void Recycle (struct Buffer::Data *data);
746  static struct Buffer::Data *Create (uint32_t size);
752  static struct Buffer::Data *Allocate (uint32_t reqSize);
757  static void Deallocate (struct Buffer::Data *data);
758 
759  struct Data *m_data;
760 
777  static uint32_t g_recommendedStart;
778 
783  uint32_t m_zeroAreaStart;
788  uint32_t m_zeroAreaEnd;
793  uint32_t m_start;
798  uint32_t m_end;
799 
800 #ifdef BUFFER_FREE_LIST
801  typedef std::vector<struct Buffer::Data*> FreeList;
805  {
807  };
808  static uint32_t g_maxSize;
811 #endif
812 };
813 
814 } // namespace ns3
815 
816 #include "ns3/assert.h"
817 #include <cstring>
818 
819 namespace ns3 {
820 
822  : m_zeroStart (0),
823  m_zeroEnd (0),
824  m_dataStart (0),
825  m_dataEnd (0),
826  m_current (0),
827  m_data (0)
828 {
829 }
831 {
832  Construct (buffer);
833  m_current = m_dataStart;
834 }
835 Buffer::Iterator::Iterator (Buffer const*buffer, bool dummy)
836 {
837  Construct (buffer);
838  m_current = m_dataEnd;
839 }
840 
841 void
843 {
844  m_zeroStart = buffer->m_zeroAreaStart;
845  m_zeroEnd = buffer->m_zeroAreaEnd;
846  m_dataStart = buffer->m_start;
847  m_dataEnd = buffer->m_end;
848  m_data = buffer->m_data->m_data;
849 }
850 
851 void
853 {
854  NS_ASSERT (m_current + 1 <= m_dataEnd);
855  m_current++;
856 }
857 void
859 {
860  NS_ASSERT (m_current >= 1);
861  m_current--;
862 }
863 void
864 Buffer::Iterator::Next (uint32_t delta)
865 {
866  NS_ASSERT (m_current + delta <= m_dataEnd);
867  m_current += delta;
868 }
869 void
870 Buffer::Iterator::Prev (uint32_t delta)
871 {
872  NS_ASSERT (m_current >= delta);
873  m_current -= delta;
874 }
875 void
877 {
878  NS_ASSERT_MSG (Check (m_current),
879  GetWriteErrorMessage ());
880 
881  if (m_current < m_zeroStart)
882  {
883  m_data[m_current] = data;
884  m_current++;
885  }
886  else
887  {
888  m_data[m_current - (m_zeroEnd-m_zeroStart)] = data;
889  m_current++;
890  }
891 }
892 
893 void
894 Buffer::Iterator::WriteU8 (uint8_t data, uint32_t len)
895 {
896  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + len),
897  GetWriteErrorMessage ());
898  if (m_current <= m_zeroStart)
899  {
900  std::memset (&(m_data[m_current]), data, len);
901  m_current += len;
902  }
903  else
904  {
905  uint8_t *buffer = &m_data[m_current - (m_zeroEnd-m_zeroStart)];
906  std::memset (buffer, data, len);
907  m_current += len;
908  }
909 }
910 
911 void
913 {
914  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + 2),
915  GetWriteErrorMessage ());
916  uint8_t *buffer;
917  if (m_current + 2 <= m_zeroStart)
918  {
919  buffer = &m_data[m_current];
920  }
921  else
922  {
923  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
924  }
925  buffer[0] = (data >> 8)& 0xff;
926  buffer[1] = (data >> 0)& 0xff;
927  m_current+= 2;
928 }
929 
930 void
932 {
933  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + 4),
934  GetWriteErrorMessage ());
935 
936  uint8_t *buffer;
937  if (m_current + 4 <= m_zeroStart)
938  {
939  buffer = &m_data[m_current];
940  }
941  else
942  {
943  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
944  }
945  buffer[0] = (data >> 24)& 0xff;
946  buffer[1] = (data >> 16)& 0xff;
947  buffer[2] = (data >> 8)& 0xff;
948  buffer[3] = (data >> 0)& 0xff;
949  m_current+= 4;
950 }
951 
952 uint16_t
954 {
955  uint8_t *buffer;
956  if (m_current + 2 <= m_zeroStart)
957  {
958  buffer = &m_data[m_current];
959  }
960  else if (m_current >= m_zeroEnd)
961  {
962  buffer = &m_data[m_current];
963  }
964  else
965  {
966  return SlowReadNtohU16 ();
967  }
968  uint16_t retval = 0;
969  retval |= buffer[0];
970  retval <<= 8;
971  retval |= buffer[1];
972  m_current += 2;
973  return retval;
974 }
975 
976 uint32_t
978 {
979  uint8_t *buffer;
980  if (m_current + 4 <= m_zeroStart)
981  {
982  buffer = &m_data[m_current];
983  }
984  else if (m_current >= m_zeroEnd)
985  {
986  buffer = &m_data[m_current];
987  }
988  else
989  {
990  return SlowReadNtohU32 ();
991  }
992  uint32_t retval = 0;
993  retval |= buffer[0];
994  retval <<= 8;
995  retval |= buffer[1];
996  retval <<= 8;
997  retval |= buffer[2];
998  retval <<= 8;
999  retval |= buffer[3];
1000  m_current += 4;
1001  return retval;
1002 }
1003 
1004 uint8_t
1006 {
1007  NS_ASSERT_MSG (m_current >= m_dataStart &&
1008  m_current <= m_dataEnd,
1009  GetReadErrorMessage ());
1010 
1011  if (m_current < m_zeroStart)
1012  {
1013  uint8_t data = m_data[m_current];
1014  return data;
1015  }
1016  else if (m_current < m_zeroEnd)
1017  {
1018  return 0;
1019  }
1020  else
1021  {
1022  uint8_t data = m_data[m_current - (m_zeroEnd-m_zeroStart)];
1023  return data;
1024  }
1025 }
1026 
1027 uint8_t
1029 {
1030  uint8_t ret = PeekU8 ();
1031  m_current ++;
1032  return ret;
1033 }
1034 
1035 uint16_t
1037 {
1038  uint8_t byte0 = ReadU8 ();
1039  uint8_t byte1 = ReadU8 ();
1040  uint16_t data = byte1;
1041  data <<= 8;
1042  data |= byte0;
1043 
1044  return data;
1045 }
1046 
1047 void
1049 {
1050  Buffer::Iterator end = *this;
1051  end.Next (size);
1052 
1053  start.Write (*this, end);
1054 }
1055 
1056 
1058  : m_data (o.m_data),
1062  m_start (o.m_start),
1063  m_end (o.m_end)
1064 {
1065  m_data->m_count++;
1067 }
1068 
1069 uint32_t
1070 Buffer::GetSize (void) const
1071 {
1072  return m_end - m_start;
1073 }
1074 
1076 Buffer::Begin (void) const
1077 {
1079  return Buffer::Iterator (this);
1080 }
1082 Buffer::End (void) const
1083 {
1085  return Buffer::Iterator (this, false);
1086 }
1087 
1088 
1089 
1090 } // namespace ns3
1091 
1092 #endif /* BUFFER_H */
uint16_t ReadU16(void)
Definition: buffer.h:1036
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
Definition: buffer.cc:1162
uint16_t SlowReadNtohU16(void)
Definition: buffer.cc:1048
void Initialize(uint32_t zeroSize)
Initializes the buffer with a number of zeroes.
Definition: buffer.cc:244
void WriteHtonU64(uint64_t data)
Definition: buffer.cc:969
uint32_t m_end
offset to the end of the data referenced by this Buffer instance from the start of m_data->m_data ...
Definition: buffer.h:798
uint32_t ReadU32(void)
Definition: buffer.cc:1001
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:501
bool IsStart(void) const
Definition: buffer.cc:833
uint8_t * m_data
a pointer to the underlying byte buffer.
Definition: buffer.h:478
void RemoveAtStart(uint32_t start)
Definition: buffer.cc:456
uint32_t m_size
the size of the m_data field below.
Definition: buffer.h:685
automatically resized byte buffer
Definition: buffer.h:92
uint64_t ReadNtohU64(void)
Definition: buffer.cc:1072
uint32_t m_count
The reference count of an instance of this data structure.
Definition: buffer.h:681
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
uint32_t GetSerializedSize(void) const
Return the number of bytes required for serialization.
Definition: buffer.cc:574
bool CheckInternalState(void) const
Checks the internal buffer structures consistency.
Definition: buffer.cc:210
Buffer & operator=(Buffer const &o)
Assignment operator.
Definition: buffer.cc:259
uint32_t ReadNtohU32(void)
Definition: buffer.h:977
Local static destructor structure.
Definition: buffer.h:804
uint32_t m_start
offset to the start of the data referenced by this Buffer instance from the start of m_data->m_data ...
Definition: buffer.h:793
uint32_t GetDistanceFrom(Iterator const &o) const
Definition: buffer.cc:811
iterator in a Buffer instance
Definition: buffer.h:98
uint32_t SlowReadNtohU32(void)
Definition: buffer.cc:1058
uint32_t m_zeroStart
offset in virtual bytes from the start of the data buffer to the start of the "virtual zero area"...
Definition: buffer.h:453
uint32_t m_dirtyEnd
offset from the start of the m_data field below to the end of the area in which user bytes were writt...
Definition: buffer.h:695
uint32_t Deserialize(const uint8_t *buffer, uint32_t size)
Definition: buffer.cc:664
bool IsEnd(void) const
Definition: buffer.cc:827
uint8_t m_data[1]
The real data buffer holds at least one byte.
Definition: buffer.h:700
This data structure is variable-sized through its last member whose size is determined at allocation ...
Definition: buffer.h:675
std::string GetWriteErrorMessage(void) const
Returns an appropriate message indicating a write error.
Definition: buffer.cc:1208
void Prev(void)
go backward by one byte
Definition: buffer.h:858
uint8_t data[writeSize]
void WriteU16(uint16_t data)
Definition: buffer.cc:899
void WriteHtonU16(uint16_t data)
Definition: buffer.h:912
static struct Buffer::Data * Create(uint32_t size)
Create a buffer data storage.
Definition: buffer.cc:119
Buffer::Iterator End(void) const
Definition: buffer.h:1082
uint8_t const * PeekData(void) const
Definition: buffer.cc:733
void Next(void)
go forward by one byte
Definition: buffer.h:852
uint32_t m_current
offset in virtual bytes from the start of the data buffer to the current position represented by this...
Definition: buffer.h:473
void WriteU64(uint64_t data)
Definition: buffer.cc:919
static FreeList * g_freeList
Buffer data container.
Definition: buffer.h:809
void CopyData(std::ostream *os, uint32_t size) const
Copy the specified amount of data from the buffer to the given output stream.
Definition: buffer.cc:743
int32_t GetCurrentEndOffset(void) const
Returns the current buffer end offset.
Definition: buffer.cc:714
void TransformIntoRealBuffer(void) const
Transform a "Virtual byte buffer" into a "Real byte buffer".
Definition: buffer.cc:722
Buffer::Iterator Begin(void) const
Definition: buffer.h:1076
bool Check(uint32_t i) const
Checks that the buffer position is not in the "virtual zero area".
Definition: buffer.cc:854
std::vector< struct Buffer::Data * > FreeList
Container for buffer data.
Definition: buffer.h:802
bool CheckNoZero(uint32_t start, uint32_t end) const
Checks that the [start, end) is not in the "virtual zero area".
Definition: buffer.cc:840
std::string GetReadErrorMessage(void) const
Returns an appropriate message indicating a read error.
Definition: buffer.cc:1195
static void Recycle(struct Buffer::Data *data)
Recycle the buffer memory.
Definition: buffer.cc:98
static uint32_t g_maxSize
Max observed data size.
Definition: buffer.h:808
uint32_t m_dataEnd
offset in virtual bytes from the start of the data buffer to the end of the data which can be read by...
Definition: buffer.h:468
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1152
uint32_t m_zeroEnd
offset in virtual bytes from the start of the data buffer to the end of the "virtual zero area"...
Definition: buffer.h:458
uint32_t m_zeroAreaStart
offset to the start of the virtual zero area from the start of m_data->m_data
Definition: buffer.h:783
uint64_t ReadU64(void)
Definition: buffer.cc:1018
void WriteHtonU32(uint32_t data)
Definition: buffer.h:931
uint32_t GetSize(void) const
Definition: buffer.h:1070
Buffer CreateFragment(uint32_t start, uint32_t length) const
Definition: buffer.cc:537
bool AddAtEnd(uint32_t end)
Definition: buffer.cc:360
void WriteHtolsbU16(uint16_t data)
Definition: buffer.cc:939
static struct Buffer::Data * Allocate(uint32_t reqSize)
Allocate a buffer data storage.
Definition: buffer.cc:163
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:84
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
Definition: buffer.cc:594
struct Data * m_data
the buffer data storage
Definition: buffer.h:759
uint32_t m_dirtyStart
offset from the start of the m_data field below to the start of the area in which user bytes were wri...
Definition: buffer.h:690
void WriteU8(uint8_t data)
Definition: buffer.h:876
uint32_t m_maxZeroAreaStart
keep track of the maximum value of m_zeroAreaStart across the lifetime of a Buffer instance...
Definition: buffer.h:771
void WriteHtolsbU64(uint64_t data)
Definition: buffer.cc:955
Buffer CreateFullCopy(void) const
Create a full copy of the buffer, including all the internal structures.
Definition: buffer.cc:549
static void Deallocate(struct Buffer::Data *data)
Deallocate the buffer memory.
Definition: buffer.cc:180
uint8_t PeekU8(void)
Definition: buffer.h:1005
uint32_t m_dataStart
offset in virtual bytes from the start of the data buffer to the start of the data which can be read ...
Definition: buffer.h:463
static uint32_t g_recommendedStart
location in a newly-allocated buffer where you should start writing data.
Definition: buffer.h:777
uint8_t ReadU8(void)
Definition: buffer.h:1028
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:982
uint32_t GetInternalSize(void) const
Get the buffer real size.
Definition: buffer.cc:296
uint16_t ReadLsbtohU16(void)
Definition: buffer.cc:1094
static struct LocalStaticDestructor g_localStaticDestructor
Local static destructor.
Definition: buffer.h:810
bool AddAtStart(uint32_t start)
Definition: buffer.cc:309
int32_t GetCurrentStartOffset(void) const
Returns the current buffer start offset.
Definition: buffer.cc:708
uint64_t ReadLsbtohU64(void)
Definition: buffer.cc:1122
uint16_t ReadNtohU16(void)
Definition: buffer.h:953
void WriteU32(uint32_t data)
Definition: buffer.cc:907
uint32_t GetInternalEnd(void) const
Get the buffer end position.
Definition: buffer.cc:302
uint32_t GetSize(void) const
Definition: buffer.cc:1187
uint32_t ReadLsbtohU32(void)
Definition: buffer.cc:1105
uint32_t m_zeroAreaEnd
offset to the end of the virtual zero area from the start of m_data->m_data
Definition: buffer.h:788
void Construct(const Buffer *buffer)
Initializes the iterator values.
Definition: buffer.h:842
void WriteHtolsbU32(uint32_t data)
Definition: buffer.cc:946