/*
 * $Id: /mirror/trunk/languages/dotnet/pmc/dotnetclassmetadata.pmc 29983 2008-08-02T22:45:13.271765Z allison  $
 * Copyright (C) 2006-2008, The Perl Foundation.
 */

/* .NET CLI Class Metadata PMC */


#include "parrot/extend.h"
#include "tableinfo.h"
#include "structures.h"


pmclass DotNetClassMetadata dynpmc group dotnet {

    /* Instance initialization. We need a custom DOD marking and destroy. */
    void init()
    {
        PObj_custom_mark_SET(SELF);
        PObj_active_destroy_SET(SELF);
    }


    /* Get string vtable function; returns the name of the class. */
    STRING* get_string()
    {
        dotnet_class *c = (dotnet_class *)PMC_struct_val(SELF);

        /* Handle cases where we've an invalid PMC. */
        if (!c || !c->str_name)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetClassMetadata PMC");

        return c->str_name;
    }


    /* Garbage Collection mark routine. */
    void mark()
    {
        /* Tell the GC about stuff we're holding on to. */
        dotnet_class *c = (dotnet_class *)PMC_struct_val(SELF);
        if (c) {
            if (c->parent)
                pobject_lives(INTERP, (PObj *)c->parent);
            if (c->str_name)
                pobject_lives(INTERP, (PObj *)c->str_name);
            if (c->str_namespace)
                pobject_lives(INTERP, (PObj *)c->str_namespace);
            if (c->str_fullname)
                pobject_lives(INTERP, (PObj *)c->str_fullname);
            if (c->fields)
                pobject_lives(INTERP, (PObj *)c->fields);
            if (c->methods)
                pobject_lives(INTERP, (PObj *)c->methods);
            if (c->interface_types)
                pobject_lives(INTERP, (PObj *)c->interface_types);
            if (c->interface_ids)
                pobject_lives(INTERP, (PObj *)c->interface_ids);
        }
    }


    /* Destructor. */
    void destroy()
    {
        /* Cleanup any memory we're using. */
        if (PMC_struct_val(SELF))
        {
            mem_sys_free(PMC_struct_val(SELF));
            PMC_struct_val(SELF) = NULL;
        }
    }


    /* Get the namespace of the class. */
        METHOD STRING* get_namespace()
    {
        dotnet_class *c = (dotnet_class *)PMC_struct_val(SELF);
        STRING       *result;

        /* Handle cases where we've an invalid PMC. */
        if (!c)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetClassMetadata PMC");

        result = c->str_namespace;
        RETURN(STRING *result);
    }


    /* Get the fully qualified name of the class. */
    METHOD STRING* get_fullname()
    {
        dotnet_class *c = (dotnet_class *)PMC_struct_val(SELF);
        STRING       *result;

        /* Handle cases where we've an invalid PMC. */
        if (!c)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetClassMetadata PMC");

        result = c->str_fullname;
        RETURN(STRING *result);
    }


    /* Get the flags of the class. */
    METHOD INTVAL get_flags()
    {
        dotnet_class *c = (dotnet_class *)PMC_struct_val(SELF);
        INTVAL        result;

        /* Handle cases where we've an invalid PMC. */
        if (!c)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetClassMetadata PMC");

        result = (INTVAL)c->flags;
        RETURN(INTVAL result);
    }

    /* Get a PMC array of fields belonging to the class. */
    METHOD PMC* get_fields()
    {
        dotnet_class *c = (dotnet_class *)PMC_struct_val(SELF);
        PMC          *result;

        /* Handle cases where we've an invalid PMC or no fields. */
        if (!c)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetClassMetadata PMC");

        if (c->fields)
            result = c->fields;
        else
            result = pmc_new(INTERP, enum_class_FixedPMCArray);

        RETURN(PMC *result);
    }


    /* Get a PMC array of methods belonging to the class. */
    METHOD PMC* get_methods()
    {
        dotnet_class *c = (dotnet_class *)PMC_struct_val(SELF);
        PMC          *result;

        /* Handle cases where we've an invalid PMC or no methods. */
        if (!c)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetClassMetadata PMC");

        if (c->methods)
            result = c->methods;
        else
            result = pmc_new(INTERP, enum_class_FixedPMCArray);

        RETURN(PMC *result);
    }


    /* Get the id of the class that this one inherits. */
    METHOD INTVAL get_parent_id()
    {
        dotnet_class *c = (dotnet_class *)PMC_struct_val(SELF);
        INTVAL        result;

        /* Handle cases where we've an invalid PMC. */
        if (!c)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetClassMetadata PMC");

        result = (INTVAL)c->parent_id;
        RETURN(INTVAL result);
    }


    /* Get the type of the class that this one inherits. This is either a
       type defined in this module or a reference to another module. */
    METHOD INTVAL get_parent_type()
    {
        dotnet_class *c = (dotnet_class *)PMC_struct_val(SELF);
        INTVAL        result;

        /* Handle cases where we've an invalid PMC. */
        if (!c)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetClassMetadata PMC");

        result = (INTVAL)c->parent_type;

        RETURN(INTVAL result);
    }


    /* Get the array of ids of the interfaces this class implements. */
    METHOD PMC* get_interface_ids()
    {
        dotnet_class *c = (dotnet_class *)PMC_struct_val(SELF);
        PMC          *result;

        /* Handle cases where we've an invalid PMC. */
        if (!c || !c->interface_ids)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetClassMetadata PMC");

        result =  c->interface_ids;
        RETURN(PMC *result);
    }


    /* Get the array of types of the interfaces this class implements. */
    METHOD PMC* get_interface_types()
    {
        dotnet_class *c = (dotnet_class *)PMC_struct_val(SELF);
        PMC          *result;

        /* Handle cases where we've an invalid PMC. */
        if (!c || !c->interface_types)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetClassMetadata PMC");

        result = c->interface_types;
        RETURN(PMC *result);
    }
}


/*
 * Local variables:
 *   c-file-style: "parrot"
 * End:
 * vim: expandtab shiftwidth=4:
 */
