aboutsummaryrefslogtreecommitdiff
path: root/src/system_wrappers/source/list_no_stl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/system_wrappers/source/list_no_stl.cc')
-rw-r--r--src/system_wrappers/source/list_no_stl.cc289
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