/* * 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 "map_no_stl.h" #include "critical_section_wrapper.h" #include "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