1 /* 2 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 28 #include "TimeRanges.h" 29 30 using namespace WebCore; 31 32 TimeRanges::TimeRanges(float start, float end) 33 { 34 add(start, end); 35 } 36 37 PassRefPtr<TimeRanges> TimeRanges::copy() 38 { 39 RefPtr<TimeRanges> newSession = TimeRanges::create(); 40 41 unsigned size = m_ranges.size(); 42 for (unsigned i = 0; i < size; i++) 43 newSession->add(m_ranges[i].m_start, m_ranges[i].m_end); 44 45 return newSession.release(); 46 } 47 48 float TimeRanges::start(unsigned index, ExceptionCode& ec) const 49 { 50 if (index >= length()) { 51 ec = INDEX_SIZE_ERR; 52 return 0; 53 } 54 return m_ranges[index].m_start; 55 } 56 57 float TimeRanges::end(unsigned index, ExceptionCode& ec) const 58 { 59 if (index >= length()) { 60 ec = INDEX_SIZE_ERR; 61 return 0; 62 } 63 return m_ranges[index].m_end; 64 } 65 66 void TimeRanges::add(float start, float end) 67 { 68 ASSERT(start <= end); 69 unsigned int overlappingArcIndex; 70 Range addedRange(start, end); 71 72 // For each present range check if we need to: 73 // - merge with the added range, in case we are overlapping or contiguous 74 // - Need to insert in place, we we are completely, not overlapping and not contiguous 75 // in between two ranges. 76 // 77 // TODO: Given that we assume that ranges are correctly ordered, this could be optimized. 78 79 for (overlappingArcIndex = 0; overlappingArcIndex < m_ranges.size(); overlappingArcIndex++) { 80 if (addedRange.isOverlappingRange(m_ranges[overlappingArcIndex]) 81 || addedRange.isContiguousWithRange(m_ranges[overlappingArcIndex])) { 82 // We need to merge the addedRange and that range. 83 addedRange = addedRange.unionWithOverlappingOrContiguousRange(m_ranges[overlappingArcIndex]); 84 m_ranges.remove(overlappingArcIndex); 85 overlappingArcIndex--; 86 } else { 87 // Check the case for which there is no more to do 88 if (!overlappingArcIndex) { 89 if (addedRange.isBeforeRange(m_ranges[0])) { 90 // First index, and we are completely before that range (and not contiguous, nor overlapping). 91 // We just need to be inserted here. 92 break; 93 } 94 } else { 95 if (m_ranges[overlappingArcIndex - 1].isBeforeRange(addedRange) 96 && addedRange.isBeforeRange(m_ranges[overlappingArcIndex])) { 97 // We are exactly after the current previous range, and before the current range, while 98 // not overlapping with none of them. Insert here. 99 break; 100 } 101 } 102 } 103 } 104 105 // Now that we are sure we don't overlap with any range, just add it. 106 m_ranges.insert(overlappingArcIndex, addedRange); 107 } 108 109 bool TimeRanges::contain(float time) const 110 { 111 ExceptionCode unused; 112 for (unsigned n = 0; n < length(); n++) { 113 if (time >= start(n, unused) && time <= end(n, unused)) 114 return true; 115 } 116 return false; 117 } 118