1 /***************************************************************************
2  begin       : Thu Jul 04 2019
3  copyright   : (C) 2019 by Martin Preuss
4     email       : martin@libchipcard.de
5 
6  ***************************************************************************
7  *                                                                         *
8  *   This library is free software; you can redistribute it and/or         *
9  *   modify it under the terms of the GNU Lesser General Public            *
10  *   License as published by the Free Software Foundation; either          *
11  *   version 2.1 of the License, or (at your option) any later version.    *
12  *                                                                         *
13  *   This library is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
16  *   Lesser General Public License for more details.                       *
17  *                                                                         *
18  *   You should have received a copy of the GNU Lesser General Public      *
19  *   License along with this library; if not, write to the Free Software   *
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
21  *   MA  02111-1307  USA                                                   *
22  *                                                                         *
23  ***************************************************************************/
24 
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #define DISABLE_DEBUGLOG
31 
32 #include "tree2_p.h"
33 #include <gwenhywfar/misc.h>
34 #include <gwenhywfar/debug.h>
35 
36 
37 
38 
GWEN_Tree2Element_new(void * d)39 GWEN_TREE2_ELEMENT *GWEN_Tree2Element_new(void *d)
40 {
41   GWEN_TREE2_ELEMENT *el;
42 
43   GWEN_NEW_OBJECT(GWEN_TREE2_ELEMENT, el);
44   el->data=d;
45 
46   return el;
47 }
48 
49 
50 
GWEN_Tree2Element_free(GWEN_TREE2_ELEMENT * el)51 void GWEN_Tree2Element_free(GWEN_TREE2_ELEMENT *el)
52 {
53   if (el) {
54     if (el->firstChild) {
55       DBG_ERROR(GWEN_LOGDOMAIN, "Tree element still has children");
56       assert(0);
57     }
58     GWEN_FREE_OBJECT(el);
59   }
60 }
61 
62 
63 
GWEN_Tree2_Unlink(GWEN_TREE2_ELEMENT * el)64 void GWEN_Tree2_Unlink(GWEN_TREE2_ELEMENT *el)
65 {
66 
67   /* unlink from previous */
68   if (el->prevElement)
69     el->prevElement->nextElement=el->nextElement;
70 
71   /* unlink from next */
72   if (el->nextElement)
73     el->nextElement->prevElement=el->prevElement;
74 
75   /* unlink from parent */
76   if (el->parent) {
77     if (el->parent->firstChild==el)
78       el->parent->firstChild=el->nextElement;
79     if (el->parent->lastChild==el)
80       el->parent->lastChild=el->prevElement;
81   }
82 
83   el->nextElement=NULL;
84   el->prevElement=NULL;
85   el->parent=NULL;
86 }
87 
88 
89 
GWEN_Tree2_Replace(GWEN_TREE2_ELEMENT * elToReplace,GWEN_TREE2_ELEMENT * elReplacement)90 void GWEN_Tree2_Replace(GWEN_TREE2_ELEMENT *elToReplace, GWEN_TREE2_ELEMENT *elReplacement)
91 {
92   elReplacement->nextElement=NULL;
93   elReplacement->prevElement=NULL;
94   elReplacement->parent=NULL;
95 
96   /* relink with previous */
97   if (elToReplace->prevElement)
98     elToReplace->prevElement->nextElement=elReplacement;
99   elReplacement->prevElement=elToReplace->prevElement;
100 
101   /* relink with next */
102   if (elToReplace->nextElement)
103     elToReplace->nextElement->prevElement=elReplacement;
104   elReplacement->nextElement=elToReplace->nextElement;
105 
106   /* relink with parent */
107   if (elToReplace->parent) {
108     elReplacement->parent=elToReplace->parent;
109     if (elToReplace->parent->firstChild==elToReplace)
110       elToReplace->parent->firstChild=elReplacement;
111     if (elToReplace->parent->lastChild==elToReplace)
112       elToReplace->parent->lastChild=elReplacement;
113   }
114 
115   elToReplace->nextElement=NULL;
116   elToReplace->prevElement=NULL;
117   elToReplace->parent=NULL;
118 }
119 
120 
121 
GWEN_Tree2_AddChild(GWEN_TREE2_ELEMENT * where,GWEN_TREE2_ELEMENT * el)122 void GWEN_Tree2_AddChild(GWEN_TREE2_ELEMENT *where, GWEN_TREE2_ELEMENT *el)
123 {
124   if (where->firstChild==NULL)
125     where->firstChild=el;
126 
127   el->prevElement=where->lastChild;
128   if (where->lastChild)
129     where->lastChild->nextElement=el;
130   where->lastChild=el;
131 
132   el->parent=where;
133 }
134 
135 
136 
GWEN_Tree2_InsertChild(GWEN_TREE2_ELEMENT * where,GWEN_TREE2_ELEMENT * el)137 void GWEN_Tree2_InsertChild(GWEN_TREE2_ELEMENT *where, GWEN_TREE2_ELEMENT *el)
138 {
139   el->nextElement=where->firstChild;
140   where->firstChild=el;
141 
142   if (where->lastChild==NULL)
143     where->lastChild=el;
144 
145   el->parent=where;
146 }
147 
148 
149 
GWEN_Tree2Element_GetPrevious(const GWEN_TREE2_ELEMENT * el)150 void *GWEN_Tree2Element_GetPrevious(const GWEN_TREE2_ELEMENT *el)
151 {
152   if (el->prevElement)
153     return el->prevElement->data;
154   return 0;
155 }
156 
157 
158 
GWEN_Tree2Element_GetNext(const GWEN_TREE2_ELEMENT * el)159 void *GWEN_Tree2Element_GetNext(const GWEN_TREE2_ELEMENT *el)
160 {
161   if (el->nextElement)
162     return el->nextElement->data;
163   return 0;
164 }
165 
166 
167 
GWEN_Tree2Element_GetBelow(const GWEN_TREE2_ELEMENT * el)168 void *GWEN_Tree2Element_GetBelow(const GWEN_TREE2_ELEMENT *el)
169 {
170   if (el->firstChild)                               /* look down */
171     return el->firstChild->data;
172   else if (el->nextElement)                         /* look right */
173     return el->nextElement->data;
174   else {
175     /* look for a parent which has a right neighbour */
176     while (el && el->parent) {
177       if (el->parent->nextElement)                  /* look right of parent */
178         return el->parent->nextElement->data;
179       /* parent has no right neighbour, consult its parent */
180       el=el->parent;
181     }
182   }
183 
184   return NULL;
185 }
186 
187 
188 
GWEN_Tree2Element_GetFirstChild(const GWEN_TREE2_ELEMENT * el)189 void *GWEN_Tree2Element_GetFirstChild(const GWEN_TREE2_ELEMENT *el)
190 {
191   if (el->firstChild)
192     return el->firstChild->data;
193   return NULL;
194 }
195 
196 
197 
GWEN_Tree2Element_GetLastChild(const GWEN_TREE2_ELEMENT * el)198 void *GWEN_Tree2Element_GetLastChild(const GWEN_TREE2_ELEMENT *el)
199 {
200   if (el->lastChild)
201     return el->lastChild->data;
202   return NULL;
203 }
204 
205 
206 
GWEN_Tree2Element_GetParent(const GWEN_TREE2_ELEMENT * el)207 void *GWEN_Tree2Element_GetParent(const GWEN_TREE2_ELEMENT *el)
208 {
209   if (el->parent)
210     return el->parent->data;
211   return NULL;
212 }
213 
214 
215 
216