* Paolo Molaro (lupus@ximian.com)
*
* Copyright 2006-2009 Novell, Inc (http://www.novell.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include "mono/metadata/mono-mlist.h"
#include "mono/metadata/class-internals.h"
#include "mono/metadata/object-internals.h"
+
+static
+MonoMList* mono_mlist_alloc_checked (MonoObject *data, MonoError *error);
+
+
/* matches the System.MonoListItem object*/
struct _MonoMList {
MonoObject object;
mono_mlist_alloc (MonoObject *data)
{
MonoError error;
+ MonoMList *result = mono_mlist_alloc_checked (data, &error);
+ mono_error_cleanup (&error);
+ return result;
+}
+
+/**
+ * mono_mlist_alloc_checked:
+ * @data: object to use as data
+ * @error: set on error
+ *
+ * Allocates a new managed list node with @data as the contents. A
+ * managed list node also represents a singly-linked list. Managed
+ * lists are garbage collected, so there is no free routine and the
+ * user is required to keep references to the managed list to prevent
+ * it from being garbage collected. On failure returns NULL and sets
+ * @error.
+ */
+MonoMList*
+mono_mlist_alloc_checked (MonoObject *data, MonoError *error)
+{
+ error_init (error);
MonoMList* res;
if (!monolist_item_vtable) {
MonoClass *klass = mono_class_load_from_name (mono_defaults.corlib, "System", "MonoListItem");
monolist_item_vtable = mono_class_vtable (mono_get_root_domain (), klass);
g_assert (monolist_item_vtable);
}
- res = (MonoMList*)mono_object_new_fast_checked (monolist_item_vtable, &error);
- mono_error_raise_exception (&error);
+ res = (MonoMList*)mono_object_new_fast_checked (monolist_item_vtable, error);
+ return_val_if_nok (error, NULL);
MONO_OBJECT_SETREF (res, data, data);
return res;
}
MonoMList*
mono_mlist_prepend (MonoMList* list, MonoObject *data)
{
- MonoMList* res = mono_mlist_alloc (data);
+ MonoError error;
+ MonoMList *result = mono_mlist_prepend_checked (list, data, &error);
+ mono_error_cleanup (&error);
+ return result;
+}
+
+/**
+ * mono_mlist_prepend_checked:
+ * @list: the managed list
+ * @data: the object to add to the list
+ * @error: set on error
+ *
+ * Allocate a new list node with @data as content and prepend it to
+ * the list @list. @list can be NULL. On failure returns NULL and sets
+ * @error.
+ */
+MonoMList*
+mono_mlist_prepend_checked (MonoMList* list, MonoObject *data, MonoError *error)
+{
+ error_init (error);
+ MonoMList* res = mono_mlist_alloc_checked (data, error);
+ return_val_if_nok (error, NULL);
+
if (list)
MONO_OBJECT_SETREF (res, next, list);
return res;
MonoMList*
mono_mlist_append (MonoMList* list, MonoObject *data)
{
- MonoMList* res = mono_mlist_alloc (data);
+ MonoError error;
+ MonoMList *result = mono_mlist_append_checked (list, data, &error);
+ mono_error_cleanup (&error);
+ return result;
+}
+
+/**
+ * mono_mlist_append_checked:
+ * @list: the managed list
+ * @data: the object to add to the list
+ * @error: set on error
+ *
+ * Allocate a new list node with @data as content and append it
+ * to the list @list. @list can be NULL.
+ * Since managed lists are singly-linked, this operation takes O(n) time.
+ * On failure returns NULL and sets @error.
+ */
+MonoMList*
+mono_mlist_append_checked (MonoMList* list, MonoObject *data, MonoError *error)
+{
+ error_init (error);
+ MonoMList* res = mono_mlist_alloc_checked (data, error);
+ return_val_if_nok (error, NULL);
+
if (list) {
MonoMList* last = mono_mlist_last (list);
MONO_OBJECT_SETREF (last, next, res);