1 /*
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "list_wrapper.h"
12
13 #include "trace.h"
14
15 namespace webrtc {
ListItem(const void * item)16 ListItem::ListItem(const void* item)
17 : this_iter_(),
18 item_ptr_(item),
19 item_(0)
20 {
21 }
22
ListItem(const unsigned int item)23 ListItem::ListItem(const unsigned int item)
24 : this_iter_(),
25 item_ptr_(0),
26 item_(item)
27 {
28 }
29
~ListItem()30 ListItem::~ListItem()
31 {
32 }
33
GetItem() const34 void* ListItem::GetItem() const
35 {
36 return const_cast<void*>(item_ptr_);
37 }
38
GetUnsignedItem() const39 unsigned int ListItem::GetUnsignedItem() const
40 {
41 return item_;
42 }
43
ListWrapper()44 ListWrapper::ListWrapper() : list_()
45 {
46 }
47
~ListWrapper()48 ListWrapper::~ListWrapper()
49 {
50 if (!Empty())
51 {
52 // TODO (hellner) I'm not sure this loggin is useful.
53 WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1,
54 "Potential memory leak in ListWrapper");
55 // Remove all remaining list items.
56 while (Erase(First()) == 0)
57 {}
58 }
59 }
60
Empty() const61 bool ListWrapper::Empty() const
62 {
63 return list_.empty();
64 }
65
GetSize() const66 unsigned int ListWrapper::GetSize() const
67 {
68 return list_.size();
69 }
70
PushBack(const void * ptr)71 int ListWrapper::PushBack(const void* ptr)
72 {
73 ListItem* item = new ListItem(ptr);
74 list_.push_back(item);
75 return 0;
76 }
77
PushBack(const unsigned int item_id)78 int ListWrapper::PushBack(const unsigned int item_id)
79 {
80 ListItem* item = new ListItem(item_id);
81 list_.push_back(item);
82 return 0;
83 }
84
PushFront(const unsigned int item_id)85 int ListWrapper::PushFront(const unsigned int item_id)
86 {
87 ListItem* item = new ListItem(item_id);
88 list_.push_front(item);
89 return 0;
90 }
91
PushFront(const void * ptr)92 int ListWrapper::PushFront(const void* ptr)
93 {
94 ListItem* item = new ListItem(ptr);
95 list_.push_front(item);
96 return 0;
97 }
98
PopFront()99 int ListWrapper::PopFront()
100 {
101 if(list_.empty())
102 {
103 return -1;
104 }
105 list_.pop_front();
106 return 0;
107 }
108
PopBack()109 int ListWrapper::PopBack()
110 {
111 if(list_.empty())
112 {
113 return -1;
114 }
115 list_.pop_back();
116 return 0;
117 }
118
First() const119 ListItem* ListWrapper::First() const
120 {
121 if(list_.empty())
122 {
123 return NULL;
124 }
125 std::list<ListItem*>::iterator item_iter = list_.begin();
126 ListItem* return_item = (*item_iter);
127 return_item->this_iter_ = item_iter;
128 return return_item;
129 }
130
Last() const131 ListItem* ListWrapper::Last() const
132 {
133 if(list_.empty())
134 {
135 return NULL;
136 }
137 // std::list::end() addresses the last item + 1. Decrement so that the
138 // actual last is accessed.
139 std::list<ListItem*>::iterator item_iter = list_.end();
140 --item_iter;
141 ListItem* return_item = (*item_iter);
142 return_item->this_iter_ = item_iter;
143 return return_item;
144 }
145
Next(ListItem * item) const146 ListItem* ListWrapper::Next(ListItem* item) const
147 {
148 if(item == NULL)
149 {
150 return NULL;
151 }
152 std::list<ListItem*>::iterator item_iter = item->this_iter_;
153 ++item_iter;
154 if (item_iter == list_.end())
155 {
156 return NULL;
157 }
158 ListItem* return_item = (*item_iter);
159 return_item->this_iter_ = item_iter;
160 return return_item;
161 }
162
Previous(ListItem * item) const163 ListItem* ListWrapper::Previous(ListItem* item) const
164 {
165 if(item == NULL)
166 {
167 return NULL;
168 }
169 std::list<ListItem*>::iterator item_iter = item->this_iter_;
170 if (item_iter == list_.begin())
171 {
172 return NULL;
173 }
174 --item_iter;
175 ListItem* return_item = (*item_iter);
176 return_item->this_iter_ = item_iter;
177 return return_item;
178 }
179
Insert(ListItem * existing_previous_item,ListItem * new_item)180 int ListWrapper::Insert(ListItem* existing_previous_item,
181 ListItem* new_item)
182 {
183 // Allow existingPreviousItem to be NULL if the list is empty.
184 // TODO (hellner) why allow this? Keep it as is for now to avoid
185 // breaking API contract.
186 if (!existing_previous_item && !Empty())
187 {
188 return -1;
189 }
190
191 if (!new_item)
192 {
193 return -1;
194 }
195
196 std::list<ListItem*>::iterator insert_location = list_.begin();
197 if (!Empty())
198 {
199 insert_location = existing_previous_item->this_iter_;
200 if(insert_location != list_.end())
201 {
202 ++insert_location;
203 }
204 }
205
206 list_.insert(insert_location,new_item);
207 return 0;
208 }
209
InsertBefore(ListItem * existing_next_item,ListItem * new_item)210 int ListWrapper::InsertBefore(ListItem* existing_next_item,
211 ListItem* new_item)
212 {
213 // Allow existing_next_item to be NULL if the list is empty.
214 // Todo: why allow this? Keep it as is for now to avoid breaking API
215 // contract.
216 if (!existing_next_item && !Empty())
217 {
218 return -1;
219 }
220 if (!new_item)
221 {
222 return -1;
223 }
224
225 std::list<ListItem*>::iterator insert_location = list_.begin();
226 if (!Empty())
227 {
228 insert_location = existing_next_item->this_iter_;
229 }
230
231 list_.insert(insert_location,new_item);
232 return 0;
233 }
234
Erase(ListItem * item)235 int ListWrapper::Erase(ListItem* item)
236 {
237 if(item == NULL)
238 {
239 return -1;
240 }
241 list_.erase(item->this_iter_);
242 return 0;
243 }
244 } // namespace webrtc
245