OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "extensions/common/value_counter.h" | 5 #include "extensions/common/value_counter.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 | 10 |
11 namespace extensions { | 11 namespace extensions { |
12 | 12 |
13 ValueCounter::ValueCounter() {} | 13 struct ValueCounter::Entry { |
| 14 explicit Entry(scoped_ptr<base::Value> value) |
| 15 : value(value.Pass()), count(1) {} |
14 | 16 |
15 ValueCounter::~ValueCounter() {} | 17 scoped_ptr<base::Value> value; |
| 18 int count; |
| 19 }; |
16 | 20 |
17 ValueCounter::Entry::Entry(const base::Value& value) | 21 ValueCounter::ValueCounter() { |
18 : value_(value.DeepCopy()), count_(1) {} | 22 } |
19 | 23 |
20 ValueCounter::Entry::~Entry() {} | 24 ValueCounter::~ValueCounter() { |
| 25 } |
21 | 26 |
22 int ValueCounter::Entry::Increment() { return ++count_; } | 27 bool ValueCounter::Add(const base::Value& value) { |
| 28 for (Entry* entry : entries_) { |
| 29 if (entry->value->Equals(&value)) { |
| 30 ++entry->count; |
| 31 return false; |
| 32 } |
| 33 } |
| 34 entries_.push_back(new Entry(value.CreateDeepCopy())); |
| 35 return true; |
| 36 } |
23 | 37 |
24 int ValueCounter::Entry::Decrement() { return --count_; } | 38 bool ValueCounter::Remove(const base::Value& value) { |
25 | 39 for (ScopedVector<Entry>::iterator it = entries_.begin(); |
26 int ValueCounter::Add(const base::Value& value) { return AddImpl(value, true); } | 40 it != entries_.end(); ++it) { |
27 | 41 if ((*it)->value->Equals(&value)) { |
28 int ValueCounter::Remove(const base::Value& value) { | 42 if (--(*it)->count == 0) { |
29 for (EntryList::iterator it = entries_.begin(); it != entries_.end(); it++) { | |
30 (*it)->value()->GetType(); | |
31 if ((*it)->value()->Equals(&value)) { | |
32 int remaining = (*it)->Decrement(); | |
33 if (remaining == 0) { | |
34 std::swap(*it, entries_.back()); | 43 std::swap(*it, entries_.back()); |
35 entries_.pop_back(); | 44 entries_.pop_back(); |
| 45 return true; // Removed the last entry. |
36 } | 46 } |
37 return remaining; | 47 return false; // Removed, but no the last entry. |
38 } | 48 } |
39 } | 49 } |
40 return 0; | 50 return false; // Nothing to remove. |
41 } | |
42 | |
43 int ValueCounter::AddIfMissing(const base::Value& value) { | |
44 return AddImpl(value, false); | |
45 } | |
46 | |
47 int ValueCounter::AddImpl(const base::Value& value, bool increment) { | |
48 for (EntryList::iterator it = entries_.begin(); it != entries_.end(); it++) { | |
49 if ((*it)->value()->Equals(&value)) | |
50 return increment ? (*it)->Increment() : (*it)->count(); | |
51 } | |
52 entries_.push_back(linked_ptr<Entry>(new Entry(value))); | |
53 return 1; | |
54 } | 51 } |
55 | 52 |
56 } // namespace extensions | 53 } // namespace extensions |
OLD | NEW |