[devel] [PATCH 1/1] base: add serial number arithmetic (RFC1982) [#3074]

2020-02-16 Thread thuan.tran
- Adapt MDS with this SNA implementation.
---
 src/base/Makefile.am |   6 +-
 src/base/sna.h   | 138 +++
 src/base/tests/sna_test.cc   | 121 +++
 src/mds/mds_tipc_fctrl_intf.cc   |   2 +-
 src/mds/mds_tipc_fctrl_portid.cc |  19 ++---
 src/mds/mds_tipc_fctrl_portid.h  |  64 +-
 6 files changed, 274 insertions(+), 76 deletions(-)
 create mode 100644 src/base/sna.h
 create mode 100644 src/base/tests/sna_test.cc

diff --git a/src/base/Makefile.am b/src/base/Makefile.am
index 025fb86a2..5082175cf 100644
--- a/src/base/Makefile.am
+++ b/src/base/Makefile.am
@@ -173,7 +173,8 @@ noinst_HEADERS += \
src/base/unix_client_socket.h \
src/base/unix_server_socket.h \
src/base/unix_socket.h \
-   src/base/usrbuf.h
+   src/base/usrbuf.h \
+   src/base/sna.h
 
 TESTS += bin/testleap bin/libbase_test bin/core_common_test
 
@@ -237,7 +238,8 @@ bin_libbase_test_SOURCES = \
src/base/tests/time_compare_test.cc \
src/base/tests/time_convert_test.cc \
src/base/tests/time_subtract_test.cc \
-   src/base/tests/unix_socket_test.cc
+   src/base/tests/unix_socket_test.cc \
+   src/base/tests/sna_test.cc
 
 bin_libbase_test_LDADD = \
$(GTEST_DIR)/lib/libgtest.la \
diff --git a/src/base/sna.h b/src/base/sna.h
new file mode 100644
index 0..4331e6119
--- /dev/null
+++ b/src/base/sna.h
@@ -0,0 +1,138 @@
+/*  -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2020 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Reference: Serial Number Arithmetic from RFC1982
+ *
+ */
+
+#ifndef BASE_SNA_H_
+#define BASE_SNA_H_
+
+#include 
+#include 
+#include 
+
+#define SNA16_MAX   (1UL << 16)
+#define SNA16_SPACE (SNA16_MAX/2)
+#define SNA32_MAX   (1ULL << 32)
+#define SNA32_SPACE (SNA32_MAX/2)
+
+template 
+class SerialNumber {
+  public:
+SerialNumber(): value_(0) {}
+SerialNumber(const SerialNumber ) {
+  value_ = t.value_;
+}
+explicit SerialNumber(const uint64_t ) {
+  if ((n < 0) || (n > (max()-1)))
+assert(0 && "Invalid initial value");
+  value_ = n;
+}
+SerialNumber& operator=(const SerialNumber ) {
+  // check for self-assignment
+  if ( == this)
+return *this;
+  value_ = t.value_;
+  return *this;
+}
+T v() const {
+  return value_;
+}
+SerialNumber& operator+=(const uint64_t& n) {
+  if ((n < 0) || (n > (space() - 1)))
+throw std::out_of_range("Invalid addition value");
+  value_ = (value_ + n) % max();
+  return *this;
+}
+friend SerialNumber operator+(SerialNumber m, const uint64_t& n) {
+  m += n;
+  return m;
+}
+// prefix ++
+SerialNumber& operator++() {
+  *this += 1;
+  return *this;
+}
+// postfix ++
+SerialNumber operator++(int) {
+  SerialNumber tmp(*this);
+  operator++();
+  return tmp;
+}
+bool operator==(const SerialNumber& rhs) {
+  return value_ == rhs.value_;
+}
+bool operator==(const uint32_t val) {
+  return value_ == val;
+}
+bool operator!=(const SerialNumber& rhs) {
+  return value_ != rhs.value_;
+}
+bool operator<(const SerialNumber& rhs) {
+  return (value_ < rhs.value_ && rhs.value_ - value_ < space()) || \
+(value_ > rhs.value_ && value_ - rhs.value_ > space());
+}
+bool operator<=(const SerialNumber& rhs) {
+  return *this == rhs || *this < rhs;
+}
+bool operator>(const SerialNumber& rhs) {
+  return (value_ < rhs.value_ && rhs.value_ - value_ > space()) || \
+(value_ > rhs.value_ && value_ - rhs.value_ < space());
+}
+bool operator>=(const SerialNumber& rhs) {
+  return *this == rhs || *this > rhs;
+}
+int64_t operator-(const SerialNumber& rhs) {
+  if (*this >= rhs) {
+if (value_ >= rhs.value_) {
+  return value_ - rhs.value_;
+} else {
+  return (value_ + max()) - rhs.value_;
+}
+  } else {
+if (value_ < rhs.value_) {
+  return value_ - rhs.value_;
+} else {
+  return value_ - (rhs.value_ + max());
+}
+  }
+}
+  private:
+T value_;
+uint64_t max() {
+  if (typeid(T) == typeid(uint64_t)) {
+return SNA32_MAX;
+  }
+  if (typeid(T) == typeid(uint32_t)) {
+return SNA16_MAX;
+  }
+  assert(0 && "Invalid data type");
+ 

Re: [devel] [PATCH 1/1] base: add serial number arithmetic (RFC1982) [#3074]

2020-02-16 Thread Thuan Tran
Hi Vu,

Thanks, I will update and send out new version.
See my replies inline.

Best Regards,
ThuanTr

From: Nguyen Minh Vu 
Sent: Monday, February 17, 2020 12:29 PM
To: Thuan Tran ; Minh Hon Chau 
; Thang Duc Nguyen ; 
Gary Lee 
Cc: opensaf-devel@lists.sourceforge.net
Subject: Re: [PATCH 1/1] base: add serial number arithmetic (RFC1982) [#3074]

Hi Thuan,

Thanks. See my responses inline.

Regards, Vu
On 2/14/20 11:48 AM, Thuan Tran wrote:
Hi Vu,

Thanks for comments. Please check my replies inline.

Best Regards,
ThuanTr

From: Nguyen Minh Vu 

Sent: Thursday, February 13, 2020 5:50 PM
To: Thuan Tran ; 
Minh Hon Chau ; 
Thang Duc Nguyen 
; Gary Lee 

Cc: 
opensaf-devel@lists.sourceforge.net
Subject: Re: [PATCH 1/1] base: add serial number arithmetic (RFC1982) [#3074]

Hi Thuan,

Ack with comments inline.

Regards, Vu
On 2/12/20 5:36 PM, thuan.tran wrote:

- Adapt MDS with this SNA implementation.

---

 src/base/Makefile.am |   6 +-

 src/base/sna.h   | 136 +++

 src/base/tests/sna_test.cc   | 117 ++

 src/mds/mds_tipc_fctrl_intf.cc   |   2 +-

 src/mds/mds_tipc_fctrl_portid.cc |  17 ++--

 src/mds/mds_tipc_fctrl_portid.h  |  64 +--

 6 files changed, 267 insertions(+), 75 deletions(-)

 create mode 100644 src/base/sna.h

 create mode 100644 src/base/tests/sna_test.cc



diff --git a/src/base/Makefile.am b/src/base/Makefile.am

index 025fb86a2..5082175cf 100644

--- a/src/base/Makefile.am

+++ b/src/base/Makefile.am

@@ -173,7 +173,8 @@ noinst_HEADERS += \

  src/base/unix_client_socket.h \

  src/base/unix_server_socket.h \

  src/base/unix_socket.h \

- src/base/usrbuf.h

+ src/base/usrbuf.h \

+ src/base/sna.h



 TESTS += bin/testleap bin/libbase_test bin/core_common_test



@@ -237,7 +238,8 @@ bin_libbase_test_SOURCES = \

  src/base/tests/time_compare_test.cc \

  src/base/tests/time_convert_test.cc \

  src/base/tests/time_subtract_test.cc \

- src/base/tests/unix_socket_test.cc

+ src/base/tests/unix_socket_test.cc \

+ src/base/tests/sna_test.cc



 bin_libbase_test_LDADD = \

  $(GTEST_DIR)/lib/libgtest.la \

diff --git a/src/base/sna.h b/src/base/sna.h

new file mode 100644

index 0..fee6627bb

--- /dev/null

+++ b/src/base/sna.h

@@ -0,0 +1,136 @@

+/*  -*- OpenSAF  -*-

+ *

+ * Copyright Ericsson AB 2020 - All Rights Reserved.

+ *

+ * This program is distributed in the hope that it will be useful, but

+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY

+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed

+ * under the GNU Lesser General Public License Version 2.1, February 1999.

+ * The complete license can be accessed from the following location:

+ * http://opensource.org/licenses/lgpl-license.php

+ * See the Copying file included with the OpenSAF distribution for full

+ * licensing terms.

+ *

+ * Reference: Serial Number Arithmetic from RFC1982

+ *

+ */

+

+#ifndef BASE_SNA_H_

+#define BASE_SNA_H_

+

+#include 

+#include 

+

+#define SNA16_MAX 65536  // 2^16

+#define SNA16_SPACE 32768  // (2^16)/2

+#define SNA32_MAX 4294967296  // 2^32

+#define SNA32_SPACE 2147483648  // (2^32)/2
[Vu] can use:
#define SNA16_MAX (1 << 16)
#define SNA32_MAX (1 << 32)

SPACE ones probably are not necessary. See my comment for space() method below.

[Thuan] Is there any benefit with 1 << 16 or 32? I think define a clear value 
is better.
[Vu] the benefit is you won't need to add the comment e.g. // 2^16
[Thuan] OK, change as your suggestion. Btw, I will change define macro SPACE 
(MAX/2).
About space(), it is intended because I don’t want CPU calculate every time 
refer to it.



+

+template 

+class _sna {
[Vu] How about `class SerialNumber {}`
[Thuan] OK, I will change the class name.



+ private:
[Vu] Declaration order should start with a public: section, followed by 
protected:, then private:
[Thuan] OK, will change order.



+  T i;
[Vu] Should use a descriptive name. e.g:
T value_ {0};
[Thuan] OK, will update the name.



+  uint64_t max() {

+if (typeid(T) == typeid(uint64_t)) {

+  return SNA32_MAX;

+}

+if (typeid(T) == typeid(uint32_t)) {

+  return SNA16_MAX;

+}



+throw std::out_of_range("Invalid type");
[Vu] OpenSAF code does not handle exception. Should use assertion instead.
e.g: assert(0 && "Invalid data type");
[Thuan] I throw to do basic test, if assert() then cannot test the case.
Btw, I think throw exception without try catch will also end with terminate?
[Vu] I think so; and if you you do tests on Seq16, Seq32, you probably won't 
reach exceptions.
[Thuan] OK, change to assert() inside max()/space(), but keep other “throw” is 
still kept for test.



+  }



+  

Re: [devel] [PATCH 1/1] base: add serial number arithmetic (RFC1982) [#3074]

2020-02-16 Thread Nguyen Minh Vu

Hi Thuan,

Thanks. See my responses inline.

Regards, Vu

On 2/14/20 11:48 AM, Thuan Tran wrote:


Hi Vu,

Thanks for comments. Please check my replies inline.

*Best Regards,*

*ThuanTr***

*From:* Nguyen Minh Vu 
*Sent:* Thursday, February 13, 2020 5:50 PM
*To:* Thuan Tran ; Minh Hon Chau 
; Thang Duc Nguyen 
; Gary Lee 

*Cc:* opensaf-devel@lists.sourceforge.net
*Subject:* Re: [PATCH 1/1] base: add serial number arithmetic 
(RFC1982) [#3074]


Hi Thuan,

Ack with comments inline.

Regards, Vu

On 2/12/20 5:36 PM, thuan.tran wrote:

- Adapt MDS with this SNA implementation.

---

  src/base/Makefile.am |   6 +-

  src/base/sna.h   | 136 +++

  src/base/tests/sna_test.cc   | 117 ++

  src/mds/mds_tipc_fctrl_intf.cc   |   2 +-

  src/mds/mds_tipc_fctrl_portid.cc |  17 ++--

  src/mds/mds_tipc_fctrl_portid.h  |  64 +--

  6 files changed, 267 insertions(+), 75 deletions(-)

  create mode 100644 src/base/sna.h

  create mode 100644 src/base/tests/sna_test.cc

diff --git a/src/base/Makefile.am b/src/base/Makefile.am

index 025fb86a2..5082175cf 100644

--- a/src/base/Makefile.am

+++ b/src/base/Makefile.am

@@ -173,7 +173,8 @@ noinst_HEADERS += \

   src/base/unix_client_socket.h \

   src/base/unix_server_socket.h \

   src/base/unix_socket.h \

- src/base/usrbuf.h

+ src/base/usrbuf.h \

+ src/base/sna.h

  


  TESTS += bin/testleap bin/libbase_test bin/core_common_test

  


@@ -237,7 +238,8 @@ bin_libbase_test_SOURCES = \

   src/base/tests/time_compare_test.cc \

   src/base/tests/time_convert_test.cc \

   src/base/tests/time_subtract_test.cc \

- src/base/tests/unix_socket_test.cc

+ src/base/tests/unix_socket_test.cc \

+ src/base/tests/sna_test.cc

  


  bin_libbase_test_LDADD = \

   $(GTEST_DIR)/lib/libgtest.la \

diff --git a/src/base/sna.h b/src/base/sna.h

new file mode 100644

index 0..fee6627bb

--- /dev/null

+++ b/src/base/sna.h

@@ -0,0 +1,136 @@

+/*  -*- OpenSAF  -*-

+ *

+ * Copyright Ericsson AB 2020 - All Rights Reserved.

+ *

+ * This program is distributed in the hope that it will be useful, but

+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
MERCHANTABILITY

+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed

+ * under the GNU Lesser General Public License Version 2.1, February 1999.

+ * The complete license can be accessed from the following location:

+ *http://opensource.org/licenses/lgpl-license.php

+ * See the Copying file included with the OpenSAF distribution for full

+ * licensing terms.

+ *

+ * Reference: Serial Number Arithmetic from RFC1982

+ *

+ */

+

+#ifndef BASE_SNA_H_

+#define BASE_SNA_H_

+

+#include 

+#include 

+

+#define SNA16_MAX 65536  // 2^16

+#define SNA16_SPACE 32768  // (2^16)/2

+#define SNA32_MAX 4294967296  // 2^32

+#define SNA32_SPACE 2147483648  // (2^32)/2

[Vu] can use:
#define SNA16_MAX (1 << 16)
#define SNA32_MAX (1 << 32)

SPACE ones probably are not necessary. See my comment for space() 
method below.


[Thuan] Is there any benefit with 1 << 16 or 32? I think define a 
clear value is better.



[Vu] the benefit is you won't need to add the comment e.g. // 2^16


About space(), it is intended because I don’t want CPU calculate every 
time refer to it.


+

+template 

+class _sna {

[Vu] How about `class SerialNumber {}`
[Thuan] OK, I will change the class name.

+ private:

[Vu] Declaration order should start with a |public:| section, followed 
by |protected:|, then |private:|


[Thuan] OK, will change order.

+  T i;

[Vu] Should use a descriptive name. e.g:
T value_ {0};
[Thuan] OK, will update the name.

+  uint64_t max() {

+    if (typeid(T) == typeid(uint64_t)) {

+  return SNA32_MAX;

+    }

+    if (typeid(T) == typeid(uint32_t)) {

+  return SNA16_MAX;

+    }

+    throw std::out_of_range("Invalid type");

[Vu] OpenSAF code does not handle exception. Should use assertion instead.
e.g: assert(0 && "Invalid data type");
[Thuan] I throw to do basic test, if assert() then cannot test the case.

Btw, I think throw exception without try catch will also end with 
terminate?


[Vu] I think so; and if you you do tests on Seq16, Seq32, you probably 
won't reach exceptions.


+  }

+  uint64_t space() {

+    if (typeid(T) == typeid(uint64_t)) {

+  return SNA32_SPACE;

+    }

+    if (typeid(T) == typeid(uint32_t)) {

+  return SNA16_SPACE;

+    }

+    throw std::out_of_range("Invalid type");

[Vu] uint64_t space() { return max()/2;}
[Thuan] As explain above, I don’t want calculate every time refer it.


Re: [devel] [PATCH 1/1] base: add serial number arithmetic (RFC1982) [#3074]

2020-02-13 Thread Thuan Tran
Hi Vu,

Thanks for comments. Please check my replies inline.

Best Regards,
ThuanTr

From: Nguyen Minh Vu 
Sent: Thursday, February 13, 2020 5:50 PM
To: Thuan Tran ; Minh Hon Chau 
; Thang Duc Nguyen ; 
Gary Lee 
Cc: opensaf-devel@lists.sourceforge.net
Subject: Re: [PATCH 1/1] base: add serial number arithmetic (RFC1982) [#3074]

Hi Thuan,

Ack with comments inline.

Regards, Vu
On 2/12/20 5:36 PM, thuan.tran wrote:

- Adapt MDS with this SNA implementation.

---

 src/base/Makefile.am |   6 +-

 src/base/sna.h   | 136 +++

 src/base/tests/sna_test.cc   | 117 ++

 src/mds/mds_tipc_fctrl_intf.cc   |   2 +-

 src/mds/mds_tipc_fctrl_portid.cc |  17 ++--

 src/mds/mds_tipc_fctrl_portid.h  |  64 +--

 6 files changed, 267 insertions(+), 75 deletions(-)

 create mode 100644 src/base/sna.h

 create mode 100644 src/base/tests/sna_test.cc



diff --git a/src/base/Makefile.am b/src/base/Makefile.am

index 025fb86a2..5082175cf 100644

--- a/src/base/Makefile.am

+++ b/src/base/Makefile.am

@@ -173,7 +173,8 @@ noinst_HEADERS += \

  src/base/unix_client_socket.h \

  src/base/unix_server_socket.h \

  src/base/unix_socket.h \

- src/base/usrbuf.h

+ src/base/usrbuf.h \

+ src/base/sna.h



 TESTS += bin/testleap bin/libbase_test bin/core_common_test



@@ -237,7 +238,8 @@ bin_libbase_test_SOURCES = \

  src/base/tests/time_compare_test.cc \

  src/base/tests/time_convert_test.cc \

  src/base/tests/time_subtract_test.cc \

- src/base/tests/unix_socket_test.cc

+ src/base/tests/unix_socket_test.cc \

+ src/base/tests/sna_test.cc



 bin_libbase_test_LDADD = \

  $(GTEST_DIR)/lib/libgtest.la \

diff --git a/src/base/sna.h b/src/base/sna.h

new file mode 100644

index 0..fee6627bb

--- /dev/null

+++ b/src/base/sna.h

@@ -0,0 +1,136 @@

+/*  -*- OpenSAF  -*-

+ *

+ * Copyright Ericsson AB 2020 - All Rights Reserved.

+ *

+ * This program is distributed in the hope that it will be useful, but

+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY

+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed

+ * under the GNU Lesser General Public License Version 2.1, February 1999.

+ * The complete license can be accessed from the following location:

+ * http://opensource.org/licenses/lgpl-license.php

+ * See the Copying file included with the OpenSAF distribution for full

+ * licensing terms.

+ *

+ * Reference: Serial Number Arithmetic from RFC1982

+ *

+ */

+

+#ifndef BASE_SNA_H_

+#define BASE_SNA_H_

+

+#include 

+#include 

+

+#define SNA16_MAX 65536  // 2^16

+#define SNA16_SPACE 32768  // (2^16)/2

+#define SNA32_MAX 4294967296  // 2^32

+#define SNA32_SPACE 2147483648  // (2^32)/2
[Vu] can use:
#define SNA16_MAX (1 << 16)
#define SNA32_MAX (1 << 32)

SPACE ones probably are not necessary. See my comment for space() method below.

[Thuan] Is there any benefit with 1 << 16 or 32? I think define a clear value 
is better.
About space(), it is intended because I don’t want CPU calculate every time 
refer to it.



+

+template 

+class _sna {
[Vu] How about `class SerialNumber {}`
[Thuan] OK, I will change the class name.



+ private:
[Vu] Declaration order should start with a public: section, followed by 
protected:, then private:
[Thuan] OK, will change order.



+  T i;
[Vu] Should use a descriptive name. e.g:
T value_ {0};
[Thuan] OK, will update the name.



+  uint64_t max() {

+if (typeid(T) == typeid(uint64_t)) {

+  return SNA32_MAX;

+}

+if (typeid(T) == typeid(uint32_t)) {

+  return SNA16_MAX;

+}



+throw std::out_of_range("Invalid type");
[Vu] OpenSAF code does not handle exception. Should use assertion instead.
e.g: assert(0 && "Invalid data type");
[Thuan] I throw to do basic test, if assert() then cannot test the case.
Btw, I think throw exception without try catch will also end with terminate?



+  }



+  uint64_t space() {

+if (typeid(T) == typeid(uint64_t)) {

+  return SNA32_SPACE;

+}

+if (typeid(T) == typeid(uint32_t)) {

+  return SNA16_SPACE;

+}

+throw std::out_of_range("Invalid type");
[Vu] uint64_t space() { return max()/2;}
[Thuan] As explain above, I don’t want calculate every time refer it.



+  }

+

+ public:

+  _sna(): i(0) {}

+  _sna(const _sna ) {



+i = t.i;

+  }

+  explicit _sna(const uint64_t ) {

+if ((n < 0) || (n > (max()-1)))

+  throw std::out_of_range("Invalid initial value");
[Vu] Use assert() instead of throwing exception.
[Thuan] Same above.



+i = n;

+  }

+  _sna& operator=(const _sna ) {

+// check for self-assignment

+if ( == this)

+  return *this;

+i = t.i;

+return *this;

+  }

+  T v() const {

+return i;

+  }

+  _sna& operator+=(const uint64_t& n) {

+if ((n < 0) || (n > (space() - 1)))

+  throw std::out_of_range("Invalid addition value");

+i = (i + n) % max();

+return 

Re: [devel] [PATCH 1/1] base: add serial number arithmetic (RFC1982) [#3074]

2020-02-13 Thread Nguyen Minh Vu

Hi Thuan,

Ack with comments inline.

Regards, Vu

On 2/12/20 5:36 PM, thuan.tran wrote:

- Adapt MDS with this SNA implementation.
---
  src/base/Makefile.am |   6 +-
  src/base/sna.h   | 136 +++
  src/base/tests/sna_test.cc   | 117 ++
  src/mds/mds_tipc_fctrl_intf.cc   |   2 +-
  src/mds/mds_tipc_fctrl_portid.cc |  17 ++--
  src/mds/mds_tipc_fctrl_portid.h  |  64 +--
  6 files changed, 267 insertions(+), 75 deletions(-)
  create mode 100644 src/base/sna.h
  create mode 100644 src/base/tests/sna_test.cc

diff --git a/src/base/Makefile.am b/src/base/Makefile.am
index 025fb86a2..5082175cf 100644
--- a/src/base/Makefile.am
+++ b/src/base/Makefile.am
@@ -173,7 +173,8 @@ noinst_HEADERS += \
src/base/unix_client_socket.h \
src/base/unix_server_socket.h \
src/base/unix_socket.h \
-   src/base/usrbuf.h
+   src/base/usrbuf.h \
+   src/base/sna.h
  
  TESTS += bin/testleap bin/libbase_test bin/core_common_test
  
@@ -237,7 +238,8 @@ bin_libbase_test_SOURCES = \

src/base/tests/time_compare_test.cc \
src/base/tests/time_convert_test.cc \
src/base/tests/time_subtract_test.cc \
-   src/base/tests/unix_socket_test.cc
+   src/base/tests/unix_socket_test.cc \
+   src/base/tests/sna_test.cc
  
  bin_libbase_test_LDADD = \

$(GTEST_DIR)/lib/libgtest.la \
diff --git a/src/base/sna.h b/src/base/sna.h
new file mode 100644
index 0..fee6627bb
--- /dev/null
+++ b/src/base/sna.h
@@ -0,0 +1,136 @@
+/*  -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2020 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Reference: Serial Number Arithmetic from RFC1982
+ *
+ */
+
+#ifndef BASE_SNA_H_
+#define BASE_SNA_H_
+
+#include 
+#include 
+
+#define SNA16_MAX 65536  // 2^16
+#define SNA16_SPACE 32768  // (2^16)/2
+#define SNA32_MAX 4294967296  // 2^32
+#define SNA32_SPACE 2147483648  // (2^32)/2

[Vu] can use:
#define SNA16_MAX (1 << 16)
#define SNA32_MAX (1 << 32)

SPACE ones probably are not necessary. See my comment for space() method 
below.



+
+template 
+class _sna {

[Vu] How about `class SerialNumber {}`

+ private:
[Vu] Declaration order should start with a |public:| section, followed 
by |protected:|, then |private:|

+  T i;

[Vu] Should use a descriptive name. e.g:
T value_ {0};

+  uint64_t max() {
+if (typeid(T) == typeid(uint64_t)) {
+  return SNA32_MAX;
+}
+if (typeid(T) == typeid(uint32_t)) {
+  return SNA16_MAX;
+}
+throw std::out_of_range("Invalid type");

[Vu] OpenSAF code does not handle exception. Should use assertion instead.
e.g: assert(0 && "Invalid data type");

+  }
+  uint64_t space() {
+if (typeid(T) == typeid(uint64_t)) {
+  return SNA32_SPACE;
+}
+if (typeid(T) == typeid(uint32_t)) {
+  return SNA16_SPACE;
+}
+throw std::out_of_range("Invalid type");

[Vu] uint64_t space() { return max()/2;}

+  }
+
+ public:
+  _sna(): i(0) {}
+  _sna(const _sna ) {
+i = t.i;
+  }
+  explicit _sna(const uint64_t ) {
+if ((n < 0) || (n > (max()-1)))
+  throw std::out_of_range("Invalid initial value");

[Vu] Use assert() instead of throwing exception.

+i = n;
+  }
+  _sna& operator=(const _sna ) {
+// check for self-assignment
+if ( == this)
+  return *this;
+i = t.i;
+return *this;
+  }
+  T v() const {
+return i;
+  }
+  _sna& operator+=(const uint64_t& n) {
+if ((n < 0) || (n > (space() - 1)))
+  throw std::out_of_range("Invalid addition value");
+i = (i + n) % max();
+return *this;
+  }
+  friend _sna operator+(_sna m, const uint64_t& n) {

[Vu] my suggestion:
friend _sna operator+(const _sna& m, ...) {
    _sna s{m};
 s += n;
    return s;
}

+m += n;
+return m;
+  }
+  // prefix ++
+  _sna& operator++() {
+*this += 1;
+return *this;
+  }
+  // postfix ++
+  _sna operator++(int) {
+_sna tmp(*this);
+operator++();
+return tmp;
+  }
+  bool operator==(const _sna& rhs) {
+return i == rhs.i;
+  }
+  bool operator==(const uint32_t val) {
+return i == val;
+  }
+  bool operator!=(const _sna& rhs) {
+return i != rhs.i;
+  }
+  bool operator<(const _sna& rhs) {
+return (i < rhs.i && rhs.i - i < space()) || \
+   (i > rhs.i && i - rhs.i > space());
+  }
+  bool operator<=(const _sna& rhs) {
+return *this == rhs || *this < rhs;
+  }
+  bool operator>(const _sna& rhs) {
+return (i 

[devel] [PATCH 1/1] base: add serial number arithmetic (RFC1982) [#3074]

2020-02-12 Thread thuan.tran
- Adapt MDS with this SNA implementation.
---
 src/base/Makefile.am |   6 +-
 src/base/sna.h   | 136 +++
 src/base/tests/sna_test.cc   | 117 ++
 src/mds/mds_tipc_fctrl_intf.cc   |   2 +-
 src/mds/mds_tipc_fctrl_portid.cc |  17 ++--
 src/mds/mds_tipc_fctrl_portid.h  |  64 +--
 6 files changed, 267 insertions(+), 75 deletions(-)
 create mode 100644 src/base/sna.h
 create mode 100644 src/base/tests/sna_test.cc

diff --git a/src/base/Makefile.am b/src/base/Makefile.am
index 025fb86a2..5082175cf 100644
--- a/src/base/Makefile.am
+++ b/src/base/Makefile.am
@@ -173,7 +173,8 @@ noinst_HEADERS += \
src/base/unix_client_socket.h \
src/base/unix_server_socket.h \
src/base/unix_socket.h \
-   src/base/usrbuf.h
+   src/base/usrbuf.h \
+   src/base/sna.h
 
 TESTS += bin/testleap bin/libbase_test bin/core_common_test
 
@@ -237,7 +238,8 @@ bin_libbase_test_SOURCES = \
src/base/tests/time_compare_test.cc \
src/base/tests/time_convert_test.cc \
src/base/tests/time_subtract_test.cc \
-   src/base/tests/unix_socket_test.cc
+   src/base/tests/unix_socket_test.cc \
+   src/base/tests/sna_test.cc
 
 bin_libbase_test_LDADD = \
$(GTEST_DIR)/lib/libgtest.la \
diff --git a/src/base/sna.h b/src/base/sna.h
new file mode 100644
index 0..fee6627bb
--- /dev/null
+++ b/src/base/sna.h
@@ -0,0 +1,136 @@
+/*  -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2020 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Reference: Serial Number Arithmetic from RFC1982
+ *
+ */
+
+#ifndef BASE_SNA_H_
+#define BASE_SNA_H_
+
+#include 
+#include 
+
+#define SNA16_MAX 65536  // 2^16
+#define SNA16_SPACE 32768  // (2^16)/2
+#define SNA32_MAX 4294967296  // 2^32
+#define SNA32_SPACE 2147483648  // (2^32)/2
+
+template 
+class _sna {
+ private:
+  T i;
+  uint64_t max() {
+if (typeid(T) == typeid(uint64_t)) {
+  return SNA32_MAX;
+}
+if (typeid(T) == typeid(uint32_t)) {
+  return SNA16_MAX;
+}
+throw std::out_of_range("Invalid type");
+  }
+  uint64_t space() {
+if (typeid(T) == typeid(uint64_t)) {
+  return SNA32_SPACE;
+}
+if (typeid(T) == typeid(uint32_t)) {
+  return SNA16_SPACE;
+}
+throw std::out_of_range("Invalid type");
+  }
+
+ public:
+  _sna(): i(0) {}
+  _sna(const _sna ) {
+i = t.i;
+  }
+  explicit _sna(const uint64_t ) {
+if ((n < 0) || (n > (max()-1)))
+  throw std::out_of_range("Invalid initial value");
+i = n;
+  }
+  _sna& operator=(const _sna ) {
+// check for self-assignment
+if ( == this)
+  return *this;
+i = t.i;
+return *this;
+  }
+  T v() const {
+return i;
+  }
+  _sna& operator+=(const uint64_t& n) {
+if ((n < 0) || (n > (space() - 1)))
+  throw std::out_of_range("Invalid addition value");
+i = (i + n) % max();
+return *this;
+  }
+  friend _sna operator+(_sna m, const uint64_t& n) {
+m += n;
+return m;
+  }
+  // prefix ++
+  _sna& operator++() {
+*this += 1;
+return *this;
+  }
+  // postfix ++
+  _sna operator++(int) {
+_sna tmp(*this);
+operator++();
+return tmp;
+  }
+  bool operator==(const _sna& rhs) {
+return i == rhs.i;
+  }
+  bool operator==(const uint32_t val) {
+return i == val;
+  }
+  bool operator!=(const _sna& rhs) {
+return i != rhs.i;
+  }
+  bool operator<(const _sna& rhs) {
+return (i < rhs.i && rhs.i - i < space()) || \
+   (i > rhs.i && i - rhs.i > space());
+  }
+  bool operator<=(const _sna& rhs) {
+return *this == rhs || *this < rhs;
+  }
+  bool operator>(const _sna& rhs) {
+return (i < rhs.i && rhs.i - i > space()) || \
+   (i > rhs.i && i - rhs.i < space());
+  }
+  bool operator>=(const _sna& rhs) {
+return *this == rhs || *this > rhs;
+  }
+  int64_t operator-(const _sna& rhs) {
+if (*this >= rhs) {
+  if (i >= rhs.v()) {
+return i - rhs.v();
+  } else {
+return (i + max()) - rhs.v();
+  }
+} else {
+  if (i < rhs.v()) {
+return i - rhs.v();
+  } else {
+return i - (rhs.v() + max());
+  }
+}
+  }
+};
+
+typedef _sna Seq16;
+typedef _sna Seq32;
+
+#endif  // BASE_SNA_H_
diff --git a/src/base/tests/sna_test.cc b/src/base/tests/sna_test.cc
new file mode 100644
index 0..b3d2d014c
--- /dev/null
+++ b/src/base/tests/sna_test.cc
@@ -0,0 +1,117 @@
+/*  -*- OpenSAF  -*-

[devel] [PATCH 1/1] base: add serial number arithmetic (RFC1982) [#3074]

2019-10-23 Thread thuan.tran
- Adapt MDS with this SNA implementation.
---
 src/base/Makefile.am |   6 +-
 src/base/sna.h   | 126 +++
 src/base/tests/sna_test.cc   | 117 
 src/mds/mds_tipc_fctrl_intf.cc   |   3 +-
 src/mds/mds_tipc_fctrl_portid.cc |  45 ++-
 src/mds/mds_tipc_fctrl_portid.h  |  79 +++
 6 files changed, 280 insertions(+), 96 deletions(-)
 create mode 100644 src/base/sna.h
 create mode 100644 src/base/tests/sna_test.cc

diff --git a/src/base/Makefile.am b/src/base/Makefile.am
index 025fb86a2..5082175cf 100644
--- a/src/base/Makefile.am
+++ b/src/base/Makefile.am
@@ -173,7 +173,8 @@ noinst_HEADERS += \
src/base/unix_client_socket.h \
src/base/unix_server_socket.h \
src/base/unix_socket.h \
-   src/base/usrbuf.h
+   src/base/usrbuf.h \
+   src/base/sna.h
 
 TESTS += bin/testleap bin/libbase_test bin/core_common_test
 
@@ -237,7 +238,8 @@ bin_libbase_test_SOURCES = \
src/base/tests/time_compare_test.cc \
src/base/tests/time_convert_test.cc \
src/base/tests/time_subtract_test.cc \
-   src/base/tests/unix_socket_test.cc
+   src/base/tests/unix_socket_test.cc \
+   src/base/tests/sna_test.cc
 
 bin_libbase_test_LDADD = \
$(GTEST_DIR)/lib/libgtest.la \
diff --git a/src/base/sna.h b/src/base/sna.h
new file mode 100644
index 0..b231fb134
--- /dev/null
+++ b/src/base/sna.h
@@ -0,0 +1,126 @@
+/*  -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2019 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Reference: Serial Number Arithmetic from RFC1982
+ *
+ */
+
+#ifndef BASE_SNA_H_
+#define BASE_SNA_H_
+
+#include 
+#include 
+
+#define MAX_16BITS 65536  // 2^16
+#define MAX_32BITS 4294967296  // 2^32
+
+template 
+class _sna {
+ private:
+  T i;
+  uint64_t max() {
+if (typeid(T) == typeid(uint64_t)) {
+  return MAX_32BITS;
+} else if (typeid(T) == typeid(uint32_t)) {
+  return MAX_16BITS;
+} else {
+  printf("Type:%s\n", typeid(T).name());
+  throw std::out_of_range("Invalid type");
+}
+  }
+
+ public:
+  _sna(): i(0) {}
+  _sna(const _sna ) {
+i = t.i;
+  }
+  explicit _sna(const uint64_t ) {
+if ((n < 0) || (n > (max()-1)))
+  throw std::out_of_range("SNA assign with invalid value");
+i = n;
+  }
+  _sna& operator=(const _sna ) {
+// check for self-assignment
+if ( == this)
+  return *this;
+i = t.i;
+return *this;
+  }
+  T v() const {
+return i;
+  }
+  _sna& operator+=(const uint64_t& n) {
+if ((n < 0) || (n > (max()/2 - 1)))
+  throw std::out_of_range("SNA received invalid addition value");
+i = (i + n) % max();
+return *this;
+  }
+  friend _sna operator+(_sna m, const uint64_t& n) {
+m += n;
+return m;
+  }
+  // prefix ++
+  _sna& operator++() {
+*this += 1;
+return *this;
+  }
+  // postfix ++
+  _sna operator++(int) {
+_sna tmp(*this);
+operator++();
+return tmp;
+  }
+  bool operator==(const _sna& rhs) {
+return i == rhs.i;
+  }
+  bool operator==(const uint32_t val) {
+return i == val;
+  }
+  bool operator!=(const _sna& rhs) {
+return i != rhs.i;
+  }
+  bool operator<(const _sna& rhs) {
+return (i < rhs.i && rhs.i - i < max()/2) || \
+   (i > rhs.i && i - rhs.i > max()/2);
+  }
+  bool operator>=(const _sna& rhs) {
+return !(*this < rhs);
+  }
+  bool operator>(const _sna& rhs) {
+return (i < rhs.i && rhs.i - i > max()/2) || \
+   (i > rhs.i && i - rhs.i < max()/2);
+  }
+  bool operator<=(const _sna& rhs) {
+return !(*this > rhs);
+  }
+  int64_t operator-(const _sna& rhs) {
+if (*this >= rhs) {
+  if (i >= rhs.v()) {
+return i - rhs.v();
+  } else {
+return (i + max()) - rhs.v();
+  }
+} else {
+  if (i < rhs.v()) {
+return i - rhs.v();
+  } else {
+return i - (rhs.v() + max());
+  }
+}
+  }
+};
+
+typedef _sna sna16_t;
+typedef _sna sna32_t;
+
+#endif  // BASE_SNA_H_
diff --git a/src/base/tests/sna_test.cc b/src/base/tests/sna_test.cc
new file mode 100644
index 0..4b7eb83e3
--- /dev/null
+++ b/src/base/tests/sna_test.cc
@@ -0,0 +1,117 @@
+/*  -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2019 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR 

[devel] [PATCH 1/1] base: add serial number arithmetic (RFC1982) [#3074]

2019-10-21 Thread thuan.tran
- Adapt MDS with this SNA implementation.
---
 src/base/Makefile.am |   6 +-
 src/base/sna.h   | 126 +++
 src/base/tests/sna_test.cc   | 117 
 src/mds/mds_tipc_fctrl_portid.cc |  45 ++-
 src/mds/mds_tipc_fctrl_portid.h  |  79 +++
 5 files changed, 278 insertions(+), 95 deletions(-)
 create mode 100644 src/base/sna.h
 create mode 100644 src/base/tests/sna_test.cc

diff --git a/src/base/Makefile.am b/src/base/Makefile.am
index 025fb86a2..5082175cf 100644
--- a/src/base/Makefile.am
+++ b/src/base/Makefile.am
@@ -173,7 +173,8 @@ noinst_HEADERS += \
src/base/unix_client_socket.h \
src/base/unix_server_socket.h \
src/base/unix_socket.h \
-   src/base/usrbuf.h
+   src/base/usrbuf.h \
+   src/base/sna.h
 
 TESTS += bin/testleap bin/libbase_test bin/core_common_test
 
@@ -237,7 +238,8 @@ bin_libbase_test_SOURCES = \
src/base/tests/time_compare_test.cc \
src/base/tests/time_convert_test.cc \
src/base/tests/time_subtract_test.cc \
-   src/base/tests/unix_socket_test.cc
+   src/base/tests/unix_socket_test.cc \
+   src/base/tests/sna_test.cc
 
 bin_libbase_test_LDADD = \
$(GTEST_DIR)/lib/libgtest.la \
diff --git a/src/base/sna.h b/src/base/sna.h
new file mode 100644
index 0..b231fb134
--- /dev/null
+++ b/src/base/sna.h
@@ -0,0 +1,126 @@
+/*  -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2019 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Reference: Serial Number Arithmetic from RFC1982
+ *
+ */
+
+#ifndef BASE_SNA_H_
+#define BASE_SNA_H_
+
+#include 
+#include 
+
+#define MAX_16BITS 65536  // 2^16
+#define MAX_32BITS 4294967296  // 2^32
+
+template 
+class _sna {
+ private:
+  T i;
+  uint64_t max() {
+if (typeid(T) == typeid(uint64_t)) {
+  return MAX_32BITS;
+} else if (typeid(T) == typeid(uint32_t)) {
+  return MAX_16BITS;
+} else {
+  printf("Type:%s\n", typeid(T).name());
+  throw std::out_of_range("Invalid type");
+}
+  }
+
+ public:
+  _sna(): i(0) {}
+  _sna(const _sna ) {
+i = t.i;
+  }
+  explicit _sna(const uint64_t ) {
+if ((n < 0) || (n > (max()-1)))
+  throw std::out_of_range("SNA assign with invalid value");
+i = n;
+  }
+  _sna& operator=(const _sna ) {
+// check for self-assignment
+if ( == this)
+  return *this;
+i = t.i;
+return *this;
+  }
+  T v() const {
+return i;
+  }
+  _sna& operator+=(const uint64_t& n) {
+if ((n < 0) || (n > (max()/2 - 1)))
+  throw std::out_of_range("SNA received invalid addition value");
+i = (i + n) % max();
+return *this;
+  }
+  friend _sna operator+(_sna m, const uint64_t& n) {
+m += n;
+return m;
+  }
+  // prefix ++
+  _sna& operator++() {
+*this += 1;
+return *this;
+  }
+  // postfix ++
+  _sna operator++(int) {
+_sna tmp(*this);
+operator++();
+return tmp;
+  }
+  bool operator==(const _sna& rhs) {
+return i == rhs.i;
+  }
+  bool operator==(const uint32_t val) {
+return i == val;
+  }
+  bool operator!=(const _sna& rhs) {
+return i != rhs.i;
+  }
+  bool operator<(const _sna& rhs) {
+return (i < rhs.i && rhs.i - i < max()/2) || \
+   (i > rhs.i && i - rhs.i > max()/2);
+  }
+  bool operator>=(const _sna& rhs) {
+return !(*this < rhs);
+  }
+  bool operator>(const _sna& rhs) {
+return (i < rhs.i && rhs.i - i > max()/2) || \
+   (i > rhs.i && i - rhs.i < max()/2);
+  }
+  bool operator<=(const _sna& rhs) {
+return !(*this > rhs);
+  }
+  int64_t operator-(const _sna& rhs) {
+if (*this >= rhs) {
+  if (i >= rhs.v()) {
+return i - rhs.v();
+  } else {
+return (i + max()) - rhs.v();
+  }
+} else {
+  if (i < rhs.v()) {
+return i - rhs.v();
+  } else {
+return i - (rhs.v() + max());
+  }
+}
+  }
+};
+
+typedef _sna sna16_t;
+typedef _sna sna32_t;
+
+#endif  // BASE_SNA_H_
diff --git a/src/base/tests/sna_test.cc b/src/base/tests/sna_test.cc
new file mode 100644
index 0..4b7eb83e3
--- /dev/null
+++ b/src/base/tests/sna_test.cc
@@ -0,0 +1,117 @@
+/*  -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2019 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program 

[devel] [PATCH 1/1] base: add serial number arithmetic (RFC1982) [#3074]

2019-09-30 Thread thuan.tran
- Adapt MDS with this SNA implementation.
---
 src/base/Makefile.am |   6 +-
 src/base/sna.h   | 123 +++
 src/base/tests/sna_test.cc   | 117 +
 src/mds/mds_tipc_fctrl_portid.cc |  39 +-
 src/mds/mds_tipc_fctrl_portid.h  |  76 ++-
 5 files changed, 270 insertions(+), 91 deletions(-)
 create mode 100644 src/base/sna.h
 create mode 100644 src/base/tests/sna_test.cc

diff --git a/src/base/Makefile.am b/src/base/Makefile.am
index 025fb86a2..5082175cf 100644
--- a/src/base/Makefile.am
+++ b/src/base/Makefile.am
@@ -173,7 +173,8 @@ noinst_HEADERS += \
src/base/unix_client_socket.h \
src/base/unix_server_socket.h \
src/base/unix_socket.h \
-   src/base/usrbuf.h
+   src/base/usrbuf.h \
+   src/base/sna.h
 
 TESTS += bin/testleap bin/libbase_test bin/core_common_test
 
@@ -237,7 +238,8 @@ bin_libbase_test_SOURCES = \
src/base/tests/time_compare_test.cc \
src/base/tests/time_convert_test.cc \
src/base/tests/time_subtract_test.cc \
-   src/base/tests/unix_socket_test.cc
+   src/base/tests/unix_socket_test.cc \
+   src/base/tests/sna_test.cc
 
 bin_libbase_test_LDADD = \
$(GTEST_DIR)/lib/libgtest.la \
diff --git a/src/base/sna.h b/src/base/sna.h
new file mode 100644
index 0..bd138293f
--- /dev/null
+++ b/src/base/sna.h
@@ -0,0 +1,123 @@
+/*  -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2019 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Reference: Serial Number Arithmetic from RFC1982
+ *
+ */
+
+#ifndef BASE_SNA_H_
+#define BASE_SNA_H_
+
+#include 
+#include 
+
+#define MAX_16BITS 65536  // 2^16
+#define MAX_32BITS 4294967296  // 2^32
+
+template 
+class _sna {
+ private:
+  T i;
+  uint64_t max() {
+if (typeid(T) == typeid(uint64_t)) {
+  return MAX_32BITS;
+} else if (typeid(T) == typeid(uint32_t)) {
+  return MAX_16BITS;
+} else {
+  printf("Type:%s\n", typeid(T).name());
+  throw std::out_of_range("Invalid type");
+}
+  }
+
+ public:
+  _sna(): i(0) {}
+  _sna(const _sna ) {
+i = t.i;
+  }
+  explicit _sna(const uint64_t ) {
+if ((n < 0) || (n > (max()-1)))
+  throw std::out_of_range("SNA assign with invalid value");
+i = n;
+  }
+  _sna& operator=(const _sna ) {
+// check for self-assignment
+if ( == this)
+  return *this;
+i = t.i;
+return *this;
+  }
+  T v() const {
+return i;
+  }
+  _sna& operator+=(const uint64_t& n) {
+if ((n < 0) || (n > (max()/2 - 1)))
+  throw std::out_of_range("SNA received invalid addition value");
+i = (i + n) % max();
+return *this;
+  }
+  friend _sna operator+(_sna m, const uint64_t& n) {
+m += n;
+return m;
+  }
+  // prefix ++
+  _sna& operator++() {
+*this += 1;
+return *this;
+  }
+  // postfix ++
+  _sna operator++(int) {
+_sna tmp(*this);
+operator++();
+return tmp;
+  }
+  bool operator==(const _sna& rhs) {
+return i == rhs.i;
+  }
+  bool operator!=(const _sna& rhs) {
+return i != rhs.i;
+  }
+  bool operator<(const _sna& rhs) {
+return (i < rhs.i && rhs.i - i < max()/2) || \
+   (i > rhs.i && i - rhs.i > max()/2);
+  }
+  bool operator>=(const _sna& rhs) {
+return !(*this < rhs);
+  }
+  bool operator>(const _sna& rhs) {
+return (i < rhs.i && rhs.i - i > max()/2) || \
+   (i > rhs.i && i - rhs.i < max()/2);
+  }
+  bool operator<=(const _sna& rhs) {
+return !(*this > rhs);
+  }
+  int32_t operator-(const _sna& rhs) {
+if (*this >= rhs) {
+  if (i >= rhs.v()) {
+return i - rhs.v();
+  } else {
+return (i + max()) - rhs.v();
+  }
+} else {
+  if (i < rhs.v()) {
+return i - rhs.v();
+  } else {
+return i - (rhs.v() + max());
+  }
+}
+  }
+};
+
+typedef _sna sna16_t;
+typedef _sna sna32_t;
+
+#endif  // BASE_SNA_H_
diff --git a/src/base/tests/sna_test.cc b/src/base/tests/sna_test.cc
new file mode 100644
index 0..4b7eb83e3
--- /dev/null
+++ b/src/base/tests/sna_test.cc
@@ -0,0 +1,117 @@
+/*  -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2019 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License 

[devel] [PATCH 1/1] base: add serial number arithmetic (RFC1982) [#3074]

2019-08-26 Thread thuan.tran
---
 src/base/Makefile.am   |   6 +-
 src/base/sna.h | 108 
 src/base/tests/sna_test.cc | 109 +
 3 files changed, 221 insertions(+), 2 deletions(-)
 create mode 100644 src/base/sna.h
 create mode 100644 src/base/tests/sna_test.cc

diff --git a/src/base/Makefile.am b/src/base/Makefile.am
index 025fb86a2..5082175cf 100644
--- a/src/base/Makefile.am
+++ b/src/base/Makefile.am
@@ -173,7 +173,8 @@ noinst_HEADERS += \
src/base/unix_client_socket.h \
src/base/unix_server_socket.h \
src/base/unix_socket.h \
-   src/base/usrbuf.h
+   src/base/usrbuf.h \
+   src/base/sna.h
 
 TESTS += bin/testleap bin/libbase_test bin/core_common_test
 
@@ -237,7 +238,8 @@ bin_libbase_test_SOURCES = \
src/base/tests/time_compare_test.cc \
src/base/tests/time_convert_test.cc \
src/base/tests/time_subtract_test.cc \
-   src/base/tests/unix_socket_test.cc
+   src/base/tests/unix_socket_test.cc \
+   src/base/tests/sna_test.cc
 
 bin_libbase_test_LDADD = \
$(GTEST_DIR)/lib/libgtest.la \
diff --git a/src/base/sna.h b/src/base/sna.h
new file mode 100644
index 0..8fc4da202
--- /dev/null
+++ b/src/base/sna.h
@@ -0,0 +1,108 @@
+/*  -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2019 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Reference: Serial Number Arithmetic from RFC1982
+ *
+ */
+
+#ifndef BASE_SNA_H_
+#define BASE_SNA_H_
+
+#include 
+#include 
+
+#define MAX_16BITS 65536 // 2^16
+#define MAX_32BITS 4294967296 // 2^32
+
+template 
+class _sna
+{
+  private:
+T i;
+uint64_t max() {
+  if (typeid(T) == typeid(uint64_t)) {
+return MAX_32BITS;
+  } else if (typeid(T) == typeid(uint32_t)) {
+return MAX_16BITS;
+  } else {
+printf("Type:%s\n", typeid(T).name());
+throw std::out_of_range("Invalid type");
+  }
+}
+  public:
+_sna(): i(0) {}
+_sna(const _sna ) {
+  i = t.i;
+}
+_sna(const uint32_t ) {
+  if ((n < 0) || (n > (max()-1)))
+throw std::out_of_range("SNA assign with invalid value");
+  i = n;
+}
+_sna& operator=(const _sna ) {
+  // check for self-assignment
+  if( == this)
+return *this;
+  i = t.i;
+  return *this;
+}
+uint64_t value() {
+  return i;
+}
+_sna& operator+=(const uint64_t& n) {
+  if ((n < 0) || (n > (max()/2 - 1)))
+throw std::out_of_range("SNA received invalid addition value");
+  i = (i + n) % max();
+  return *this;
+}
+friend _sna operator+(_sna m, const uint64_t& n) {
+  m += n;
+  return m;
+}
+// prefix ++
+_sna& operator++() {
+  *this += 1;
+  return *this;
+}
+// postfix ++
+_sna operator++(int) {
+  _sna tmp(*this);
+  operator++();
+  return tmp;
+}
+bool operator==(const _sna& rhs) {
+  return i == rhs.i;
+}
+bool operator!=(const _sna& rhs) {
+  return i != rhs.i;
+}
+bool operator<(const _sna& rhs) {
+  return (i < rhs.i && rhs.i - i < max()/2) || \
+ (i > rhs.i && i - rhs.i > max()/2);
+}
+bool operator>=(const _sna& rhs) {
+  return !(*this < rhs);
+}
+bool operator>(const _sna& rhs) {
+  return (i < rhs.i && rhs.i - i > max()/2) || \
+ (i > rhs.i && i - rhs.i < max()/2);
+}
+bool operator<=(const _sna& rhs) {
+  return !(*this > rhs);
+}
+};
+
+typedef _sna uint16_sna_t;
+typedef _sna uint32_sna_t;
+
+#endif  // BASE_SNA_H_
\ No newline at end of file
diff --git a/src/base/tests/sna_test.cc b/src/base/tests/sna_test.cc
new file mode 100644
index 0..9510dfbc0
--- /dev/null
+++ b/src/base/tests/sna_test.cc
@@ -0,0 +1,109 @@
+/*  -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2019 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Reference: Serial Number Arithmetic from RFC1982
+ *
+ */
+
+#include 

[devel] [PATCH 1/1] base: add serial number arithmetic (RFC1982) [#3074]

2019-08-26 Thread thuan.tran
---
 src/base/Makefile.am   |   6 +-
 src/base/sna.h | 108 
 src/base/tests/sna_test.cc | 109 +
 3 files changed, 221 insertions(+), 2 deletions(-)
 create mode 100755 src/base/sna.h
 create mode 100755 src/base/tests/sna_test.cc

diff --git a/src/base/Makefile.am b/src/base/Makefile.am
index 025fb86a2..5082175cf 100644
--- a/src/base/Makefile.am
+++ b/src/base/Makefile.am
@@ -173,7 +173,8 @@ noinst_HEADERS += \
src/base/unix_client_socket.h \
src/base/unix_server_socket.h \
src/base/unix_socket.h \
-   src/base/usrbuf.h
+   src/base/usrbuf.h \
+   src/base/sna.h
 
 TESTS += bin/testleap bin/libbase_test bin/core_common_test
 
@@ -237,7 +238,8 @@ bin_libbase_test_SOURCES = \
src/base/tests/time_compare_test.cc \
src/base/tests/time_convert_test.cc \
src/base/tests/time_subtract_test.cc \
-   src/base/tests/unix_socket_test.cc
+   src/base/tests/unix_socket_test.cc \
+   src/base/tests/sna_test.cc
 
 bin_libbase_test_LDADD = \
$(GTEST_DIR)/lib/libgtest.la \
diff --git a/src/base/sna.h b/src/base/sna.h
new file mode 100755
index 0..8fc4da202
--- /dev/null
+++ b/src/base/sna.h
@@ -0,0 +1,108 @@
+/*  -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2019 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Reference: Serial Number Arithmetic from RFC1982
+ *
+ */
+
+#ifndef BASE_SNA_H_
+#define BASE_SNA_H_
+
+#include 
+#include 
+
+#define MAX_16BITS 65536 // 2^16
+#define MAX_32BITS 4294967296 // 2^32
+
+template 
+class _sna
+{
+  private:
+T i;
+uint64_t max() {
+  if (typeid(T) == typeid(uint64_t)) {
+return MAX_32BITS;
+  } else if (typeid(T) == typeid(uint32_t)) {
+return MAX_16BITS;
+  } else {
+printf("Type:%s\n", typeid(T).name());
+throw std::out_of_range("Invalid type");
+  }
+}
+  public:
+_sna(): i(0) {}
+_sna(const _sna ) {
+  i = t.i;
+}
+_sna(const uint32_t ) {
+  if ((n < 0) || (n > (max()-1)))
+throw std::out_of_range("SNA assign with invalid value");
+  i = n;
+}
+_sna& operator=(const _sna ) {
+  // check for self-assignment
+  if( == this)
+return *this;
+  i = t.i;
+  return *this;
+}
+uint64_t value() {
+  return i;
+}
+_sna& operator+=(const uint64_t& n) {
+  if ((n < 0) || (n > (max()/2 - 1)))
+throw std::out_of_range("SNA received invalid addition value");
+  i = (i + n) % max();
+  return *this;
+}
+friend _sna operator+(_sna m, const uint64_t& n) {
+  m += n;
+  return m;
+}
+// prefix ++
+_sna& operator++() {
+  *this += 1;
+  return *this;
+}
+// postfix ++
+_sna operator++(int) {
+  _sna tmp(*this);
+  operator++();
+  return tmp;
+}
+bool operator==(const _sna& rhs) {
+  return i == rhs.i;
+}
+bool operator!=(const _sna& rhs) {
+  return i != rhs.i;
+}
+bool operator<(const _sna& rhs) {
+  return (i < rhs.i && rhs.i - i < max()/2) || \
+ (i > rhs.i && i - rhs.i > max()/2);
+}
+bool operator>=(const _sna& rhs) {
+  return !(*this < rhs);
+}
+bool operator>(const _sna& rhs) {
+  return (i < rhs.i && rhs.i - i > max()/2) || \
+ (i > rhs.i && i - rhs.i < max()/2);
+}
+bool operator<=(const _sna& rhs) {
+  return !(*this > rhs);
+}
+};
+
+typedef _sna uint16_sna_t;
+typedef _sna uint32_sna_t;
+
+#endif  // BASE_SNA_H_
\ No newline at end of file
diff --git a/src/base/tests/sna_test.cc b/src/base/tests/sna_test.cc
new file mode 100755
index 0..9510dfbc0
--- /dev/null
+++ b/src/base/tests/sna_test.cc
@@ -0,0 +1,109 @@
+/*  -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2019 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Reference: Serial Number Arithmetic from RFC1982
+ *
+ */
+
+#include