| /* |
| * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include "webrtc/system_wrappers/interface/list_wrapper.h" |
| |
| #include "webrtc/system_wrappers/interface/trace.h" |
| |
| namespace webrtc { |
| |
| ListItem::ListItem(const void* item) |
| : this_iter_(), |
| item_ptr_(item), |
| item_(0) { |
| } |
| |
| ListItem::ListItem(const unsigned int item) |
| : this_iter_(), |
| item_ptr_(0), |
| item_(item) { |
| } |
| |
| ListItem::~ListItem() { |
| } |
| |
| void* ListItem::GetItem() const { |
| return const_cast<void*>(item_ptr_); |
| } |
| |
| unsigned int ListItem::GetUnsignedItem() const { |
| return item_; |
| } |
| |
| ListWrapper::ListWrapper() |
| : list_() { |
| } |
| |
| ListWrapper::~ListWrapper() { |
| if (!Empty()) { |
| // TODO(hellner) I'm not sure this loggin is useful. |
| WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, |
| "Potential memory leak in ListWrapper"); |
| // Remove all remaining list items. |
| while (Erase(First()) == 0) {} |
| } |
| } |
| |
| bool ListWrapper::Empty() const { |
| return list_.empty(); |
| } |
| |
| unsigned int ListWrapper::GetSize() const { |
| return list_.size(); |
| } |
| |
| int ListWrapper::PushBack(const void* ptr) { |
| ListItem* item = new ListItem(ptr); |
| list_.push_back(item); |
| return 0; |
| } |
| |
| int ListWrapper::PushBack(const unsigned int item_id) { |
| ListItem* item = new ListItem(item_id); |
| list_.push_back(item); |
| return 0; |
| } |
| |
| int ListWrapper::PushFront(const unsigned int item_id) { |
| ListItem* item = new ListItem(item_id); |
| list_.push_front(item); |
| return 0; |
| } |
| |
| int ListWrapper::PushFront(const void* ptr) { |
| ListItem* item = new ListItem(ptr); |
| list_.push_front(item); |
| return 0; |
| } |
| |
| int ListWrapper::PopFront() { |
| if (list_.empty()) { |
| return -1; |
| } |
| list_.pop_front(); |
| return 0; |
| } |
| |
| int ListWrapper::PopBack() { |
| if (list_.empty()) { |
| return -1; |
| } |
| list_.pop_back(); |
| return 0; |
| } |
| |
| ListItem* ListWrapper::First() const { |
| if (list_.empty()) { |
| return NULL; |
| } |
| std::list<ListItem*>::iterator item_iter = list_.begin(); |
| ListItem* return_item = (*item_iter); |
| return_item->this_iter_ = item_iter; |
| return return_item; |
| } |
| |
| ListItem* ListWrapper::Last() const { |
| if (list_.empty()) { |
| return NULL; |
| } |
| // std::list::end() addresses the last item + 1. Decrement so that the |
| // actual last is accessed. |
| std::list<ListItem*>::iterator item_iter = list_.end(); |
| --item_iter; |
| ListItem* return_item = (*item_iter); |
| return_item->this_iter_ = item_iter; |
| return return_item; |
| } |
| |
| ListItem* ListWrapper::Next(ListItem* item) const { |
| if (item == NULL) { |
| return NULL; |
| } |
| std::list<ListItem*>::iterator item_iter = item->this_iter_; |
| ++item_iter; |
| if (item_iter == list_.end()) { |
| return NULL; |
| } |
| ListItem* return_item = (*item_iter); |
| return_item->this_iter_ = item_iter; |
| return return_item; |
| } |
| |
| ListItem* ListWrapper::Previous(ListItem* item) const { |
| if (item == NULL) { |
| return NULL; |
| } |
| std::list<ListItem*>::iterator item_iter = item->this_iter_; |
| if (item_iter == list_.begin()) { |
| return NULL; |
| } |
| --item_iter; |
| ListItem* return_item = (*item_iter); |
| return_item->this_iter_ = item_iter; |
| return return_item; |
| } |
| |
| int ListWrapper::Insert(ListItem* existing_previous_item, |
| ListItem* new_item) { |
| // Allow existing_previous_item to be NULL if the list is empty. |
| // TODO(hellner) why allow this? Keep it as is for now to avoid |
| // breaking API contract. |
| if (!existing_previous_item && !Empty()) { |
| return -1; |
| } |
| |
| if (!new_item) { |
| return -1; |
| } |
| |
| std::list<ListItem*>::iterator insert_location = list_.begin(); |
| if (!Empty()) { |
| insert_location = existing_previous_item->this_iter_; |
| if (insert_location != list_.end()) { |
| ++insert_location; |
| } |
| } |
| |
| list_.insert(insert_location, new_item); |
| return 0; |
| } |
| |
| int ListWrapper::InsertBefore(ListItem* existing_next_item, |
| ListItem* new_item) { |
| // Allow existing_next_item to be NULL if the list is empty. |
| // Todo: why allow this? Keep it as is for now to avoid breaking API |
| // contract. |
| if (!existing_next_item && !Empty()) { |
| return -1; |
| } |
| if (!new_item) { |
| return -1; |
| } |
| |
| std::list<ListItem*>::iterator insert_location = list_.begin(); |
| if (!Empty()) { |
| insert_location = existing_next_item->this_iter_; |
| } |
| |
| list_.insert(insert_location, new_item); |
| return 0; |
| } |
| |
| int ListWrapper::Erase(ListItem* item) { |
| if (item == NULL) { |
| return -1; |
| } |
| list_.erase(item->this_iter_); |
| return 0; |
| } |
| |
| } // namespace webrtc |