You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
396 lines
13 KiB
396 lines
13 KiB
/* |
|
* Copyright (C) 2015 Cenk Gündoğan <cnkgndgn@gmail.com> |
|
* |
|
* This file is subject to the terms and conditions of the GNU Lesser |
|
* General Public License v2.1. See the file LICENSE in the top level |
|
* directory for more details. |
|
*/ |
|
|
|
/** |
|
* @defgroup sys_seq Serial Number Arithmetic |
|
* @ingroup sys |
|
* @brief Serial Number Arithmetic (RFC 1982) |
|
* @{ |
|
* |
|
* @file |
|
* @brief Serial Number Arithmetic (RFC 1982) |
|
* @see <a href="https://tools.ietf.org/html/rfc1982"> |
|
* RFC 1982 - Serial Number Arithmetic |
|
* </a> |
|
* |
|
* @author Cenk Gündoğan <cnkgndgn@gmail.com> |
|
*/ |
|
|
|
#ifndef SEQ_H |
|
#define SEQ_H |
|
|
|
#include <stdint.h> |
|
#include <errno.h> |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
/** |
|
* @brief Maximum for the addition of a positive integer. X denotes the size of the space |
|
*/ |
|
#define SEQ_LIMIT(X) (X >> 1) |
|
|
|
/** |
|
* @brief A 8 bit sequence number |
|
*/ |
|
typedef uint8_t seq8_t; |
|
|
|
/** |
|
* @brief A 16 bit sequence number |
|
*/ |
|
typedef uint16_t seq16_t; |
|
|
|
/** |
|
* @brief A 32 bit sequence number |
|
*/ |
|
typedef uint32_t seq32_t; |
|
|
|
/** |
|
* @brief A 64 bit sequence number |
|
*/ |
|
typedef uint64_t seq64_t; |
|
|
|
/** |
|
* @brief Addition of a 8 bit sequence number @p s and a positive integer @p n |
|
* in the serial number @p space |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.1"> |
|
* 3.1. Addition |
|
* </a> |
|
* @param[in] s sequence number |
|
* @param[in] n positive integer in the range of [0 .. ((@p space / 2) - 1)] |
|
* @param[in] space serial number space must be a power of 2 minus 1 |
|
* @return s + n, if valid |
|
* @return s, if n is out of range |
|
*/ |
|
seq8_t seq8_adds(seq8_t s, uint8_t n, uint8_t space); |
|
|
|
/** |
|
* @brief Addition of a 8 bit sequence number @p s and a positive integer @p n |
|
* in the serial number space UINT8_MAX |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.1"> |
|
* 3.1. Addition |
|
* </a> |
|
* @param[in] s sequence number |
|
* @param[in] n positive integer in the range of [0 .. 127] |
|
* @return s + n, if valid |
|
* @return s, if n is out of range |
|
*/ |
|
static inline seq8_t seq8_add(seq8_t s, uint8_t n) |
|
{ |
|
return seq8_adds(s, n, UINT8_MAX); |
|
} |
|
|
|
/** |
|
* @brief Increment a sequence number @p s by 1 in the serial number @p space |
|
* @param[in] s sequence number |
|
* @param[in] space serial number space must be a power of 2 minus 1 |
|
* @return s + 1 |
|
*/ |
|
static inline seq8_t seq8_incs(seq8_t s, uint8_t space) |
|
{ |
|
return seq8_adds(s, 1, space); |
|
} |
|
|
|
/** |
|
* @brief Increment a sequence number @p s by 1 in the serial number space UINT8_MAX |
|
* @param[in] s sequence number |
|
* @return s + 1 |
|
*/ |
|
static inline seq8_t seq8_inc(seq8_t s) |
|
{ |
|
return seq8_adds(s, 1, UINT8_MAX); |
|
} |
|
|
|
/** |
|
* @brief Compare sequence numbers @p s1, @p s2 in the serial number @p space |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.2"> |
|
* 3.2. Comparison |
|
* </a> |
|
* @param[in] s1 first sequence number |
|
* @param[in] s2 second sequence number |
|
* @param[in] space serial number space must be a power of 2 minus 1 |
|
* @return -1, if s1 < s2 |
|
* @return 0, if s1 == s2 |
|
* @return 1, if s1 > s2 |
|
* @return -EINVAL, if comparison of the pair (s1,s2) is undefined |
|
*/ |
|
int seq8_compares(seq8_t s1, seq8_t s2, uint8_t space); |
|
|
|
/** |
|
* @brief Compare sequence numbers @p s1, @p s2 in the serial number space UINT8_MAX |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.2"> |
|
* 3.2. Comparison |
|
* </a> |
|
* @param[in] s1 first sequence number |
|
* @param[in] s2 second sequence number |
|
* @return -1, if s1 < s2 |
|
* @return 0, if s1 == s2 |
|
* @return 1, if s1 > s2 |
|
* @return -EINVAL, if comparison of the pair (s1,s2) is undefined |
|
*/ |
|
static inline int seq8_compare(seq8_t s1, seq8_t s2) |
|
{ |
|
return seq8_compares(s1, s2, UINT8_MAX); |
|
} |
|
|
|
/** |
|
* @brief Addition of a 16 bit sequence number @p s and a positive integer @p n |
|
* in the serial number @p space |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.1"> |
|
* 3.1. Addition |
|
* </a> |
|
* @param[in] s sequence number |
|
* @param[in] n positive integer in the range of [0 .. ((@p space / 2) - 1)] |
|
* @param[in] space serial number space must be a power of 2 minus 1 |
|
* @return s + n, if valid |
|
* @return s, if n is out of range |
|
*/ |
|
seq16_t seq16_adds(seq16_t s, uint16_t n, uint16_t space); |
|
|
|
/** |
|
* @brief Addition of a 16 bit sequence number @p s and a positive integer @p n |
|
* in the serial number space UINT16_MAX |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.1"> |
|
* 3.1. Addition |
|
* </a> |
|
* @param[in] s sequence number |
|
* @param[in] n positive integer in the range of [0 .. 127] |
|
* @return s + n, if valid |
|
* @return s, if n is out of range |
|
*/ |
|
static inline seq16_t seq16_add(seq16_t s, uint16_t n) |
|
{ |
|
return seq16_adds(s, n, UINT16_MAX); |
|
} |
|
|
|
/** |
|
* @brief Increment a sequence number @p s by 1 in the serial number @p space |
|
* @param[in] s sequence number |
|
* @param[in] space serial number space must be a power of 2 minus 1 |
|
* @return s + 1 |
|
*/ |
|
static inline seq16_t seq16_incs(seq16_t s, uint16_t space) |
|
{ |
|
return seq16_adds(s, 1, space); |
|
} |
|
|
|
/** |
|
* @brief Increment a sequence number @p s by 1 in the serial number space UINT16_MAX |
|
* @param[in] s sequence number |
|
* @return s + 1 |
|
*/ |
|
static inline seq16_t seq16_inc(seq16_t s) |
|
{ |
|
return seq16_adds(s, 1, UINT16_MAX); |
|
} |
|
|
|
/** |
|
* @brief Compare sequence numbers @p s1, @p s2 in the serial number @p space |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.2"> |
|
* 3.2. Comparison |
|
* </a> |
|
* @param[in] s1 first sequence number |
|
* @param[in] s2 second sequence number |
|
* @param[in] space serial number space must be a power of 2 minus 1 |
|
* @return -1, if s1 < s2 |
|
* @return 0, if s1 == s2 |
|
* @return 1, if s1 > s2 |
|
* @return -EINVAL, if comparison of the pair (s1,s2) is undefined |
|
*/ |
|
int seq16_compares(seq16_t s1, seq16_t s2, uint16_t space); |
|
|
|
/** |
|
* @brief Compare sequence numbers @p s1, @p s2 in the serial number space UINT16_MAX |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.2"> |
|
* 3.2. Comparison |
|
* </a> |
|
* @param[in] s1 first sequence number |
|
* @param[in] s2 second sequence number |
|
* @return -1, if s1 < s2 |
|
* @return 0, if s1 == s2 |
|
* @return 1, if s1 > s2 |
|
* @return -EINVAL, if comparison of the pair (s1,s2) is undefined |
|
*/ |
|
static inline int seq16_compare(seq16_t s1, seq16_t s2) |
|
{ |
|
return seq16_compares(s1, s2, UINT16_MAX); |
|
} |
|
|
|
/** |
|
* @brief Addition of a 32 bit sequence number @p s and a positive integer @p n |
|
* in the serial number @p space |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.1"> |
|
* 3.1. Addition |
|
* </a> |
|
* @param[in] s sequence number |
|
* @param[in] n positive integer in the range of [0 .. ((@p space / 2) - 1)] |
|
* @param[in] space serial number space must be a power of 2 minus 1 |
|
* @return s + n, if valid |
|
* @return s, if n is out of range |
|
*/ |
|
seq32_t seq32_adds(seq32_t s, uint32_t n, uint32_t space); |
|
|
|
/** |
|
* @brief Addition of a 32 bit sequence number @p s and a positive integer @p n |
|
* in the serial number space UINT32_MAX |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.1"> |
|
* 3.1. Addition |
|
* </a> |
|
* @param[in] s sequence number |
|
* @param[in] n positive integer in the range of [0 .. 127] |
|
* @return s + n, if valid |
|
* @return s, if n is out of range |
|
*/ |
|
static inline seq32_t seq32_add(seq32_t s, uint32_t n) |
|
{ |
|
return seq32_adds(s, n, UINT32_MAX); |
|
} |
|
|
|
/** |
|
* @brief Increment a sequence number @p s by 1 in the serial number @p space |
|
* @param[in] s sequence number |
|
* @param[in] space serial number space must be a power of 2 minus 1 |
|
* @return s + 1 |
|
*/ |
|
static inline seq32_t seq32_incs(seq32_t s, uint32_t space) |
|
{ |
|
return seq32_adds(s, 1, space); |
|
} |
|
|
|
/** |
|
* @brief Increment a sequence number @p s by 1 in the serial number space UINT32_MAX |
|
* @param[in] s sequence number |
|
* @return s + 1 |
|
*/ |
|
static inline seq32_t seq32_inc(seq32_t s) |
|
{ |
|
return seq32_adds(s, 1, UINT32_MAX); |
|
} |
|
|
|
/** |
|
* @brief Compare sequence numbers @p s1, @p s2 in the serial number @p space |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.2"> |
|
* 3.2. Comparison |
|
* </a> |
|
* @param[in] s1 first sequence number |
|
* @param[in] s2 second sequence number |
|
* @param[in] space serial number space must be a power of 2 minus 1 |
|
* @return -1, if s1 < s2 |
|
* @return 0, if s1 == s2 |
|
* @return 1, if s1 > s2 |
|
* @return -EINVAL, if comparison of the pair (s1,s2) is undefined |
|
*/ |
|
int seq32_compares(seq32_t s1, seq32_t s2, uint32_t space); |
|
|
|
/** |
|
* @brief Compare sequence numbers @p s1, @p s2 in the serial number space UINT32_MAX |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.2"> |
|
* 3.2. Comparison |
|
* </a> |
|
* @param[in] s1 first sequence number |
|
* @param[in] s2 second sequence number |
|
* @return -1, if s1 < s2 |
|
* @return 0, if s1 == s2 |
|
* @return 1, if s1 > s2 |
|
* @return -EINVAL, if comparison of the pair (s1,s2) is undefined |
|
*/ |
|
static inline int seq32_compare(seq32_t s1, seq32_t s2) |
|
{ |
|
return seq32_compares(s1, s2, UINT32_MAX); |
|
} |
|
|
|
/** |
|
* @brief Addition of a 64 bit sequence number @p s and a positive integer @p n |
|
* in the serial number @p space |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.1"> |
|
* 3.1. Addition |
|
* </a> |
|
* @param[in] s sequence number |
|
* @param[in] n positive integer in the range of [0 .. ((@p space / 2) - 1)] |
|
* @param[in] space serial number space must be a power of 2 minus 1 |
|
* @return s + n, if valid |
|
* @return s, if n is out of range |
|
*/ |
|
seq64_t seq64_adds(seq64_t s, uint64_t n, uint64_t space); |
|
|
|
/** |
|
* @brief Addition of a 64 bit sequence number @p s and a positive integer @p n |
|
* in the serial number space UINT64_MAX |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.1"> |
|
* 3.1. Addition |
|
* </a> |
|
* @param[in] s sequence number |
|
* @param[in] n positive integer in the range of [0 .. 127] |
|
* @return s + n, if valid |
|
* @return s, if n is out of range |
|
*/ |
|
static inline seq64_t seq64_add(seq64_t s, uint64_t n) |
|
{ |
|
return seq64_adds(s, n, UINT64_MAX); |
|
} |
|
|
|
/** |
|
* @brief Increment a sequence number @p s by 1 in the serial number @p space |
|
* @param[in] s sequence number |
|
* @param[in] space serial number space must be a power of 2 minus 1 |
|
* @return s + 1 |
|
*/ |
|
static inline seq64_t seq64_incs(seq64_t s, uint64_t space) |
|
{ |
|
return seq64_adds(s, 1, space); |
|
} |
|
|
|
/** |
|
* @brief Increment a sequence number @p s by 1 in the serial number space UINT64_MAX |
|
* @param[in] s sequence number |
|
* @return s + 1 |
|
*/ |
|
static inline seq64_t seq64_inc(seq64_t s) |
|
{ |
|
return seq64_adds(s, 1, UINT64_MAX); |
|
} |
|
|
|
/** |
|
* @brief Compare sequence numbers @p s1, @p s2 in the serial number @p space |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.2"> |
|
* 3.2. Comparison |
|
* </a> |
|
* @param[in] s1 first sequence number |
|
* @param[in] s2 second sequence number |
|
* @param[in] space serial number space must be a power of 2 minus 1 |
|
* @return -1, if s1 < s2 |
|
* @return 0, if s1 == s2 |
|
* @return 1, if s1 > s2 |
|
* @return -EINVAL, if comparison of the pair (s1,s2) is undefined |
|
*/ |
|
int seq64_compares(seq64_t s1, seq64_t s2, uint64_t space); |
|
|
|
/** |
|
* @brief Compare sequence numbers @p s1, @p s2 in the serial number space UINT64_MAX |
|
* @see <a href="https://tools.ietf.org/html/rfc1982#section-3.2"> |
|
* 3.2. Comparison |
|
* </a> |
|
* @param[in] s1 first sequence number |
|
* @param[in] s2 second sequence number |
|
* @return -1, if s1 < s2 |
|
* @return 0, if s1 == s2 |
|
* @return 1, if s1 > s2 |
|
* @return -EINVAL, if comparison of the pair (s1,s2) is undefined |
|
*/ |
|
static inline int seq64_compare(seq64_t s1, seq64_t s2) |
|
{ |
|
return seq64_compares(s1, s2, UINT64_MAX); |
|
} |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
|
|
/** @} */ |
|
#endif /* SEQ_H */
|
|
|