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 
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 
506  void AddAtStart (uint32_t start);
516  void AddAtEnd (uint32_t end);
517 
525  void AddAtEnd (const Buffer &o);
533  void RemoveAtStart (uint32_t start);
541  void RemoveAtEnd (uint32_t end);
542 
550  Buffer CreateFragment (uint32_t start, uint32_t length) const;
551 
556  inline Buffer::Iterator Begin (void) const;
561  inline Buffer::Iterator End (void) const;
562 
567  uint32_t GetSerializedSize (void) const;
568 
579  uint32_t Serialize (uint8_t* buffer, uint32_t maxSize) const;
580 
589  uint32_t Deserialize (const uint8_t* buffer, uint32_t size);
590 
597  void CopyData (std::ostream *os, uint32_t size) const;
598 
606  uint32_t CopyData (uint8_t *buffer, uint32_t size) const;
607 
612  inline Buffer (Buffer const &o);
618  Buffer &operator = (Buffer const &o);
619  Buffer ();
627  Buffer (uint32_t dataSize);
637  Buffer (uint32_t dataSize, bool initialize);
638  ~Buffer ();
639 private:
654  struct Data
655  {
660  uint32_t m_count;
664  uint32_t m_size;
669  uint32_t m_dirtyStart;
674  uint32_t m_dirtyEnd;
679  uint8_t m_data[1];
680  };
681 
688  Buffer CreateFullCopy (void) const;
689 
693  void TransformIntoRealBuffer (void) const;
701  bool CheckInternalState (void) const;
702 
708  void Initialize (uint32_t zeroSize);
709 
715  uint32_t GetInternalSize (void) const;
716 
721  uint32_t GetInternalEnd (void) const;
722 
727  static void Recycle (struct Buffer::Data *data);
733  static struct Buffer::Data *Create (uint32_t size);
739  static struct Buffer::Data *Allocate (uint32_t reqSize);
744  static void Deallocate (struct Buffer::Data *data);
745 
746  struct Data *m_data;
747 
764  static uint32_t g_recommendedStart;
765 
770  uint32_t m_zeroAreaStart;
775  uint32_t m_zeroAreaEnd;
780  uint32_t m_start;
785  uint32_t m_end;
786 
787 #ifdef BUFFER_FREE_LIST
788  typedef std::vector<struct Buffer::Data*> FreeList;
792  {
794  };
795  static uint32_t g_maxSize;
796  static FreeList *g_freeList;
798 #endif
799 };
800 
801 } // namespace ns3
802 
803 #include "ns3/assert.h"
804 #include <cstring>
805 
806 namespace ns3 {
807 
809  : m_zeroStart (0),
810  m_zeroEnd (0),
811  m_dataStart (0),
812  m_dataEnd (0),
813  m_current (0),
814  m_data (0)
815 {
816 }
818 {
819  Construct (buffer);
820  m_current = m_dataStart;
821 }
822 Buffer::Iterator::Iterator (Buffer const*buffer, bool dummy)
823 {
824  Construct (buffer);
825  m_current = m_dataEnd;
826 }
827 
828 void
830 {
831  m_zeroStart = buffer->m_zeroAreaStart;
832  m_zeroEnd = buffer->m_zeroAreaEnd;
833  m_dataStart = buffer->m_start;
834  m_dataEnd = buffer->m_end;
835  m_data = buffer->m_data->m_data;
836 }
837 
838 void
840 {
841  NS_ASSERT (m_current + 1 <= m_dataEnd);
842  m_current++;
843 }
844 void
846 {
847  NS_ASSERT (m_current >= 1);
848  m_current--;
849 }
850 void
851 Buffer::Iterator::Next (uint32_t delta)
852 {
853  NS_ASSERT (m_current + delta <= m_dataEnd);
854  m_current += delta;
855 }
856 void
857 Buffer::Iterator::Prev (uint32_t delta)
858 {
859  NS_ASSERT (m_current >= delta);
860  m_current -= delta;
861 }
862 void
864 {
865  NS_ASSERT_MSG (Check (m_current),
866  GetWriteErrorMessage ());
867 
868  if (m_current < m_zeroStart)
869  {
870  m_data[m_current] = data;
871  m_current++;
872  }
873  else
874  {
875  m_data[m_current - (m_zeroEnd-m_zeroStart)] = data;
876  m_current++;
877  }
878 }
879 
880 void
881 Buffer::Iterator::WriteU8 (uint8_t data, uint32_t len)
882 {
883  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + len),
884  GetWriteErrorMessage ());
885  if (m_current <= m_zeroStart)
886  {
887  std::memset (&(m_data[m_current]), data, len);
888  m_current += len;
889  }
890  else
891  {
892  uint8_t *buffer = &m_data[m_current - (m_zeroEnd-m_zeroStart)];
893  std::memset (buffer, data, len);
894  m_current += len;
895  }
896 }
897 
898 void
900 {
901  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + 2),
902  GetWriteErrorMessage ());
903  uint8_t *buffer;
904  if (m_current + 2 <= m_zeroStart)
905  {
906  buffer = &m_data[m_current];
907  }
908  else
909  {
910  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
911  }
912  buffer[0] = (data >> 8)& 0xff;
913  buffer[1] = (data >> 0)& 0xff;
914  m_current+= 2;
915 }
916 
917 void
919 {
920  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + 4),
921  GetWriteErrorMessage ());
922 
923  uint8_t *buffer;
924  if (m_current + 4 <= m_zeroStart)
925  {
926  buffer = &m_data[m_current];
927  }
928  else
929  {
930  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
931  }
932  buffer[0] = (data >> 24)& 0xff;
933  buffer[1] = (data >> 16)& 0xff;
934  buffer[2] = (data >> 8)& 0xff;
935  buffer[3] = (data >> 0)& 0xff;
936  m_current+= 4;
937 }
938 
939 uint16_t
941 {
942  uint8_t *buffer;
943  if (m_current + 2 <= m_zeroStart)
944  {
945  buffer = &m_data[m_current];
946  }
947  else if (m_current >= m_zeroEnd)
948  {
949  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
950  }
951  else
952  {
953  return SlowReadNtohU16 ();
954  }
955  uint16_t retval = 0;
956  retval |= buffer[0];
957  retval <<= 8;
958  retval |= buffer[1];
959  m_current += 2;
960  return retval;
961 }
962 
963 uint32_t
965 {
966  uint8_t *buffer;
967  if (m_current + 4 <= m_zeroStart)
968  {
969  buffer = &m_data[m_current];
970  }
971  else if (m_current >= m_zeroEnd)
972  {
973  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
974  }
975  else
976  {
977  return SlowReadNtohU32 ();
978  }
979  uint32_t retval = 0;
980  retval |= buffer[0];
981  retval <<= 8;
982  retval |= buffer[1];
983  retval <<= 8;
984  retval |= buffer[2];
985  retval <<= 8;
986  retval |= buffer[3];
987  m_current += 4;
988  return retval;
989 }
990 
991 uint8_t
993 {
994  NS_ASSERT_MSG (m_current >= m_dataStart &&
995  m_current < m_dataEnd,
996  GetReadErrorMessage ());
997 
998  if (m_current < m_zeroStart)
999  {
1000  uint8_t data = m_data[m_current];
1001  return data;
1002  }
1003  else if (m_current < m_zeroEnd)
1004  {
1005  return 0;
1006  }
1007  else
1008  {
1009  uint8_t data = m_data[m_current - (m_zeroEnd-m_zeroStart)];
1010  return data;
1011  }
1012 }
1013 
1014 uint8_t
1016 {
1017  uint8_t ret = PeekU8 ();
1018  m_current ++;
1019  return ret;
1020 }
1021 
1022 uint16_t
1024 {
1025  uint8_t byte0 = ReadU8 ();
1026  uint8_t byte1 = ReadU8 ();
1027  uint16_t data = byte1;
1028  data <<= 8;
1029  data |= byte0;
1030 
1031  return data;
1032 }
1033 
1034 void
1036 {
1037  Buffer::Iterator end = *this;
1038  end.Next (size);
1039 
1040  start.Write (*this, end);
1041 }
1042 
1043 
1045  : m_data (o.m_data),
1049  m_start (o.m_start),
1050  m_end (o.m_end)
1051 {
1052  m_data->m_count++;
1054 }
1055 
1056 uint32_t
1057 Buffer::GetSize (void) const
1058 {
1059  return m_end - m_start;
1060 }
1061 
1063 Buffer::Begin (void) const
1064 {
1066  return Buffer::Iterator (this);
1067 }
1069 Buffer::End (void) const
1070 {
1072  return Buffer::Iterator (this, false);
1073 }
1074 
1075 
1076 
1077 } // namespace ns3
1078 
1079 #endif /* BUFFER_H */
uint16_t ReadU16(void)
Definition: buffer.h:1023
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:785
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:478
void RemoveAtStart(uint32_t start)
Definition: buffer.cc:441
uint32_t m_size
the size of the m_data field below.
Definition: buffer.h:664
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:660
#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:964
Local static destructor structure.
Definition: buffer.h:791
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:780
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: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:674
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:679
This data structure is variable-sized through its last member whose size is determined at allocation ...
Definition: buffer.h:654
std::string GetWriteErrorMessage(void) const
Returns an appropriate message indicating a write error.
Definition: buffer.cc:1179
void Prev(void)
go backward by one byte
Definition: buffer.h:845
uint8_t data[writeSize]
void WriteU16(uint16_t data)
Definition: buffer.cc:870
void WriteHtonU16(uint16_t data)
Definition: buffer.h:899
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:1069
uint8_t const * PeekData(void) const
Definition: buffer.cc:705
void Next(void)
go forward by one byte
Definition: buffer.h:839
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:890
static FreeList * g_freeList
Buffer data container.
Definition: buffer.h:796
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:1063
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:789
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:1166
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:795
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: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: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:770
uint64_t ReadU64(void)
Definition: buffer.cc:989
void WriteHtonU32(uint32_t data)
Definition: buffer.h:918
uint32_t GetSize(void) const
Definition: buffer.h:1057
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:746
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:669
void WriteU8(uint8_t data)
Definition: buffer.h:863
uint32_t m_maxZeroAreaStart
keep track of the maximum value of m_zeroAreaStart across the lifetime of a Buffer instance...
Definition: buffer.h:758
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:992
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:764
uint8_t ReadU8(void)
Definition: buffer.h:1015
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:797
uint64_t ReadLsbtohU64(void)
Definition: buffer.cc:1093
uint16_t ReadNtohU16(void)
Definition: buffer.h:940
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:775
void Construct(const Buffer *buffer)
Initializes the iterator values.
Definition: buffer.h:829
void WriteHtolsbU32(uint32_t data)
Definition: buffer.cc:917