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:
386  friend class Buffer;
392  inline Iterator (Buffer const*buffer);
399  inline Iterator (Buffer const*buffer, bool dummy);
405  inline void Construct (const Buffer *buffer);
413  bool CheckNoZero (uint32_t start, uint32_t end) const;
420  bool Check (uint32_t i) const;
430  uint16_t SlowReadNtohU16 (void);
440  uint32_t SlowReadNtohU32 (void);
445  std::string GetReadErrorMessage (void) const;
453  std::string GetWriteErrorMessage (void) const;
454 
459  uint32_t m_zeroStart;
464  uint32_t m_zeroEnd;
469  uint32_t m_dataStart;
474  uint32_t m_dataEnd;
479  uint32_t m_current;
484  uint8_t *m_data;
485  };
486 
490  inline uint32_t GetSize (void) const;
491 
501  uint8_t const*PeekData (void) const;
502 
512  void AddAtStart (uint32_t start);
522  void AddAtEnd (uint32_t end);
523 
531  void AddAtEnd (const Buffer &o);
539  void RemoveAtStart (uint32_t start);
547  void RemoveAtEnd (uint32_t end);
548 
556  Buffer CreateFragment (uint32_t start, uint32_t length) const;
557 
562  inline Buffer::Iterator Begin (void) const;
567  inline Buffer::Iterator End (void) const;
568 
573  uint32_t GetSerializedSize (void) const;
574 
585  uint32_t Serialize (uint8_t* buffer, uint32_t maxSize) const;
586 
595  uint32_t Deserialize (const uint8_t* buffer, uint32_t size);
596 
603  void CopyData (std::ostream *os, uint32_t size) const;
604 
612  uint32_t CopyData (uint8_t *buffer, uint32_t size) const;
613 
618  inline Buffer (Buffer const &o);
624  Buffer &operator = (Buffer const &o);
625  Buffer ();
633  Buffer (uint32_t dataSize);
643  Buffer (uint32_t dataSize, bool initialize);
644  ~Buffer ();
645 private:
660  struct Data
661  {
666  uint32_t m_count;
670  uint32_t m_size;
675  uint32_t m_dirtyStart;
680  uint32_t m_dirtyEnd;
685  uint8_t m_data[1];
686  };
687 
694  Buffer CreateFullCopy (void) const;
695 
699  void TransformIntoRealBuffer (void) const;
707  bool CheckInternalState (void) const;
708 
714  void Initialize (uint32_t zeroSize);
715 
721  uint32_t GetInternalSize (void) const;
722 
727  uint32_t GetInternalEnd (void) const;
728 
733  static void Recycle (struct Buffer::Data *data);
739  static struct Buffer::Data *Create (uint32_t size);
745  static struct Buffer::Data *Allocate (uint32_t reqSize);
750  static void Deallocate (struct Buffer::Data *data);
751 
752  struct Data *m_data;
753 
770  static uint32_t g_recommendedStart;
771 
776  uint32_t m_zeroAreaStart;
781  uint32_t m_zeroAreaEnd;
786  uint32_t m_start;
791  uint32_t m_end;
792 
793 #ifdef BUFFER_FREE_LIST
795  typedef std::vector<struct Buffer::Data*> FreeList;
798  {
800  };
801  static uint32_t g_maxSize;
804 #endif
805 };
806 
807 } // namespace ns3
808 
809 #include "ns3/assert.h"
810 #include <cstring>
811 
812 namespace ns3 {
813 
815  : m_zeroStart (0),
816  m_zeroEnd (0),
817  m_dataStart (0),
818  m_dataEnd (0),
819  m_current (0),
820  m_data (0)
821 {
822 }
824 {
825  Construct (buffer);
826  m_current = m_dataStart;
827 }
828 Buffer::Iterator::Iterator (Buffer const*buffer, bool dummy)
829 {
830  Construct (buffer);
831  m_current = m_dataEnd;
832 }
833 
834 void
836 {
837  m_zeroStart = buffer->m_zeroAreaStart;
838  m_zeroEnd = buffer->m_zeroAreaEnd;
839  m_dataStart = buffer->m_start;
840  m_dataEnd = buffer->m_end;
841  m_data = buffer->m_data->m_data;
842 }
843 
844 void
846 {
847  NS_ASSERT (m_current + 1 <= m_dataEnd);
848  m_current++;
849 }
850 void
852 {
853  NS_ASSERT (m_current >= 1);
854  m_current--;
855 }
856 void
857 Buffer::Iterator::Next (uint32_t delta)
858 {
859  NS_ASSERT (m_current + delta <= m_dataEnd);
860  m_current += delta;
861 }
862 void
863 Buffer::Iterator::Prev (uint32_t delta)
864 {
865  NS_ASSERT (m_current >= delta);
866  m_current -= delta;
867 }
868 void
870 {
871  NS_ASSERT_MSG (Check (m_current),
872  GetWriteErrorMessage ());
873 
874  if (m_current < m_zeroStart)
875  {
876  m_data[m_current] = data;
877  m_current++;
878  }
879  else
880  {
881  m_data[m_current - (m_zeroEnd-m_zeroStart)] = data;
882  m_current++;
883  }
884 }
885 
886 void
887 Buffer::Iterator::WriteU8 (uint8_t data, uint32_t len)
888 {
889  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + len),
890  GetWriteErrorMessage ());
891  if (m_current <= m_zeroStart)
892  {
893  std::memset (&(m_data[m_current]), data, len);
894  m_current += len;
895  }
896  else
897  {
898  uint8_t *buffer = &m_data[m_current - (m_zeroEnd-m_zeroStart)];
899  std::memset (buffer, data, len);
900  m_current += len;
901  }
902 }
903 
904 void
906 {
907  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + 2),
908  GetWriteErrorMessage ());
909  uint8_t *buffer;
910  if (m_current + 2 <= m_zeroStart)
911  {
912  buffer = &m_data[m_current];
913  }
914  else
915  {
916  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
917  }
918  buffer[0] = (data >> 8)& 0xff;
919  buffer[1] = (data >> 0)& 0xff;
920  m_current+= 2;
921 }
922 
923 void
925 {
926  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + 4),
927  GetWriteErrorMessage ());
928 
929  uint8_t *buffer;
930  if (m_current + 4 <= m_zeroStart)
931  {
932  buffer = &m_data[m_current];
933  }
934  else
935  {
936  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
937  }
938  buffer[0] = (data >> 24)& 0xff;
939  buffer[1] = (data >> 16)& 0xff;
940  buffer[2] = (data >> 8)& 0xff;
941  buffer[3] = (data >> 0)& 0xff;
942  m_current+= 4;
943 }
944 
945 uint16_t
947 {
948  uint8_t *buffer;
949  if (m_current + 2 <= m_zeroStart)
950  {
951  buffer = &m_data[m_current];
952  }
953  else if (m_current >= m_zeroEnd)
954  {
955  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
956  }
957  else
958  {
959  return SlowReadNtohU16 ();
960  }
961  uint16_t retval = 0;
962  retval |= buffer[0];
963  retval <<= 8;
964  retval |= buffer[1];
965  m_current += 2;
966  return retval;
967 }
968 
969 uint32_t
971 {
972  uint8_t *buffer;
973  if (m_current + 4 <= m_zeroStart)
974  {
975  buffer = &m_data[m_current];
976  }
977  else if (m_current >= m_zeroEnd)
978  {
979  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
980  }
981  else
982  {
983  return SlowReadNtohU32 ();
984  }
985  uint32_t retval = 0;
986  retval |= buffer[0];
987  retval <<= 8;
988  retval |= buffer[1];
989  retval <<= 8;
990  retval |= buffer[2];
991  retval <<= 8;
992  retval |= buffer[3];
993  m_current += 4;
994  return retval;
995 }
996 
997 uint8_t
999 {
1000  NS_ASSERT_MSG (m_current >= m_dataStart &&
1001  m_current < m_dataEnd,
1002  GetReadErrorMessage ());
1003 
1004  if (m_current < m_zeroStart)
1005  {
1006  uint8_t data = m_data[m_current];
1007  return data;
1008  }
1009  else if (m_current < m_zeroEnd)
1010  {
1011  return 0;
1012  }
1013  else
1014  {
1015  uint8_t data = m_data[m_current - (m_zeroEnd-m_zeroStart)];
1016  return data;
1017  }
1018 }
1019 
1020 uint8_t
1022 {
1023  uint8_t ret = PeekU8 ();
1024  m_current ++;
1025  return ret;
1026 }
1027 
1028 uint16_t
1030 {
1031  uint8_t byte0 = ReadU8 ();
1032  uint8_t byte1 = ReadU8 ();
1033  uint16_t data = byte1;
1034  data <<= 8;
1035  data |= byte0;
1036 
1037  return data;
1038 }
1039 
1040 void
1042 {
1043  Buffer::Iterator end = *this;
1044  end.Next (size);
1045 
1046  start.Write (*this, end);
1047 }
1048 
1049 
1051  : m_data (o.m_data),
1055  m_start (o.m_start),
1056  m_end (o.m_end)
1057 {
1058  m_data->m_count++;
1060 }
1061 
1062 uint32_t
1063 Buffer::GetSize (void) const
1064 {
1065  return m_end - m_start;
1066 }
1067 
1069 Buffer::Begin (void) const
1070 {
1072  return Buffer::Iterator (this);
1073 }
1075 Buffer::End (void) const
1076 {
1078  return Buffer::Iterator (this, false);
1079 }
1080 
1081 
1082 
1083 } // namespace ns3
1084 
1085 #endif /* BUFFER_H */
iterator in a Buffer instance
Definition: buffer.h:99
void WriteU64(uint64_t data)
Definition: buffer.cc:891
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:954
void Construct(const Buffer *buffer)
Initializes the iterator values.
Definition: buffer.h:835
void WriteU32(uint32_t data)
Definition: buffer.cc:879
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:474
uint16_t ReadNtohU16(void)
Definition: buffer.h:946
bool IsEnd(void) const
Definition: buffer.cc:804
bool IsStart(void) const
Definition: buffer.cc:810
void WriteHtonU64(uint64_t data)
Definition: buffer.cc:941
void WriteHtolsbU16(uint16_t data)
Definition: buffer.cc:911
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:469
uint64_t ReadNtohU64(void)
Definition: buffer.cc:1044
uint32_t ReadLsbtohU32(void)
Definition: buffer.cc:1077
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
Definition: buffer.cc:1134
void WriteU8(uint8_t data)
Definition: buffer.h:869
uint8_t * m_data
a pointer to the underlying byte buffer.
Definition: buffer.h:484
uint32_t GetRemainingSize(void) const
Definition: buffer.cc:1166
void WriteHtolsbU32(uint32_t data)
Definition: buffer.cc:918
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:464
bool Check(uint32_t i) const
Checks that the buffer position is not in the "virtual zero area".
Definition: buffer.cc:826
uint32_t SlowReadNtohU32(void)
Definition: buffer.cc:1030
void Next(void)
go forward by one byte
Definition: buffer.h:845
void WriteU16(uint16_t data)
Definition: buffer.cc:871
uint16_t ReadU16(void)
Definition: buffer.h:1029
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:479
uint8_t ReadU8(void)
Definition: buffer.h:1021
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1124
void WriteHtolsbU64(uint64_t data)
Definition: buffer.cc:927
void WriteHtonU16(uint16_t data)
Definition: buffer.h:905
uint16_t ReadLsbtohU16(void)
Definition: buffer.cc:1066
void Prev(void)
go backward by one byte
Definition: buffer.h:851
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:459
std::string GetWriteErrorMessage(void) const
Returns an appropriate message indicating a write error.
Definition: buffer.cc:1187
uint64_t ReadLsbtohU64(void)
Definition: buffer.cc:1094
uint16_t SlowReadNtohU16(void)
Definition: buffer.cc:1020
uint64_t ReadU64(void)
Definition: buffer.cc:990
bool CheckNoZero(uint32_t start, uint32_t end) const
Checks that the [start, end) is not in the "virtual zero area".
Definition: buffer.cc:817
void WriteHtonU32(uint32_t data)
Definition: buffer.h:924
uint32_t GetDistanceFrom(Iterator const &o) const
Definition: buffer.cc:788
std::string GetReadErrorMessage(void) const
Returns an appropriate message indicating a read error.
Definition: buffer.cc:1174
uint32_t GetSize(void) const
Definition: buffer.cc:1159
uint32_t ReadU32(void)
Definition: buffer.cc:973
uint8_t PeekU8(void)
Definition: buffer.h:998
uint32_t ReadNtohU32(void)
Definition: buffer.h:970
automatically resized byte buffer
Definition: buffer.h:93
uint32_t GetInternalSize(void) const
Get the buffer real size.
Definition: buffer.cc:296
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:791
bool CheckInternalState(void) const
Checks the internal buffer structures consistency.
Definition: buffer.cc:210
Buffer CreateFragment(uint32_t start, uint32_t length) const
Definition: buffer.cc:524
static FreeList * g_freeList
Buffer data container.
Definition: buffer.h:802
static struct Buffer::Data * Create(uint32_t size)
Create a buffer data storage.
Definition: buffer.cc:119
static uint32_t g_maxSize
Max observed data size.
Definition: buffer.h:801
static struct LocalStaticDestructor g_localStaticDestructor
Local static destructor.
Definition: buffer.h:803
uint32_t m_zeroAreaEnd
offset to the end of the virtual zero area from the start of m_data->m_data
Definition: buffer.h:781
std::vector< struct Buffer::Data * > FreeList
Container for buffer data.
Definition: buffer.h:795
static void Deallocate(struct Buffer::Data *data)
Deallocate the buffer memory.
Definition: buffer.cc:180
uint32_t m_maxZeroAreaStart
keep track of the maximum value of m_zeroAreaStart across the lifetime of a Buffer instance.
Definition: buffer.h:764
uint32_t GetSize(void) const
Definition: buffer.h:1063
static uint32_t g_recommendedStart
location in a newly-allocated buffer where you should start writing data.
Definition: buffer.h:770
uint32_t GetInternalEnd(void) const
Get the buffer end position.
Definition: buffer.cc:302
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:720
Buffer CreateFullCopy(void) const
Create a full copy of the buffer, including all the internal structures.
Definition: buffer.cc:536
static struct Buffer::Data * Allocate(uint32_t reqSize)
Allocate a buffer data storage.
Definition: buffer.cc:163
Buffer & operator=(Buffer const &o)
Assignment operator.
Definition: buffer.cc:259
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:488
void AddAtStart(uint32_t start)
Definition: buffer.cc:309
void AddAtEnd(uint32_t end)
Definition: buffer.cc:354
uint32_t GetSerializedSize(void) const
Return the number of bytes required for serialization.
Definition: buffer.cc:561
void TransformIntoRealBuffer(void) const
Transform a "Virtual byte buffer" into a "Real byte buffer".
Definition: buffer.cc:699
static void Recycle(struct Buffer::Data *data)
Recycle the buffer memory.
Definition: buffer.cc:98
struct Data * m_data
the buffer data storage
Definition: buffer.h:752
Buffer::Iterator End(void) const
Definition: buffer.h:1075
uint8_t const * PeekData(void) const
Definition: buffer.cc:710
void Initialize(uint32_t zeroSize)
Initializes the buffer with a number of zeroes.
Definition: buffer.cc:244
Buffer::Iterator Begin(void) const
Definition: buffer.h:1069
uint32_t Deserialize(const uint8_t *buffer, uint32_t size)
Definition: buffer.cc:653
void RemoveAtStart(uint32_t start)
Definition: buffer.cc:443
uint32_t m_zeroAreaStart
offset to the start of the virtual zero area from the start of m_data->m_data
Definition: buffer.h:776
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
Definition: buffer.cc:581
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:786
#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
#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:88
Every class exported by the ns3 library is enclosed in the ns3 namespace.
def start()
Definition: core.py:1853
uint8_t data[writeSize]
This data structure is variable-sized through its last member whose size is determined at allocation ...
Definition: buffer.h:661
uint8_t m_data[1]
The real data buffer holds at least one byte.
Definition: buffer.h:685
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:680
uint32_t m_count
The reference count of an instance of this data structure.
Definition: buffer.h:666
uint32_t m_size
the size of the m_data field below.
Definition: buffer.h:670
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:675
Local static destructor structure.
Definition: buffer.h:798