/*
 *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
 *  CVS Info
 *     $Id: managedstruct.pmc,v 1.17 2003/10/04 13:38:38 leo Exp $
 *  Overview:
 *     PMC class to hold structs that parrot's responsible for disposing of
 *  Data Structure and Algorithms:
 *  History:
 *     Initial revision by sean 2002/08/04
 *  Notes:
 *  References:
 */

#include "parrot/parrot.h"
#include "parrot/method_util.h"

pmclass ManagedStruct extends UnManagedStruct need_ext {

    void init () {
	SUPER();
	PObj_active_destroy_SET(SELF);
	SELF->cache.int_val = 0;
    }

    void init_pmc (PMC* value) {

	SELF.init();
	SUPER(value);
    }

    void destroy () {
	if (PMC_data(SELF)) {
	    mem_sys_free(PMC_data(SELF));
	}
    }

    /* Returns -1 for out-of-bounds access */
    INTVAL get_integer_keyed(PMC* key) {
	INTVAL ix;

	if (!key)
            return -1;
        ix = key_integer(INTERP, key);
        if (!PMC_ptr2p(SELF) && (ix < 0 || ix >= SELF->cache.int_val))
	    return -1;
	return SUPER(key);

    }

    INTVAL get_integer_keyed_int(INTVAL ix) {
        if (!PMC_ptr2p(SELF) && (ix < 0 || ix >= SELF->cache.int_val))
	    return -1;
	return SUPER(ix);
    }

    /* Does nothing for out-of-bound access */
    void set_integer_keyed (PMC* key, INTVAL value) {
        INTVAL ix;

        if (!key)
            return;
        ix = key_integer(INTERP, key);
        if (!PMC_ptr2p(SELF) && (ix < 0 || ix >= SELF->cache.int_val))
            return;
        SUPER(key, value);
    }

    void set_integer_keyed_int (INTVAL ix, INTVAL value) {
        if (!PMC_ptr2p(SELF) && (ix < 0 || ix >= SELF->cache.int_val))
            return;
        SUPER(ix, value);
    }

    INTVAL get_integer () {
        return(SELF->cache.int_val);
    }

    void set_integer_native (INTVAL value) {
        if (PMC_data(SELF) && (! value)) {
            mem_sys_free(PMC_data(SELF));
            PMC_data(SELF) = NULL;
            SELF->cache.int_val = 0;
        }
        else if (value && (! PMC_data(SELF))) {
            PMC_data(SELF) = mem_sys_allocate_zeroed(value);
            SELF->cache.int_val = value;
        }
        else if (value && PMC_data(SELF)) {
            PMC_data(SELF) = mem_sys_realloc(PMC_data(SELF), value);
            SELF->cache.int_val = value;
        }
        return;
    }

}
