diff options
Diffstat (limited to 'src/system_wrappers/source/list_no_stl.cc')
-rw-r--r-- | src/system_wrappers/source/list_no_stl.cc | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/src/system_wrappers/source/list_no_stl.cc b/src/system_wrappers/source/list_no_stl.cc new file mode 100644 index 0000000000..d45f27b310 --- /dev/null +++ b/src/system_wrappers/source/list_no_stl.cc @@ -0,0 +1,289 @@ +/* + * 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 "list_wrapper.h" + +#include "critical_section_wrapper.h" +#include "trace.h" + +namespace webrtc { +ListItem::ListItem(const void* item) + : next_(0), + prev_(0), + item_ptr_(item), + item_(0) +{ +} + +ListItem::ListItem(const unsigned int item) + : next_(0), + prev_(0), + 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() + : critical_section_(CriticalSectionWrapper::CreateCriticalSection()), + first_(0), + last_(0), + size_(0) +{ +} + +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) + {} + } + delete critical_section_; +} + +bool ListWrapper::Empty() const +{ + return !first_ && !last_; +} + +unsigned int ListWrapper::GetSize() const +{ + return size_; +} + +int ListWrapper::PushBack(const void* ptr) +{ + ListItem* item = new ListItem(ptr); + CriticalSectionScoped lock(*critical_section_); + PushBackImpl(item); + return 0; +} + +int ListWrapper::PushBack(const unsigned int item_id) +{ + ListItem* item = new ListItem(item_id); + CriticalSectionScoped lock(*critical_section_); + PushBackImpl(item); + return 0; +} + +int ListWrapper::PushFront(const unsigned int item_id) +{ + ListItem* item = new ListItem(item_id); + CriticalSectionScoped lock(*critical_section_); + PushFrontImpl(item); + return 0; +} + +int ListWrapper::PushFront(const void* ptr) +{ + ListItem* item = new ListItem(ptr); + CriticalSectionScoped lock(*critical_section_); + PushFrontImpl(item); + return 0; +} + +int ListWrapper::PopFront() +{ + return Erase(first_); +} + +int ListWrapper::PopBack() +{ + return Erase(last_); +} + +ListItem* ListWrapper::First() const +{ + return first_; +} + +ListItem* ListWrapper::Last() const +{ + return last_; +} + +ListItem* ListWrapper::Next(ListItem* item) const +{ + if(!item) + { + return 0; + } + return item->next_; +} + +ListItem* ListWrapper::Previous(ListItem* item) const +{ + if (!item) + { + return 0; + } + return item->prev_; +} + +int ListWrapper::Insert(ListItem* existing_previous_item, ListItem* new_item) +{ + if (!new_item) + { + return -1; + } + // 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; + } + CriticalSectionScoped lock(*critical_section_); + if (!existing_previous_item) + { + PushBackImpl(new_item); + return 0; + } + ListItem* next_item = existing_previous_item->next_; + new_item->next_ = existing_previous_item->next_; + new_item->prev_ = existing_previous_item; + existing_previous_item->next_ = new_item; + if (next_item) + { + next_item->prev_ = new_item; + } + else + { + last_ = new_item; + } + size_++; + return 0; +} + +int ListWrapper::InsertBefore(ListItem* existing_next_item, + ListItem* new_item) +{ + if (!new_item) + { + return -1; + } + // 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; + } + CriticalSectionScoped lock(*critical_section_); + if (!existing_next_item) + { + PushBackImpl(new_item); + return 0; + } + + ListItem* previous_item = existing_next_item->prev_; + new_item->next_ = existing_next_item; + new_item->prev_ = previous_item; + existing_next_item->prev_ = new_item; + if (previous_item) + { + previous_item->next_ = new_item; + } + else + { + first_ = new_item; + } + size_++; + return 0; +} + +int ListWrapper::Erase(ListItem* item) +{ + if (!item) + { + return -1; + } + size_--; + ListItem* previous_item = item->prev_; + ListItem* next_item = item->next_; + if (!previous_item) + { + if(next_item) + { + next_item->prev_ = 0; + } + first_ = next_item; + } + else + { + previous_item->next_ = next_item; + } + if (!next_item) + { + if(previous_item) + { + previous_item->next_ = 0; + } + last_ = previous_item; + } + else + { + next_item->prev_ = previous_item; + } + delete item; + return 0; +} + +void ListWrapper::PushBackImpl(ListItem* item) +{ + if (Empty()) + { + first_ = item; + last_ = item; + size_++; + return; + } + + item->prev_ = last_; + last_->next_ = item; + last_ = item; + size_++; +} + +void ListWrapper::PushFrontImpl(ListItem* item) +{ + if (Empty()) + { + first_ = item; + last_ = item; + size_++; + return; + } + + item->next_ = first_; + first_->prev_ = item; + first_ = item; + size_++; +} +} //namespace webrtc |