Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: 777/no_pretty_…
Fetching contributors…

Cannot retrieve contributors at this time

290 lines (187 sloc) 6.326 kb
/*
Copyright (C) 2001-2010, Parrot Foundation.
=head1 NAME
src/pmc/packfiledirectory.pmc - PackfileDirectory PMC
=head1 DESCRIPTION
This class implements a PackfileDirectory object, a segment of the .pbc data
file used for listing the rest of the file's contents. Essentially this
segment is a container for all other segments within a Packfile.
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.
=head2 Methods
=over 4
=cut
*/
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */
pmclass PackfileDirectory auto_attrs extends PackfileSegment {
/* Directory is a hash of Segments */
ATTR PMC *hash;
/*
=item C<void init()>
Initialize PackfileDirectory.
=cut
*/
VTABLE void init() {
Parrot_PackfileDirectory_attributes * const attrs =
PMC_data_typed(SELF, Parrot_PackfileDirectory_attributes*);
attrs->hash = Parrot_pmc_new(INTERP, enum_class_Hash);
PObj_custom_mark_SET(SELF);
}
/*
=item C<void mark()>
Marks the object as live.
=cut
*/
VTABLE void mark() {
Parrot_PackfileDirectory_attributes * const attrs =
PARROT_PACKFILEDIRECTORY(SELF);
Parrot_gc_mark_PMC_alive(INTERP, attrs->hash);
SUPER();
}
/*
=item C<void set_pointer(void *ptr)>
Initialize PackfileDirectory from PackFile_Directory.
=cut
*/
VTABLE void set_pointer(void *ptr) {
const PackFile_Directory * const pfd = (const PackFile_Directory *)ptr;
size_t i;
SUPER(ptr);
/* Iterate over elements and create corresponded PMCs */
for (i=0; i < pfd->num_segments; ++i) {
PackFile_Segment * const pfseg = pfd->segments[i];
int pmc_type;
PMC *segment;
STRING *name;
switch (pfseg->type) {
case PF_DIR_SEG:
pmc_type = enum_class_PackfileDirectory;
break;
case PF_CONST_SEG:
pmc_type = enum_class_PackfileConstantTable;
break;
case PF_ANNOTATIONS_SEG:
pmc_type = enum_class_PackfileAnnotations;
break;
case PF_DEBUG_SEG:
pmc_type = enum_class_PackfileDebug;
break;
case PF_BYTEC_SEG:
pmc_type = enum_class_PackfileBytecodeSegment;
break;
case PF_UNKNOWN_SEG:
default:
pmc_type = enum_class_PackfileRawSegment;
break;
}
segment = Parrot_pmc_new(INTERP, pmc_type);
name = pfseg->name;
VTABLE_set_pmc_keyed_str(INTERP, SELF, name, segment);
/* Initialize internal PMC structure */
VTABLE_set_pointer(INTERP, segment, pfseg);
}
}
/*
=item C<void *get_pointer()>
Creates PackFile for given directory.
=cut
*/
VTABLE void *get_pointer() {
Parrot_PackfileDirectory_attributes * attrs =
PARROT_PACKFILEDIRECTORY(SELF);
PackFile * const pf = PackFile_new(INTERP, 0); /* dummy PackFile... */
PackFile_Directory * const pfdir = &pf->directory;
PMC * const iter = VTABLE_get_iter(INTERP, attrs->hash);
/* Create Segments. Add to Directory with transfering ownership */
while (VTABLE_get_bool(INTERP, iter)) {
STRING * const name = VTABLE_shift_string(INTERP, iter);
PMC * const seg = VTABLE_get_pmc_keyed_str(INTERP, attrs->hash, name);
PackFile_Segment * const pfseg = (PackFile_Segment *)VTABLE_get_pointer(INTERP, seg);
pfseg->pf = pf;
pfseg->name = name;
PackFile_add_segment(INTERP, pfdir, pfseg);
}
return pf;
}
/*
=item C<INTVAL elements()>
Get the number of elements in the array.
=cut
*/
VTABLE INTVAL elements() {
return VTABLE_elements(INTERP, PARROT_PACKFILEDIRECTORY(SELF)->hash);
}
/*
=item C<PMC *get_iter()>
Return a new iterator for the directory.
=cut
*/
VTABLE PMC *get_iter() {
return VTABLE_get_iter(INTERP, PARROT_PACKFILEDIRECTORY(SELF)->hash);
}
/*
=item C<PMC *get_pmc_keyed_str(STRING *name)>
Search the array for a segment with the given name, and return it if it exists.
=cut
*/
VTABLE PMC *get_pmc_keyed_str(STRING *name) {
return VTABLE_get_pmc_keyed_str(INTERP,
PARROT_PACKFILEDIRECTORY(SELF)->hash, name);
}
/*
=item C<PMC *get_pmc_keyed(PMC *key)>
Fetch a keyed string value from the packfiledirectory object.
=cut
*/
VTABLE PMC *get_pmc_keyed(PMC *key) {
STRING * const s_key = VTABLE_get_string(INTERP, key);
return VTABLE_get_pmc_keyed_str(INTERP,
PARROT_PACKFILEDIRECTORY(SELF)->hash, s_key);
}
/*
=item C<void set_pmc_keyed_str(STRING *name, PMC *segment)>
Add a segment with the given name to the directory. If a segment with this
name already existed, it will be replaced with the new segment.
=cut
TODO: check type
*/
VTABLE void set_pmc_keyed_str(STRING *name, PMC *segment) {
Parrot_pcc_invoke_method_from_c_args(INTERP, segment,
Parrot_str_new_constant(INTERP, "set_directory"),
"P->", SELF);
VTABLE_set_pmc_keyed_str(INTERP,
PARROT_PACKFILEDIRECTORY(SELF)->hash, name, segment);
}
/*
=item C<PMC *set_pmc_keyed(PMC *key, PMC *segment)>
Add a segment with the given name to the directory. Dispatches to
set_pmc_keyed_str.
=cut
*/
VTABLE void set_pmc_keyed(PMC *key, PMC *segment) {
STRING * const s_key = VTABLE_get_string(INTERP, key);
VTABLE_set_pmc_keyed_str(INTERP, SELF, s_key, segment);
}
/*
=item C<PMC *delete_keyed(PMC *key)>
Delete the specified segment from the directory.
=cut
*/
VTABLE void delete_keyed(PMC *key) {
VTABLE_delete_keyed(INTERP,
PARROT_PACKFILEDIRECTORY(SELF)->hash, key);
}
}
/*
=back
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/
Jump to Line
Something went wrong with that request. Please try again.