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
30namespace ns3 {
31
92class Buffer
93{
94public:
98 class Iterator
99 {
100public:
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);
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
384private:
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);
445 std::string GetReadErrorMessage (void) const;
453 std::string GetWriteErrorMessage (void) const;
454
484 uint8_t *m_data;
485 };
486
490 inline uint32_t GetSize (void) const;
491
501 uint8_t const*PeekData (void) const;
502
522 void AddAtEnd (uint32_t end);
523
531 void AddAtEnd (const Buffer &o);
547 void RemoveAtEnd (uint32_t end);
548
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 ();
645private:
660 struct Data
661 {
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
771
792
793#ifdef BUFFER_FREE_LIST
795 typedef std::vector<struct Buffer::Data*> FreeList;
798 {
800 };
804#endif
805};
806
807} // namespace ns3
808
809#include "ns3/assert.h"
810#include <cstring>
811
812namespace 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}
828Buffer::Iterator::Iterator (Buffer const*buffer, bool dummy)
829{
830 Construct (buffer);
831 m_current = m_dataEnd;
832}
833
834void
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
844void
846{
847 NS_ASSERT (m_current + 1 <= m_dataEnd);
848 m_current++;
849}
850void
852{
853 NS_ASSERT (m_current >= 1);
854 m_current--;
855}
856void
858{
859 NS_ASSERT (m_current + delta <= m_dataEnd);
860 m_current += delta;
861}
862void
864{
865 NS_ASSERT (m_current >= delta);
866 m_current -= delta;
867}
868void
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
886void
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
904void
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
923void
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
945uint16_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
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
997uint8_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
1020uint8_t
1022{
1023 uint8_t ret = PeekU8 ();
1024 m_current ++;
1025 return ret;
1026}
1027
1028uint16_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
1040void
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
1062uint32_t
1064{
1065 return m_end - m_start;
1066}
1067
1069Buffer::Begin (void) const
1070{
1072 return Buffer::Iterator (this);
1073}
1075Buffer::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