Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #include "txList.h" |
michael@0 | 7 | |
michael@0 | 8 | //----------------------------/ |
michael@0 | 9 | //- Implementation of txList -/ |
michael@0 | 10 | //----------------------------/ |
michael@0 | 11 | |
michael@0 | 12 | /** |
michael@0 | 13 | * Default constructor for a txList; |
michael@0 | 14 | **/ |
michael@0 | 15 | |
michael@0 | 16 | txList::txList() { |
michael@0 | 17 | firstItem = 0; |
michael@0 | 18 | lastItem = 0; |
michael@0 | 19 | itemCount = 0; |
michael@0 | 20 | } //-- txList; |
michael@0 | 21 | |
michael@0 | 22 | /** |
michael@0 | 23 | * txList destructor, cleans up ListItems, but will not delete the Object |
michael@0 | 24 | * references |
michael@0 | 25 | */ |
michael@0 | 26 | txList::~txList() { |
michael@0 | 27 | clear(); |
michael@0 | 28 | } //-- ~txList |
michael@0 | 29 | |
michael@0 | 30 | nsresult txList::add(void* objPtr) |
michael@0 | 31 | { |
michael@0 | 32 | return insertBefore(objPtr, 0); |
michael@0 | 33 | } //-- add |
michael@0 | 34 | |
michael@0 | 35 | /** |
michael@0 | 36 | * Returns the number of items in this txList |
michael@0 | 37 | **/ |
michael@0 | 38 | int32_t List::getLength() { |
michael@0 | 39 | return itemCount; |
michael@0 | 40 | } //-- getLength |
michael@0 | 41 | |
michael@0 | 42 | |
michael@0 | 43 | /** |
michael@0 | 44 | * Inserts the given Object pointer as the item just after refItem. |
michael@0 | 45 | * If refItem is a null pointer the Object will be inserted at the |
michael@0 | 46 | * beginning of the txList (ie, insert after nothing). |
michael@0 | 47 | * This method assumes refItem is a member of this list, and since this |
michael@0 | 48 | * is a private method, I feel that's a valid assumption |
michael@0 | 49 | **/ |
michael@0 | 50 | nsresult txList::insertAfter(void* objPtr, ListItem* refItem) |
michael@0 | 51 | { |
michael@0 | 52 | //-- if refItem == null insert at front |
michael@0 | 53 | if (!refItem) |
michael@0 | 54 | return insertBefore(objPtr, firstItem); |
michael@0 | 55 | return insertBefore(objPtr, refItem->nextItem); |
michael@0 | 56 | } //-- insertAfter |
michael@0 | 57 | |
michael@0 | 58 | /** |
michael@0 | 59 | * Inserts the given Object pointer as the item just before refItem. |
michael@0 | 60 | * If refItem is a null pointer the Object will be inserted at the |
michael@0 | 61 | * end of the txList (ie, insert before nothing). |
michael@0 | 62 | * This method assumes refItem is a member of this list, and since this |
michael@0 | 63 | * is a private method, I feel that's a valid assumption |
michael@0 | 64 | **/ |
michael@0 | 65 | nsresult txList::insertBefore(void* objPtr, ListItem* refItem) |
michael@0 | 66 | { |
michael@0 | 67 | ListItem* item = new ListItem; |
michael@0 | 68 | NS_ENSURE_TRUE(item, NS_ERROR_OUT_OF_MEMORY); |
michael@0 | 69 | |
michael@0 | 70 | item->objPtr = objPtr; |
michael@0 | 71 | item->nextItem = 0; |
michael@0 | 72 | item->prevItem = 0; |
michael@0 | 73 | |
michael@0 | 74 | //-- if refItem == null insert at end |
michael@0 | 75 | if (!refItem) { |
michael@0 | 76 | //-- add to back of list |
michael@0 | 77 | if (lastItem) { |
michael@0 | 78 | lastItem->nextItem = item; |
michael@0 | 79 | item->prevItem = lastItem; |
michael@0 | 80 | } |
michael@0 | 81 | lastItem = item; |
michael@0 | 82 | if (!firstItem) |
michael@0 | 83 | firstItem = item; |
michael@0 | 84 | } |
michael@0 | 85 | else { |
michael@0 | 86 | //-- insert before given item |
michael@0 | 87 | item->nextItem = refItem; |
michael@0 | 88 | item->prevItem = refItem->prevItem; |
michael@0 | 89 | refItem->prevItem = item; |
michael@0 | 90 | |
michael@0 | 91 | if (item->prevItem) |
michael@0 | 92 | item->prevItem->nextItem = item; |
michael@0 | 93 | else |
michael@0 | 94 | firstItem = item; |
michael@0 | 95 | } |
michael@0 | 96 | |
michael@0 | 97 | // increase the item count |
michael@0 | 98 | ++itemCount; |
michael@0 | 99 | |
michael@0 | 100 | return NS_OK; |
michael@0 | 101 | } //-- insertBefore |
michael@0 | 102 | |
michael@0 | 103 | txList::ListItem* txList::remove(ListItem* item) { |
michael@0 | 104 | |
michael@0 | 105 | if (!item) |
michael@0 | 106 | return item; |
michael@0 | 107 | |
michael@0 | 108 | //-- adjust the previous item's next pointer |
michael@0 | 109 | if (item->prevItem) { |
michael@0 | 110 | item->prevItem->nextItem = item->nextItem; |
michael@0 | 111 | } |
michael@0 | 112 | //-- adjust the next item's previous pointer |
michael@0 | 113 | if (item->nextItem) { |
michael@0 | 114 | item->nextItem->prevItem = item->prevItem; |
michael@0 | 115 | } |
michael@0 | 116 | |
michael@0 | 117 | //-- adjust first and last items |
michael@0 | 118 | if (item == firstItem) |
michael@0 | 119 | firstItem = item->nextItem; |
michael@0 | 120 | if (item == lastItem) |
michael@0 | 121 | lastItem = item->prevItem; |
michael@0 | 122 | |
michael@0 | 123 | //-- decrease Item count |
michael@0 | 124 | --itemCount; |
michael@0 | 125 | return item; |
michael@0 | 126 | } //-- remove |
michael@0 | 127 | |
michael@0 | 128 | void txList::clear() |
michael@0 | 129 | { |
michael@0 | 130 | ListItem* item = firstItem; |
michael@0 | 131 | while (item) { |
michael@0 | 132 | ListItem* tItem = item; |
michael@0 | 133 | item = item->nextItem; |
michael@0 | 134 | delete tItem; |
michael@0 | 135 | } |
michael@0 | 136 | firstItem = 0; |
michael@0 | 137 | lastItem = 0; |
michael@0 | 138 | itemCount = 0; |
michael@0 | 139 | } |
michael@0 | 140 | |
michael@0 | 141 | //------------------------------------/ |
michael@0 | 142 | //- Implementation of txListIterator -/ |
michael@0 | 143 | //------------------------------------/ |
michael@0 | 144 | |
michael@0 | 145 | |
michael@0 | 146 | /** |
michael@0 | 147 | * Creates a new txListIterator for the given txList |
michael@0 | 148 | * @param list, the txList to create an Iterator for |
michael@0 | 149 | **/ |
michael@0 | 150 | txListIterator::txListIterator(txList* list) { |
michael@0 | 151 | this->list = list; |
michael@0 | 152 | currentItem = 0; |
michael@0 | 153 | atEndOfList = false; |
michael@0 | 154 | } //-- txListIterator |
michael@0 | 155 | |
michael@0 | 156 | /** |
michael@0 | 157 | * Adds the Object pointer to the txList pointed to by this txListIterator. |
michael@0 | 158 | * The Object pointer is inserted as the next item in the txList |
michael@0 | 159 | * based on the current position within the txList |
michael@0 | 160 | * @param objPtr the Object pointer to add to the list |
michael@0 | 161 | **/ |
michael@0 | 162 | nsresult txListIterator::addAfter(void* objPtr) |
michael@0 | 163 | { |
michael@0 | 164 | if (currentItem || !atEndOfList) |
michael@0 | 165 | return list->insertAfter(objPtr, currentItem); |
michael@0 | 166 | return list->insertBefore(objPtr, 0); |
michael@0 | 167 | |
michael@0 | 168 | } //-- addAfter |
michael@0 | 169 | |
michael@0 | 170 | /** |
michael@0 | 171 | * Adds the Object pointer to the txList pointed to by this txListIterator. |
michael@0 | 172 | * The Object pointer is inserted as the previous item in the txList |
michael@0 | 173 | * based on the current position within the txList |
michael@0 | 174 | * @param objPtr the Object pointer to add to the list |
michael@0 | 175 | **/ |
michael@0 | 176 | nsresult txListIterator::addBefore(void* objPtr) |
michael@0 | 177 | { |
michael@0 | 178 | if (currentItem || atEndOfList) |
michael@0 | 179 | return list->insertBefore(objPtr, currentItem); |
michael@0 | 180 | return list->insertAfter(objPtr, 0); |
michael@0 | 181 | |
michael@0 | 182 | } //-- addBefore |
michael@0 | 183 | |
michael@0 | 184 | /** |
michael@0 | 185 | * Returns true if a successful call to the next() method can be made |
michael@0 | 186 | * @return true if a successful call to the next() method can be made, |
michael@0 | 187 | * otherwise false |
michael@0 | 188 | **/ |
michael@0 | 189 | bool txListIterator::hasNext() { |
michael@0 | 190 | bool hasNext = false; |
michael@0 | 191 | if (currentItem) |
michael@0 | 192 | hasNext = (currentItem->nextItem != 0); |
michael@0 | 193 | else if (!atEndOfList) |
michael@0 | 194 | hasNext = (list->firstItem != 0); |
michael@0 | 195 | |
michael@0 | 196 | return hasNext; |
michael@0 | 197 | } //-- hasNext |
michael@0 | 198 | |
michael@0 | 199 | /** |
michael@0 | 200 | * Returns the next Object pointer in the list |
michael@0 | 201 | **/ |
michael@0 | 202 | void* txListIterator::next() { |
michael@0 | 203 | |
michael@0 | 204 | void* obj = 0; |
michael@0 | 205 | if (currentItem) |
michael@0 | 206 | currentItem = currentItem->nextItem; |
michael@0 | 207 | else if (!atEndOfList) |
michael@0 | 208 | currentItem = list->firstItem; |
michael@0 | 209 | |
michael@0 | 210 | if (currentItem) |
michael@0 | 211 | obj = currentItem->objPtr; |
michael@0 | 212 | else |
michael@0 | 213 | atEndOfList = true; |
michael@0 | 214 | |
michael@0 | 215 | return obj; |
michael@0 | 216 | } //-- next |
michael@0 | 217 | |
michael@0 | 218 | /** |
michael@0 | 219 | * Returns the previous Object in the list |
michael@0 | 220 | **/ |
michael@0 | 221 | void* txListIterator::previous() { |
michael@0 | 222 | |
michael@0 | 223 | void* obj = 0; |
michael@0 | 224 | |
michael@0 | 225 | if (currentItem) |
michael@0 | 226 | currentItem = currentItem->prevItem; |
michael@0 | 227 | else if (atEndOfList) |
michael@0 | 228 | currentItem = list->lastItem; |
michael@0 | 229 | |
michael@0 | 230 | if (currentItem) |
michael@0 | 231 | obj = currentItem->objPtr; |
michael@0 | 232 | |
michael@0 | 233 | atEndOfList = false; |
michael@0 | 234 | |
michael@0 | 235 | return obj; |
michael@0 | 236 | } //-- previous |
michael@0 | 237 | |
michael@0 | 238 | /** |
michael@0 | 239 | * Returns the current Object |
michael@0 | 240 | **/ |
michael@0 | 241 | void* txListIterator::current() { |
michael@0 | 242 | |
michael@0 | 243 | if (currentItem) |
michael@0 | 244 | return currentItem->objPtr; |
michael@0 | 245 | |
michael@0 | 246 | return 0; |
michael@0 | 247 | } //-- current |
michael@0 | 248 | |
michael@0 | 249 | /** |
michael@0 | 250 | * Removes the Object last returned by the next() or previous() methods; |
michael@0 | 251 | * @return the removed Object pointer |
michael@0 | 252 | **/ |
michael@0 | 253 | void* txListIterator::remove() { |
michael@0 | 254 | |
michael@0 | 255 | void* obj = 0; |
michael@0 | 256 | if (currentItem) { |
michael@0 | 257 | obj = currentItem->objPtr; |
michael@0 | 258 | txList::ListItem* item = currentItem; |
michael@0 | 259 | previous(); //-- make previous item the current item |
michael@0 | 260 | list->remove(item); |
michael@0 | 261 | delete item; |
michael@0 | 262 | } |
michael@0 | 263 | return obj; |
michael@0 | 264 | } //-- remove |
michael@0 | 265 | |
michael@0 | 266 | /** |
michael@0 | 267 | * Resets the current location within the txList to the beginning of the txList |
michael@0 | 268 | **/ |
michael@0 | 269 | void txListIterator::reset() { |
michael@0 | 270 | atEndOfList = false; |
michael@0 | 271 | currentItem = 0; |
michael@0 | 272 | } //-- reset |
michael@0 | 273 | |
michael@0 | 274 | /** |
michael@0 | 275 | * Move the iterator to right after the last element |
michael@0 | 276 | **/ |
michael@0 | 277 | void txListIterator::resetToEnd() { |
michael@0 | 278 | atEndOfList = true; |
michael@0 | 279 | currentItem = 0; |
michael@0 | 280 | } //-- moveToEnd |