A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
buffer.h
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 noBUFFER_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 
259  inline uint8_t ReadU8 (void);
267  inline uint16_t ReadU16 (void);
275  uint32_t ReadU32 (void);
283  uint64_t ReadU64 (void);
291  inline uint16_t ReadNtohU16 (void);
299  inline uint32_t ReadNtohU32 (void);
307  uint64_t ReadNtohU64 (void);
315  uint16_t ReadLsbtohU16 (void);
323  uint32_t ReadLsbtohU32 (void);
331  uint64_t ReadLsbtohU64 (void);
340  void Read (uint8_t *buffer, uint32_t size);
341 
347  uint16_t CalculateIpChecksum (uint16_t size);
348 
355  uint16_t CalculateIpChecksum (uint16_t size, uint32_t initialChecksum);
356 
360  uint32_t GetSize (void) const;
361 
362 private:
363  friend class Buffer;
364  inline Iterator (Buffer const*buffer);
365  inline Iterator (Buffer const*buffer, bool);
366  inline void Construct (const Buffer *buffer);
367  bool CheckNoZero (uint32_t start, uint32_t end) const;
368  bool Check (uint32_t i) const;
369  uint16_t SlowReadNtohU16 (void);
370  uint32_t SlowReadNtohU32 (void);
371  std::string GetReadErrorMessage (void) const;
372  std::string GetWriteErrorMessage (void) const;
373 
374  /* offset in virtual bytes from the start of the data buffer to the
375  * start of the "virtual zero area".
376  */
377  uint32_t m_zeroStart;
378  /* offset in virtual bytes from the start of the data buffer to the
379  * end of the "virtual zero area".
380  */
381  uint32_t m_zeroEnd;
382  /* offset in virtual bytes from the start of the data buffer to the
383  * start of the data which can be read by this iterator
384  */
385  uint32_t m_dataStart;
386  /* offset in virtual bytes from the start of the data buffer to the
387  * end of the data which can be read by this iterator
388  */
389  uint32_t m_dataEnd;
390  /* offset in virtual bytes from the start of the data buffer to the
391  * current position represented by this iterator.
392  */
393  uint32_t m_current;
394  /* a pointer to the underlying byte buffer. All offsets are relative
395  * to this pointer.
396  */
397  uint8_t *m_data;
398  };
399 
403  inline uint32_t GetSize (void) const;
404 
414  uint8_t const*PeekData (void) const;
415 
426  bool AddAtStart (uint32_t start);
437  bool AddAtEnd (uint32_t end);
438 
446  void AddAtEnd (const Buffer &o);
454  void RemoveAtStart (uint32_t start);
462  void RemoveAtEnd (uint32_t end);
463 
471  Buffer CreateFragment (uint32_t start, uint32_t length) const;
472 
477  inline Buffer::Iterator Begin (void) const;
482  inline Buffer::Iterator End (void) const;
483 
484  Buffer CreateFullCopy (void) const;
485 
489  uint32_t GetSerializedSize (void) const;
490 
501  uint32_t Serialize (uint8_t* buffer, uint32_t maxSize) const;
502 
511  uint32_t Deserialize (const uint8_t* buffer, uint32_t size);
512 
513  int32_t GetCurrentStartOffset (void) const;
514  int32_t GetCurrentEndOffset (void) const;
515 
522  void CopyData (std::ostream *os, uint32_t size) const;
523 
524  uint32_t CopyData (uint8_t *buffer, uint32_t size) const;
525 
526  inline Buffer (Buffer const &o);
527  Buffer &operator = (Buffer const &o);
528  Buffer ();
529  Buffer (uint32_t dataSize);
530  Buffer (uint32_t dataSize, bool initialize);
531  ~Buffer ();
532 private:
547  struct Data
548  {
549  /* The reference count of an instance of this data structure.
550  * Each buffer which references an instance holds a count.
551  */
552  uint32_t m_count;
553  /* the size of the m_data field below.
554  */
555  uint32_t m_size;
556  /* offset from the start of the m_data field below to the
557  * start of the area in which user bytes were written.
558  */
559  uint32_t m_dirtyStart;
560  /* offset from the start of the m_data field below to the
561  * end of the area in which user bytes were written.
562  */
563  uint32_t m_dirtyEnd;
564  /* The real data buffer holds _at least_ one byte.
565  * Its real size is stored in the m_size field.
566  */
567  uint8_t m_data[1];
568  };
569 
570  void TransformIntoRealBuffer (void) const;
571  bool CheckInternalState (void) const;
572  void Initialize (uint32_t zeroSize);
573  uint32_t GetInternalSize (void) const;
574  uint32_t GetInternalEnd (void) const;
575  static void Recycle (struct Buffer::Data *data);
576  static struct Buffer::Data *Create (uint32_t size);
577  static struct Buffer::Data *Allocate (uint32_t reqSize);
578  static void Deallocate (struct Buffer::Data *data);
579 
580  struct Data *m_data;
581 
582  /* keep track of the maximum value of m_zeroAreaStart across
583  * the lifetime of a Buffer instance. This variable is used
584  * purely as a source of information for the heuristics which
585  * decide on the position of the zero area in new buffers.
586  * It is read from the Buffer destructor to update the global
587  * heuristic data and these global heuristic data are used from
588  * the Buffer constructor to choose an initial value for
589  * m_zeroAreaStart.
590  */
591  uint32_t m_maxZeroAreaStart;
597  static uint32_t g_recommendedStart;
598 
599  /* offset to the start of the virtual zero area from the start
600  * of m_data->m_data
601  */
602  uint32_t m_zeroAreaStart;
603  /* offset to the end of the virtual zero area from the start
604  * of m_data->m_data
605  */
606  uint32_t m_zeroAreaEnd;
607  /* offset to the start of the data referenced by this Buffer
608  * instance from the start of m_data->m_data
609  */
610  uint32_t m_start;
611  /* offset to the end of the data referenced by this Buffer
612  * instance from the start of m_data->m_data
613  */
614  uint32_t m_end;
615 
616 #ifdef BUFFER_FREE_LIST
617  typedef std::vector<struct Buffer::Data*> FreeList;
618  struct LocalStaticDestructor
619  {
620  ~LocalStaticDestructor ();
621  };
622  static uint32_t g_maxSize;
623  static FreeList *g_freeList;
624  static struct LocalStaticDestructor g_localStaticDestructor;
625 #endif
626 };
627 
628 } // namespace ns3
629 
630 #include "ns3/assert.h"
631 #include <cstring>
632 
633 namespace ns3 {
634 
635 Buffer::Iterator::Iterator ()
636  : m_zeroStart (0),
637  m_zeroEnd (0),
638  m_dataStart (0),
639  m_dataEnd (0),
640  m_current (0),
641  m_data (0)
642 {
643 }
644 Buffer::Iterator::Iterator (Buffer const*buffer)
645 {
646  Construct (buffer);
647  m_current = m_dataStart;
648 }
649 Buffer::Iterator::Iterator (Buffer const*buffer, bool dummy)
650 {
651  Construct (buffer);
652  m_current = m_dataEnd;
653 }
654 
655 void
656 Buffer::Iterator::Construct (const Buffer *buffer)
657 {
658  m_zeroStart = buffer->m_zeroAreaStart;
659  m_zeroEnd = buffer->m_zeroAreaEnd;
660  m_dataStart = buffer->m_start;
661  m_dataEnd = buffer->m_end;
662  m_data = buffer->m_data->m_data;
663 }
664 
665 void
667 {
668  NS_ASSERT (m_current + 1 <= m_dataEnd);
669  m_current++;
670 }
671 void
673 {
674  NS_ASSERT (m_current >= 1);
675  m_current--;
676 }
677 void
678 Buffer::Iterator::Next (uint32_t delta)
679 {
680  NS_ASSERT (m_current + delta <= m_dataEnd);
681  m_current += delta;
682 }
683 void
684 Buffer::Iterator::Prev (uint32_t delta)
685 {
686  NS_ASSERT (m_current >= delta);
687  m_current -= delta;
688 }
689 void
691 {
692  NS_ASSERT_MSG (Check (m_current),
693  GetWriteErrorMessage ());
694 
695  if (m_current < m_zeroStart)
696  {
697  m_data[m_current] = data;
698  m_current++;
699  }
700  else
701  {
702  m_data[m_current - (m_zeroEnd-m_zeroStart)] = data;
703  m_current++;
704  }
705 }
706 
707 void
708 Buffer::Iterator::WriteU8 (uint8_t data, uint32_t len)
709 {
710  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + len),
711  GetWriteErrorMessage ());
712  if (m_current <= m_zeroStart)
713  {
714  std::memset (&(m_data[m_current]), data, len);
715  m_current += len;
716  }
717  else
718  {
719  uint8_t *buffer = &m_data[m_current - (m_zeroEnd-m_zeroStart)];
720  std::memset (buffer, data, len);
721  m_current += len;
722  }
723 }
724 
725 void
727 {
728  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + 2),
729  GetWriteErrorMessage ());
730  uint8_t *buffer;
731  if (m_current + 2 <= m_zeroStart)
732  {
733  buffer = &m_data[m_current];
734  }
735  else
736  {
737  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
738  }
739  buffer[0] = (data >> 8)& 0xff;
740  buffer[1] = (data >> 0)& 0xff;
741  m_current+= 2;
742 }
743 
744 void
746 {
747  NS_ASSERT_MSG (CheckNoZero (m_current, m_current + 4),
748  GetWriteErrorMessage ());
749 
750  uint8_t *buffer;
751  if (m_current + 4 <= m_zeroStart)
752  {
753  buffer = &m_data[m_current];
754  }
755  else
756  {
757  buffer = &m_data[m_current - (m_zeroEnd - m_zeroStart)];
758  }
759  buffer[0] = (data >> 24)& 0xff;
760  buffer[1] = (data >> 16)& 0xff;
761  buffer[2] = (data >> 8)& 0xff;
762  buffer[3] = (data >> 0)& 0xff;
763  m_current+= 4;
764 }
765 
766 uint16_t
768 {
769  uint8_t *buffer;
770  if (m_current + 2 <= m_zeroStart)
771  {
772  buffer = &m_data[m_current];
773  }
774  else if (m_current >= m_zeroEnd)
775  {
776  buffer = &m_data[m_current];
777  }
778  else
779  {
780  return SlowReadNtohU16 ();
781  }
782  uint16_t retval = 0;
783  retval |= buffer[0];
784  retval <<= 8;
785  retval |= buffer[1];
786  m_current += 2;
787  return retval;
788 }
789 
790 uint32_t
792 {
793  uint8_t *buffer;
794  if (m_current + 4 <= m_zeroStart)
795  {
796  buffer = &m_data[m_current];
797  }
798  else if (m_current >= m_zeroEnd)
799  {
800  buffer = &m_data[m_current];
801  }
802  else
803  {
804  return SlowReadNtohU32 ();
805  }
806  uint32_t retval = 0;
807  retval |= buffer[0];
808  retval <<= 8;
809  retval |= buffer[1];
810  retval <<= 8;
811  retval |= buffer[2];
812  retval <<= 8;
813  retval |= buffer[3];
814  m_current += 4;
815  return retval;
816 }
817 
818 uint8_t
820 {
821  NS_ASSERT_MSG (m_current >= m_dataStart &&
822  m_current <= m_dataEnd,
823  GetReadErrorMessage ());
824 
825  if (m_current < m_zeroStart)
826  {
827  uint8_t data = m_data[m_current];
828  m_current++;
829  return data;
830  }
831  else if (m_current < m_zeroEnd)
832  {
833  m_current++;
834  return 0;
835  }
836  else
837  {
838  uint8_t data = m_data[m_current - (m_zeroEnd-m_zeroStart)];
839  m_current++;
840  return data;
841  }
842 }
843 
844 uint16_t
846 {
847  uint8_t byte0 = ReadU8 ();
848  uint8_t byte1 = ReadU8 ();
849  uint16_t data = byte1;
850  data <<= 8;
851  data |= byte0;
852 
853  return data;
854 }
855 
856 Buffer::Buffer (Buffer const&o)
857  : m_data (o.m_data),
858  m_maxZeroAreaStart (o.m_zeroAreaStart),
859  m_zeroAreaStart (o.m_zeroAreaStart),
860  m_zeroAreaEnd (o.m_zeroAreaEnd),
861  m_start (o.m_start),
862  m_end (o.m_end)
863 {
864  m_data->m_count++;
865  NS_ASSERT (CheckInternalState ());
866 }
867 
868 uint32_t
869 Buffer::GetSize (void) const
870 {
871  return m_end - m_start;
872 }
873 
875 Buffer::Begin (void) const
876 {
877  NS_ASSERT (CheckInternalState ());
878  return Buffer::Iterator (this);
879 }
881 Buffer::End (void) const
882 {
883  NS_ASSERT (CheckInternalState ());
884  return Buffer::Iterator (this, false);
885 }
886 
887 
888 
889 } // namespace ns3
890 
891 #endif /* BUFFER_H */
uint16_t ReadU16(void)
Definition: buffer.h:845
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
Definition: buffer.cc:1158
void WriteHtonU64(uint64_t data)
Definition: buffer.cc:965
uint32_t ReadU32(void)
Definition: buffer.cc:997
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:497
bool IsStart(void) const
Definition: buffer.cc:829
void RemoveAtStart(uint32_t start)
Definition: buffer.cc:452
automatically resized byte buffer
Definition: buffer.h:92
uint64_t ReadNtohU64(void)
Definition: buffer.cc:1068
#define NS_ASSERT(condition)
Definition: assert.h:64
uint32_t GetSerializedSize(void) const
Definition: buffer.cc:570
uint32_t ReadNtohU32(void)
Definition: buffer.h:791
uint32_t GetDistanceFrom(Iterator const &o) const
Definition: buffer.cc:807
iterator in a Buffer instance
Definition: buffer.h:98
uint32_t Deserialize(const uint8_t *buffer, uint32_t size)
Definition: buffer.cc:660
bool IsEnd(void) const
Definition: buffer.cc:823
void Prev(void)
Definition: buffer.h:672
void WriteU16(uint16_t data)
Definition: buffer.cc:895
void WriteHtonU16(uint16_t data)
Definition: buffer.h:726
Buffer::Iterator End(void) const
Definition: buffer.h:881
uint8_t const * PeekData(void) const
Definition: buffer.cc:729
void Next(void)
Definition: buffer.h:666
void WriteU64(uint64_t data)
Definition: buffer.cc:915
void CopyData(std::ostream *os, uint32_t size) const
Definition: buffer.cc:739
Buffer::Iterator Begin(void) const
Definition: buffer.h:875
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1148
uint64_t ReadU64(void)
Definition: buffer.cc:1014
void WriteHtonU32(uint32_t data)
Definition: buffer.h:745
uint32_t GetSize(void) const
Definition: buffer.h:869
Buffer CreateFragment(uint32_t start, uint32_t length) const
Definition: buffer.cc:533
bool AddAtEnd(uint32_t end)
Definition: buffer.cc:356
void WriteHtolsbU16(uint16_t data)
Definition: buffer.cc:935
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
Definition: buffer.cc:590
void WriteU8(uint8_t data)
Definition: buffer.h:690
void WriteHtolsbU64(uint64_t data)
Definition: buffer.cc:951
static uint32_t g_recommendedStart
Definition: buffer.h:597
uint8_t ReadU8(void)
Definition: buffer.h:819
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:978
uint16_t ReadLsbtohU16(void)
Definition: buffer.cc:1090
bool AddAtStart(uint32_t start)
Definition: buffer.cc:305
uint64_t ReadLsbtohU64(void)
Definition: buffer.cc:1118
uint16_t ReadNtohU16(void)
Definition: buffer.h:767
void WriteU32(uint32_t data)
Definition: buffer.cc:903
uint32_t GetSize(void) const
Definition: buffer.cc:1183
uint32_t ReadLsbtohU32(void)
Definition: buffer.cc:1101
void WriteHtolsbU32(uint32_t data)
Definition: buffer.cc:942