1 /* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "map_no_stl.h" 12 13 #include "critical_section_wrapper.h" 14 #include "trace.h" 15 16 namespace webrtc { 17 MapNoStlItem::MapNoStlItem(int id, void* item) 18 : next_(0), 19 prev_(0), 20 item_id_(id), 21 item_ptr_(item) 22 { 23 } 24 25 MapNoStlItem::~MapNoStlItem() 26 { 27 } 28 29 void* MapNoStlItem::GetItem() 30 { 31 return item_ptr_; 32 } 33 34 int MapNoStlItem::GetId() 35 { 36 return item_id_; 37 } 38 39 unsigned int MapNoStlItem::GetUnsignedId() 40 { 41 return static_cast<unsigned int>(item_id_); 42 } 43 44 void MapNoStlItem::SetItem(void* ptr) 45 { 46 item_ptr_ = ptr; 47 } 48 49 MapNoStl::MapNoStl() 50 : critical_section_(CriticalSectionWrapper::CreateCriticalSection()), 51 first_(0), 52 last_(0), 53 size_(0) 54 { 55 } 56 57 MapNoStl::~MapNoStl() 58 { 59 if (First()) 60 { 61 WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, 62 "Potential memory leak in MapNoStl"); 63 while (Erase(First()) == 0) 64 {} 65 } 66 delete critical_section_; 67 } 68 69 int MapNoStl::Size() const 70 { 71 return size_; 72 } 73 74 int MapNoStl::Insert(int id, void* ptr) 75 { 76 MapNoStlItem* new_item = new MapNoStlItem(id, ptr); 77 78 CriticalSectionScoped lock(critical_section_); 79 MapNoStlItem* item = first_; 80 size_++; 81 if (!item) 82 { 83 first_ = new_item; 84 last_ = new_item; 85 return 0; 86 } 87 while(item->next_) 88 { 89 // Three scenarios 90 // 1. Item should be inserted first. 91 // 2. Item should be inserted between two items 92 // 3. Item should be inserted last 93 if (item->GetId() > id) 94 { 95 new_item->next_ = item; 96 item->prev_ = new_item; 97 if (item == first_) 98 { 99 first_ = new_item; 100 } 101 else 102 { 103 new_item->prev_ = item->prev_; 104 new_item->prev_->next_ = new_item; 105 } 106 return 0; 107 } 108 item = item->next_; 109 } 110 // 3 111 item->next_ = new_item; 112 new_item->prev_ = item; 113 last_ = new_item; 114 return 0; 115 } 116 117 MapNoStlItem* MapNoStl::First() const 118 { 119 return first_; 120 } 121 122 MapNoStlItem* MapNoStl::Last() const 123 { 124 return last_; 125 } 126 127 MapNoStlItem* MapNoStl::Next(MapNoStlItem* item) const 128 { 129 if (!item) 130 { 131 return 0; 132 } 133 return item->next_; 134 } 135 136 MapNoStlItem* MapNoStl::Previous(MapNoStlItem* item) const 137 { 138 if (!item) 139 { 140 return 0; 141 } 142 return item->prev_; 143 } 144 145 MapNoStlItem* MapNoStl::Find(int id) const 146 { 147 CriticalSectionScoped lock(critical_section_); 148 MapNoStlItem* item = Locate(id); 149 return item; 150 } 151 152 int MapNoStl::Erase(MapNoStlItem* item) 153 { 154 if(!item) 155 { 156 return -1; 157 } 158 CriticalSectionScoped lock(critical_section_); 159 return Remove(item); 160 } 161 162 int MapNoStl::Erase(const int id) 163 { 164 CriticalSectionScoped lock(critical_section_); 165 MapNoStlItem* item = Locate(id); 166 if(!item) 167 { 168 return -1; 169 } 170 return Remove(item); 171 } 172 173 MapNoStlItem* MapNoStl::Locate(int id) const 174 { 175 MapNoStlItem* item = first_; 176 while(item) 177 { 178 if (item->GetId() == id) 179 { 180 return item; 181 } 182 item = item->next_; 183 } 184 return 0; 185 } 186 187 int MapNoStl::Remove(MapNoStlItem* item) 188 { 189 if (!item) 190 { 191 return -1; 192 } 193 size_--; 194 MapNoStlItem* previous_item = item->prev_; 195 MapNoStlItem* next_item = item->next_; 196 if (!previous_item) 197 { 198 next_item->prev_ = 0; 199 first_ = next_item; 200 } 201 else 202 { 203 previous_item->next_ = next_item; 204 } 205 if (!next_item) 206 { 207 previous_item->next_ = 0; 208 last_ = previous_item; 209 } 210 else 211 { 212 next_item->prev_ = previous_item; 213 } 214 delete item; 215 return 0; 216 } 217 } // namespace webrtc 218