diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/libwebrtc/net/dcsctp/common/sequence_numbers.h | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/net/dcsctp/common/sequence_numbers.h')
-rw-r--r-- | third_party/libwebrtc/net/dcsctp/common/sequence_numbers.h | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/third_party/libwebrtc/net/dcsctp/common/sequence_numbers.h b/third_party/libwebrtc/net/dcsctp/common/sequence_numbers.h new file mode 100644 index 0000000000..d324fb223a --- /dev/null +++ b/third_party/libwebrtc/net/dcsctp/common/sequence_numbers.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#ifndef NET_DCSCTP_COMMON_SEQUENCE_NUMBERS_H_ +#define NET_DCSCTP_COMMON_SEQUENCE_NUMBERS_H_ + +#include <cstdint> +#include <limits> +#include <utility> + +#include "net/dcsctp/common/internal_types.h" +#include "rtc_base/numerics/sequence_number_unwrapper.h" + +namespace dcsctp { + +// UnwrappedSequenceNumber handles wrapping sequence numbers and unwraps them to +// an int64_t value space, to allow wrapped sequence numbers to be easily +// compared for ordering. +// +// Sequence numbers are expected to be monotonically increasing, but they do not +// need to be unwrapped in order, as long as the difference to the previous one +// is not larger than half the range of the wrapped sequence number. +// +// The WrappedType must be a webrtc::StrongAlias type. +template <typename WrappedType> +class UnwrappedSequenceNumber { + public: + static_assert( + !std::numeric_limits<typename WrappedType::UnderlyingType>::is_signed, + "The wrapped type must be unsigned"); + static_assert( + std::numeric_limits<typename WrappedType::UnderlyingType>::max() < + std::numeric_limits<int64_t>::max(), + "The wrapped type must be less than the int64_t value space"); + + // The unwrapper is a sort of factory and converts wrapped sequence numbers to + // unwrapped ones. + class Unwrapper { + public: + Unwrapper() = default; + Unwrapper(const Unwrapper&) = default; + Unwrapper& operator=(const Unwrapper&) = default; + + // Given a wrapped `value`, and with knowledge of its current last seen + // largest number, will return a value that can be compared using normal + // operators, such as less-than, greater-than etc. + // + // This will also update the Unwrapper's state, to track the last seen + // largest value. + UnwrappedSequenceNumber<WrappedType> Unwrap(WrappedType value) { + return UnwrappedSequenceNumber<WrappedType>(unwrapper_.Unwrap(*value)); + } + + // Similar to `Unwrap`, but will not update the Unwrappers's internal state. + UnwrappedSequenceNumber<WrappedType> PeekUnwrap(WrappedType value) const { + return UnwrappedSequenceNumber<WrappedType>( + unwrapper_.PeekUnwrap(*value)); + } + + // Resets the Unwrapper to its pristine state. Used when a sequence number + // is to be reset to zero. + void Reset() { unwrapper_.Reset(); } + + private: + webrtc::SeqNumUnwrapper<typename WrappedType::UnderlyingType> unwrapper_; + }; + + // Returns the wrapped value this type represents. + WrappedType Wrap() const { + return static_cast<WrappedType>(value_ % kValueLimit); + } + + template <typename H> + friend H AbslHashValue(H state, + const UnwrappedSequenceNumber<WrappedType>& hash) { + return H::combine(std::move(state), hash.value_); + } + + bool operator==(const UnwrappedSequenceNumber<WrappedType>& other) const { + return value_ == other.value_; + } + bool operator!=(const UnwrappedSequenceNumber<WrappedType>& other) const { + return value_ != other.value_; + } + bool operator<(const UnwrappedSequenceNumber<WrappedType>& other) const { + return value_ < other.value_; + } + bool operator>(const UnwrappedSequenceNumber<WrappedType>& other) const { + return value_ > other.value_; + } + bool operator>=(const UnwrappedSequenceNumber<WrappedType>& other) const { + return value_ >= other.value_; + } + bool operator<=(const UnwrappedSequenceNumber<WrappedType>& other) const { + return value_ <= other.value_; + } + + // Const accessors for underlying value. + constexpr const int64_t* operator->() const { return &value_; } + constexpr const int64_t& operator*() const& { return value_; } + constexpr const int64_t&& operator*() const&& { return std::move(value_); } + constexpr const int64_t& value() const& { return value_; } + constexpr const int64_t&& value() const&& { return std::move(value_); } + constexpr explicit operator const int64_t&() const& { return value_; } + + // Increments the value. + void Increment() { ++value_; } + + // Returns the next value relative to this sequence number. + UnwrappedSequenceNumber<WrappedType> next_value() const { + return UnwrappedSequenceNumber<WrappedType>(value_ + 1); + } + + // Returns a new sequence number based on `value`, and adding `delta` (which + // may be negative). + static UnwrappedSequenceNumber<WrappedType> AddTo( + UnwrappedSequenceNumber<WrappedType> value, + int delta) { + return UnwrappedSequenceNumber<WrappedType>(value.value_ + delta); + } + + // Returns the absolute difference between `lhs` and `rhs`. + static typename WrappedType::UnderlyingType Difference( + UnwrappedSequenceNumber<WrappedType> lhs, + UnwrappedSequenceNumber<WrappedType> rhs) { + return (lhs.value_ > rhs.value_) ? (lhs.value_ - rhs.value_) + : (rhs.value_ - lhs.value_); + } + + private: + explicit UnwrappedSequenceNumber(int64_t value) : value_(value) {} + static constexpr int64_t kValueLimit = + static_cast<int64_t>(1) + << std::numeric_limits<typename WrappedType::UnderlyingType>::digits; + + int64_t value_; +}; + +// Unwrapped Transmission Sequence Numbers (TSN) +using UnwrappedTSN = UnwrappedSequenceNumber<TSN>; + +// Unwrapped Stream Sequence Numbers (SSN) +using UnwrappedSSN = UnwrappedSequenceNumber<SSN>; + +// Unwrapped Message Identifier (MID) +using UnwrappedMID = UnwrappedSequenceNumber<MID>; + +} // namespace dcsctp + +#endif // NET_DCSCTP_COMMON_SEQUENCE_NUMBERS_H_ |