A Discrete-Event Network Simulator
API
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 
382  uint32_t GetRemainingSize (void) const;
383 
384 private:
385  friend class Buffer;
391  inline Iterator (Buffer const*buffer);
398  inline Iterator (Buffer const*buffer, bool dummy);
404  inline void Construct (const Buffer *buffer);
412  bool CheckNoZero (uint32_t start, uint32_t end) const;
419  bool Check (uint32_t i) const;
429  uint16_t SlowReadNtohU16 (void);
439  uint32_t SlowReadNtohU32 (void);
444  std::string GetReadErrorMessage (void) const;
452  std::string GetWriteErrorMessage (void) const;
453 
458  uint32_t m_zeroStart;
463  uint32_t m_zeroEnd;
468  uint32_t m_dataStart;
473  uint32_t m_dataEnd;
478  uint32_t m_current;
483  uint8_t *m_data;
484  };
485 
489  inline uint32_t GetSize (void) const;
490 
500  uint8_t const*PeekData (void) const;
501 
511  void AddAtStart (uint32_t start);
521  void AddAtEnd (uint32_t end);
522 
530  void AddAtEnd (const Buffer &o);
538  void RemoveAtStart (uint32_t start);
546  void RemoveAtEnd (uint32_t end);
547 
555  Buffer CreateFragment (uint32_t start, uint32_t length) const;
556 
561  inline Buffer::Iterator Begin (void) const;
566  inline Buffer::Iterator End (void) const;
567 
572  uint32_t GetSerializedSize (void) const;
573 
584  uint32_t Serialize (uint8_t* buffer, uint32_t maxSize) const;
585 
594  uint32_t Deserialize (const uint8_t* buffer, uint32_t size);
595 
602  void CopyData (std::ostream *os, uint32_t size) const;
603 
611  uint32_t CopyData (uint8_t *buffer, uint32_t size) const;
612 
617  inline Buffer (Buffer const &o);
623  Buffer &operator = (Buffer const &o);
624  Buffer ();
632  Buffer (uint32_t dataSize);
642  Buffer (uint32_t dataSize, bool initialize);
643  ~Buffer ();
644 private:
659  struct Data
660  {
665  uint32_t m_count;
669  uint32_t m_size;
674  uint32_t m_dirtyStart;
679  uint32_t m_dirtyEnd;
684  uint8_t m_data[1];
685  };
686 
693  Buffer CreateFullCopy (void) const;
694 
698  void TransformIntoRealBuffer (void) const;
706  bool CheckInternalState (void) const;
707 
713  void Initialize (uint32_t zeroSize);
714 
720  uint32_t GetInternalSize (void) const;
721 
726  uint32_t GetInternalEnd (void) const;
727 
732  static void Recycle (struct Buffer::Data *data);
738  static struct Buffer::Data *Create (uint32_t size);
744  static struct Buffer::Data *Allocate (uint32_t reqSize);
749  static void Deallocate (struct Buffer::Data *data);
750 
751  struct Data *m_data;
752 
769  static uint32_t g_recommendedStart;
770 
775  uint32_t m_zeroAreaStart;
780  uint32_t m_zeroAreaEnd;
785  uint32_t m_start;
790  uint32_t m_end;
791 
792 #ifdef BUFFER_FREE_LIST
793  typedef std::vector<struct Buffer::Data*> FreeList;
797  {
799  };
800  static uint32_t g_maxSize;
801  static FreeList *g_freeList;
803 #endif
804 };
805 
806 } // namespace ns3
807 
808 #include "ns3/assert.h"
809 #include <cstring>
810 
811 namespace ns3 {
812 
814  : m_zeroStart (0),
815  m_zeroEnd (0),
816  m_dataStart (0),
817  m_dataEnd (0),
818  m_current (0),
819  m_data (0)
820 {
821 }
823 {
824  Construct (buffer);
825  m_current = m_dataStart;
826 }
827 Buffer::Iterator::Iterator (Buffer const*buffer, bool dummy)
828 {
829  Construct (buffer);
830  m_current = m_dataEnd;
831 }
832 
833 void
835 {
836  m_zeroStart = buffer->m_zeroAreaStart;
837  m_zeroEnd = buffer->m_zeroAreaEnd;
838  m_dataStart = buffer->m_start;
839  m_dataEnd = buffer->m_end;
840  m_data = buffer->m_data->m_data;
841 }
842 
843 void
845 {
846  NS_ASSERT (m_current + 1 <= m_dataEnd);
847  m_current++;
848 }
849 void
851 {
852  NS_ASSERT (m_current >= 1);
853  m_current--;
854 }
855 void
856 Buffer::Iterator::Next (uint32_t delta)
857 {
858  NS_ASSERT (m_current + delta <= m_dataEnd);
859  m_current += delta;
860 }
861 void
862 Buffer::Iterator::Prev (uint32_t delta)
863 {
864  NS_ASSERT (m_current >= delta);
865  m_current -= delta;
866 }
867 void
869 {
870  NS_ASSERT_MSG (Check (m_current),
871  GetWriteErrorMessage ());
872 
873  if (m_current < m_zeroStart)
874  {
875  m_data[m_current] = data;
876  m_current++;
877  }
878  else
879  {
880  m_data[m_current - (m_zeroEnd-m_zeroStart)] = data;
881  m_current++;
882  }
883 }
884 
885 void
886 Buffer::Iterator::WriteU8 (uint8_t data, uint32_t len)
887 {
888  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + len),
889  GetWriteErrorMessage ());
890  if (m_current <= m_zeroStart)
891  {
892  std::memset (&(m_data[m_current]), data, len);
893  m_current += len;
894  }
895  else
896  {
897  uint8_t *buffer = &m_data[m_current - (m_zeroEnd-m_zeroStart)];
898  std::memset (buffer, data, len);
899  m_current += len;
900  }
901 }
902 
903 void
905 {
906  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + 2),
907  GetWriteErrorMessage ());
908  uint8_t *buffer;
909  if (m_current + 2 <= m_zeroStart)
910  {
911  buffer = &m_data[m_current];
912  }
913  else
914  {
915  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
916  }
917  buffer[0] = (data >> 8)& 0xff;
918  buffer[1] = (data >> 0)& 0xff;
919  m_current+= 2;
920 }
921 
922 void
924 {
925  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + 4),
926  GetWriteErrorMessage ());
927 
928  uint8_t *buffer;
929  if (m_current + 4 <= m_zeroStart)
930  {
931  buffer = &m_data[m_current];
932  }
933  else
934  {
935  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
936  }
937  buffer[0] = (data >> 24)& 0xff;
938  buffer[1] = (data >> 16)& 0xff;
939  buffer[2] = (data >> 8)& 0xff;
940  buffer[3] = (data >> 0)& 0xff;
941  m_current+= 4;
942 }
943 
944 uint16_t
946 {
947  uint8_t *buffer;
948  if (m_current + 2 <= m_zeroStart)
949  {
950  buffer = &m_data[m_current];
951  }
952  else if (m_current >= m_zeroEnd)
953  {
954  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
955  }
956  else
957  {
958  return SlowReadNtohU16 ();
959  }
960  uint16_t retval = 0;
961  retval |= buffer[0];
962  retval <<= 8;
963  retval |= buffer[1];
964  m_current += 2;
965  return retval;
966 }
967 
968 uint32_t
970 {
971  uint8_t *buffer;
972  if (m_current + 4 <= m_zeroStart)
973  {
974  buffer = &m_data[m_current];
975  }
976  else if (m_current >= m_zeroEnd)
977  {
978  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
979  }
980  else
981  {
982  return SlowReadNtohU32 ();
983  }
984  uint32_t retval = 0;
985  retval |= buffer[0];
986  retval <<= 8;
987  retval |= buffer[1];
988  retval <<= 8;
989  retval |= buffer[2];
990  retval <<= 8;
991  retval |= buffer[3];
992  m_current += 4;
993  return retval;
994 }
995 
996 uint8_t
998 {
999  NS_ASSERT_MSG (m_current >= m_dataStart &&
1000  m_current < m_dataEnd,
1001  GetReadErrorMessage ());
1002 
1003  if (m_current < m_zeroStart)
1004  {
1005  uint8_t data = m_data[m_current];
1006  return data;
1007  }
1008  else if (m_current < m_zeroEnd)
1009  {
1010  return 0;
1011  }
1012  else
1013  {
1014  uint8_t data = m_data[m_current - (m_zeroEnd-m_zeroStart)];
1015  return data;
1016  }
1017 }
1018 
1019 uint8_t
1021 {
1022  uint8_t ret = PeekU8 ();
1023  m_current ++;
1024  return ret;
1025 }
1026 
1027 uint16_t
1029 {
1030  uint8_t byte0 = ReadU8 ();
1031  uint8_t byte1 = ReadU8 ();
1032  uint16_t data = byte1;
1033  data <<= 8;
1034  data |= byte0;
1035 
1036  return data;
1037 }
1038 
1039 void
1041 {
1042  Buffer::Iterator end = *this;
1043  end.Next (size);
1044 
1045  start.Write (*this, end);
1046 }
1047 
1048 
1050  : m_data (o.m_data),
1054  m_start (o.m_start),
1055  m_end (o.m_end)
1056 {
1057  m_data->m_count++;
1059 }
1060 
1061 uint32_t
1062 Buffer::GetSize (void) const
1063 {
1064  return m_end - m_start;
1065 }
1066 
1068 Buffer::Begin (void) const
1069 {
1071  return Buffer::Iterator (this);
1072 }
1074 Buffer::End (void) const
1075 {
1077  return Buffer::Iterator (this, false);
1078 }
1079 
1080 
1081 
1082 } // namespace ns3
1083 
1084 #endif /* BUFFER_H */
uint16_t ReadU16(void)
Definition: buffer.h:1028
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
Definition: buffer.cc:1133
uint16_t SlowReadNtohU16(void)
Definition: buffer.cc:1019
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:940
void AddAtStart(uint32_t start)
Definition: buffer.cc:309
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:790
uint32_t ReadU32(void)
Definition: buffer.cc:972
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:486
bool IsStart(void) const
Definition: buffer.cc:805
uint8_t * m_data
a pointer to the underlying byte buffer.
Definition: buffer.h:483
void RemoveAtStart(uint32_t start)
Definition: buffer.cc:441
uint32_t m_size
the size of the m_data field below.
Definition: buffer.h:669
automatically resized byte buffer
Definition: buffer.h:92
def start()
Definition: core.py:1482
uint64_t ReadNtohU64(void)
Definition: buffer.cc:1043
uint32_t m_count
The reference count of an instance of this data structure.
Definition: buffer.h:665
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
uint32_t GetSerializedSize(void) const
Return the number of bytes required for serialization.
Definition: buffer.cc:559
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:969
Local static destructor structure.
Definition: buffer.h:796
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:785
uint32_t GetDistanceFrom(Iterator const &o) const
Definition: buffer.cc:783
iterator in a Buffer instance
Definition: buffer.h:98
uint32_t SlowReadNtohU32(void)
Definition: buffer.cc:1029
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:458
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:679
uint32_t Deserialize(const uint8_t *buffer, uint32_t size)
Definition: buffer.cc:649
bool IsEnd(void) const
Definition: buffer.cc:799
uint8_t m_data[1]
The real data buffer holds at least one byte.
Definition: buffer.h:684
This data structure is variable-sized through its last member whose size is determined at allocation ...
Definition: buffer.h:659
std::string GetWriteErrorMessage(void) const
Returns an appropriate message indicating a write error.
Definition: buffer.cc:1186
void Prev(void)
go backward by one byte
Definition: buffer.h:850
uint8_t data[writeSize]
void WriteU16(uint16_t data)
Definition: buffer.cc:870
void WriteHtonU16(uint16_t data)
Definition: buffer.h:904
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:1074
uint8_t const * PeekData(void) const
Definition: buffer.cc:705
void Next(void)
go forward by one byte
Definition: buffer.h:844
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:478
uint32_t GetRemainingSize(void) const
Definition: buffer.cc:1165
void WriteU64(uint64_t data)
Definition: buffer.cc:890
static FreeList * g_freeList
Buffer data container.
Definition: buffer.h:801
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:715
void TransformIntoRealBuffer(void) const
Transform a "Virtual byte buffer" into a "Real byte buffer".
Definition: buffer.cc:694
Buffer::Iterator Begin(void) const
Definition: buffer.h:1068
bool Check(uint32_t i) const
Checks that the buffer position is not in the "virtual zero area".
Definition: buffer.cc:825
void AddAtEnd(uint32_t end)
Definition: buffer.cc:354
std::vector< struct Buffer::Data * > FreeList
Container for buffer data.
Definition: buffer.h:794
bool CheckNoZero(uint32_t start, uint32_t end) const
Checks that the [start, end) is not in the "virtual zero area".
Definition: buffer.cc:812
std::string GetReadErrorMessage(void) const
Returns an appropriate message indicating a read error.
Definition: buffer.cc:1173
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:800
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:473
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1123
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:463
uint32_t m_zeroAreaStart
offset to the start of the virtual zero area from the start of m_data->m_data
Definition: buffer.h:775
uint64_t ReadU64(void)
Definition: buffer.cc:989
void WriteHtonU32(uint32_t data)
Definition: buffer.h:923
uint32_t GetSize(void) const
Definition: buffer.h:1062
Buffer CreateFragment(uint32_t start, uint32_t length) const
Definition: buffer.cc:522
void WriteHtolsbU16(uint16_t data)
Definition: buffer.cc:910
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:90
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
Definition: buffer.cc:579
struct Data * m_data
the buffer data storage
Definition: buffer.h:751
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:674
void WriteU8(uint8_t data)
Definition: buffer.h:868
uint32_t m_maxZeroAreaStart
keep track of the maximum value of m_zeroAreaStart across the lifetime of a Buffer instance...
Definition: buffer.h:763
void WriteHtolsbU64(uint64_t data)
Definition: buffer.cc:926
Buffer CreateFullCopy(void) const
Create a full copy of the buffer, including all the internal structures.
Definition: buffer.cc:534
static void Deallocate(struct Buffer::Data *data)
Deallocate the buffer memory.
Definition: buffer.cc:180
uint8_t PeekU8(void)
Definition: buffer.h:997
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:468
static uint32_t g_recommendedStart
location in a newly-allocated buffer where you should start writing data.
Definition: buffer.h:769
uint8_t ReadU8(void)
Definition: buffer.h:1020
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:953
uint32_t GetInternalSize(void) const
Get the buffer real size.
Definition: buffer.cc:296
uint16_t ReadLsbtohU16(void)
Definition: buffer.cc:1065
static struct LocalStaticDestructor g_localStaticDestructor
Local static destructor.
Definition: buffer.h:802
uint64_t ReadLsbtohU64(void)
Definition: buffer.cc:1093
uint16_t ReadNtohU16(void)
Definition: buffer.h:945
void WriteU32(uint32_t data)
Definition: buffer.cc:878
uint32_t GetInternalEnd(void) const
Get the buffer end position.
Definition: buffer.cc:302
uint32_t GetSize(void) const
Definition: buffer.cc:1158
uint32_t ReadLsbtohU32(void)
Definition: buffer.cc:1076
uint32_t m_zeroAreaEnd
offset to the end of the virtual zero area from the start of m_data->m_data
Definition: buffer.h:780
void Construct(const Buffer *buffer)
Initializes the iterator values.
Definition: buffer.h:834
void WriteHtolsbU32(uint32_t data)
Definition: buffer.cc:917