diff --git a/rtc_base/numerics/sequence_number_util.h b/rtc_base/numerics/sequence_number_util.h index 96a4974ec5..5b4ad10e94 100644 --- a/rtc_base/numerics/sequence_number_util.h +++ b/rtc_base/numerics/sequence_number_util.h @@ -109,6 +109,28 @@ class SeqNumUnwrapper { return last_unwrapped_; } + int64_t UnwrapForward(T value) { + if (!last_value_) { + last_unwrapped_ = {value}; + } else { + last_unwrapped_ += ForwardDiff(*last_value_, value); + } + + last_value_ = value; + return last_unwrapped_; + } + + int64_t UnwrapBackwards(T value) { + if (!last_value_) { + last_unwrapped_ = {value}; + } else { + last_unwrapped_ -= ReverseDiff(*last_value_, value); + } + + last_value_ = value; + return last_unwrapped_; + } + private: int64_t last_unwrapped_ = 0; absl::optional last_value_; diff --git a/rtc_base/numerics/sequence_number_util_unittest.cc b/rtc_base/numerics/sequence_number_util_unittest.cc index d7fa0b1467..c353c921fa 100644 --- a/rtc_base/numerics/sequence_number_util_unittest.cc +++ b/rtc_base/numerics/sequence_number_util_unittest.cc @@ -303,4 +303,32 @@ TEST(SeqNumUnwrapper, ManyBackwardWraps) { } } +TEST(SeqNumUnwrapper, UnwrapForward) { + SeqNumUnwrapper unwrapper; + EXPECT_EQ(255, unwrapper.Unwrap(255)); + EXPECT_EQ(256, unwrapper.UnwrapForward(0)); + EXPECT_EQ(511, unwrapper.UnwrapForward(255)); +} + +TEST(SeqNumUnwrapper, UnwrapForwardWithDivisor) { + SeqNumUnwrapper unwrapper; + EXPECT_EQ(30, unwrapper.UnwrapForward(30)); + EXPECT_EQ(36, unwrapper.UnwrapForward(3)); + EXPECT_EQ(63, unwrapper.UnwrapForward(30)); +} + +TEST(SeqNumUnwrapper, UnwrapBackwards) { + SeqNumUnwrapper unwrapper; + EXPECT_EQ(0, unwrapper.UnwrapBackwards(0)); + EXPECT_EQ(-2, unwrapper.UnwrapBackwards(254)); + EXPECT_EQ(-256, unwrapper.UnwrapBackwards(0)); +} + +TEST(SeqNumUnwrapper, UnwrapBackwardsWithDivisor) { + SeqNumUnwrapper unwrapper; + EXPECT_EQ(0, unwrapper.Unwrap(0)); + EXPECT_EQ(-2, unwrapper.UnwrapBackwards(31)); + EXPECT_EQ(-33, unwrapper.UnwrapBackwards(0)); +} + } // namespace webrtc