1 
2 /*-
3  *
4  * New BSD License 2006
5  *
6  * Copyright (c) 2006, Jorgen Lundman
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are
11  * met:
12  *
13  * 1 Redistributions of source code must retain the above copyright
14  *   notice, this list of conditions and the following disclaimer.
15  * 2 Redistributions in binary form must reproduce the above
16  *   copyright notice, this list of conditions and the following
17  *   disclaimer in the documentation and/or other materials provided
18  *   with the distribution.
19  * 3 Neither the name of the stuff nor the names of its contributors
20  *   may be used to endorse or promote products derived from this
21  *   software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  *
35  */
36 
37 #include <stdio.h>
38 #include <stdlib.h>
39 
40 
41 #include "object.h"
42 
43 
44 
45 // Start of our linked list. It is made static so it can not be touched
46 // outside of this module. You should call the functions provided.
47 
48 static object_t *object_listhead = NULL;
49 
50 
51 
52 
53 
54 
55 
object_new(void)56 object_t *object_new(void)
57 {
58 	object_t *retval;
59 
60 
61 	retval = (object_t *)malloc(sizeof(*retval));
62 
63 	if (!retval) {
64 		perror("object_new");
65 		exit(-1);
66 	}
67 
68 
69 	// Clear the node, always good practise.
70 	memset(retval, 0, sizeof(*retval));
71 
72 
73 	// Insert into linked list.
74 	// For this sample, a linked list is never really required but
75 	// I have included it as an example, and therefor we can do
76 	// object_free_all, as well as a "iterate all connected" command.
77 	retval->next = object_listhead;
78 	object_listhead = retval;
79 
80 	// Return it to the caller
81 	return retval;
82 
83 }
84 
85 
86 
87 
88 
object_free(object_t * node)89 void object_free(object_t *node)
90 {
91 	object_t *prev, *runner;
92 
93 	if (node->username) {
94 		free( node->username );
95 		node->username = NULL;
96 	}
97 
98 
99 	// Remove it from the linked list.
100 
101 	for (prev = NULL, runner = object_listhead;
102 		 runner;
103 		 prev = runner, runner = runner->next) {
104 
105 
106 		if (runner == node) {  // This is the one to remove
107 
108 			if (!prev) {
109 
110 				// If no previous node, then it's at the start of the list
111 
112 				object_listhead = runner->next;
113 
114 			} else {
115 
116 				// In the middle somewhere
117 
118 				prev->next = runner->next;
119 
120 			}
121 
122 			break;  // Stop spinning in the for-loop.
123 
124 		} // if runner == node
125 
126 	} // for
127 
128 
129 	// Release it
130 	free( node );
131 
132 }
133 
134 
135 
object_free_all(void)136 void object_free_all(void)
137 {
138 
139 	// Since we call object_free() which re-arranges the linked-list
140 	// we can't just iterate it. So, slightly different semantics.
141 
142 	while( object_listhead ) {
143 
144 		object_free( object_listhead );
145 
146 	}
147 
148 
149 }
150 
151 
152 
153 //
154 // Find a particular node, or, iterate the list.
155 //
156 // IN:  comparison function, expected to return 0 on match
157 // IN:  two optional arguments that are simply passed on
158 // OUT: pointer to matching node, or NULL if end reached
159 //
object_find(int (* compare)(object_t *,void *,void *),void * optarg1,void * optarg2)160 object_t *object_find( int (*compare)(object_t *, void *, void *),
161 					   void *optarg1, void *optarg2)
162 {
163   object_t *runner;
164 
165   for (runner = object_listhead; runner; runner = runner->next) {
166 
167 	  if (!compare(runner, optarg1, optarg2)) {
168 
169 		  // Found it, apparently
170 		  return runner;
171 
172 	  }
173 
174   }
175 
176   // Didn't find it
177   return NULL;
178 
179 }
180 
181