xref: /aoo42x/main/vcl/source/fontsubset/list.cxx (revision 4aceadf7)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 /*[]---------------------------------------------------[]*/
29 /*|                                                     |*/
30 /*|     list.c - bidirectional list class               |*/
31 /*|                                                     |*/
32 /*|                                                     |*/
33 /*|  Author: Alexander Gelfenbain                       |*/
34 /*[]---------------------------------------------------[]*/
35 
36 #include <rtl/alloc.h>
37 
38 #if OSL_DEBUG_LEVEL == 0
39 #  ifndef NDEBUG
40 #    define NDEBUG
41 #  endif
42 #endif
43 
44 #include <assert.h>
45 
46 /* #define TEST */
47 #include "list.h"
48 
49 /*- private data types */
50 typedef struct _lnode {
51     struct _lnode *next;
52     struct _lnode *prev;
53 
54     void *value;
55 
56 } lnode;
57 
58 struct _list {
59     lnode *head, *tail, *cptr;
60     size_t aCount;
61     list_destructor eDtor;
62 };
63 
64 /*- private methods */
65 
66 static lnode *newNode(void *el)
67 {
68     lnode *ptr = rtl_allocateMemory(sizeof(lnode));
69     assert(ptr != 0);
70 
71     ptr->value = el;
72 
73     return ptr;
74 }
75 
76 static lnode *appendPrim(list this, void *el)
77 {
78     lnode *ptr = newNode(el);
79     lnode **flink, *blink;
80 
81     if (this->tail != 0) {
82         flink = &(this->tail->next);
83         blink = this->tail;
84     } else {
85         flink = &this->head;
86         blink = 0;
87         this->cptr = ptr;                         /*- list was empty - set current to this element */
88     }
89 
90     *flink  = ptr;
91     this->tail = ptr;
92 
93     ptr->prev = blink;
94     ptr->next = 0;
95 
96     this->aCount++;
97     return ptr;
98 }
99 #ifdef TEST
100 static lnode *prependPrim(list this, void *el)
101 {
102     lnode *ptr = newNode(el);
103     lnode *flink, **blink;
104 
105     if (this->head != 0) {
106         blink = &(this->head->prev);
107         flink = this->head;
108     } else {
109         blink = &this->tail;
110         flink = 0;
111         this->cptr  = ptr;                        /*- list was empty - set current to this element */
112     }
113 
114     *blink = ptr;
115     this->head   = ptr;
116 
117     ptr->next = flink;
118     ptr->prev = 0;
119 
120     this->aCount++;
121     return ptr;
122 }
123 #endif
124 
125 /*- public methods  */
126 list listNewEmpty(void)                           /*- default ctor */
127 {
128     list this = rtl_allocateMemory(sizeof(struct _list));
129     assert(this != 0);
130 
131     this->aCount = 0;
132     this->eDtor = 0;
133     this->head = this->tail = this->cptr = 0;
134 
135     return this;
136 }
137 
138 #ifdef TEST
139 list listNewCopy(list l)                          /*- copy ctor */
140 {
141     lnode *ptr, *c;
142     list this;
143     assert(l != 0);
144 
145     this = rtl_allocateMemory(sizeof(struct _list));
146     assert(this != 0);
147 
148     ptr = l->head;
149 
150     this->aCount = 0;
151     this->eDtor = 0;
152     this->head = this->tail = this->cptr = 0;
153 
154     while (ptr) {
155         c = appendPrim(this, ptr->value);
156         if (ptr == l->cptr) this->cptr = c;
157         ptr = ptr->next;
158     }
159 
160     return this;
161 }
162 #endif
163 
164 void listDispose(list this)                       /*- dtor */
165 {
166     assert(this != 0);
167     listClear(this);
168     rtl_freeMemory(this);
169 }
170 
171 void listSetElementDtor(list this, list_destructor f)
172 {
173     assert(this != 0);
174     this->eDtor = f;
175 }
176 
177 /* calling this function on an empty list is a run-time error */
178 void *listCurrent(list this)
179 {
180     assert(this != 0);
181     assert(this->cptr != 0);
182     return this->cptr->value;
183 }
184 
185 int   listCount(list this)
186 {
187     assert(this != 0);
188     return this->aCount;
189 }
190 
191 int   listIsEmpty(list this)
192 {
193     assert(this != 0);
194     return this->aCount == 0;
195 }
196 
197 
198 #ifdef TEST
199 int   listAtFirst(list this)
200 {
201     assert(this != 0);
202     return this->cptr == this->head;
203 }
204 
205 int   listAtLast(list this)
206 {
207     assert(this != 0);
208     return this->cptr == this->tail;
209 }
210 
211 int   listPosition(list this)
212 {
213     int res = 0;
214     lnode *ptr;
215     assert(this != 0);
216 
217     ptr = this->head;
218 
219     while (ptr != this->cptr) {
220         ptr = ptr->next;
221         res++;
222     }
223 
224     return res;
225 }
226 #endif
227 int    listFind(list this, void *el)
228 {
229     lnode *ptr;
230     assert(this != 0);
231 
232     ptr = this->head;
233 
234     while (ptr) {
235         if (ptr->value == el) {
236             this->cptr = ptr;
237             return 1;
238         }
239         ptr = ptr->next;
240     }
241 
242     return 0;
243 }
244 
245 int    listNext(list this)
246 {
247     return listSkipForward(this, 1);
248 }
249 
250 int    listSkipForward(list this, int n)
251 {
252     int m = 0;
253     assert(this != 0);
254 
255     if (this->cptr == 0) return 0;
256 
257     while (n != 0) {
258         if (this->cptr->next == 0) break;
259         this->cptr = this->cptr->next;
260         n--;
261         m++;
262     }
263     return m;
264 }
265 
266 int    listToFirst(list this)
267 {
268     assert(this != 0);
269 
270     if (this->cptr != this->head) {
271         this->cptr = this->head;
272         return 1;
273     }
274     return 0;
275 }
276 
277 int    listToLast(list this)
278 {
279     assert(this != 0);
280 
281     if (this->cptr != this->tail) {
282         this->cptr = this->tail;
283         return 1;
284     }
285     return 0;
286 }
287 
288 int    listPositionAt(list this, int n)                     /*- returns the actual position number */
289 {
290     int m = 0;
291     assert(this != 0);
292 
293     this->cptr = this->head;
294     while (n != 0) {
295         if (this->cptr->next == 0) break;
296         this->cptr = this->cptr->next;
297         n--;
298         m++;
299     }
300     return m;
301 }
302 
303 list   listAppend(list this, void *el)
304 {
305     assert(this != 0);
306 
307     appendPrim(this, el);
308     return this;
309 }
310 #ifdef TEST
311 list   listPrepend(list this, void *el)
312 {
313     assert(this != 0);
314 
315     prependPrim(this, el);
316     return this;
317 }
318 
319 list   listInsertAfter(list this, void *el)
320 {
321     lnode *ptr;
322     assert(this != 0);
323 
324     if (this->cptr == 0) return listAppend(this, el);
325 
326     ptr = newNode(el);
327 
328     ptr->prev  = this->cptr;
329     ptr->next  = this->cptr->next;
330     this->cptr->next = ptr;
331 
332     if (ptr->next != 0) {
333         ptr->next->prev = ptr;
334     } else {
335         this->tail = ptr;
336     }
337     this->aCount++;
338     return this;
339 }
340 
341 list   listInsertBefore(list this, void *el)
342 {
343     lnode *ptr;
344     assert(this != 0);
345 
346     if (this->cptr == 0) return listAppend(this, el);
347 
348     ptr = newNode(el);
349 
350     ptr->prev  = this->cptr->prev;
351     ptr->next  = this->cptr;
352     this->cptr->prev = ptr;
353 
354     if (ptr->prev != 0) {
355         ptr->prev->next = ptr;
356     } else {
357         this->head = ptr;
358     }
359     this->aCount++;
360     return this;
361 }
362 #endif
363 list   listRemove(list this)
364 {
365     lnode *ptr = 0;
366     if (this->cptr == 0) return this;
367 
368     if (this->cptr->next != 0) {
369         ptr  = this->cptr->next;
370         this->cptr->next->prev = this->cptr->prev;
371     } else {
372         this->tail = this->cptr->prev;
373     }
374 
375     if (this->cptr->prev != 0) {
376         if (ptr == 0) ptr = this->cptr->prev;
377         this->cptr->prev->next = this->cptr->next;
378     } else {
379         this->head = this->cptr->next;
380     }
381 
382     if (this->eDtor) this->eDtor(this->cptr->value);        /* call the dtor callback */
383 
384     rtl_freeMemory(this->cptr);
385     this->aCount--;
386     this->cptr = ptr;
387     return this;
388 }
389 
390 list   listClear(list this)
391 {
392     lnode *node = this->head, *ptr;
393 
394     while (node) {
395         ptr = node->next;
396         if (this->eDtor) this->eDtor(node->value);           /* call the dtor callback */
397         rtl_freeMemory(node);
398         this->aCount--;
399         node = ptr;
400     }
401 
402     this->head = this->tail = this->cptr = 0;
403     assert(this->aCount == 0);
404     return this;
405 }
406 
407 #ifdef TEST
408 
409 void   listForAll(list this, void (*f)(void *))
410 {
411     lnode *ptr = this->head;
412     while (ptr) {
413         f(ptr->value);
414         ptr = ptr->next;
415     }
416 }
417 
418 
419 #include <stdio.h>
420 
421 void printlist(list l)
422 {
423     int saved;
424     assert(l != 0);
425     saved = listPosition(l);
426 
427     printf("[ ");
428 
429     if (!listIsEmpty(l)) {
430         listToFirst(l);
431         do {
432             printf("%d ", (int) listCurrent(l));
433         } while (listNext(l));
434     }
435 
436     printf("]\n");
437 
438     listPositionAt(l, saved);
439 }
440 
441 void printstringlist(list l)
442 {
443     int saved;
444     assert(l != 0);
445     saved = listPosition(l);
446 
447     printf("[ ");
448 
449     if (!listIsEmpty(l)) {
450         listToFirst(l);
451         do {
452             printf("'%s' ", (char *) listCurrent(l));
453         } while (listNext(l));
454     }
455 
456     printf("]\n");
457 
458     listPositionAt(l, saved);
459 }
460 
461 void printstat(list l)
462 {
463     printf("count: %d, position: %d, isEmpty: %d, atFirst: %d, atLast: %d.\n",
464            listCount(l), listPosition(l), listIsEmpty(l), listAtFirst(l), listAtLast(l));
465 }
466 
467 void allfunc(void *e)
468 {
469     printf("%d ", e);
470 }
471 
472 void edtor(void *ptr)
473 {
474     printf("element dtor: 0x%08x\n", ptr);
475     rtl_freeMemory(ptr);
476 }
477 
478 int main()
479 {
480     list l1, l2;
481     char *ptr;
482     int i;
483 
484     l1 = listNewEmpty();
485     printstat(l1);
486 
487     listAppend(l1, 1);
488     printstat(l1);
489 
490     listAppend(l1, 2);
491     printstat(l1);
492 
493     listAppend(l1, 3);
494     printstat(l1);
495 
496     printlist(l1);
497 
498     listToFirst(l1);
499     listInsertBefore(l1, -5);
500     printlist(l1);
501 
502     l2 = listNewCopy(l1);
503     printlist(l2);
504 
505     listForAll(l2, allfunc);
506     printf("\n");
507 
508     listClear(l1);
509     listSetElementDtor(l1, edtor);
510 
511     for(i=0; i<10; i++) {
512         ptr = rtl_allocateMemory(20);
513         snprintf(ptr, 20, "element # %d", i);
514         listAppend(l1, ptr);
515     }
516 
517     printstringlist(l1);
518 
519 
520     listDispose(l1);
521     listDispose(l2);
522 
523 
524     return 0;
525 }
526 #endif
527 
528 
529