build fix: no comphelper/profilezone.hxx in this branch
[LibreOffice.git] / vcl / source / fontsubset / list.cxx
blobaab4bf40d2f6a85d5b80162aabbcaaaa1e15b536
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 /*[]---------------------------------------------------[]*/
21 /*| |*/
22 /*| list.c - bidirectional list class |*/
23 /*| |*/
24 /*| |*/
25 /*| Author: Alexander Gelfenbain |*/
26 /*[]---------------------------------------------------[]*/
28 #include <rtl/alloc.h>
29 #include <assert.h>
31 #include "list.h"
33 /*- private data types */
34 struct lnode {
35 struct lnode *next;
36 struct lnode *prev;
38 void *value;
42 struct list_ {
43 lnode *head, *tail, *cptr;
44 size_t aCount;
45 list_destructor eDtor;
48 /*- private methods */
50 static lnode *newNode(void *el)
52 lnode *ptr = static_cast<lnode *>(rtl_allocateMemory(sizeof(lnode)));
53 assert(ptr != nullptr);
55 ptr->value = el;
57 return ptr;
60 static lnode *appendPrim(list pThis, void *el)
62 lnode *ptr = newNode(el);
63 lnode **flink, *blink;
65 if (pThis->tail != nullptr) {
66 flink = &(pThis->tail->next);
67 blink = pThis->tail;
68 } else {
69 flink = &pThis->head;
70 blink = nullptr;
71 pThis->cptr = ptr; /*- list was empty - set current to this element */
74 *flink = ptr;
75 pThis->tail = ptr;
77 ptr->prev = blink;
78 ptr->next = nullptr;
80 pThis->aCount++;
81 return ptr;
84 /*- public methods */
85 list listNewEmpty() /*- default ctor */
87 list pThis = static_cast<list>(rtl_allocateMemory(sizeof(struct list_)));
88 assert(pThis != nullptr);
90 pThis->aCount = 0;
91 pThis->eDtor = nullptr;
92 pThis->head = pThis->tail = pThis->cptr = nullptr;
94 return pThis;
97 void listDispose(list pThis) /*- dtor */
99 assert(pThis != nullptr);
100 listClear(pThis);
101 rtl_freeMemory(pThis);
104 void listSetElementDtor(list pThis, list_destructor f)
106 assert(pThis != nullptr);
107 pThis->eDtor = f;
110 /* calling this function on an empty list is a run-time error */
111 void *listCurrent(list pThis)
113 assert(pThis != nullptr);
114 assert(pThis->cptr != nullptr);
115 return pThis->cptr->value;
118 int listCount(list pThis)
120 assert(pThis != nullptr);
121 return pThis->aCount;
124 int listIsEmpty(list pThis)
126 assert(pThis != nullptr);
127 return pThis->aCount == 0;
130 int listNext(list pThis)
132 return listSkipForward(pThis, 1);
135 int listSkipForward(list pThis, int n)
137 int m = 0;
138 assert(pThis != nullptr);
140 if (pThis->cptr == nullptr) return 0;
142 while (n != 0) {
143 if (pThis->cptr->next == nullptr) break;
144 pThis->cptr = pThis->cptr->next;
145 n--;
146 m++;
148 return m;
151 int listToFirst(list pThis)
153 assert(pThis != nullptr);
155 if (pThis->cptr != pThis->head) {
156 pThis->cptr = pThis->head;
157 return 1;
159 return 0;
162 int listToLast(list pThis)
164 assert(pThis != nullptr);
166 if (pThis->cptr != pThis->tail) {
167 pThis->cptr = pThis->tail;
168 return 1;
170 return 0;
173 list listAppend(list pThis, void *el)
175 assert(pThis != nullptr);
177 appendPrim(pThis, el);
178 return pThis;
181 list listRemove(list pThis)
183 lnode *ptr = nullptr;
184 if (pThis->cptr == nullptr) return pThis;
186 if (pThis->cptr->next != nullptr) {
187 ptr = pThis->cptr->next;
188 pThis->cptr->next->prev = pThis->cptr->prev;
189 } else {
190 pThis->tail = pThis->cptr->prev;
193 if (pThis->cptr->prev != nullptr) {
194 if (ptr == nullptr) ptr = pThis->cptr->prev;
195 pThis->cptr->prev->next = pThis->cptr->next;
196 } else {
197 pThis->head = pThis->cptr->next;
200 if (pThis->eDtor) pThis->eDtor(pThis->cptr->value); /* call the dtor callback */
202 rtl_freeMemory(pThis->cptr);
203 pThis->aCount--;
204 pThis->cptr = ptr;
205 return pThis;
208 list listClear(list pThis)
210 lnode *node = pThis->head, *ptr;
212 while (node) {
213 ptr = node->next;
214 if (pThis->eDtor) pThis->eDtor(node->value); /* call the dtor callback */
215 rtl_freeMemory(node);
216 pThis->aCount--;
217 node = ptr;
220 pThis->head = pThis->tail = pThis->cptr = nullptr;
221 assert(pThis->aCount == 0);
222 return pThis;
225 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */