blob: 63b8445857ef78d74118165592c8c68e7d508742 [file] [log] [blame]
/* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version
* 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* etch_collection.c -- collection support
*/
#include "etch_collection.h"
#include "etch_object.h"
#include "etch_objecttypes.h"
#include "etch_mem.h"
int default_iterable_first (etch_iterator*);
int default_iterable_next (etch_iterator*);
int default_iterable_has_next(etch_iterator*);
/**
* new_iterable()
* constructor for an i_iterable interface
*/
i_iterable* new_iterable(i_iterable* thisp, i_iterable* parent, iterable_first func_first,
iterable_next func_next, iterable_has_next func_hasnext)
{
i_iterable* vtab = NULL;
if (thisp) /* initializing existing object? */
vtab = thisp;
else vtab = new_vtable(parent, sizeof(i_iterable), CLASSID_ITERABLE_VTAB);
if (NULL == vtab) return NULL;
vtab->first = func_first? func_first: default_iterable_first;
vtab->next = func_next? func_next: default_iterable_next;
vtab->has_next = func_hasnext? func_hasnext: default_iterable_has_next;
return vtab;
}
/**
* destroy_iterator()
* iterator destructor
*/
int destroy_iterator(void* data)
{
etch_iterator* iterator = data;
/* iterator owns itself, and possibly the collection.
* its vtable is owned by the collection. */
if (!is_etchobj_static_shell(iterator))
{
if (iterator->is_own_collection)
((etch_object*)iterator->collection)->destroy(iterator->collection);
etch_free(iterator);
}
return 0;
}
/**
* clone_iterator()
* iterator copy constructor
*/
void* clone_iterator(void* data)
{
etch_iterator* iterator = data;
etch_iterator* newobj = etch_malloc(sizeof(struct etch_iterator), ETCHTYPEB_ITERATOR);
memcpy(newobj, iterator, sizeof(struct etch_iterator));
return newobj;
}
/**
* new_iterator()
* constructor for an etch_iterator object.
*/
etch_iterator* new_iterator(void* collection, i_iterable* iterable)
{
etch_iterator* iterator = etch_malloc(sizeof(etch_iterator), ETCHTYPEB_ITERATOR);
set_iterator(iterator, collection, iterable);
return iterator;
}
/**
* set_iterator()
* constructor for an existing etch_iterator object.
*/
int set_iterator(etch_iterator* iterator, void* collection, i_iterable* iterable)
{
memset(iterator, 0, sizeof(etch_iterator));
((etch_object*)iterator)->obj_type = ETCHTYPEB_ITERATOR;
((etch_object*)iterator)->class_id = CLASSID_ITERATOR;
((etch_object*)iterator)->vtab = (vtabmask*)iterable;
iterator->collection = collection;
((etch_object*)iterator)->destroy = destroy_iterator;
((etch_object*)iterator)->clone = clone_iterator;
iterator->first = iterable->first;
iterator->next = iterable->next;
iterator->has_next = iterable->has_next;
iterator->first(iterator); /* establish initial position */
return 0;
}
/**
* new_empty_iterator()
* constructor for an empty etch_iterator object, i.e. has_next() is false
*/
etch_iterator* new_empty_iterator()
{
etch_iterator* iterator = etch_malloc(sizeof(etch_iterator), ETCHTYPEB_ITERATOR);
((etch_object*)iterator)->obj_type = ETCHTYPEB_ITERATOR;
((etch_object*)iterator)->class_id = CLASSID_ITERATOR;
((etch_object*)iterator)->destroy = destroy_iterator;
iterator->first = default_iterable_first;
iterator->next = default_iterable_next;
iterator->has_next = default_iterable_has_next;
return iterator;
}
/**
* default_iterable_first()
* i_iterable first() default virtual method
*/
int default_iterable_first(etch_iterator* i)
{
return -1;
}
/**
* default_iterable_next()
* i_iterable next() default virtual method
*/
int default_iterable_next(etch_iterator* i)
{
return -1;
}
/**
* default_iterable_has_next()
* i_iterable has_next() default virtual method
*/
int default_iterable_has_next (etch_iterator* i)
{
return FALSE;
}
/**
* etch_comparator_noteq(), etch_comparator_equal
* comparators to use when a result not dependent on parameters is desired,
* such as when using an add_from method to add to a collection when the
* target collection is empty and thus no contains() comparison is needed.
*/
int etch_comparator_noteq(void* a, void* b) { return -1;}
int etch_comparator_equal(void* a, void* b) { return 0; }