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

(-)e30bc51d0eee (+195 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
//
3
// Copyright (c) 2008-2010 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
#include "seq-num.h"
22
#include "ns3/test.h"
23
#include "ns3/object.h"
24
#include "ns3/traced-value.h"
25
#include "ns3/trace-source-accessor.h"
26
27
namespace ns3 {
28
29
class SeqNumTestObj : public Object
30
{
31
  TracedValue<SeqNum32> m_testTracedSeqNum;
32
33
34
public:
35
36
  SeqNumTestObj () 
37
  {
38
    m_testTracedSeqNum = SeqNum32 (0);
39
  }
40
  
41
  static TypeId GetTypeId (void)
42
  {
43
    static TypeId tid = TypeId("ns3::SeqNumTestObj")
44
      .SetParent<Object> ()
45
      .AddTraceSource ("TestTracedSeqNum",
46
                       "A traceable sequence number",
47
                       MakeTraceSourceAccessor (&SeqNumTestObj::m_testTracedSeqNum))
48
      .AddConstructor<SeqNumTestObj> ()
49
      ;
50
    return tid;
51
  }
52
  
53
  TypeId GetInstanceTypeId (void) const
54
  {
55
    return GetTypeId ();
56
  }
57
58
  void IncSeqNum ()
59
  {
60
    ++m_testTracedSeqNum;
61
  }
62
  
63
64
};
65
66
class SeqNumTestCase : public TestCase
67
{
68
  SeqNum32 m_oldval;
69
  SeqNum32 m_newval;
70
71
  void SeqNumTracer (SeqNum32 oldval, SeqNum32 newval);
72
73
public:
74
75
  SeqNumTestCase ();
76
  virtual ~SeqNumTestCase ();
77
  virtual bool DoRun (void);
78
};
79
80
SeqNumTestCase::SeqNumTestCase ()
81
  : TestCase ("SeqNum")
82
{
83
  m_oldval = 0;
84
  m_newval = 0;
85
}
86
87
SeqNumTestCase::~SeqNumTestCase ()
88
{}
89
90
void
91
SeqNumTestCase::SeqNumTracer (SeqNum32 oldval, SeqNum32 newval) 
92
{
93
  m_oldval = oldval;
94
  m_newval = newval;
95
}
96
97
bool SeqNumTestCase::DoRun (void)
98
{
99
#define NS_TEST_ASSERT_EQUAL(a,b) NS_TEST_ASSERT_MSG_EQ(a,b, "foo")
100
#define NS_TEST_ASSERT(a) NS_TEST_ASSERT_MSG_EQ(bool(a), true, "foo")
101
102
  {
103
      SeqNum32 num1 (3), num2 (5);
104
      uint32_t value;
105
106
      value = (num1 + num2).GetValue ();
107
      NS_TEST_ASSERT_EQUAL (value, 8);
108
109
      num1 += num2.GetValue ();
110
      NS_TEST_ASSERT_EQUAL (num1, SeqNum32 (8));
111
      
112
      ++num1;
113
      NS_TEST_ASSERT_EQUAL (num1, SeqNum32 (9));
114
115
      --num1;
116
      NS_TEST_ASSERT_EQUAL (num1, SeqNum32 (8));
117
118
      num1++;
119
      NS_TEST_ASSERT_EQUAL (num1, SeqNum32 (9));
120
121
      num1--;
122
      NS_TEST_ASSERT_EQUAL (num1, SeqNum32 (8));
123
      
124
  }
125
126
  {
127
      SeqNum16 num1 (60900), num2 (5), num3 (10000);
128
129
      NS_TEST_ASSERT (num1 == num1);
130
131
      NS_TEST_ASSERT (num2 != num1);
132
133
      NS_TEST_ASSERT (num3 > num2);
134
      NS_TEST_ASSERT (num3 >= num2);
135
      NS_TEST_ASSERT (num1 < num3);
136
      NS_TEST_ASSERT (num1 <= num3);
137
138
      NS_TEST_ASSERT (num1 < num2);
139
      NS_TEST_ASSERT (num1 <= num2);
140
      NS_TEST_ASSERT (num2 > num1);
141
      NS_TEST_ASSERT (num2 >= num1);
142
143
      NS_TEST_ASSERT (num1+num2 > num1);
144
      NS_TEST_ASSERT (num1+num2 >= num1);
145
      NS_TEST_ASSERT (num1 < num1+num2);
146
      NS_TEST_ASSERT (num1 <= num1+num2);
147
148
      NS_TEST_ASSERT (num1 < num1+num3);
149
      NS_TEST_ASSERT (num1 <= num1+num3);
150
      NS_TEST_ASSERT (num1+num3 > num1);
151
      NS_TEST_ASSERT (num1+num3 >= num1);
152
  }
153
154
  {
155
    NS_TEST_ASSERT_EQUAL ((SeqNum16 (1000) + SeqNum16 (6000)) - SeqNum16 (1000), 6000);
156
    NS_TEST_ASSERT_EQUAL ((SeqNum16 (60000) + SeqNum16 (6000)) - SeqNum16 (60000), 6000);
157
    NS_TEST_ASSERT_EQUAL (SeqNum16 (1000) - SeqNum16 (6000), -5000);
158
    NS_TEST_ASSERT_EQUAL ((SeqNum16 (60000) + SeqNum16 (1000)) - SeqNum16 (65000), -4000);
159
  }
160
  
161
  {
162
    SeqNum32 num1 (3);
163
    
164
    NS_TEST_ASSERT_EQUAL (num1 + 10, SeqNum32 (13));
165
    num1 += -1;
166
    NS_TEST_ASSERT_EQUAL (num1, SeqNum32 (2));
167
    
168
    NS_TEST_ASSERT_EQUAL (num1 - (num1 - 100), 100);
169
  }
170
171
  {
172
    Ptr<SeqNumTestObj> obj = CreateObject<SeqNumTestObj> ();
173
    obj->TraceConnectWithoutContext ("TestTracedSeqNum", MakeCallback (&SeqNumTestCase::SeqNumTracer, this));
174
    obj->IncSeqNum ();
175
    NS_TEST_ASSERT_EQUAL (m_oldval, SeqNum32 (0));
176
    NS_TEST_ASSERT_EQUAL (m_newval, SeqNum32 (1));
177
    obj->Dispose ();
178
  }
179
  
180
181
  return false;
182
}
183
184
static class SeqNumTestSuite : public TestSuite
185
{
186
public:
187
  SeqNumTestSuite ()
188
    : TestSuite ("SeqNum", UNIT) 
189
  {
190
    AddTestCase (new SeqNumTestCase ());
191
  }
192
} g_seqNumTests;
193
194
}
195
(-)e30bc51d0eee (+270 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
//
3
// Copyright (c) 2008-2010 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 <iostream>
26
#include <stdint.h>
27
28
namespace ns3 {
29
30
template<typename NUMERIC_TYPE, typename SIGNED_TYPE>
31
class SeqNum
32
{
33
public:
34
  SeqNum ()
35
    : m_value (0)
36
  {}
37
38
  // contruct from a plain number; but the contructor is _explicit_, so not called automatically, ever.
39
  explicit SeqNum (NUMERIC_TYPE value)
40
    : m_value (value)
41
  {}
42
43
  // copy contructor
44
  SeqNum (SeqNum<NUMERIC_TYPE, SIGNED_TYPE> const &value)
45
    : m_value (value.m_value)
46
  {}
47
48
  // assignment from a plain number
49
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& operator= (NUMERIC_TYPE value)
50
  {
51
    m_value = value;
52
    return *this;
53
  }
54
55
  // assignment from a sequence number
56
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& operator= (SeqNum<NUMERIC_TYPE, SIGNED_TYPE> const &value)
57
  {
58
    m_value = value.m_value;
59
    return *this;
60
  }
61
62
#if 0
63
  // a SeqNum implicitly converts to a plain number, but not the other way around
64
  operator NUMERIC_TYPE () const
65
  {
66
    return m_value;
67
  }
68
#endif
69
70
  NUMERIC_TYPE GetValue () const
71
  {
72
    return m_value;
73
  }
74
75
  // prefix ++
76
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator++ ()
77
  {
78
    m_value++;
79
    return *this;
80
  }
81
82
  // postfix ++
83
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator++ (int)
84
  {
85
    SeqNum<NUMERIC_TYPE, SIGNED_TYPE> retval (m_value);
86
    m_value++;
87
    return retval;
88
  }
89
90
  // prefix --
91
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator-- ()
92
  {
93
    m_value--;
94
    return *this;
95
  }
96
97
  // postfix --
98
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator-- (int)
99
  {
100
    SeqNum<NUMERIC_TYPE, SIGNED_TYPE> retval (m_value);
101
    m_value--;
102
    return retval;
103
  }
104
105
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& operator+= (SIGNED_TYPE value)
106
  {
107
    m_value += value;
108
    return *this;
109
  }
110
111
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& operator-= (SIGNED_TYPE value)
112
  {
113
    m_value -= value;
114
    return *this;
115
  }
116
117
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator + (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
118
  {
119
    return SeqNum<NUMERIC_TYPE, SIGNED_TYPE> (m_value + other.m_value);
120
  }
121
122
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator + (SIGNED_TYPE delta)
123
  {
124
    return SeqNum<NUMERIC_TYPE, SIGNED_TYPE> (m_value + delta);
125
  }
126
127
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator - (SIGNED_TYPE delta)
128
  {
129
    return SeqNum<NUMERIC_TYPE, SIGNED_TYPE> (m_value - delta);
130
  }
131
132
  SIGNED_TYPE operator - (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
133
  {
134
    static const NUMERIC_TYPE maxValue = std::numeric_limits<NUMERIC_TYPE>::max ();
135
    static const NUMERIC_TYPE halfMaxValue = std::numeric_limits<NUMERIC_TYPE>::max () / 2;
136
    if (m_value > other.m_value)
137
      {
138
        NUMERIC_TYPE diff = m_value - other.m_value;
139
        if (diff < halfMaxValue)
140
          {
141
            return static_cast<SIGNED_TYPE> (diff);
142
          }
143
        else
144
          {
145
            //      |------------|------------|
146
            //       ====                  ===
147
            //          ^                  ^
148
            //       other.m_value      m_value
149
            return -(static_cast<SIGNED_TYPE> (maxValue - m_value + 1 + other.m_value));
150
          }
151
      }
152
    else
153
      {
154
        NUMERIC_TYPE diff = other.m_value - m_value;
155
        if (diff < halfMaxValue)
156
          {
157
            //      |------------|------------|
158
            //          ========
159
            //          ^      ^
160
            //     m_value   other.m_value
161
            return -(static_cast<SIGNED_TYPE> (diff));
162
          }
163
        else
164
          {
165
            //      |------------|------------|
166
            //       ====                  ===
167
            //          ^                  ^
168
            //       m_value      other.m_value
169
            return static_cast<SIGNED_TYPE> (maxValue - other.m_value + 1 + m_value);
170
          }
171
      }
172
  }
173
174
175
  // Here is the critical part, how the comparison is made taking into
176
  // account wrap-around.  From RFC 3626:
177
  //
178
  //   The sequence number S1 is said to be "greater than" the sequence
179
  //    number S2 if:
180
  //
181
  //           S1 > S2 AND S1 - S2 <= MAXVALUE/2 OR
182
  //
183
  //           S2 > S1 AND S2 - S1 > MAXVALUE/2
184
  bool operator > (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
185
  {
186
    static const NUMERIC_TYPE halfMaxValue = std::numeric_limits<NUMERIC_TYPE>::max () / 2;
187
188
    return (((m_value > other.m_value) && (m_value - other.m_value) <= halfMaxValue)
189
            || ((other.m_value > m_value) && (other.m_value - m_value) > halfMaxValue));
190
  }
191
192
  bool operator == (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
193
  {
194
    return (m_value == other.m_value);
195
  }
196
197
  bool operator != (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
198
  {
199
    return (m_value != other.m_value);
200
  }
201
202
  bool operator <= (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
203
  {
204
    return (!this->operator> (other));
205
  }
206
207
  bool operator >= (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
208
  {
209
    return (this->operator> (other) || this->operator== (other));
210
  }
211
212
  bool operator < (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &other)
213
  {
214
    return !this->operator> (other) && m_value != other.m_value;
215
  }
216
217
218
  template<typename NUMERIC_TYPE2, typename SIGNED_TYPE2>
219
  friend std::ostream & operator<< (std::ostream& os, const SeqNum<NUMERIC_TYPE2, SIGNED_TYPE2> &val);
220
221
  template<typename NUMERIC_TYPE2, typename SIGNED_TYPE2>
222
  friend std::istream & operator >> (std::istream &is, const SeqNum<NUMERIC_TYPE2, SIGNED_TYPE2> &val);
223
224
private: // unimplemented operators
225
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& operator+= (SeqNum<NUMERIC_TYPE, SIGNED_TYPE> const &value);
226
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& operator-= (SeqNum<NUMERIC_TYPE, SIGNED_TYPE> const &value);
227
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator* (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
228
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator/ (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
229
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator% (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
230
  bool operator ! () const;
231
  bool operator && (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
232
  bool operator || (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
233
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator~ () const;
234
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator& (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
235
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator| (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
236
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator^ (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
237
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator<< (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
238
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE> operator>> (const SeqNum<NUMERIC_TYPE, SIGNED_TYPE>& b) const;
239
  int operator* ();
240
  SeqNum<NUMERIC_TYPE, SIGNED_TYPE>* operator& ();
241
242
private:
243
  NUMERIC_TYPE m_value;
244
};
245
246
247
template<typename NUMERIC_TYPE, typename SIGNED_TYPE>
248
std::ostream &
249
operator<< (std::ostream& os, const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &val)
250
{
251
  os << val.m_value;
252
  return os;
253
}
254
  
255
template<typename NUMERIC_TYPE, typename SIGNED_TYPE>
256
std::istream & operator >> (std::istream &is, const SeqNum<NUMERIC_TYPE, SIGNED_TYPE> &val)
257
{
258
  is >> val.m_value;
259
  return is;
260
}
261
262
263
typedef SeqNum<uint32_t, int32_t> SeqNum32;
264
typedef SeqNum<uint16_t, int16_t> SeqNum16;
265
266
} // namespace ns3
267
268
#endif
269
270
(-)a/src/contrib/wscript (+2 lines)
 Lines 31-36    Link Here 
31
        'attribute-default-iterator.cc',
31
        'attribute-default-iterator.cc',
32
        'file-config.cc',
32
        'file-config.cc',
33
        'raw-text-config.cc',
33
        'raw-text-config.cc',
34
        'seq-num.cc',
34
        ]
35
        ]
35
36
36
    headers = bld.new_task_gen('ns3header')
37
    headers = bld.new_task_gen('ns3header')
 Lines 43-48    Link Here 
43
        'config-store.h',
44
        'config-store.h',
44
        'flow-id-tag.h',
45
        'flow-id-tag.h',
45
        'average.h',
46
        'average.h',
47
        'seq-num.h',
46
        ]
48
        ]
47
49
48
    if bld.env['ENABLE_GTK_CONFIG_STORE']:
50
    if bld.env['ENABLE_GTK_CONFIG_STORE']:

Return to bug 385