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