blob: 171483e1562d3f7837dee500fdef98c395a4dfa2 [file] [log] [blame]
/*
* 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/source/map_no_stl.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/trace.h"
namespace webrtc {
MapNoStlItem::MapNoStlItem(int id, void* item)
: next_(0),
prev_(0),
item_id_(id),
item_ptr_(item) {
}
MapNoStlItem::~MapNoStlItem() {
}
void* MapNoStlItem::GetItem() {
return item_ptr_;
}
int MapNoStlItem::GetId() {
return item_id_;
}
unsigned int MapNoStlItem::GetUnsignedId() {
return static_cast<unsigned int>(item_id_);
}
void MapNoStlItem::SetItem(void* ptr) {
item_ptr_ = ptr;
}
MapNoStl::MapNoStl()
: critical_section_(CriticalSectionWrapper::CreateCriticalSection()),
first_(0),
last_(0),
size_(0) {
}
MapNoStl::~MapNoStl() {
if (First()) {
WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1,
"Potential memory leak in MapNoStl");
while (Erase(First()) == 0)
{}
}
delete critical_section_;
}
int MapNoStl::Size() const {
return size_;
}
int MapNoStl::Insert(int id, void* ptr) {
MapNoStlItem* new_item = new MapNoStlItem(id, ptr);
CriticalSectionScoped lock(critical_section_);
MapNoStlItem* item = first_;
size_++;
if (!item) {
first_ = new_item;
last_ = new_item;
return 0;
}
while (item->next_) {
// Three scenarios
// 1. Item should be inserted first.
// 2. Item should be inserted between two items
// 3. Item should be inserted last
if (item->GetId() > id) {
new_item->next_ = item;
item->prev_ = new_item;
if (item == first_) {
first_ = new_item;
} else {
new_item->prev_ = item->prev_;
new_item->prev_->next_ = new_item;
}
return 0;
}
item = item->next_;
}
// 3
item->next_ = new_item;
new_item->prev_ = item;
last_ = new_item;
return 0;
}
MapNoStlItem* MapNoStl::First() const {
return first_;
}
MapNoStlItem* MapNoStl::Last() const {
return last_;
}
MapNoStlItem* MapNoStl::Next(MapNoStlItem* item) const {
if (!item) {
return 0;
}
return item->next_;
}
MapNoStlItem* MapNoStl::Previous(MapNoStlItem* item) const {
if (!item) {
return 0;
}
return item->prev_;
}
MapNoStlItem* MapNoStl::Find(int id) const {
CriticalSectionScoped lock(critical_section_);
MapNoStlItem* item = Locate(id);
return item;
}
int MapNoStl::Erase(MapNoStlItem* item) {
if (!item) {
return -1;
}
CriticalSectionScoped lock(critical_section_);
return Remove(item);
}
int MapNoStl::Erase(const int id) {
CriticalSectionScoped lock(critical_section_);
MapNoStlItem* item = Locate(id);
if (!item) {
return -1;
}
return Remove(item);
}
MapNoStlItem* MapNoStl::Locate(int id) const {
MapNoStlItem* item = first_;
while (item) {
if (item->GetId() == id) {
return item;
}
item = item->next_;
}
return 0;
}
int MapNoStl::Remove(MapNoStlItem* item) {
if (!item) {
return -1;
}
size_--;
MapNoStlItem* previous_item = item->prev_;
MapNoStlItem* next_item = item->next_;
if (!previous_item) {
next_item->prev_ = 0;
first_ = next_item;
} else {
previous_item->next_ = next_item;
}
if (!next_item) {
previous_item->next_ = 0;
last_ = previous_item;
} else {
next_item->prev_ = previous_item;
}
delete item;
return 0;
}
} // namespace webrtc