/*
Copyright (C) 2001-2010, Parrot Foundation.
$Id: packfiledebug.pmc 46156 2010-04-29 21:37:43Z mikehh $

=head1 NAME

src/pmc/packfiledebug.pmc - Packfile Debug Segment PMC

=head1 DESCRIPTION

This class implements a PackfileDebug object, a segment of the .pbc
data file used for storing pir debug information.

See packfile.pmc for the toplevel Packfile interface, see packfilesegment.pmc
for the list of common methods every packfile segment pmc must implement; see
PDD13 for the design spec.

Initial and experimental version, using some vtables as a quick way of testing.

=head2 Vtable functions

=over 4

=cut

*/

/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */

pmclass PackfileDebug auto_attrs extends PackfileRawSegment {
    /* Number of file mappings */
    ATTR INTVAL num_mappings;
    /* File name mapping */
    ATTR PMC *mapping_offset;
    ATTR PMC *mapping_filename;

/*

=item C<init>

Create empty PackfileDebug.

=cut

*/

    VTABLE void init() {
        SUPER();
        SET_ATTR_type(INTERP, SELF, PF_DEBUG_SEG);
    }

/*

=item C<void mark()>

Marks the object as live.

=cut

*/

    VTABLE void mark() {
        PMC *mapping_offset;
        PMC *mapping_filename;
        GET_ATTR_mapping_offset(INTERP, SELF, mapping_offset);
        GET_ATTR_mapping_filename(INTERP, SELF, mapping_filename);
        Parrot_gc_mark_PMC_alive(INTERP, mapping_offset);
        Parrot_gc_mark_PMC_alive(INTERP, mapping_filename);

        SUPER();
    }


/*

=item C<set_pointer>

Set pointer to underlying PackFile_ConstTable

=cut

*/

    VTABLE void set_pointer(void * pointer) {
        PackFile_Debug *p = (PackFile_Debug *) pointer;
        INTVAL num_mappings = p->num_mappings;
        PMC *mapping_offset = Parrot_pmc_new_init_int(INTERP,
                                                      enum_class_FixedIntegerArray, num_mappings);
        PMC *mapping_filename = Parrot_pmc_new_init_int(INTERP,
                                                      enum_class_FixedIntegerArray, num_mappings);
        INTVAL i;
        STRING *t = CONST_STRING(INTERP, "test");

        SUPER(pointer);
        for (i = 0; i < num_mappings; ++i) {
            VTABLE_set_integer_keyed_int(INTERP, mapping_offset, i, p->mappings[i].offset);
            VTABLE_set_integer_keyed_int(INTERP, mapping_filename, i, p->mappings[i].filename);
        }
        SET_ATTR_num_mappings(INTERP, SELF, p->num_mappings);
        SET_ATTR_mapping_offset(INTERP, SELF, mapping_offset);
        SET_ATTR_mapping_filename(INTERP, SELF, mapping_filename);
    }

/*

=item C<void *get_pointer()>
=cut

*/

    VTABLE void *get_pointer() {
        PackFile_Debug *p = (PackFile_Debug *) mem_gc_realloc_n_typed(INTERP,
                                                           SUPER(), sizeof (PackFile_Debug), char);
        INTVAL num_mappings;
        PMC *mapping_offset;
        PMC *mapping_filename;
        INTVAL i;
        GET_ATTR_num_mappings(INTERP, SELF, num_mappings);
        GET_ATTR_mapping_offset(INTERP, SELF, mapping_offset);
        GET_ATTR_mapping_filename(INTERP, SELF, mapping_filename);
        p->num_mappings = num_mappings;
        p->mappings = mem_gc_allocate_n_typed(INTERP, num_mappings, PackFile_DebugFilenameMapping);
        for (i = 0; i < num_mappings; ++i) {
            p->mappings[i].offset = VTABLE_get_integer_keyed_int(INTERP, mapping_offset, i);
            p->mappings[i].filename = VTABLE_get_integer_keyed_int(INTERP, mapping_filename, i);
        }
        return p;
    }

/*

=item C<INTVAL get_integer()>

Get the number of filename mappings.

=cut

*/

    VTABLE INTVAL get_integer() {
        INTVAL num_mappings;
        GET_ATTR_num_mappings(INTERP, SELF, num_mappings);
        return num_mappings;
    }

/*

=item C<INTVAL get_string_keyed_int(INTVAL n)>

Get the filename mapping n.

=cut

*/

    VTABLE PMC *get_pmc_keyed_int(INTVAL n) {
        INTVAL num_mappings;
        GET_ATTR_num_mappings(INTERP, SELF, num_mappings);
        if (n < num_mappings) {
            PMC *mapping_offset;
            INTVAL offset;
            PMC *result;
            GET_ATTR_mapping_offset(INTERP, SELF, mapping_offset);
            offset = VTABLE_get_integer_keyed_int(INTERP, mapping_offset, n);
            result = Parrot_pmc_new(INTERP, enum_class_Integer);
            VTABLE_set_integer_native(INTERP, result, offset);
            return result;
        }
        else return PMCNULL;
    }

/*

=item C<INTVAL get_string_keyed_int(INTVAL n)>

Get the filename mapping n.

=cut

*/

    VTABLE STRING *get_string_keyed_int(INTVAL n) {
        INTVAL num_mappings;
        GET_ATTR_num_mappings(INTERP, SELF, num_mappings);
        if (n < num_mappings) {
            PMC *mapping_filename;
            GET_ATTR_mapping_filename(INTERP, SELF, mapping_filename);
            return VTABLE_get_string_keyed_int(INTERP, mapping_filename, n);
        }
        else return STRINGNULL;
    }

}

/*

=back

=cut

*/

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