View | Details | Raw Unified | Return to bug 385
Collapse All | Expand All

(-)d5baf90cf1d8 (+104 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
3
#ifdef RUN_SELF_TESTS
4
5
#include "seq-num.h"
6
#include "ns3/test.h"
7
8
9
namespace ns3 {
10
11
class SeqNumTest : public ns3::Test {
12
private:
13
public:
14
  SeqNumTest ();
15
  virtual bool RunTests (void);
16
};
17
18
SeqNumTest::SeqNumTest ()
19
  : ns3::Test ("SeqNum")
20
{}
21
22
bool 
23
SeqNumTest::RunTests (void)
24
{
25
  bool result = true;
26
27
  {
28
      SeqNum32 num1 (3), num2 (5);
29
      uint32_t value;
30
31
      value = num1 + num2;
32
      NS_TEST_ASSERT_EQUAL (value, 8);
33
34
      num1 += num2;
35
      NS_TEST_ASSERT_EQUAL (num1, 8);
36
      
37
      ++num1;
38
      NS_TEST_ASSERT_EQUAL (num1, 9);
39
40
      --num1;
41
      NS_TEST_ASSERT_EQUAL (num1, 8);
42
43
      num1++;
44
      NS_TEST_ASSERT_EQUAL (num1, 9);
45
46
      num1--;
47
      NS_TEST_ASSERT_EQUAL (num1, 8);
48
      
49
  }
50
51
  {
52
      SeqNum16 num1 (60900), num2 (5), num3 (10000);
53
54
      NS_TEST_ASSERT (num1 == num1);
55
56
      NS_TEST_ASSERT (num2 != num1);
57
58
      NS_TEST_ASSERT (num3 > num2);
59
      NS_TEST_ASSERT (num3 >= num2);
60
      NS_TEST_ASSERT (num1 < num3);
61
      NS_TEST_ASSERT (num1 <= num3);
62
63
      NS_TEST_ASSERT (num1 < num2);
64
      NS_TEST_ASSERT (num1 <= num2);
65
      NS_TEST_ASSERT (num2 > num1);
66
      NS_TEST_ASSERT (num2 >= num1);
67
68
      NS_TEST_ASSERT (num1+num2 > num1);
69
      NS_TEST_ASSERT (num1+num2 >= num1);
70
      NS_TEST_ASSERT (num1 < num1+num2);
71
      NS_TEST_ASSERT (num1 <= num1+num2);
72
73
      NS_TEST_ASSERT (num1 < num1+num3);
74
      NS_TEST_ASSERT (num1 <= num1+num3);
75
      NS_TEST_ASSERT (num1+num3 > num1);
76
      NS_TEST_ASSERT (num1+num3 >= num1);
77
  }
78
79
  {
80
      NS_TEST_ASSERT_EQUAL ((SeqNum16 (1000) + SeqNum16 (6000)) - SeqNum16 (1000), 6000);
81
      NS_TEST_ASSERT_EQUAL ((SeqNum16 (60000) + SeqNum16 (6000)) - SeqNum16 (60000), 6000);
82
      NS_TEST_ASSERT_EQUAL (SeqNum16 (1000) - SeqNum16 (6000), -5000);
83
      NS_TEST_ASSERT_EQUAL ((SeqNum16 (60000) + SeqNum16 (1000)) - SeqNum16 (65000), -4000);
84
  }
85
86
  {
87
      SeqNum32 num1 (3);
88
89
      NS_TEST_ASSERT_EQUAL (num1 + 10, 13);
90
      num1 += -1;
91
      NS_TEST_ASSERT_EQUAL (num1, 2);
92
      
93
      NS_TEST_ASSERT_EQUAL (num1 - (num1 - 100), 100);
94
  }
95
96
  return result;
97
}
98
99
static SeqNumTest gSeqNumTest;
100
101
}; // namespace
102
103
104
#endif /* RUN_SELF_TESTS */
(-)d5baf90cf1d8 (+207 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
//
3
// Copyright (c) 2008 INESC Porto
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: Gustavo J. A. M. Carneiro  <gjc@inescporto.pt> <gjcarneiro@gmail.com>
19
//
20
21
#ifndef __NS3_SEQ_NUM_H__
22
#define __NS3_SEQ_NUM_H__
23
24
#include <limits>
25
#include <stdint.h>
26
27
namespace ns3 {
28
29
template<typename NUMERIC_TYPE, typename SIGNED_TYPE>
30
class SeqNum
31
{
32
public:
33
  SeqNum ()
34
    : m_value (0)
35
  {}
36
37
  explicit SeqNum (NUMERIC_TYPE value)
38
    : m_value (value)
39
  {}
40
41
  operator NUMERIC_TYPE () const
42
  {
43
    return m_value;
44
  }
45
46
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& operator= (NUMERIC_TYPE value)
47
  {
48
    m_value = value;
49
    return *this;
50
  }
51
52
  // prefix ++
53
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator++ ()
54
  {
55
    m_value++;
56
    return *this;
57
  }
58
59
  // postfix ++
60
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator++ (int)
61
  {
62
    SeqNum<NUMERIC_TYPE, SIGNED_TYPE> retval (m_value);
63
    m_value++;
64
    return retval;
65
  }
66
67
  // prefix --
68
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator-- ()
69
  {
70
    m_value--;
71
    return *this;
72
  }
73
74
  // postfix --
75
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator-- (int)
76
  {
77
    SeqNum<NUMERIC_TYPE, SIGNED_TYPE> retval (m_value);
78
    m_value--;
79
    return retval;
80
  }
81
82
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& operator+= (SIGNED_TYPE value)
83
  {
84
    m_value += value;
85
    return *this;
86
  }
87
88
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& operator-= (SIGNED_TYPE value)
89
  {
90
    m_value -= value;
91
    return *this;
92
  }
93
94
   SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator + (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
95
   {
96
     return SeqNum<NUMERIC_TYPE, SIGNED_TYPE> (m_value + other.m_value);
97
   }
98
99
100
   SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator + (SIGNED_TYPE delta)
101
   {
102
     return SeqNum<NUMERIC_TYPE, SIGNED_TYPE> (m_value + delta);
103
   }
104
105
   SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator - (SIGNED_TYPE delta)
106
   {
107
     return SeqNum<NUMERIC_TYPE, SIGNED_TYPE> (m_value - delta);
108
   }
109
110
111
   SIGNED_TYPE operator - (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
112
   {
113
     static const NUMERIC_TYPE maxValue = std::numeric_limits<NUMERIC_TYPE>::max ();
114
     static const NUMERIC_TYPE halfMaxValue = std::numeric_limits<NUMERIC_TYPE>::max () / 2;
115
     if (m_value > other.m_value)
116
       {
117
         NUMERIC_TYPE diff = m_value - other.m_value;
118
         if (diff < halfMaxValue)
119
           {
120
             return static_cast<SIGNED_TYPE> (diff);
121
           }
122
         else
123
           {
124
             //      |------------|------------|
125
             //       ====                  ===
126
             //          ^                  ^   
127
             //       other.m_value      m_value
128
             return -(static_cast<SIGNED_TYPE> (maxValue - m_value + 1 + other.m_value));
129
           }
130
       }
131
     else
132
       {
133
         NUMERIC_TYPE diff = other.m_value - m_value;
134
         if (diff < halfMaxValue)
135
           {
136
             //      |------------|------------|
137
             //          ========
138
             //          ^      ^   
139
             //     m_value   other.m_value
140
             return -(static_cast<SIGNED_TYPE> (diff));
141
           }
142
         else
143
           {
144
             //      |------------|------------|
145
             //       ====                  ===
146
             //          ^                  ^   
147
             //       m_value      other.m_value
148
             return static_cast<SIGNED_TYPE> (maxValue - other.m_value + 1 + m_value);
149
           }
150
       }
151
   }
152
153
154
  // Here is the critical part, how the comparison is made taking into
155
  // account wrap-around.  From RFC 3626:
156
  //
157
  //   The sequence number S1 is said to be "greater than" the sequence
158
  //    number S2 if:
159
  //
160
  //           S1 > S2 AND S1 - S2 <= MAXVALUE/2 OR
161
  //
162
  //           S2 > S1 AND S2 - S1 > MAXVALUE/2
163
  bool operator > (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
164
  {
165
    static const NUMERIC_TYPE halfMaxValue = std::numeric_limits<NUMERIC_TYPE>::max () / 2;
166
167
    return (((m_value > other.m_value) && (m_value - other.m_value) <= halfMaxValue)
168
            || ((other.m_value > m_value) && (other.m_value - m_value) > halfMaxValue));
169
  }
170
171
  bool operator == (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
172
  {
173
    return (m_value == other.m_value);
174
  }
175
176
  bool operator != (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
177
  {
178
    return (m_value != other.m_value);
179
  }
180
181
  bool operator <= (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
182
  {
183
    return (!this->operator> (other));
184
  }
185
186
  bool operator >= (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
187
  {
188
    return (this->operator> (other) || this->operator== (other));
189
  }
190
191
  bool operator < (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
192
  {
193
    return !this->operator> (other) && m_value != other.m_value;
194
  }
195
196
private:
197
  NUMERIC_TYPE m_value;
198
};
199
200
typedef SeqNum<uint32_t, int32_t> SeqNum32;
201
typedef SeqNum<uint16_t, int16_t> SeqNum16;
202
203
} // namespace ns3
204
205
#endif
206
207
(-)a/src/contrib/wscript (+2 lines)
 Lines 21-26    Link Here 
21
        'delay-jitter-estimation.cc',
21
        'delay-jitter-estimation.cc',
22
        'attribute-iterator.cc',
22
        'attribute-iterator.cc',
23
        'config-store.cc',
23
        'config-store.cc',
24
        'seq-num.cc',
24
        ]
25
        ]
25
26
26
    headers = bld.create_obj('ns3header')
27
    headers = bld.create_obj('ns3header')
 Lines 31-36    Link Here 
31
        'gnuplot.h',
32
        'gnuplot.h',
32
        'delay-jitter-estimation.h',
33
        'delay-jitter-estimation.h',
33
        'config-store.h',
34
        'config-store.h',
35
        'seq-num.h',
34
        ]
36
        ]
35
37
36
    if bld.env()['ENABLE_GTK_CONFIG_STORE']:
38
    if bld.env()['ENABLE_GTK_CONFIG_STORE']:

Return to bug 385