OEMCrypto and OPK v20 prerelease initial commit
This commit is contained in:
286
util/include/wv_duration.h
Normal file
286
util/include/wv_duration.h
Normal file
@@ -0,0 +1,286 @@
|
||||
// Copyright 2025 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
#ifndef WVCDM_UTIL_WV_DURATION_H_
|
||||
#define WVCDM_UTIL_WV_DURATION_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <ostream>
|
||||
#include <ratio>
|
||||
#include <string>
|
||||
|
||||
#include "wv_class_utils.h"
|
||||
|
||||
namespace wvutil {
|
||||
// Wrappers around various std::chono::duration units.
|
||||
using Nanoseconds = std::chrono::nanoseconds;
|
||||
using Microseconds = std::chrono::microseconds;
|
||||
using Milliseconds = std::chrono::milliseconds;
|
||||
using Seconds = std::chrono::seconds;
|
||||
using Minutes = std::chrono::minutes;
|
||||
using Hours = std::chrono::hours;
|
||||
#if __cplusplus >= 202002L // C++20
|
||||
using Days = std::chrono::days;
|
||||
#else
|
||||
// Days is not declared in C++17, the standard C++ library
|
||||
// uses the following implementation for C++20.
|
||||
using Days = std::chrono::duration<int64_t, std::ratio<86400> >;
|
||||
#endif
|
||||
|
||||
// A high-level duration struct for storing a duration and
|
||||
// easily accessing the components.
|
||||
// A duration measures a concrete amount of time between two
|
||||
// different points in time.
|
||||
//
|
||||
// Precision of Duration is in milliseconds.
|
||||
class Duration final {
|
||||
public:
|
||||
constexpr Duration() = default;
|
||||
// Initialize duration from some kind of chrono duration type that
|
||||
// can easily convert to milliseconds.
|
||||
// Compiler will not allow irreconcilable duration types to be used
|
||||
// without caller explicitly chrono::duration_cast<milliseconds>.
|
||||
template <class Rep, class Period>
|
||||
constexpr Duration(const std::chrono::duration<Rep, Period>& total_duration)
|
||||
: total_milliseconds_(total_duration) {}
|
||||
WVCDM_CONSTEXPR_DEFAULT_COPY_AND_MOVE(Duration);
|
||||
|
||||
private:
|
||||
// Note: This private section is needed here.
|
||||
// clang++ with -Wundefined-inline will complain about certain
|
||||
// inline members not being declared before use in other inline
|
||||
// methods.
|
||||
|
||||
// Helper function for performing truncate (round towards zero)
|
||||
// operation on chrono::duration types.
|
||||
// The standard C++ chrono library does not provide such a function.
|
||||
template <class ToDuration, class Rep, class Period>
|
||||
static constexpr ToDuration DurationTruncate(
|
||||
const std::chrono::duration<Rep, Period>& duration) {
|
||||
return duration >= std::chrono::duration<Rep, Period>::zero()
|
||||
? std::chrono::floor<ToDuration>(duration)
|
||||
: std::chrono::ceil<ToDuration>(duration);
|
||||
}
|
||||
|
||||
// Helper function for performing truncate on Duration class's
|
||||
// |total_milliseconds_|, returning it in a chrono::duration type
|
||||
// which is specified by template parameter |ToDuration|.
|
||||
template <class ToDuration>
|
||||
constexpr Duration GetTruncateInternal() const {
|
||||
return Duration(DurationTruncate<ToDuration>(total_milliseconds_));
|
||||
}
|
||||
|
||||
public:
|
||||
// == Special Initializers ==
|
||||
|
||||
static constexpr Duration Zero() { return Duration(); }
|
||||
static constexpr Duration FromMilliseconds(int64_t milliseconds) {
|
||||
return Duration(Milliseconds(milliseconds));
|
||||
}
|
||||
static constexpr Duration FromSeconds(int64_t seconds) {
|
||||
return Duration(Seconds(seconds));
|
||||
}
|
||||
|
||||
constexpr bool IsZero() const {
|
||||
return total_milliseconds_ == Milliseconds::zero();
|
||||
}
|
||||
constexpr bool IsNegative() const {
|
||||
return total_milliseconds_ < Milliseconds::zero();
|
||||
}
|
||||
constexpr bool IsPositive() const {
|
||||
return total_milliseconds_ > Milliseconds::zero();
|
||||
}
|
||||
constexpr bool IsNonNegative() const {
|
||||
return total_milliseconds_ >= Milliseconds::zero();
|
||||
}
|
||||
|
||||
// Basic accessor and conversions (rounds down).
|
||||
constexpr Milliseconds total_milliseconds() const {
|
||||
return total_milliseconds_;
|
||||
}
|
||||
constexpr Seconds total_seconds() const {
|
||||
return DurationTruncate<Seconds>(total_milliseconds_);
|
||||
}
|
||||
constexpr Minutes total_minutes() const {
|
||||
return DurationTruncate<Minutes>(total_milliseconds_);
|
||||
}
|
||||
constexpr Hours total_hours() const {
|
||||
return DurationTruncate<Hours>(total_milliseconds_);
|
||||
}
|
||||
constexpr Days total_days() const {
|
||||
return DurationTruncate<Days>(total_milliseconds_);
|
||||
}
|
||||
|
||||
// Access duration absolute components bounded within a
|
||||
// particular unit.
|
||||
// Milliseconds modulo milliseconds per-second (0-999)
|
||||
constexpr uint32_t milliseconds() const {
|
||||
if (IsNegative()) return GetAbsolute().milliseconds();
|
||||
return static_cast<uint32_t>(
|
||||
(total_milliseconds() - total_seconds()).count());
|
||||
}
|
||||
// Seconds modulo seconds per-minute (0-59)
|
||||
constexpr uint32_t seconds() const {
|
||||
if (IsNegative()) return GetAbsolute().seconds();
|
||||
return static_cast<uint32_t>((total_seconds() - total_minutes()).count());
|
||||
}
|
||||
// Minutes modulo minutes per-hour (0-59).
|
||||
constexpr uint32_t minutes() const {
|
||||
if (IsNegative()) return GetAbsolute().minutes();
|
||||
return static_cast<uint32_t>((total_minutes() - total_hours()).count());
|
||||
}
|
||||
// Hours modulo hours per-day (0-23)
|
||||
constexpr uint32_t hours() const {
|
||||
if (IsNegative()) return GetAbsolute().hours();
|
||||
return static_cast<uint32_t>((total_hours() - total_days()).count());
|
||||
}
|
||||
// Days (total).
|
||||
constexpr uint32_t days() const {
|
||||
if (IsNegative()) return GetAbsolute().days();
|
||||
return static_cast<uint32_t>(total_days().count());
|
||||
}
|
||||
|
||||
// Obtain the absolute value.
|
||||
constexpr Duration GetAbsolute() const {
|
||||
return Duration(std::chrono::abs(total_milliseconds_));
|
||||
}
|
||||
|
||||
// Obtain the truncated (math term for rounding towards zero)
|
||||
// value by units.
|
||||
constexpr Duration GetTruncateBySeconds() const {
|
||||
return GetTruncateInternal<Seconds>();
|
||||
}
|
||||
constexpr Duration GetTruncateByMinutes() const {
|
||||
return GetTruncateInternal<Minutes>();
|
||||
}
|
||||
constexpr Duration GetTruncateByHours() const {
|
||||
return GetTruncateInternal<Hours>();
|
||||
}
|
||||
constexpr Duration GetTruncateByDays() const {
|
||||
return GetTruncateInternal<Days>();
|
||||
}
|
||||
|
||||
// Comparison operators (between another Duration class)
|
||||
constexpr bool IsEqualTo(const Duration& other) const {
|
||||
return total_milliseconds_ == other.total_milliseconds_;
|
||||
}
|
||||
constexpr int64_t CompareTo(const Duration& other) const {
|
||||
return static_cast<int64_t>(total_milliseconds_.count() -
|
||||
other.total_milliseconds_.count());
|
||||
}
|
||||
WVCDM_DEFINE_CONSTEXPR_EQ_AND_CMP_OPERATORS(Duration);
|
||||
|
||||
// Comparison operators (between other duration types)
|
||||
template <class Rep, class Period>
|
||||
constexpr bool operator==(
|
||||
const std::chrono::duration<Rep, Period>& other) const {
|
||||
return total_milliseconds_ == other;
|
||||
}
|
||||
template <class Rep, class Period>
|
||||
constexpr bool operator!=(
|
||||
const std::chrono::duration<Rep, Period>& other) const {
|
||||
return total_milliseconds_ != other;
|
||||
}
|
||||
template <class Rep, class Period>
|
||||
constexpr bool operator<=(
|
||||
const std::chrono::duration<Rep, Period>& other) const {
|
||||
return total_milliseconds_ <= other;
|
||||
}
|
||||
template <class Rep, class Period>
|
||||
constexpr bool operator<(
|
||||
const std::chrono::duration<Rep, Period>& other) const {
|
||||
return total_milliseconds_ < other;
|
||||
}
|
||||
template <class Rep, class Period>
|
||||
constexpr bool operator>=(
|
||||
const std::chrono::duration<Rep, Period>& other) const {
|
||||
return total_milliseconds_ >= other;
|
||||
}
|
||||
template <class Rep, class Period>
|
||||
constexpr bool operator>(
|
||||
const std::chrono::duration<Rep, Period>& other) const {
|
||||
return total_milliseconds_ > other;
|
||||
}
|
||||
|
||||
// Unary plus/minus operators
|
||||
constexpr Duration operator+() const { return Duration(total_milliseconds_); }
|
||||
constexpr Duration operator-() const {
|
||||
return Duration(-total_milliseconds_);
|
||||
}
|
||||
|
||||
// Add/subtract operators (between another Duration class)
|
||||
constexpr Duration operator+(const Duration& other) const {
|
||||
return Duration(total_milliseconds_ + other.total_milliseconds_);
|
||||
}
|
||||
constexpr Duration operator-(const Duration& other) const {
|
||||
return Duration(total_milliseconds_ - other.total_milliseconds_);
|
||||
}
|
||||
|
||||
// Add/subtract operators (between other duration types)
|
||||
// Note 1: This is intentionally implemented as a member function to
|
||||
// force the caller the put the Duration class first in the
|
||||
// expression.
|
||||
// Note 2: These operators are not defined for duration types that
|
||||
// smaller than chrono::milliseconds. This could cause
|
||||
// unexpected behavior as operations would be truncated.
|
||||
// Ex: (Duration(5s) + 500us + 500us) = Duration(5s)
|
||||
// Compiler will not allow such operations.
|
||||
template <class Rep, class Period>
|
||||
constexpr Duration operator+(
|
||||
const std::chrono::duration<Rep, Period>& other) const {
|
||||
return Duration(total_milliseconds_ + other);
|
||||
}
|
||||
template <class Rep, class Period>
|
||||
constexpr Duration operator-(
|
||||
const std::chrono::duration<Rep, Period>& other) const {
|
||||
return Duration(total_milliseconds_ - other);
|
||||
}
|
||||
|
||||
// Increment/decrement operators (between another Duration class)
|
||||
constexpr Duration& operator+=(const Duration& other) {
|
||||
total_milliseconds_ += other.total_milliseconds_;
|
||||
return *this;
|
||||
}
|
||||
constexpr Duration& operator-=(const Duration& other) {
|
||||
total_milliseconds_ -= other.total_milliseconds_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Increment/decrement operators (between another duration types)
|
||||
// Note: These operators are not defined for duration types that
|
||||
// smaller than chrono::milliseconds (see '+' operator
|
||||
// comment for details).
|
||||
template <class Rep, class Period>
|
||||
constexpr Duration& operator+=(
|
||||
const std::chrono::duration<Rep, Period>& other) {
|
||||
total_milliseconds_ += other;
|
||||
return *this;
|
||||
}
|
||||
template <class Rep, class Period>
|
||||
constexpr Duration& operator-=(
|
||||
const std::chrono::duration<Rep, Period>& other) {
|
||||
total_milliseconds_ -= other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// To string operator.
|
||||
// Converts the Duration to its string representation.
|
||||
// Examples:
|
||||
// Duration::FromMilliseconds(4000123).ToString()
|
||||
// ==> "1h6m40s123ms"
|
||||
// Duration::FromSeconds(4000).ToString()
|
||||
// ==> "1h6m40s"
|
||||
bool PrintTo(std::ostream* out) const;
|
||||
std::string ToString() const;
|
||||
|
||||
private:
|
||||
// Internally, the Duration class stores durations in milliseconds.
|
||||
Milliseconds total_milliseconds_ = Milliseconds::zero();
|
||||
}; // class Duration
|
||||
|
||||
// == GTest Printer ==
|
||||
void PrintTo(const Duration& duration, std::ostream* out);
|
||||
} // namespace wvutil
|
||||
#endif // WVCDM_UTIL_WV_DURATION_H_
|
||||
Reference in New Issue
Block a user