summaryrefslogtreecommitdiffstats
path: root/dom/xslt/base/txList.cpp
blob: a361490784dc972c4d32aa12c65955962b20401b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "txList.h"

//----------------------------/
//- Implementation of txList -/
//----------------------------/

/**
 * Default constructor for a txList;
 **/

txList::txList() {
  firstItem = 0;
  lastItem = 0;
  itemCount = 0;
}  //-- txList;

/**
 * txList destructor, cleans up ListItems, but will not delete the Object
 * references
 */
txList::~txList() { clear(); }  //-- ~txList

void txList::add(void* objPtr) { insertBefore(objPtr, nullptr); }  //-- add

/**
 * Returns the number of items in this txList
 **/
int32_t List::getLength() { return itemCount; }  //-- getLength

/**
 * Inserts the given Object pointer as the item just after refItem.
 * If refItem is a null pointer the Object will be inserted at the
 * beginning of the txList (ie, insert after nothing).
 * This method assumes refItem is a member of this list, and since this
 * is a private method, I feel that's a valid assumption
 **/
void txList::insertAfter(void* objPtr, ListItem* refItem) {
  insertBefore(objPtr, refItem ? refItem->nextItem : firstItem);
}  //-- insertAfter

/**
 * Inserts the given Object pointer as the item just before refItem.
 * If refItem is a null pointer the Object will be inserted at the
 * end of the txList (ie, insert before nothing).
 * This method assumes refItem is a member of this list, and since this
 * is a private method, I feel that's a valid assumption
 **/
void txList::insertBefore(void* objPtr, ListItem* refItem) {
  ListItem* item = new ListItem;
  item->objPtr = objPtr;
  item->nextItem = 0;
  item->prevItem = 0;

  //-- if refItem == null insert at end
  if (!refItem) {
    //-- add to back of list
    if (lastItem) {
      lastItem->nextItem = item;
      item->prevItem = lastItem;
    }
    lastItem = item;
    if (!firstItem) firstItem = item;
  } else {
    //-- insert before given item
    item->nextItem = refItem;
    item->prevItem = refItem->prevItem;
    refItem->prevItem = item;

    if (item->prevItem)
      item->prevItem->nextItem = item;
    else
      firstItem = item;
  }

  // increase the item count
  ++itemCount;
}  //-- insertBefore

txList::ListItem* txList::remove(ListItem* item) {
  if (!item) return item;

  //-- adjust the previous item's next pointer
  if (item->prevItem) {
    item->prevItem->nextItem = item->nextItem;
  }
  //-- adjust the next item's previous pointer
  if (item->nextItem) {
    item->nextItem->prevItem = item->prevItem;
  }

  //-- adjust first and last items
  if (item == firstItem) firstItem = item->nextItem;
  if (item == lastItem) lastItem = item->prevItem;

  //-- decrease Item count
  --itemCount;
  return item;
}  //-- remove

void txList::clear() {
  ListItem* item = firstItem;
  while (item) {
    ListItem* tItem = item;
    item = item->nextItem;
    delete tItem;
  }
  firstItem = 0;
  lastItem = 0;
  itemCount = 0;
}

//------------------------------------/
//- Implementation of txListIterator -/
//------------------------------------/

/**
 * Creates a new txListIterator for the given txList
 * @param list, the txList to create an Iterator for
 **/
txListIterator::txListIterator(txList* list) {
  this->list = list;
  currentItem = 0;
  atEndOfList = false;
}  //-- txListIterator

/**
 * Adds the Object pointer to the txList pointed to by this txListIterator.
 * The Object pointer is inserted as the next item in the txList
 * based on the current position within the txList
 * @param objPtr the Object pointer to add to the list
 **/
void txListIterator::addAfter(void* objPtr) {
  if (currentItem || !atEndOfList) {
    list->insertAfter(objPtr, currentItem);
  } else {
    list->insertBefore(objPtr, nullptr);
  }
}  //-- addAfter

/**
 * Adds the Object pointer to the txList pointed to by this txListIterator.
 * The Object pointer is inserted as the previous item in the txList
 * based on the current position within the txList
 * @param objPtr the Object pointer to add to the list
 **/
void txListIterator::addBefore(void* objPtr) {
  if (currentItem || atEndOfList) {
    list->insertBefore(objPtr, currentItem);
  } else {
    list->insertAfter(objPtr, nullptr);
  }
}  //-- addBefore

/**
 * Returns true if a successful call to the next() method can be made
 * @return true if a successful call to the next() method can be made,
 * otherwise false
 **/
bool txListIterator::hasNext() {
  bool hasNext = false;
  if (currentItem)
    hasNext = (currentItem->nextItem != 0);
  else if (!atEndOfList)
    hasNext = (list->firstItem != 0);

  return hasNext;
}  //-- hasNext

/**
 * Returns the next Object pointer in the list
 **/
void* txListIterator::next() {
  void* obj = 0;
  if (currentItem)
    currentItem = currentItem->nextItem;
  else if (!atEndOfList)
    currentItem = list->firstItem;

  if (currentItem)
    obj = currentItem->objPtr;
  else
    atEndOfList = true;

  return obj;
}  //-- next

/**
 * Returns the previous Object in the list
 **/
void* txListIterator::previous() {
  void* obj = 0;

  if (currentItem)
    currentItem = currentItem->prevItem;
  else if (atEndOfList)
    currentItem = list->lastItem;

  if (currentItem) obj = currentItem->objPtr;

  atEndOfList = false;

  return obj;
}  //-- previous

/**
 * Returns the current Object
 **/
void* txListIterator::current() {
  if (currentItem) return currentItem->objPtr;

  return 0;
}  //-- current

/**
 * Removes the Object last returned by the next() or previous() methods;
 * @return the removed Object pointer
 **/
void* txListIterator::remove() {
  void* obj = 0;
  if (currentItem) {
    obj = currentItem->objPtr;
    txList::ListItem* item = currentItem;
    previous();  //-- make previous item the current item
    list->remove(item);
    delete item;
  }
  return obj;
}  //-- remove

/**
 * Resets the current location within the txList to the beginning of the txList
 **/
void txListIterator::reset() {
  atEndOfList = false;
  currentItem = 0;
}  //-- reset

/**
 * Move the iterator to right after the last element
 **/
void txListIterator::resetToEnd() {
  atEndOfList = true;
  currentItem = 0;
}  //-- moveToEnd