X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmono-mlist.c;h=657a21348dc8829ec9fe6e635292728495b5f9a7;hb=5c11fe647563fa051f73d3571da839dfccd26f8e;hp=7e90b652dd5901714b31f60bfb95725fd85a8404;hpb=3c2f3d4ea99c758f9de2d3493d25849824678956;p=mono.git diff --git a/mono/metadata/mono-mlist.c b/mono/metadata/mono-mlist.c index 7e90b652dd5..657a21348dc 100644 --- a/mono/metadata/mono-mlist.c +++ b/mono/metadata/mono-mlist.c @@ -5,6 +5,7 @@ * 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" @@ -12,6 +13,11 @@ #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; @@ -39,14 +45,35 @@ MonoMList* 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; } @@ -151,7 +178,29 @@ mono_mlist_last (MonoMList* list) 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; @@ -169,7 +218,30 @@ mono_mlist_prepend (MonoMList* list, MonoObject *data) 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);