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