LCOV - code coverage report
Current view: top level - dom/media - TimeUnits.h (source / functions) Hit Total Coverage
Test: output.info Lines: 3 111 2.7 %
Date: 2017-07-14 16:53:18 Functions: 1 44 2.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef TIME_UNITS_H
       8             : #define TIME_UNITS_H
       9             : 
      10             : #include "Intervals.h"
      11             : #include "mozilla/CheckedInt.h"
      12             : #include "mozilla/FloatingPoint.h"
      13             : #include "mozilla/Maybe.h"
      14             : #include "mozilla/dom/TimeRanges.h"
      15             : #include "mozilla/TimeStamp.h"
      16             : 
      17             : namespace mozilla {
      18             : namespace media {
      19             : class TimeIntervals;
      20             : } // namespace media
      21             : } // namespace mozilla
      22             : // CopyChooser specalization for nsTArray
      23             : template<>
      24             : struct nsTArray_CopyChooser<mozilla::media::TimeIntervals>
      25             : {
      26             :   typedef nsTArray_CopyWithConstructors<mozilla::media::TimeIntervals> Type;
      27             : };
      28             : 
      29             : namespace mozilla {
      30             : 
      31             : // Number of microseconds per second. 1e6.
      32             : static const int64_t USECS_PER_S = 1000000;
      33             : 
      34             : // Number of microseconds per millisecond.
      35             : static const int64_t USECS_PER_MS = 1000;
      36             : 
      37             : namespace media {
      38             : 
      39             : // Number of nanoseconds per second. 1e9.
      40             : static const int64_t NSECS_PER_S = 1000000000;
      41             : 
      42             : // TimeUnit at present uses a CheckedInt64 as storage.
      43             : // INT64_MAX has the special meaning of being +oo.
      44             : class TimeUnit final {
      45             : public:
      46           0 :   static TimeUnit FromSeconds(double aValue) {
      47           0 :     MOZ_ASSERT(!IsNaN(aValue));
      48             : 
      49           0 :     if (mozilla::IsInfinite<double>(aValue)) {
      50           0 :       return FromInfinity();
      51             :     }
      52             :     // Due to internal double representation, this
      53             :     // operation is not commutative, do not attempt to simplify.
      54           0 :     double val = (aValue + .0000005) * USECS_PER_S;
      55           0 :     if (val >= double(INT64_MAX)) {
      56           0 :       return FromMicroseconds(INT64_MAX);
      57           0 :     } else if (val <= double(INT64_MIN)) {
      58           0 :       return FromMicroseconds(INT64_MIN);
      59             :     } else {
      60           0 :       return FromMicroseconds(int64_t(val));
      61             :     }
      62             :   }
      63             : 
      64           0 :   static constexpr TimeUnit FromMicroseconds(int64_t aValue) {
      65           0 :     return TimeUnit(aValue);
      66             :   }
      67             : 
      68           0 :   static constexpr TimeUnit FromNanoseconds(int64_t aValue) {
      69           0 :     return TimeUnit(aValue / 1000);
      70             :   }
      71             : 
      72           0 :   static constexpr TimeUnit FromInfinity() {
      73           0 :     return TimeUnit(INT64_MAX);
      74             :   }
      75             : 
      76           0 :   static TimeUnit FromTimeDuration(const TimeDuration& aDuration) {
      77           0 :     return FromSeconds(aDuration.ToSeconds());
      78             :   }
      79             : 
      80           0 :   static constexpr TimeUnit Zero() {
      81           0 :     return TimeUnit(0);
      82             :   }
      83             : 
      84           0 :   static TimeUnit Invalid() {
      85           0 :     TimeUnit ret;
      86           0 :     ret.mValue = CheckedInt64(INT64_MAX);
      87             :     // Force an overflow to render the CheckedInt invalid.
      88           0 :     ret.mValue += 1;
      89           0 :     return ret;
      90             :   }
      91             : 
      92           0 :   int64_t ToMicroseconds() const {
      93           0 :     return mValue.value();
      94             :   }
      95             : 
      96           0 :   int64_t ToNanoseconds() const {
      97           0 :     return mValue.value() * 1000;
      98             :   }
      99             : 
     100           0 :   double ToSeconds() const {
     101           0 :     if (IsInfinite()) {
     102           0 :       return PositiveInfinity<double>();
     103             :     }
     104           0 :     return double(mValue.value()) / USECS_PER_S;
     105             :   }
     106             : 
     107           0 :   TimeDuration ToTimeDuration() const {
     108           0 :     return TimeDuration::FromMicroseconds(mValue.value());
     109             :   }
     110             : 
     111           0 :   bool IsInfinite() const {
     112           0 :     return mValue.value() == INT64_MAX;
     113             :   }
     114             : 
     115           0 :   bool IsPositive() const {
     116           0 :     return mValue.value() > 0;
     117             :   }
     118             : 
     119           0 :   bool IsNegative() const {
     120           0 :     return mValue.value() < 0;
     121             :   }
     122             : 
     123           0 :   bool operator == (const TimeUnit& aOther) const {
     124           0 :     MOZ_ASSERT(IsValid() && aOther.IsValid());
     125           0 :     return mValue.value() == aOther.mValue.value();
     126             :   }
     127           0 :   bool operator != (const TimeUnit& aOther) const {
     128           0 :     MOZ_ASSERT(IsValid() && aOther.IsValid());
     129           0 :     return mValue.value() != aOther.mValue.value();
     130             :   }
     131           0 :   bool operator >= (const TimeUnit& aOther) const {
     132           0 :     MOZ_ASSERT(IsValid() && aOther.IsValid());
     133           0 :     return mValue.value() >= aOther.mValue.value();
     134             :   }
     135           0 :   bool operator > (const TimeUnit& aOther) const {
     136           0 :     return !(*this <= aOther);
     137             :   }
     138           0 :   bool operator <= (const TimeUnit& aOther) const {
     139           0 :     MOZ_ASSERT(IsValid() && aOther.IsValid());
     140           0 :     return mValue.value() <= aOther.mValue.value();
     141             :   }
     142           0 :   bool operator < (const TimeUnit& aOther) const {
     143           0 :     return !(*this >= aOther);
     144             :   }
     145           0 :   TimeUnit operator + (const TimeUnit& aOther) const {
     146           0 :     if (IsInfinite() || aOther.IsInfinite()) {
     147           0 :       return FromInfinity();
     148             :     }
     149           0 :     return TimeUnit(mValue + aOther.mValue);
     150             :   }
     151           0 :   TimeUnit operator - (const TimeUnit& aOther) const {
     152           0 :     if (IsInfinite() && !aOther.IsInfinite()) {
     153           0 :       return FromInfinity();
     154             :     }
     155           0 :     MOZ_ASSERT(!IsInfinite() && !aOther.IsInfinite());
     156           0 :     return TimeUnit(mValue - aOther.mValue);
     157             :   }
     158           0 :   TimeUnit& operator += (const TimeUnit& aOther) {
     159           0 :     *this = *this + aOther;
     160           0 :     return *this;
     161             :   }
     162             :   TimeUnit& operator -= (const TimeUnit& aOther) {
     163             :     *this = *this - aOther;
     164             :     return *this;
     165             :   }
     166             : 
     167             :   template <typename T>
     168           0 :   TimeUnit operator*(T aVal) const {
     169             :     // See bug 853398 for the reason to block double multiplier.
     170             :     // If required, use MultDouble below and with caution.
     171             :     static_assert(mozilla::IsIntegral<T>::value, "Must be an integral type");
     172           0 :     return TimeUnit(mValue * aVal);
     173             :   }
     174           0 :   TimeUnit MultDouble(double aVal) const {
     175           0 :     return TimeUnit::FromSeconds(ToSeconds() * aVal);
     176             :   }
     177           0 :   friend TimeUnit operator/ (const TimeUnit& aUnit, int aVal) {
     178           0 :     return TimeUnit(aUnit.mValue / aVal);
     179             :   }
     180             : 
     181           0 :   bool IsValid() const
     182             :   {
     183           0 :     return mValue.isValid();
     184             :   }
     185             : 
     186           5 :   constexpr TimeUnit()
     187           5 :     : mValue(CheckedInt64(0))
     188           5 :   {}
     189             : 
     190             :   TimeUnit(const TimeUnit&) = default;
     191             : 
     192             :   TimeUnit& operator = (const TimeUnit&) = default;
     193             : 
     194             : private:
     195           0 :   explicit constexpr TimeUnit(CheckedInt64 aMicroseconds)
     196           0 :     : mValue(aMicroseconds)
     197           0 :   {}
     198             : 
     199             :   // Our internal representation is in microseconds.
     200             :   CheckedInt64 mValue;
     201             : };
     202             : 
     203             : typedef Maybe<TimeUnit> NullableTimeUnit;
     204             : 
     205             : typedef Interval<TimeUnit> TimeInterval;
     206             : 
     207           0 : class TimeIntervals : public IntervalSet<TimeUnit>
     208             : {
     209             : public:
     210             :   typedef IntervalSet<TimeUnit> BaseType;
     211             : 
     212             :   // We can't use inherited constructors yet. So we have to duplicate all the
     213             :   // constructors found in IntervalSet base class.
     214             :   // all this could be later replaced with:
     215             :   // using IntervalSet<TimeUnit>::IntervalSet;
     216             : 
     217             :   // MOZ_IMPLICIT as we want to enable initialization in the form:
     218             :   // TimeIntervals i = ... like we would do with IntervalSet<T> i = ...
     219           0 :   MOZ_IMPLICIT TimeIntervals(const BaseType& aOther)
     220           0 :     : BaseType(aOther)
     221           0 :   {}
     222           0 :   MOZ_IMPLICIT TimeIntervals(BaseType&& aOther)
     223           0 :     : BaseType(Move(aOther))
     224           0 :   {}
     225             :   explicit TimeIntervals(const BaseType::ElemType& aOther)
     226             :     : BaseType(aOther)
     227             :   {}
     228           0 :   explicit TimeIntervals(BaseType::ElemType&& aOther)
     229           0 :     : BaseType(Move(aOther))
     230           0 :   {}
     231             : 
     232           0 :   static TimeIntervals Invalid()
     233             :   {
     234           0 :     return TimeIntervals(TimeInterval(TimeUnit::FromMicroseconds(INT64_MIN),
     235           0 :                                       TimeUnit::FromMicroseconds(INT64_MIN)));
     236             :   }
     237           0 :   bool IsInvalid() const
     238             :   {
     239           0 :     return Length() == 1 && Start(0).ToMicroseconds() == INT64_MIN &&
     240           0 :       End(0).ToMicroseconds() == INT64_MIN;
     241             :   }
     242             : 
     243           0 :   TimeIntervals() = default;
     244             : 
     245             :   // Make TimeIntervals interchangeable with dom::TimeRanges.
     246           0 :   explicit TimeIntervals(dom::TimeRanges* aRanges)
     247           0 :   {
     248           0 :     for (uint32_t i = 0; i < aRanges->Length(); i++) {
     249           0 :       ErrorResult rv;
     250             :       *this +=
     251           0 :         TimeInterval(TimeUnit::FromSeconds(aRanges->Start(i, rv)),
     252           0 :                      TimeUnit::FromSeconds(aRanges->End(i, rv)));
     253             :     }
     254           0 :   }
     255             :   TimeIntervals& operator = (dom::TimeRanges* aRanges)
     256             :   {
     257             :     *this = TimeIntervals(aRanges);
     258             :     return *this;
     259             :   }
     260             : 
     261             :   static TimeIntervals FromTimeRanges(dom::TimeRanges* aRanges)
     262             :   {
     263             :     return TimeIntervals(aRanges);
     264             :   }
     265             : 
     266           0 :   void ToTimeRanges(dom::TimeRanges* aRanges) const
     267             :   {
     268           0 :     for (IndexType i = 0; i < Length(); i++) {
     269           0 :       aRanges->Add(Start(i).ToSeconds(), End(i).ToSeconds());
     270             :     }
     271           0 :   }
     272             : };
     273             : 
     274             : } // namespace media
     275             : } // namespace mozilla
     276             : 
     277             : #endif // TIME_UNITS_H

Generated by: LCOV version 1.13