2010-03-30 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mono / metadata / mono-mlist.c
bloba7543b50f851ec194734d38cd5c576bf9ad65d40
1 /*
2 * mono-mlist.c: Managed object list implementation
4 * Author:
5 * Paolo Molaro (lupus@ximian.com)
7 * Copyright 2006-2009 Novell, Inc (http://www.novell.com)
8 */
10 #include "mono/metadata/mono-mlist.h"
11 #include "mono/metadata/appdomain.h"
12 #include "mono/metadata/class-internals.h"
14 /* matches the System.MonoListItem object*/
15 struct _MonoMList {
16 MonoObject object;
17 MonoMList *next;
18 MonoObject *data;
21 /*
22 * note: we only allocate in the root domain: this lists are
23 * not exposed to managed code
25 static MonoVTable *monolist_item_vtable = NULL;
27 /**
28 * mono_mlist_alloc:
29 * @data: object to use as data
31 * Allocates a new managed list node with @data as the contents.
32 * A managed list node also represents a singly-linked list.
33 * Managed lists are garbage collected, so there is no free routine
34 * and the user is required to keep references to the managed list
35 * to prevent it from being garbage collected.
37 MonoMList*
38 mono_mlist_alloc (MonoObject *data)
40 MonoMList* res;
41 if (!monolist_item_vtable) {
42 MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System", "MonoListItem");
43 monolist_item_vtable = mono_class_vtable (mono_get_root_domain (), klass);
44 g_assert (monolist_item_vtable);
46 res = (MonoMList*)mono_object_new_fast (monolist_item_vtable);
47 MONO_OBJECT_SETREF (res, data, data);
48 return res;
51 /**
52 * mono_mlist_get_data:
53 * @list: the managed list node
55 * Get the object stored in the list node @list.
57 MonoObject*
58 mono_mlist_get_data (MonoMList* list)
60 return list->data;
63 /**
64 * mono_mlist_set_data:
65 * @list: the managed list node
67 * Set the object content in the list node @list.
69 void
70 mono_mlist_set_data (MonoMList* list, MonoObject *data)
72 MONO_OBJECT_SETREF (list, data, data);
75 /**
76 * mono_mlist_set_next:
77 * @list: a managed list node
78 * @next: list node that will be next for the @list node.
80 * Set next node for @list to @next.
82 MonoMList *
83 mono_mlist_set_next (MonoMList* list, MonoMList *next)
85 if (!list)
86 return next;
88 MONO_OBJECT_SETREF (list, next, next);
89 return list;
92 /**
93 * mono_mlist_length:
94 * @list: the managed list
96 * Get the number of items in the list @list.
97 * Since managed lists are singly-linked, this operation takes O(n) time.
99 int
100 mono_mlist_length (MonoMList* list)
102 int len = 0;
103 while (list) {
104 list = list->next;
105 ++len;
107 return len;
111 * mono_mlist_next:
112 * @list: the managed list node
114 * Returns the next managed list node starting from @list.
116 MonoMList*
117 mono_mlist_next (MonoMList* list)
119 return list->next;
123 * mono_mlist_last:
124 * @list: the managed list node
126 * Returns the last managed list node in list @list.
127 * Since managed lists are singly-linked, this operation takes O(n) time.
129 MonoMList*
130 mono_mlist_last (MonoMList* list)
132 if (list) {
133 while (list->next)
134 list = list->next;
135 return list;
137 return NULL;
141 * mono_mlist_prepend:
142 * @list: the managed list
143 * @data: the object to add to the list
145 * Allocate a new list node with @data as content and prepend it
146 * to the list @list. @list can be NULL.
148 MonoMList*
149 mono_mlist_prepend (MonoMList* list, MonoObject *data)
151 MonoMList* res = mono_mlist_alloc (data);
152 if (list)
153 MONO_OBJECT_SETREF (res, next, list);
154 return res;
158 * mono_mlist_append:
159 * @list: the managed list
160 * @data: the object to add to the list
162 * Allocate a new list node with @data as content and append it
163 * to the list @list. @list can be NULL.
164 * Since managed lists are singly-linked, this operation takes O(n) time.
166 MonoMList*
167 mono_mlist_append (MonoMList* list, MonoObject *data)
169 MonoMList* res = mono_mlist_alloc (data);
170 if (list) {
171 MonoMList* last = mono_mlist_last (list);
172 MONO_OBJECT_SETREF (last, next, res);
173 return list;
174 } else {
175 return res;
179 static MonoMList*
180 find_prev (MonoMList* list, MonoMList *item)
182 MonoMList* prev = NULL;
183 while (list) {
184 if (list == item)
185 break;
186 prev = list;
187 list = list->next;
189 return prev;
193 * mono_mlist_remove_item:
194 * @list: the managed list
195 * @data: the object to remove from the list
197 * Remove the list node @item from the managed list @list.
198 * Since managed lists are singly-linked, this operation can take O(n) time.
200 MonoMList*
201 mono_mlist_remove_item (MonoMList* list, MonoMList *item)
203 MonoMList* prev;
204 if (list == item) {
205 list = item->next;
206 item->next = NULL;
207 return list;
209 prev = find_prev (list, item);
210 if (prev) {
211 MONO_OBJECT_SETREF (prev, next, item->next);
212 item->next = NULL;
213 return list;
214 } else {
215 /* not found */
216 return list;