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 15namespace webrtc { 16ListItem::ListItem(const void* item) 17 : this_iter_(), 18 item_ptr_(item), 19 item_(0) 20{ 21} 22 23ListItem::ListItem(const unsigned int item) 24 : this_iter_(), 25 item_ptr_(0), 26 item_(item) 27{ 28} 29 30ListItem::~ListItem() 31{ 32} 33 34void* ListItem::GetItem() const 35{ 36 return const_cast<void*>(item_ptr_); 37} 38 39unsigned int ListItem::GetUnsignedItem() const 40{ 41 return item_; 42} 43 44ListWrapper::ListWrapper() : list_() 45{ 46} 47 48ListWrapper::~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 61bool ListWrapper::Empty() const 62{ 63 return list_.empty(); 64} 65 66unsigned int ListWrapper::GetSize() const 67{ 68 return list_.size(); 69} 70 71int ListWrapper::PushBack(const void* ptr) 72{ 73 ListItem* item = new ListItem(ptr); 74 list_.push_back(item); 75 return 0; 76} 77 78int 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 85int 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 92int ListWrapper::PushFront(const void* ptr) 93{ 94 ListItem* item = new ListItem(ptr); 95 list_.push_front(item); 96 return 0; 97} 98 99int ListWrapper::PopFront() 100{ 101 if(list_.empty()) 102 { 103 return -1; 104 } 105 list_.pop_front(); 106 return 0; 107} 108 109int ListWrapper::PopBack() 110{ 111 if(list_.empty()) 112 { 113 return -1; 114 } 115 list_.pop_back(); 116 return 0; 117} 118 119ListItem* 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 131ListItem* 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 146ListItem* 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 163ListItem* 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 180int 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 210int 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 235int 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