Golem  v0.1.1
Generic Operating system Libraries for Embedded Multitasking
 All Data Structures Files Functions Variables Pages
glm_list.c
1 
11 /* INCLUDES *******************************************************************/
12 #include "glm_list.h"
13 
14 
15 /* PUBLIC FUNCTIONS ***********************************************************/
16 
17 list_t *
18 list_create(heap_id_t a_heap_id)
19 {
20  list_t * list = NULL;
21 
22  // Allocate memory for the list
23  list = heap_malloc(a_heap_id, sizeof(list_t));
24 
25  // Initialize it upon a successful creation
26  if (NULL != list)
27  {
28  list->first = NULL;
29  list->last = NULL;
30  list->length = 0;
31  }
32 
33  return list;
34 }
35 
36 
37 void
38 list_destroy(list_t *a_list)
39 {
40  if (NULL != a_list)
41  {
42  // Free all items in the list
43  list_clear(a_list);
44 
45  // Finally free the list
46  heap_free(a_list);
47  }
48 }
49 
50 
51 void
52 list_clear(list_t *a_list)
53 {
54  if (NULL != a_list)
55  {
56  // Delete the first item until length equals zero
57  while(a_list->length)
58  {
59  list_item_delete(a_list, a_list->first);
60  }
61  }
62 }
63 
64 
65 uint_base_t
66 list_length(list_t * a_list)
67 {
68  uint_base_t len = 0;
69 
70  if (NULL != a_list)
71  {
72  len = a_list->length;
73  }
74 
75  return len;
76 }
77 
78 
80 list_item_create(list_t * a_list, void * a_object)
81 {
82  list_item_t * item = NULL;
83 
84  if( (NULL != a_list) &&
85  (NULL != a_object) )
86  {
87  // Allocate memory for the list and initialize it before returning it.
88  item = heap_malloc(heap_get_id(a_list), sizeof(list_item_t));
89 
90  // Initialize it upon successful creation
91  if (NULL != item)
92  {
93  item->next = NULL;
94  item->prev = NULL;
95  item->object = a_object;
96 
97  // Make sure to transfer ownership of object to owner of list
98  heap_transfer_owner(a_object, heap_get_id(a_list));
99  }
100  }
101 
102  return item;
103 }
104 
105 
106 list_item_t *
107 list_item_delete(list_t * a_list, list_item_t * a_item)
108 {
109  list_item_t * item_prev = NULL;
110  list_item_t * item_next = NULL;
111  void * object = NULL;
112 
113  if( (NULL != a_list) &&
114  (NULL != a_item) )
115  {
116  // Temporarily store given item's properties
117  item_prev = a_item->prev;
118  item_next = a_item->next;
119  object = a_item->object;
120 
121  // Update previous and next item administration
122  if(NULL == item_prev)
123  {
124  // a_item was first of list and is going to be deleted, so update
125  // first of list to a_item's next (which will be NULL if there are
126  // none).
127  a_list->first = item_next;
128  }
129  else
130  {
131  item_prev->next = a_item->next;
132  }
133  if(NULL == item_next)
134  {
135  // a_item was last of list and is going to be deteled, so update
136  // last of list to a_item's previous (which will be NULL if there
137  // are none.
138  a_list->last = item_prev;
139  }
140  else
141  {
142  item_next->prev = a_item->prev;
143  }
144 
145  // Free heap memory by destroying the ADT-object if it is still present
146  if(NULL != object)
147  {
148  heap_free(object);
149  }
150 
151  // Destroy list item itself
152  heap_free(a_item);
153  a_list->length--;
154  }
155 
156  // Return pointer to next item on the list (in any) or NULL in case we
157  // reached the end of the list.
158  return item_next;
159 }
160 
161 
162 void *
163 list_item_remove(list_t * a_list, list_item_t * a_item)
164 {
165  void *object = NULL;
166 
167  if( (NULL != a_list) &&
168  (NULL != a_item) )
169  {
170  // Obtain ADT-object from list item
171  object = a_item->object;
172  a_item->object = NULL;
173 
174  // Delete the list item (which is now without ADT-object)
175  list_item_delete(a_list, a_item);
176  }
177 
178  return object;
179 }
180 
181 
182 bool
183 list_append(list_t *a_list, list_item_t * a_item)
184 {
185  list_item_t * item = NULL;
186  bool is_appended = false;
187 
188  if( (NULL != a_list) &&
189  (NULL != a_item) )
190  {
191  if(a_list->length > 0)
192  {
193  // Get last item on list
194  item = a_list->last;
195 
196  // Update new item's previous property and last item's next
197  // property. The update list's last-item property.
198  item->next = a_item;
199  a_item->prev = item;
200  a_list->last = a_item;
201  }
202  else
203  {
204  // Store first item
205  a_list->first = a_list->last = a_item;
206  }
207  a_list->length++;
208  is_appended = true;
209  }
210 
211  // Return success or failure to append
212  return is_appended;
213 }
214 
215 
216 bool
217 list_prepend(list_t *a_list, list_item_t * a_item)
218 {
219  list_item_t * item = NULL;
220  bool is_prepended = false;
221 
222  if( (NULL != a_list) &&
223  (NULL != a_item) )
224  {
225  if(a_list->length > 0)
226  {
227  // Get last item on list
228  item = a_list->first;
229 
230  // Update new item's previous property and last item's next
231  // property. The update list's last-item property.
232  item->prev = a_item;
233  a_item->next = item;
234  a_list->first = a_item;
235  }
236  else
237  {
238  // Store first item
239  a_list->first = a_list->last = a_item;
240  }
241  a_list->length++;
242  is_prepended = true;
243  }
244 
245  // Return success or failure to prepend
246  return is_prepended;
247 }
248 
249 
250 list_item_t *
251 list_first_item(list_t *a_list)
252 {
253  list_item_t * item = NULL;
254 
255  // Access valid lists only
256  if(NULL != a_list)
257  {
258  item = a_list->first;
259  }
260 
261  // Return first list item or NULL in case of an invalid or empty list
262  return item;
263 }
264 
265 
266 list_item_t *
267 list_last_item(list_t *a_list)
268 {
269  list_item_t * item = NULL;
270 
271  // Access valid lists only
272  if(NULL != a_list) item = a_list->last;
273 
274  // Return last list item or NULL in case of an invalid or empty list
275  return item;
276 }
277 
278 
279 bool
280 list_insert_after_item( list_t * a_list, list_item_t *a_item,
281  list_item_t *a_item_new )
282 {
283  bool is_inserted = false;
284 
285  // Continue only if given list and item are valid
286  if( (NULL != a_list) &&
287  (NULL != a_item) &&
288  (NULL != a_item_new) )
289  {
290  // Update new item's previous and next properties
291  a_item_new->prev = a_item;
292  a_item_new->next = a_item->next;
293  a_item->next = a_item_new;
294 
295  // Increase list-length and update its last property if necessary
296  a_list->length++;
297  if(NULL == a_item_new->next) a_list->last = a_item_new;
298  is_inserted = true;
299  }
300 
301  // Return pointer to inserted new item or NULL in case of failure
302  return is_inserted;
303 }
304 
305 
306 bool
307 list_insert_before_item(list_t * a_list, list_item_t *a_item,
308  list_item_t *a_item_new )
309 {
310  bool is_inserted = false;
311 
312  // Continue only if given list and item are valid
313  if( (NULL != a_list) &&
314  (NULL != a_item) &&
315  (NULL != a_item_new) )
316  {
317  // Update new item's previous and next property
318  a_item_new->next = a_item;
319  a_item_new->prev = a_item->prev;
320 
321  // Update given item administation
322  a_item->prev = a_item_new;
323 
324  // Increase list-length and update its last property
325  a_list->length++;
326  if (NULL == a_item_new->prev) a_list->first = a_item_new;
327  is_inserted = true;
328  }
329 
330  // Return pointer to inserted new item or NULL in case of failure
331  return is_inserted;
332 }
333 
334 
335 list_item_t *
336 list_item_get_previous(list_item_t * a_item)
337 {
338  list_item_t * item = NULL;
339 
340  // Access valid list item only
341  if(NULL != a_item) item = a_item->prev;
342 
343  // Return pointer to the previous list item or NULL in case an invalid list
344  // item is given or if the given list item is the first list item.
345  return item;
346 }
347 
348 
349 list_item_t *
350 list_item_get_next(list_item_t * a_item)
351 {
352  list_item_t * item = NULL;
353 
354  // Access valid list item only
355  if(NULL != a_item) item = a_item->next;
356 
357  // Return pointer to the next list item or NULL in case an invalid list
358  // item is given or if the given list item is the last list item.
359  return item;
360 }
361 
362 
363 void *
364 list_get_object(list_item_t *a_item)
365 {
366  void * object = NULL;
367 
368  // Access valid list item only
369  if(NULL != a_item) object = a_item->object;
370 
371  // Return pointer to list item's object or NULL in case of an invalid list
372  // item or in case there is no object.
373  return object;
374 }