00001
00002
00003
00004
00005 #ifndef __FSLIST_H_
00006 #define __FSLIST_H_
00007
00008 namespace fs
00009 {
00010
00011 template <class T>
00012 class list
00013 {
00014
00015 public:
00016 template <class T>
00017 struct ListItem
00018 {
00019 T data;
00020 ListItem *next, *prev;
00021 };
00022
00023 void lock ()
00024 {
00025 EnterCriticalSection (&m_cs);
00026 }
00027
00028 void unlock ()
00029 {
00030 LeaveCriticalSection (&m_cs);
00031 }
00032
00033 BOOL save (HANDLE hFile)
00034 {
00035 lock ();
00036
00037 int sz = size ();
00038 DWORD dw;
00039
00040 if (!WriteFile (hFile, &sz, sizeof (sz), &dw, NULL))
00041 {
00042 unlock ();
00043 return FALSE;
00044 }
00045
00046 for (int i = 0; i < sz; i++)
00047 {
00048 if (!WriteFile (hFile, &at (i), sizeof (T), &dw, NULL))
00049 {
00050 unlock ();
00051 return FALSE;
00052 }
00053 }
00054
00055 unlock ();
00056 return TRUE;
00057 }
00058
00059 BOOL load (HANDLE hFile)
00060 {
00061 lock ();
00062
00063 int sz;
00064 DWORD dw;
00065
00066 if (!ReadFile (hFile, &sz, sizeof (sz), &dw, NULL) || dw != sizeof (sz))
00067 {
00068 unlock ();
00069 return FALSE;
00070 }
00071
00072 if (sz < 0)
00073 {
00074 unlock ();
00075 return FALSE;
00076 }
00077
00078 while (sz--)
00079 {
00080 T data;
00081 if (!ReadFile (hFile, &data, sizeof (T), &dw, NULL) || dw != sizeof (T))
00082 {
00083 unlock ();
00084 return FALSE;
00085 }
00086
00087 add (data);
00088 }
00089
00090 unlock ();
00091 return TRUE;
00092 }
00093
00094 void add (T data)
00095 {
00096 lock ();
00097
00098 ListItem <T> *item = new ListItem <T>;
00099
00100 item->data = data;
00101 item->next = item->prev = NULL;
00102
00103 if (end)
00104 {
00105 end->next = item;
00106 item->prev = end;
00107 end = item;
00108 }
00109 else
00110 {
00111 start = end = item;
00112 }
00113
00114 _size++;
00115
00116 unlock ();
00117 }
00118
00119 void insert (int iInsert, T data)
00120 {
00121 lock ();
00122
00123 ListItem <T> *itemAfter = start;
00124 ListItem <T> *itemBefore = start;
00125 ListItem <T> *item;
00126
00127 last = NULL;
00128
00129 while (iInsert && itemAfter)
00130 {
00131 itemBefore = itemAfter;
00132 itemAfter = itemAfter->next;
00133 iInsert--;
00134 }
00135
00136 if (itemAfter == NULL)
00137 {
00138 add (data);
00139 unlock ();
00140 return;
00141 }
00142
00143 item = new ListItem <T>;
00144
00145 item->data = data;
00146 item->next = itemAfter;
00147 item->prev = itemBefore;
00148
00149 itemAfter->prev = item;
00150
00151 if (itemAfter == itemBefore)
00152 {
00153 start = item;
00154 item->prev = NULL;
00155 }
00156 else
00157 {
00158 itemBefore->next = item;
00159 }
00160
00161 _size++;
00162 unlock ();
00163 }
00164
00165 void del (int i)
00166 {
00167 lock ();
00168
00169 ListItem <T> *item = start;
00170
00171 while (item && i--)
00172 {
00173 item = item->next;
00174 }
00175
00176 if (item == NULL)
00177 return;
00178
00179 if (item->prev)
00180 item->prev->next = item->next;
00181 else
00182 start = item->next;
00183
00184 if (item->next)
00185 item->next->prev = item->prev;
00186 else
00187 end = item->prev;
00188
00189 delete item;
00190
00191 last = NULL;
00192
00193 _size--;
00194
00195 unlock ();
00196 }
00197
00198 void clear ()
00199 {
00200 lock ();
00201
00202 if (!start)
00203 {
00204 unlock ();
00205 return;
00206 }
00207
00208 ListItem <T> *item;
00209
00210 while (start)
00211 {
00212 item = start->next;
00213 delete start;
00214 start = item;
00215 }
00216
00217 start = end = NULL;
00218 last = NULL;
00219 _size = 0;
00220
00221 unlock ();
00222 }
00223
00224 int size () const
00225 {
00226 return _size;
00227 }
00228
00229 T& at (int i)
00230 {
00231 lock ();
00232
00233 ListItem <T> *item = NULL;
00234
00235 if (last)
00236 {
00237 if (lastIndex == i)
00238 item = last;
00239 else if (i == lastIndex - 1)
00240 {
00241 item = last->prev;
00242 }
00243 else if (i == lastIndex+1)
00244 {
00245 item = last->next;
00246 }
00247 }
00248
00249 lastIndex = i;
00250
00251 if (item == NULL)
00252 {
00253 item = start;
00254 while (i--)
00255 item = item->next;
00256 }
00257
00258 last = item;
00259
00260 unlock ();
00261
00262 return item->data;
00263 }
00264
00265 int find (T& item)
00266 {
00267 lock ();
00268 for (int i = 0; i < size (); i++)
00269 if (at (i) == item)
00270 break;
00271
00272 unlock ();
00273 return i != size () ? i : -1;
00274 }
00275
00276 T& operator [] (int i)
00277 {
00278 return at (i);
00279 }
00280
00281 list& operator = (list& l)
00282 {
00283 lock ();
00284
00285 clear ();
00286 for (int i = 0; i < l.size (); i++)
00287 add (l [i]);
00288
00289 unlock ();
00290
00291 return *this;
00292 }
00293
00294 list (list& l)
00295 {
00296 start = end = NULL;
00297 last = NULL;
00298 _size = 0;
00299 InitializeCriticalSection (&m_cs);
00300
00301 *this = l;
00302 }
00303
00304 list ()
00305 {
00306 start = end = NULL;
00307 last = NULL;
00308 _size = 0;
00309 InitializeCriticalSection (&m_cs);
00310 }
00311
00312 ~list ()
00313 {
00314 clear ();
00315 DeleteCriticalSection (&m_cs);
00316 };
00317
00318 private:
00319 ListItem <T> *start, *end;
00320 ListItem <T> *last; int lastIndex;
00321 int _size;
00322 CRITICAL_SECTION m_cs;
00323 };
00324
00325 };
00326
00327 #endif