Bug 1494333 - index crons just like artifacts r=Callek
[gecko.git] / dom / html / TimeRanges.cpp
blobdab5904c88f4aaf193059af92e42dc4229092823
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/. */
7 #include "mozilla/dom/TimeRanges.h"
8 #include "mozilla/dom/TimeRangesBinding.h"
9 #include "mozilla/dom/HTMLMediaElement.h"
10 #include "TimeUnits.h"
11 #include "nsError.h"
13 namespace mozilla {
14 namespace dom {
16 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TimeRanges, mParent)
17 NS_IMPL_CYCLE_COLLECTING_ADDREF(TimeRanges)
18 NS_IMPL_CYCLE_COLLECTING_RELEASE(TimeRanges)
19 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TimeRanges)
20 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
21 NS_INTERFACE_MAP_ENTRY(nsISupports)
22 NS_INTERFACE_MAP_END
24 TimeRanges::TimeRanges()
25 : mParent(nullptr)
29 TimeRanges::TimeRanges(nsISupports* aParent)
30 : mParent(aParent)
34 TimeRanges::TimeRanges(nsISupports* aParent,
35 const media::TimeIntervals& aTimeIntervals)
36 : TimeRanges(aParent)
38 if (aTimeIntervals.IsInvalid()) {
39 return;
41 for (const media::TimeInterval& interval : aTimeIntervals) {
42 Add(interval.mStart.ToSeconds(), interval.mEnd.ToSeconds());
46 TimeRanges::TimeRanges(const media::TimeIntervals& aTimeIntervals)
47 : TimeRanges(nullptr, aTimeIntervals)
51 media::TimeIntervals
52 TimeRanges::ToTimeIntervals() const
54 media::TimeIntervals t;
55 for (uint32_t i = 0; i < Length(); i++) {
56 t += media::TimeInterval(media::TimeUnit::FromSeconds(Start(i)),
57 media::TimeUnit::FromSeconds(End(i)));
59 return t;
62 TimeRanges::~TimeRanges()
66 double
67 TimeRanges::Start(uint32_t aIndex, ErrorResult& aRv) const
69 if (aIndex >= mRanges.Length()) {
70 aRv = NS_ERROR_DOM_INDEX_SIZE_ERR;
71 return 0;
74 return Start(aIndex);
77 double
78 TimeRanges::End(uint32_t aIndex, ErrorResult& aRv) const
80 if (aIndex >= mRanges.Length()) {
81 aRv = NS_ERROR_DOM_INDEX_SIZE_ERR;
82 return 0;
85 return End(aIndex);
88 void
89 TimeRanges::Add(double aStart, double aEnd)
91 if (aStart > aEnd) {
92 NS_WARNING("Can't add a range if the end is older that the start.");
93 return;
95 mRanges.AppendElement(TimeRange(aStart,aEnd));
98 double
99 TimeRanges::GetStartTime()
101 if (mRanges.IsEmpty()) {
102 return -1.0;
104 return mRanges[0].mStart;
107 double
108 TimeRanges::GetEndTime()
110 if (mRanges.IsEmpty()) {
111 return -1.0;
113 return mRanges[mRanges.Length() - 1].mEnd;
116 void
117 TimeRanges::Normalize(double aTolerance)
119 if (mRanges.Length() >= 2) {
120 AutoTArray<TimeRange,4> normalized;
122 mRanges.Sort(CompareTimeRanges());
124 // This merges the intervals.
125 TimeRange current(mRanges[0]);
126 for (uint32_t i = 1; i < mRanges.Length(); i++) {
127 if (current.mStart <= mRanges[i].mStart &&
128 current.mEnd >= mRanges[i].mEnd) {
129 continue;
131 if (current.mEnd + aTolerance >= mRanges[i].mStart) {
132 current.mEnd = mRanges[i].mEnd;
133 } else {
134 normalized.AppendElement(current);
135 current = mRanges[i];
139 normalized.AppendElement(current);
141 mRanges = normalized;
145 void
146 TimeRanges::Union(const TimeRanges* aOtherRanges, double aTolerance)
148 mRanges.AppendElements(aOtherRanges->mRanges);
149 Normalize(aTolerance);
152 void
153 TimeRanges::Intersection(const TimeRanges* aOtherRanges)
155 AutoTArray<TimeRange,4> intersection;
157 const nsTArray<TimeRange>& otherRanges = aOtherRanges->mRanges;
158 for (index_type i = 0, j = 0; i < mRanges.Length() && j < otherRanges.Length();) {
159 double start = std::max(mRanges[i].mStart, otherRanges[j].mStart);
160 double end = std::min(mRanges[i].mEnd, otherRanges[j].mEnd);
161 if (start < end) {
162 intersection.AppendElement(TimeRange(start, end));
164 if (mRanges[i].mEnd < otherRanges[j].mEnd) {
165 i += 1;
166 } else {
167 j += 1;
171 mRanges = intersection;
174 TimeRanges::index_type
175 TimeRanges::Find(double aTime, double aTolerance /* = 0 */)
177 for (index_type i = 0; i < mRanges.Length(); ++i) {
178 if (aTime < mRanges[i].mEnd && (aTime + aTolerance) >= mRanges[i].mStart) {
179 return i;
182 return NoIndex;
185 JSObject*
186 TimeRanges::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
188 return TimeRanges_Binding::Wrap(aCx, this, aGivenProto);
191 nsISupports*
192 TimeRanges::GetParentObject() const
194 return mParent;
197 void
198 TimeRanges::Shift(double aOffset)
200 for (index_type i = 0; i < mRanges.Length(); ++i) {
201 mRanges[i].mStart += aOffset;
202 mRanges[i].mEnd += aOffset;
206 } // namespace dom
207 } // namespace mozilla