Chromium Code Reviews| Index: media/base/text_ranges.cc | 
| diff --git a/media/base/text_ranges.cc b/media/base/text_ranges.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..5c27667cbef924383909502bb9131450e5471f57 | 
| --- /dev/null | 
| +++ b/media/base/text_ranges.cc | 
| @@ -0,0 +1,138 @@ | 
| +// Copyright 2014 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "media/base/text_ranges.h" | 
| + | 
| +#include "base/logging.h" | 
| + | 
| +namespace media { | 
| + | 
| +TextRanges::TextRanges() { | 
| + Reset(); | 
| +} | 
| + | 
| +void TextRanges::Reset() { | 
| + curr_range_itr_ = range_map_.end(); | 
| +} | 
| + | 
| +bool TextRanges::AddCue(base::TimeDelta start_time) { | 
| + typedef RangeMap::iterator Itr; | 
| + | 
| + if (curr_range_itr_ == range_map_.end()) { | 
| + // There is no active time range, so this is the first AddCue() | 
| + // attempt that follows a Reset(). | 
| + | 
| + if (range_map_.empty()) { | 
| + NewRange(start_time); | 
| + return true; | 
| + } | 
| + | 
| + if (start_time < range_map_.begin()->first) { | 
| + NewRange(start_time); | 
| + return true; | 
| + } | 
| + | 
| + const Itr itr = --Itr(range_map_.upper_bound(start_time)); | 
| + DCHECK(start_time >= itr->first); | 
| + | 
| + Range& range = itr->second; | 
| + | 
| + if (start_time > range.last_time()) { | 
| + NewRange(start_time); | 
| + return true; | 
| + } | 
| + | 
| + range.ResetCount(start_time); | 
| + curr_range_itr_ = itr; | 
| + return false; | 
| + } | 
| + | 
| + DCHECK(start_time >= curr_range_itr_->first); | 
| + | 
| + Range& curr_range = curr_range_itr_->second; | 
| + | 
| + if (start_time <= curr_range.last_time()) | 
| + return curr_range.AddCue(start_time); | 
| + | 
| + const Itr next_range_itr = ++Itr(curr_range_itr_); | 
| + | 
| + if (next_range_itr != range_map_.end()) { | 
| + DCHECK(next_range_itr->first > curr_range.last_time()); | 
| + DCHECK(start_time <= next_range_itr->first); | 
| + | 
| + if (start_time == next_range_itr->first) { | 
| + // We have walked off the currrent range, and onto the next one. | 
| 
 
acolwell GONE FROM CHROMIUM
2014/02/07 18:30:52
nit: s/currrent/current/
 
Matthew Heaney (Chromium)
2014/02/07 18:49:07
Done.
 
 | 
| + // There is now no ambiguity about where the current time range | 
| + // ends, and so we coalesce the current and next ranges. | 
| + | 
| + Merge(curr_range, next_range_itr); | 
| + return false; | 
| + } | 
| + } | 
| + | 
| + // Either curr_range is the last range in the map, or there is a | 
| 
 
acolwell GONE FROM CHROMIUM
2014/02/07 18:30:52
nit: s/curr_range/|curr_range|/ here and elsewhere
 
Matthew Heaney (Chromium)
2014/02/07 18:49:07
Done.
 
 | 
| + // next range beyond curr_range, but its start time is ahead of this | 
| + // cue's start time. In either case, this cue becomes the new | 
| + // last_time for curr_range. Eventually we will see a cue whose | 
| + // time matches the start time of the next range, in which case we | 
| + // coalesce the current and next ranges. | 
| + | 
| + curr_range.SetLastTime(start_time); | 
| + return true; | 
| +} | 
| + | 
| +size_t TextRanges::RangeCountForTesting() const { | 
| + return range_map_.size(); | 
| +} | 
| + | 
| +void TextRanges::NewRange(base::TimeDelta start_time) { | 
| + Range range; | 
| + range.SetLastTime(start_time); | 
| + | 
| + std::pair<RangeMap::iterator, bool> result = | 
| + range_map_.insert(std::make_pair(start_time, range)); | 
| + DCHECK(result.second); | 
| + | 
| + curr_range_itr_ = result.first; | 
| +} | 
| + | 
| +void TextRanges::Merge( | 
| + Range& curr_range, | 
| + const RangeMap::iterator& next_range_itr) { | 
| + curr_range = next_range_itr->second; | 
| + curr_range.ResetCount(next_range_itr->first); | 
| + range_map_.erase(next_range_itr); | 
| +} | 
| + | 
| +void TextRanges::Range::ResetCount(base::TimeDelta start_time) { | 
| + count_ = (start_time < last_time_) ? 0 : 1; | 
| +} | 
| + | 
| +void TextRanges::Range::SetLastTime(base::TimeDelta last_time) { | 
| + last_time_ = last_time; | 
| + count_ = 1; | 
| + max_count_ = 1; | 
| +} | 
| + | 
| +bool TextRanges::Range::AddCue(base::TimeDelta start_time) { | 
| + if (start_time < last_time_) { | 
| + DCHECK_EQ(count_, 0); | 
| + return false; | 
| + } | 
| + | 
| + DCHECK(start_time == last_time_); | 
| + | 
| + ++count_; | 
| + if (count_ <= max_count_) | 
| + return false; | 
| + | 
| + ++max_count_; | 
| + return true; | 
| +} | 
| + | 
| +base::TimeDelta TextRanges::Range::last_time() const { | 
| + return last_time_; | 
| +} | 
| + | 
| +} // namespace media |