00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <iostream>
00029
00030 #include <jutils.h>
00031 #include <linklist.h>
00032 #include <config.h>
00033
00034 Linklist::Linklist() {
00035 length = 0;
00036 first = NULL;
00037 last = NULL;
00038 if(pthread_mutex_init (&_mutex,NULL))
00039 error("%i:%s error initializing POSIX thread mutex",
00040 __LINE__,__FILE__);
00041 }
00042
00043 Linklist::~Linklist() {
00044 clear();
00045 if(pthread_mutex_destroy(&_mutex))
00046 error("error destroying POSIX thread mutex",
00047 __LINE__,__FILE__);
00048 }
00049
00050 void Linklist::lock() {
00051 pthread_mutex_lock(&_mutex);
00052 }
00053 void Linklist::unlock() {
00054 pthread_mutex_unlock(&_mutex);
00055 }
00056
00057
00058 void Linklist::append(Entry *addr) {
00059 Entry *ptr = NULL;
00060 if(addr->list) addr->rem();
00061
00062 lock();
00063
00064 if(!last) {
00065 last = addr;
00066 last->next = NULL;
00067 last->prev = NULL;
00068 first = last;
00069 } else {
00070 ptr = last;
00071 ptr->next = addr;
00072 addr->next = NULL;
00073 addr->prev = ptr;
00074 last = addr;
00075 }
00076
00077 addr->list = this;
00078 length++;
00079
00080 unlock();
00081
00082 }
00083
00084 void Linklist::prepend(Entry *addr) {
00085 Entry *ptr = NULL;
00086 if(addr->list) addr->rem();
00087 lock();
00088
00089 if(!first) {
00090 first = addr;
00091 first->next = NULL;
00092 first->prev = NULL;
00093 last = first;
00094 } else {
00095 ptr = first;
00096 ptr->prev = addr;
00097 addr->next = ptr;
00098 addr->prev = NULL;
00099 first = addr;
00100 }
00101 addr->list = this;
00102 length++;
00103 unlock();
00104 }
00105
00106
00107
00108
00109
00110
00111 void Linklist::insert(Entry *addr, int pos) {
00112 if(length<=pos) {
00113 append(addr);
00114 return;
00115 } else if(pos<=1) {
00116 prepend(addr);
00117 return;
00118 }
00119
00120 if(addr->list) addr->rem();
00121
00122 Entry *ptr = pick(pos);
00123
00124 lock();
00125 ptr->prev->next = addr;
00126 addr->prev = ptr->prev;
00127
00128 ptr->prev = addr;
00129 addr->next = ptr;
00130
00131 length++;
00132 addr->list = this;
00133 unlock();
00134 }
00135
00136
00137
00138
00139
00140 bool Linklist::clear() {
00141
00142
00143
00144 lock();
00145 sel(0);
00146 length = 0;
00147 first = NULL;
00148 last = NULL;
00149 unlock();
00150 return(true);
00151 }
00152
00153
00154
00155
00156
00157
00158
00159 Entry *Linklist::pick(int pos) {
00160 if((length<pos)||(pos<1)) return(NULL);
00161 if(pos==1) return(first);
00162 if(pos==length) return(last);
00163
00164 Entry *ptr = first;
00165 int c;
00166 for(c=1;c<pos;c++) ptr = ptr->next;
00167
00168 return(ptr);
00169 }
00170
00171
00172
00173
00174 bool Linklist::moveup(int pos) {
00175 Entry *p = pick(pos);
00176 if(!p) return(false);
00177 return( p->up() );
00178 }
00179 bool Linklist::movedown(int pos) {
00180 Entry *p = pick(pos);
00181 if(!p) return(false);
00182 return( p->down() );
00183 }
00184 bool Linklist::moveto(int num, int pos) {
00185 Entry
00186 *p = pick(num);
00187 if(!p) return(false);
00188 return( p->move(pos) );
00189 }
00190
00191 bool Linklist::rem(int pos) {
00192 Entry *ptr = pick(pos);
00193 if(ptr==NULL) return(false);
00194 ptr->rem();
00195 return(true);
00196 }
00197
00198
00199
00200 bool Linklist::sel(int pos) {
00201 int c;
00202 bool res = false;
00203 Entry *ptr = last;
00204
00205 if(pos>length) return(res);
00206
00207 for(c=length;c>0;c--) {
00208 if(c==pos) {
00209 if(ptr->select)
00210 res = false;
00211 else {
00212 ptr->sel(true);
00213 res = true;
00214 }
00215 } else ptr->sel(false);
00216 ptr = ptr->prev;
00217 }
00218 return(res);
00219 }
00220
00221
00222
00223 Entry *Linklist::selected() {
00224 int c;
00225 Entry *ptr = last;
00226 for(c=length;c>0;c--) {
00227 if(ptr->select) return ptr;
00228 ptr = ptr->prev;
00229 }
00230 return NULL;
00231 }
00232
00233 Entry::Entry() {
00234 next = NULL;
00235 prev = NULL;
00236 list = NULL;
00237 select = false;
00238 }
00239
00240 Entry::Entry(void *val) {
00241 Entry();
00242 set_value(val);
00243 }
00244
00245 Entry::~Entry() {
00246 rem();
00247 }
00248
00249 void Entry::set_value(void *val) {
00250 value=val;
00251 }
00252
00253 void *Entry::get_value() {
00254 return value;
00255 }
00256
00257
00258 bool Entry::up() {
00259 if(!prev || !list) return(false);
00260 list->lock();
00261
00262 Entry *tprev = prev,
00263 *tnext = next,
00264 *pp = prev->prev;
00265
00266 if(!next)
00267 list->last = prev;
00268
00269 if(tnext)
00270 tnext->prev = tprev;
00271
00272 next = tprev;
00273 prev = pp;
00274 tprev->next = tnext;
00275 tprev->prev = this;
00276
00277 if(pp)
00278 pp->next = this;
00279
00280 if(!prev)
00281 list->first = this;
00282
00283 list->unlock();
00284 return(true);
00285 }
00286
00287 bool Entry::down() {
00288 if(!next || !list) return(false);
00289 list->lock();
00290
00291 Entry *tprev = prev,
00292 *tnext = next,
00293 *nn = next->next;
00294
00295 if(!prev)
00296 list->first = next;
00297
00298 if(tprev)
00299 tprev->next = tnext;
00300
00301 prev = tnext;
00302 next = nn;
00303 tnext->prev = tprev;
00304 tnext->next = this;
00305 if(nn)
00306 nn->prev = this;
00307
00308 if(!next)
00309 list->last = this;
00310
00311 list->unlock();
00312 return(true);
00313 }
00314
00315
00316 bool Entry::move(int pos) {
00317 func("Entry::move(%i) - NEW LINKLIST MOVE");
00318 if(!list) return(false);
00319 list->lock();
00320
00321 Entry *tn, *tp;
00322
00323 Entry *swapping = list->pick(pos);
00324 if(swapping == this) return(true);
00325 if(!swapping) return(false);
00326
00327 tn = swapping->next;
00328 tp = swapping->prev;
00329
00330 swapping->next = next;
00331 swapping->prev = prev;
00332 if(next) next->prev = swapping;
00333 else list->last = swapping;
00334 if(prev) prev->next = swapping;
00335 else list->first = swapping;
00336
00337 next = tn;
00338 prev = tp;
00339 if(next) next->prev = this;
00340 else list->last = this;
00341 if(prev) prev->next = this;
00342 else list->first = this;
00343
00344 list->unlock();
00345 func("LINKLIST MOVE RETURNS SUCCESS");
00346
00347 return(true);
00348 }
00349
00350 void Entry::rem() {
00351 if(!list) return;
00352 list->lock();
00353
00354 if(prev)
00355 prev->next = next;
00356 else list->first = next;
00357
00358 if(next)
00359 next->prev = prev;
00360 else list->last = prev;
00361
00362 list->length--;
00363 list->unlock();
00364 list = NULL;
00365 }
00366
00367 void Entry::sel(bool on) {
00368 select = on;
00369 }
00370
00371
00372
00373 Entry *Linklist::pick_id(int id) {
00374 Entry *d = begin();
00375
00376 while(d) {
00377 if(d->id == id) break;
00378 d = d->next;
00379 }
00380 return d;
00381 }
00382
00383 int Linklist::selected_pos() {
00384 int c;
00385 Entry *ptr = last;
00386 for(c=length;c>0;c--) {
00387 if(ptr->select) return c;
00388 ptr = ptr->prev;
00389 }
00390 return 0;
00391 }