2 Copyright (C) 2001-2010, Parrot Foundation.
7 src/pmc/packfiledirectory.pmc - PackfileDirectory PMC
11 This class implements a PackfileDirectory object, a segment of the .pbc data
12 file used for listing the rest of the file's contents. Essentially this
13 segment is a container for all other segments within a Packfile.
15 See packfile.pmc for the toplevel Packfile interface, see packfilesegment.pmc
16 for the list of common methods every packfile segment pmc must implement; see
17 PDD13 for the design spec.
28 /* HEADERIZER HFILE: none */
29 /* HEADERIZER BEGIN: static */
30 /* HEADERIZER END: static */
32 pmclass PackfileDirectory auto_attrs extends PackfileSegment {
33 /* Directory is a hash of Segments */
40 Initialize PackfileDirectory.
46 Parrot_PackfileDirectory_attributes * const attrs =
47 PMC_data_typed(SELF, Parrot_PackfileDirectory_attributes*);
49 attrs->hash = Parrot_pmc_new(INTERP, enum_class_Hash);
51 PObj_custom_mark_SET(SELF);
58 Marks the object as live.
65 Parrot_PackfileDirectory_attributes * const attrs =
66 PARROT_PACKFILEDIRECTORY(SELF);
68 Parrot_gc_mark_PMC_alive(INTERP, attrs->hash);
75 =item C<void set_pointer(void *ptr)>
77 Initialize PackfileDirectory from PackFile_Directory.
83 VTABLE void set_pointer(void *ptr) {
84 const PackFile_Directory * const pfd = (const PackFile_Directory *)ptr;
89 /* Iterate over elements and create corresponded PMCs */
90 for (i=0; i < pfd->num_segments; ++i) {
91 PackFile_Segment * const pfseg = pfd->segments[i];
96 switch (pfseg->type) {
98 pmc_type = enum_class_PackfileDirectory;
101 pmc_type = enum_class_PackfileFixupTable;
104 pmc_type = enum_class_PackfileConstantTable;
106 case PF_ANNOTATIONS_SEG:
107 pmc_type = enum_class_PackfileAnnotations;
110 pmc_type = enum_class_PackfileDebug;
115 pmc_type = enum_class_PackfileRawSegment;
119 segment = Parrot_pmc_new(INTERP, pmc_type);
121 VTABLE_set_pmc_keyed_str(INTERP, SELF, name, segment);
123 /* Initialize internal PMC structure */
124 VTABLE_set_pointer(INTERP, segment, pfseg);
131 =item C<void *get_pointer()>
133 Creates PackFile for given directory.
139 VTABLE void *get_pointer() {
140 Parrot_PackfileDirectory_attributes * attrs =
141 PARROT_PACKFILEDIRECTORY(SELF);
142 PackFile * const pf = PackFile_new(INTERP, 0); /* dummy PackFile... */
143 PackFile_Directory * const pfdir = &pf->directory;
144 PMC * const iter = VTABLE_get_iter(INTERP, attrs->hash);
146 /* Create Segments. Add to Directory with transfering ownership */
147 while (VTABLE_get_bool(INTERP, iter)) {
148 STRING * const name = VTABLE_shift_string(INTERP, iter);
149 PMC * const seg = VTABLE_get_pmc_keyed_str(INTERP, attrs->hash, name);
150 PackFile_Segment * const pfseg = (PackFile_Segment *)VTABLE_get_pointer(INTERP, seg);
154 PackFile_add_segment(INTERP, pfdir, pfseg);
162 =item C<INTVAL elements()>
164 Get the number of elements in the array.
169 VTABLE INTVAL elements() {
170 return VTABLE_elements(INTERP, PARROT_PACKFILEDIRECTORY(SELF)->hash);
176 =item C<PMC *get_iter()>
178 Return a new iterator for the directory.
184 VTABLE PMC *get_iter() {
185 return VTABLE_get_iter(INTERP, PARROT_PACKFILEDIRECTORY(SELF)->hash);
190 =item C<PMC *get_pmc_keyed_str(STRING *name)>
192 Search the array for a segment with the given name, and return it if it exists.
197 VTABLE PMC *get_pmc_keyed_str(STRING *name) {
198 return VTABLE_get_pmc_keyed_str(INTERP,
199 PARROT_PACKFILEDIRECTORY(SELF)->hash, name);
205 =item C<PMC *get_pmc_keyed(PMC *key)>
207 Fetch a keyed string value from the packfiledirectory object.
212 VTABLE PMC *get_pmc_keyed(PMC *key) {
213 STRING * const s_key = VTABLE_get_string(INTERP, key);
214 return VTABLE_get_pmc_keyed_str(INTERP,
215 PARROT_PACKFILEDIRECTORY(SELF)->hash, s_key);
221 =item C<void set_pmc_keyed_str(STRING *name, PMC *segment)>
223 Add a segment with the given name to the directory. If a segment with this
224 name already existed, it will be replaced with the new segment.
231 VTABLE void set_pmc_keyed_str(STRING *name, PMC *segment) {
232 Parrot_pcc_invoke_method_from_c_args(INTERP, segment,
233 Parrot_str_new_constant(INTERP, "set_directory"),
235 VTABLE_set_pmc_keyed_str(INTERP,
236 PARROT_PACKFILEDIRECTORY(SELF)->hash, name, segment);
241 =item C<PMC *set_pmc_keyed(PMC *key, PMC *segment)>
243 Add a segment with the given name to the directory. Dispatches to
250 VTABLE void set_pmc_keyed(PMC *key, PMC *segment) {
251 STRING * const s_key = VTABLE_get_string(INTERP, key);
252 VTABLE_set_pmc_keyed_str(INTERP, SELF, s_key, segment);
257 =item C<PMC *delete_keyed(PMC *key)>
259 Delete the specified segment from the directory.
265 VTABLE void delete_keyed(PMC *key) {
266 VTABLE_delete_keyed(INTERP,
267 PARROT_PACKFILEDIRECTORY(SELF)->hash, key);
283 * c-file-style: "parrot"
285 * vim: expandtab shiftwidth=4: