A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
buffer.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005,2006,2007 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 #ifndef BUFFER_H
20 #define BUFFER_H
21 
22 #include "ns3/assert.h"
23 
24 #include <ostream>
25 #include <stdint.h>
26 #include <vector>
27 
28 #define BUFFER_FREE_LIST 1
29 
30 namespace ns3
31 {
32 
93 class Buffer
94 {
95  public:
99  class Iterator
100  {
101  public:
102  inline Iterator();
106  inline void Next();
110  inline void Prev();
114  inline void Next(uint32_t delta);
118  inline void Prev(uint32_t delta);
127  uint32_t GetDistanceFrom(const Iterator& o) const;
128 
133  bool IsEnd() const;
138  bool IsStart() const;
139 
146  inline void WriteU8(uint8_t data);
154  inline void WriteU8(uint8_t data, uint32_t len);
164  void WriteU16(uint16_t data);
174  void WriteU32(uint32_t data);
184  void WriteU64(uint64_t data);
192  void WriteHtolsbU16(uint16_t data);
200  void WriteHtolsbU32(uint32_t data);
208  void WriteHtolsbU64(uint64_t data);
216  inline void WriteHtonU16(uint16_t data);
224  inline void WriteHtonU32(uint32_t data);
232  void WriteHtonU64(uint64_t data);
240  void Write(const uint8_t* buffer, uint32_t size);
252  void Write(Iterator start, Iterator end);
253 
259  inline uint8_t PeekU8();
260 
267  inline uint8_t ReadU8();
275  inline uint16_t ReadU16();
283  uint32_t ReadU32();
291  uint64_t ReadU64();
299  inline uint16_t ReadNtohU16();
307  inline uint32_t ReadNtohU32();
315  uint64_t ReadNtohU64();
323  uint16_t ReadLsbtohU16();
331  uint32_t ReadLsbtohU32();
339  uint64_t ReadLsbtohU64();
348  void Read(uint8_t* buffer, uint32_t size);
349 
358  inline void Read(Iterator start, uint32_t size);
359 
365  uint16_t CalculateIpChecksum(uint16_t size);
366 
373  uint16_t CalculateIpChecksum(uint16_t size, uint32_t initialChecksum);
374 
378  uint32_t GetSize() const;
379 
383  uint32_t GetRemainingSize() const;
384 
385  private:
387  friend class Buffer;
393  inline Iterator(const Buffer* buffer);
400  inline Iterator(const Buffer* buffer, bool dummy);
406  inline void Construct(const Buffer* buffer);
414  bool CheckNoZero(uint32_t start, uint32_t end) const;
421  bool Check(uint32_t i) const;
431  uint16_t SlowReadNtohU16();
441  uint32_t SlowReadNtohU32();
446  std::string GetReadErrorMessage() const;
454  std::string GetWriteErrorMessage() const;
455 
460  uint32_t m_zeroStart;
465  uint32_t m_zeroEnd;
470  uint32_t m_dataStart;
475  uint32_t m_dataEnd;
480  uint32_t m_current;
485  uint8_t* m_data;
486  };
487 
491  inline uint32_t GetSize() const;
492 
502  const uint8_t* PeekData() const;
503 
513  void AddAtStart(uint32_t start);
523  void AddAtEnd(uint32_t end);
524 
532  void AddAtEnd(const Buffer& o);
540  void RemoveAtStart(uint32_t start);
548  void RemoveAtEnd(uint32_t end);
549 
557  Buffer CreateFragment(uint32_t start, uint32_t length) const;
558 
563  inline Buffer::Iterator Begin() const;
568  inline Buffer::Iterator End() const;
569 
574  uint32_t GetSerializedSize() const;
575 
586  uint32_t Serialize(uint8_t* buffer, uint32_t maxSize) const;
587 
596  uint32_t Deserialize(const uint8_t* buffer, uint32_t size);
597 
604  void CopyData(std::ostream* os, uint32_t size) const;
605 
613  uint32_t CopyData(uint8_t* buffer, uint32_t size) const;
614 
619  inline Buffer(const Buffer& o);
625  Buffer& operator=(const Buffer& o);
626  Buffer();
634  Buffer(uint32_t dataSize);
644  Buffer(uint32_t dataSize, bool initialize);
645  ~Buffer();
646 
647  private:
662  struct Data
663  {
668  uint32_t m_count;
672  uint32_t m_size;
677  uint32_t m_dirtyStart;
682  uint32_t m_dirtyEnd;
687  uint8_t m_data[1];
688  };
689 
696  Buffer CreateFullCopy() const;
697 
701  void TransformIntoRealBuffer() const;
709  bool CheckInternalState() const;
710 
716  void Initialize(uint32_t zeroSize);
717 
723  uint32_t GetInternalSize() const;
724 
729  uint32_t GetInternalEnd() const;
730 
735  static void Recycle(Buffer::Data* data);
741  static Buffer::Data* Create(uint32_t size);
747  static Buffer::Data* Allocate(uint32_t reqSize);
752  static void Deallocate(Buffer::Data* data);
753 
755 
772  static uint32_t g_recommendedStart;
773 
778  uint32_t m_zeroAreaStart;
783  uint32_t m_zeroAreaEnd;
788  uint32_t m_start;
793  uint32_t m_end;
794 
795 #ifdef BUFFER_FREE_LIST
797  typedef std::vector<Buffer::Data*> FreeList;
798 
801  {
803  };
804 
805  static uint32_t g_maxSize;
808 #endif
809 };
810 
811 } // namespace ns3
812 
813 #include "ns3/assert.h"
814 
815 #include <cstring>
816 
817 namespace ns3
818 {
819 
821  : m_zeroStart(0),
822  m_zeroEnd(0),
823  m_dataStart(0),
824  m_dataEnd(0),
825  m_current(0),
826  m_data(nullptr)
827 {
828 }
829 
831 {
832  Construct(buffer);
833  m_current = m_dataStart;
834 }
835 
836 Buffer::Iterator::Iterator(const Buffer* buffer, bool dummy)
837 {
838  Construct(buffer);
839  m_current = m_dataEnd;
840 }
841 
842 void
844 {
845  m_zeroStart = buffer->m_zeroAreaStart;
846  m_zeroEnd = buffer->m_zeroAreaEnd;
847  m_dataStart = buffer->m_start;
848  m_dataEnd = buffer->m_end;
849  m_data = buffer->m_data->m_data;
850 }
851 
852 void
854 {
855  NS_ASSERT(m_current + 1 <= m_dataEnd);
856  m_current++;
857 }
858 
859 void
861 {
862  NS_ASSERT(m_current >= 1);
863  m_current--;
864 }
865 
866 void
868 {
869  NS_ASSERT(m_current + delta <= m_dataEnd);
870  m_current += delta;
871 }
872 
873 void
875 {
876  NS_ASSERT(m_current >= delta);
877  m_current -= delta;
878 }
879 
880 void
882 {
883  NS_ASSERT_MSG(Check(m_current), GetWriteErrorMessage());
884 
885  if (m_current < m_zeroStart)
886  {
887  m_data[m_current] = data;
888  m_current++;
889  }
890  else
891  {
892  m_data[m_current - (m_zeroEnd - m_zeroStart)] = data;
893  m_current++;
894  }
895 }
896 
897 void
898 Buffer::Iterator::WriteU8(uint8_t data, uint32_t len)
899 {
900  NS_ASSERT_MSG(CheckNoZero(m_current, m_current + len), GetWriteErrorMessage());
901  if (m_current <= m_zeroStart)
902  {
903  std::memset(&(m_data[m_current]), data, len);
904  m_current += len;
905  }
906  else
907  {
908  uint8_t* buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
909  std::memset(buffer, data, len);
910  m_current += len;
911  }
912 }
913 
914 void
916 {
917  NS_ASSERT_MSG(CheckNoZero(m_current, m_current + 2), GetWriteErrorMessage());
918  uint8_t* buffer;
919  if (m_current + 2 <= m_zeroStart)
920  {
921  buffer = &m_data[m_current];
922  }
923  else
924  {
925  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
926  }
927  buffer[0] = (data >> 8) & 0xff;
928  buffer[1] = (data >> 0) & 0xff;
929  m_current += 2;
930 }
931 
932 void
934 {
935  NS_ASSERT_MSG(CheckNoZero(m_current, m_current + 4), GetWriteErrorMessage());
936 
937  uint8_t* buffer;
938  if (m_current + 4 <= m_zeroStart)
939  {
940  buffer = &m_data[m_current];
941  }
942  else
943  {
944  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
945  }
946  buffer[0] = (data >> 24) & 0xff;
947  buffer[1] = (data >> 16) & 0xff;
948  buffer[2] = (data >> 8) & 0xff;
949  buffer[3] = (data >> 0) & 0xff;
950  m_current += 4;
951 }
952 
953 uint16_t
955 {
956  uint8_t* buffer;
957  if (m_current + 2 <= m_zeroStart)
958  {
959  buffer = &m_data[m_current];
960  }
961  else if (m_current >= m_zeroEnd)
962  {
963  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
964  }
965  else
966  {
967  return SlowReadNtohU16();
968  }
969  uint16_t retval = 0;
970  retval |= buffer[0];
971  retval <<= 8;
972  retval |= buffer[1];
973  m_current += 2;
974  return retval;
975 }
976 
977 uint32_t
979 {
980  uint8_t* buffer;
981  if (m_current + 4 <= m_zeroStart)
982  {
983  buffer = &m_data[m_current];
984  }
985  else if (m_current >= m_zeroEnd)
986  {
987  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
988  }
989  else
990  {
991  return SlowReadNtohU32();
992  }
993  uint32_t retval = 0;
994  retval |= buffer[0];
995  retval <<= 8;
996  retval |= buffer[1];
997  retval <<= 8;
998  retval |= buffer[2];
999  retval <<= 8;
1000  retval |= buffer[3];
1001  m_current += 4;
1002  return retval;
1003 }
1004 
1005 uint8_t
1007 {
1008  NS_ASSERT_MSG(m_current >= m_dataStart && m_current < m_dataEnd, GetReadErrorMessage());
1009 
1010  if (m_current < m_zeroStart)
1011  {
1012  uint8_t data = m_data[m_current];
1013  return data;
1014  }
1015  else if (m_current < m_zeroEnd)
1016  {
1017  return 0;
1018  }
1019  else
1020  {
1021  uint8_t data = m_data[m_current - (m_zeroEnd - m_zeroStart)];
1022  return data;
1023  }
1024 }
1025 
1026 uint8_t
1028 {
1029  uint8_t ret = PeekU8();
1030  m_current++;
1031  return ret;
1032 }
1033 
1034 uint16_t
1036 {
1037  uint8_t byte0 = ReadU8();
1038  uint8_t byte1 = ReadU8();
1039  uint16_t data = byte1;
1040  data <<= 8;
1041  data |= byte0;
1042 
1043  return data;
1044 }
1045 
1046 void
1048 {
1049  Buffer::Iterator end = *this;
1050  end.Next(size);
1051 
1052  start.Write(*this, end);
1053 }
1054 
1056  : m_data(o.m_data),
1060  m_start(o.m_start),
1061  m_end(o.m_end)
1062 {
1063  m_data->m_count++;
1065 }
1066 
1067 uint32_t
1069 {
1070  return m_end - m_start;
1071 }
1072 
1075 {
1077  return Buffer::Iterator(this);
1078 }
1079 
1082 {
1084  return Buffer::Iterator(this, false);
1085 }
1086 
1087 } // namespace ns3
1088 
1089 #endif /* BUFFER_H */
iterator in a Buffer instance
Definition: buffer.h:100
void WriteU64(uint64_t data)
Definition: buffer.cc:881
uint32_t GetRemainingSize() const
Definition: buffer.cc:1173
void Construct(const Buffer *buffer)
Initializes the iterator values.
Definition: buffer.h:843
uint64_t ReadU64()
Definition: buffer.cc:984
void WriteU32(uint32_t data)
Definition: buffer.cc:868
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:475
void WriteHtonU64(uint64_t data)
Definition: buffer.cc:934
void WriteHtolsbU16(uint16_t data)
Definition: buffer.cc:902
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:470
uint64_t ReadNtohU64()
Definition: buffer.cc:1041
uint8_t ReadU8()
Definition: buffer.h:1027
std::string GetReadErrorMessage() const
Returns an appropriate message indicating a read error.
Definition: buffer.cc:1180
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
Definition: buffer.cc:1135
void WriteU8(uint8_t data)
Definition: buffer.h:881
uint16_t SlowReadNtohU16()
Definition: buffer.cc:1015
uint8_t * m_data
a pointer to the underlying byte buffer.
Definition: buffer.h:485
void WriteHtolsbU32(uint32_t data)
Definition: buffer.cc:910
void Write(const uint8_t *buffer, uint32_t size)
Definition: buffer.cc:948
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:465
uint16_t ReadLsbtohU16()
Definition: buffer.cc:1064
bool Check(uint32_t i) const
Checks that the buffer position is not in the "virtual zero area".
Definition: buffer.cc:818
void WriteU16(uint16_t data)
Definition: buffer.cc:859
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:480
uint32_t SlowReadNtohU32()
Definition: buffer.cc:1026
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1125
uint64_t ReadLsbtohU64()
Definition: buffer.cc:1094
void WriteHtolsbU64(uint64_t data)
Definition: buffer.cc:920
void WriteHtonU16(uint16_t data)
Definition: buffer.h:915
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:460
bool CheckNoZero(uint32_t start, uint32_t end) const
Checks that the [start, end) is not in the "virtual zero area".
Definition: buffer.cc:810
uint32_t ReadNtohU32()
Definition: buffer.h:978
uint8_t PeekU8()
Definition: buffer.h:1006
bool IsEnd() const
Definition: buffer.cc:796
bool IsStart() const
Definition: buffer.cc:803
uint32_t ReadU32()
Definition: buffer.cc:966
void WriteHtonU32(uint32_t data)
Definition: buffer.h:933
uint16_t ReadNtohU16()
Definition: buffer.h:954
uint32_t GetDistanceFrom(const Iterator &o) const
Definition: buffer.cc:780
void Prev()
go backward by one byte
Definition: buffer.h:860
uint32_t GetSize() const
Definition: buffer.cc:1166
uint16_t ReadU16()
Definition: buffer.h:1035
std::string GetWriteErrorMessage() const
Returns an appropriate message indicating a write error.
Definition: buffer.cc:1194
uint32_t ReadLsbtohU32()
Definition: buffer.cc:1076
void Next()
go forward by one byte
Definition: buffer.h:853
automatically resized byte buffer
Definition: buffer.h:94
uint32_t GetSerializedSize() const
Return the number of bytes required for serialization.
Definition: buffer.cc:566
std::vector< Buffer::Data * > FreeList
Container for buffer data.
Definition: buffer.h:797
uint32_t GetInternalEnd() const
Get the buffer end position.
Definition: buffer.cc:307
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:793
static Buffer::Data * Allocate(uint32_t reqSize)
Allocate a buffer data storage.
Definition: buffer.cc:166
Buffer CreateFragment(uint32_t start, uint32_t length) const
Definition: buffer.cc:529
static FreeList * g_freeList
Buffer data container.
Definition: buffer.h:806
Data * m_data
the buffer data storage
Definition: buffer.h:754
static Buffer::Data * Create(uint32_t size)
Create a buffer data storage.
Definition: buffer.cc:120
static uint32_t g_maxSize
Max observed data size.
Definition: buffer.h:805
static LocalStaticDestructor g_localStaticDestructor
Local static destructor.
Definition: buffer.h:807
uint32_t m_zeroAreaEnd
offset to the end of the virtual zero area from the start of m_data->m_data
Definition: buffer.h:783
uint32_t m_maxZeroAreaStart
keep track of the maximum value of m_zeroAreaStart across the lifetime of a Buffer instance.
Definition: buffer.h:766
static uint32_t g_recommendedStart
location in a newly-allocated buffer where you should start writing data.
Definition: buffer.h:772
static void Deallocate(Buffer::Data *data)
Deallocate the buffer memory.
Definition: buffer.cc:184
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:713
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:493
void TransformIntoRealBuffer() const
Transform a "Virtual byte buffer" into a "Real byte buffer".
Definition: buffer.cc:693
uint32_t GetSize() const
Definition: buffer.h:1068
void AddAtStart(uint32_t start)
Definition: buffer.cc:314
uint32_t GetInternalSize() const
Get the buffer real size.
Definition: buffer.cc:300
Buffer::Iterator Begin() const
Definition: buffer.h:1074
void AddAtEnd(uint32_t end)
Definition: buffer.cc:360
Buffer::Iterator End() const
Definition: buffer.h:1081
Buffer & operator=(const Buffer &o)
Assignment operator.
Definition: buffer.cc:263
Buffer CreateFullCopy() const
Create a full copy of the buffer, including all the internal structures.
Definition: buffer.cc:541
static void Recycle(Buffer::Data *data)
Recycle the buffer memory.
Definition: buffer.cc:101
bool CheckInternalState() const
Checks the internal buffer structures consistency.
Definition: buffer.cc:214
void Initialize(uint32_t zeroSize)
Initializes the buffer with a number of zeroes.
Definition: buffer.cc:248
uint32_t Deserialize(const uint8_t *buffer, uint32_t size)
Definition: buffer.cc:648
void RemoveAtStart(uint32_t start)
Definition: buffer.cc:447
uint32_t m_zeroAreaStart
offset to the start of the virtual zero area from the start of m_data->m_data
Definition: buffer.h:778
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
Definition: buffer.cc:582
const uint8_t * PeekData() const
Definition: buffer.cc:703
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:788
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#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:86
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint8_t data[writeSize]
This data structure is variable-sized through its last member whose size is determined at allocation ...
Definition: buffer.h:663
uint8_t m_data[1]
The real data buffer holds at least one byte.
Definition: buffer.h:687
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:682
uint32_t m_count
The reference count of an instance of this data structure.
Definition: buffer.h:668
uint32_t m_size
the size of the m_data field below.
Definition: buffer.h:672
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:677
Local static destructor structure.
Definition: buffer.h:801