00001 /* BEGIN_COPYRIGHT */ 00002 /* */ 00003 /* Open Diameter: Open-source software for the Diameter and */ 00004 /* Diameter related protocols */ 00005 /* */ 00006 /* Copyright (C) 2002-2004 Open Diameter Project */ 00007 /* */ 00008 /* This library is free software; you can redistribute it and/or modify */ 00009 /* it under the terms of the GNU Lesser General Public License as */ 00010 /* published by the Free Software Foundation; either version 2.1 of the */ 00011 /* License, or (at your option) any later version. */ 00012 /* */ 00013 /* This library is distributed in the hope that it will be useful, */ 00014 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 00015 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ 00016 /* Lesser General Public License for more details. */ 00017 /* */ 00018 /* You should have received a copy of the GNU Lesser General Public */ 00019 /* License along with this library; if not, write to the Free Software */ 00020 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ 00021 /* USA. */ 00022 /* */ 00023 /* In addition, when you copy and redistribute some or the entire part of */ 00024 /* the source code of this software with or without modification, you */ 00025 /* MUST include this copyright notice in each copy. */ 00026 /* */ 00027 /* If you make any changes that are appeared to be useful, please send */ 00028 /* sources that include the changed part to */ 00029 /* diameter-developers@lists.sourceforge.net so that we can reflect your */ 00030 /* changes to one unified version of this software. */ 00031 /* */ 00032 /* END_COPYRIGHT */ 00033 00034 #ifndef __PANA_SERIAL_NUM_H__ 00035 #define __PANA_SERIAL_NUM_H__ 00036 00037 #include "ace/OS.h" 00038 #include "ace/System_Time.h" 00039 00069 class PANA_SerialNumber 00070 { 00071 public: 00075 PANA_SerialNumber(ACE_UINT32 seed = 0) : m_SerialNum(seed) { } 00076 00077 00078 /* 00079 Serial numbers may be incremented by the addition of a positive 00080 integer n, where n is taken from the range of integers 00081 [0 .. (2^(SERIAL_BITS - 1) - 1)]. For a sequence number s, the 00082 result of such an addition, s', is defined as 00083 00084 s' = (s + n) modulo (2 ^ SERIAL_BITS) 00085 00086 where the addition and modulus operations here act upon values that 00087 are non-negative values of unbounded size in the usual ways of 00088 integer arithmetic. 00089 00090 Addition of a value outside the range 00091 [0 .. (2^(SERIAL_BITS - 1) - 1)] is undefined. 00092 */ 00093 00099 ACE_UINT32 operator+(ACE_UINT32 num) { 00100 return (m_SerialNum = (m_SerialNum + num) % (2 ^ sizeof(ACE_UINT32))); 00101 } 00102 00108 ACE_UINT32 operator+(PANA_SerialNumber &num) { 00109 return ((*this) + num.value()); 00110 } 00111 00115 ACE_UINT32 operator++() { 00116 return ((*this) + 1); 00117 } 00118 00119 /* 00120 3.2. Comparison 00121 00122 Any two serial numbers, s1 and s2, may be compared. The definition 00123 of the result of this comparison is as follows. 00124 00125 For the purposes of this definition, consider two integers, i1 and 00126 i2, from the unbounded set of non-negative integers, such that i1 and 00127 s1 have the same numeric value, as do i2 and s2. Arithmetic and 00128 comparisons applied to i1 and i2 use ordinary unbounded integer 00129 arithmetic. 00130 00131 Then, s1 is said to be equal to s2 if and only if i1 is equal to i2, 00132 in all other cases, s1 is not equal to s2. 00133 00134 s1 is said to be less than s2 if, and only if, s1 is not equal to s2, 00135 and 00136 00137 (i1 < i2 and i2 - i1 < 2^(SERIAL_BITS - 1)) or 00138 (i1 > i2 and i1 - i2 > 2^(SERIAL_BITS - 1)) 00139 00140 s1 is said to be greater than s2 if, and only if, s1 is not equal to 00141 s2, and 00142 00143 (i1 < i2 and i2 - i1 > 2^(SERIAL_BITS - 1)) or 00144 (i1 > i2 and i1 - i2 < 2^(SERIAL_BITS - 1)) 00145 00146 Note that there are some pairs of values s1 and s2 for which s1 is 00147 not equal to s2, but for which s1 is neither greater than, nor less 00148 than, s2. An attempt to use these ordering operators on such pairs 00149 of values produces an undefined result. 00150 00151 The reason for this is that those pairs of values are such that any 00152 simple definition that were to define s1 to be less than s2 where 00153 (s1, s2) is such a pair, would also usually cause s2 to be less than 00154 s1, when the pair is (s2, s1). This would mean that the particular 00155 order selected for a test could cause the result to differ, leading 00156 to unpredictable implementations. 00157 00158 While it would be possible to define the test in such a way that the 00159 inequality would not have this surprising property, while being 00160 defined for all pairs of values, such a definition would be 00161 00162 unnecessarily burdensome to implement, and difficult to understand, 00163 and would still allow cases where 00164 00165 s1 < s2 and (s1 + 1) > (s2 + 1) 00166 00167 which is just as non-intuitive. 00168 00169 Thus the problem case is left undefined, implementations are free to 00170 return either result, or to flag an error, and users must take care 00171 not to depend on any particular outcome. Usually this will mean 00172 avoiding allowing those particular pairs of numbers to co-exist. 00173 00174 The relationships greater than or equal to, and less than or equal 00175 to, follow in the natural way from the above definitions. 00176 */ 00177 00183 ACE_UINT32 operator==(ACE_UINT32 num) { 00184 return (m_SerialNum == num); 00185 } 00186 00192 ACE_UINT32 operator==(PANA_SerialNumber &num) { 00193 return ((*this) == num.value()); 00194 } 00195 00201 ACE_UINT32 operator<(ACE_UINT32 num) { 00202 return (((m_SerialNum < num) && ((num - m_SerialNum) < (2^(sizeof(ACE_UINT32) - 1)))) || 00203 ((m_SerialNum > num) && ((m_SerialNum - num) > (2^(sizeof(ACE_UINT32) - 1))))); 00204 } 00205 00211 ACE_UINT32 operator<(PANA_SerialNumber &num) { 00212 return ((*this) < num.value()); 00213 } 00214 00220 ACE_UINT32 operator>(ACE_UINT32 num) { 00221 return (((m_SerialNum < num) && ( (num - m_SerialNum) > (2^(sizeof(ACE_UINT32) - 1)))) || 00222 ((m_SerialNum > num) && ((m_SerialNum - num) < (2^(sizeof(ACE_UINT32) - 1))))); 00223 } 00224 00230 ACE_UINT32 operator>(PANA_SerialNumber &num) { 00231 return ((*this) > num.value()); 00232 } 00233 00237 ACE_UINT32 value() { return m_SerialNum; } 00238 00244 static inline ACE_UINT32 generateIsn(ACE_UINT32 seed = 0) { 00245 if (seed == 0) { 00246 ACE_System_Time::get_local_system_time(seed); 00247 } 00248 00249 // simple time seeded randon number generator 00250 ACE_OS::srand(seed); 00251 return ACE_OS::rand(); 00252 } 00253 00254 protected: 00255 00256 ACE_UINT32 m_SerialNum; 00257 }; 00258 00259 #endif /* __PANA_SERIAL_NUM_H__ */ 00260