fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / pmc / packfiledirectory.pmc
blob410fcbb9cc51d34881937e2a014eb9fcd94f55df
1 /*
2 Copyright (C) 2001-2010, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc/packfiledirectory.pmc - PackfileDirectory PMC
9 =head1 DESCRIPTION
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.
20 =head2 Methods
22 =over 4
24 =cut
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 */
34     ATTR PMC *hash;
38 =item C<void init()>
40 Initialize PackfileDirectory.
42 =cut
45     VTABLE void init() {
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);
52     }
56 =item C<void mark()>
58 Marks the object as live.
60 =cut
64     VTABLE void mark() {
65         Parrot_PackfileDirectory_attributes * const attrs =
66                 PARROT_PACKFILEDIRECTORY(SELF);
68         Parrot_gc_mark_PMC_alive(INTERP, attrs->hash);
70         SUPER();
71     }
75 =item C<void set_pointer(void *ptr)>
77 Initialize PackfileDirectory from PackFile_Directory.
79 =cut
83     VTABLE void set_pointer(void *ptr) {
84         const PackFile_Directory * const pfd = (const PackFile_Directory *)ptr;
85         size_t i;
87         SUPER(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];
92             int     pmc_type;
93             PMC     *segment;
94             STRING  *name;
96             switch (pfseg->type) {
97               case PF_DIR_SEG:
98                 pmc_type = enum_class_PackfileDirectory;
99                 break;
100               case PF_FIXUP_SEG:
101                 pmc_type = enum_class_PackfileFixupTable;
102                 break;
103               case PF_CONST_SEG:
104                 pmc_type = enum_class_PackfileConstantTable;
105                 break;
106               case PF_ANNOTATIONS_SEG:
107                 pmc_type = enum_class_PackfileAnnotations;
108                 break;
109               case PF_DEBUG_SEG:
110                 pmc_type = enum_class_PackfileDebug;
111                 break;
112               case PF_BYTEC_SEG:
113               case PF_UNKNOWN_SEG:
114               default:
115                 pmc_type = enum_class_PackfileRawSegment;
116                 break;
117             }
119             segment = Parrot_pmc_new(INTERP, pmc_type);
120             name    = pfseg->name;
121             VTABLE_set_pmc_keyed_str(INTERP, SELF, name, segment);
123             /* Initialize internal PMC structure */
124             VTABLE_set_pointer(INTERP, segment, pfseg);
126         }
127     }
131 =item C<void *get_pointer()>
133 Creates PackFile for given directory.
135 =cut
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);
152             pfseg->pf   = pf;
153             pfseg->name = name;
154             PackFile_add_segment(INTERP, pfdir, pfseg);
155         }
157         return pf;
158     }
162 =item C<INTVAL elements()>
164 Get the number of elements in the array.
166 =cut
169     VTABLE INTVAL elements() {
170         return VTABLE_elements(INTERP, PARROT_PACKFILEDIRECTORY(SELF)->hash);
171     }
176 =item C<PMC *get_iter()>
178 Return a new iterator for the directory.
180 =cut
184     VTABLE PMC *get_iter() {
185         return VTABLE_get_iter(INTERP, PARROT_PACKFILEDIRECTORY(SELF)->hash);
186     }
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.
194 =cut
197     VTABLE PMC *get_pmc_keyed_str(STRING *name)  {
198         return VTABLE_get_pmc_keyed_str(INTERP,
199                 PARROT_PACKFILEDIRECTORY(SELF)->hash, name);
200     }
205 =item C<PMC *get_pmc_keyed(PMC *key)>
207 Fetch a keyed string value from the packfiledirectory object.
209 =cut
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);
216     }
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.
226 =cut
228 TODO: check type
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"),
234             "P->", SELF);
235         VTABLE_set_pmc_keyed_str(INTERP,
236             PARROT_PACKFILEDIRECTORY(SELF)->hash, name, segment);
237     }
241 =item C<PMC *set_pmc_keyed(PMC *key, PMC *segment)>
243 Add a segment with the given name to the directory.  Dispatches to
244 set_pmc_keyed_str.
246 =cut
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);
253     }
257 =item C<PMC *delete_keyed(PMC *key)>
259 Delete the specified segment from the directory.
261 =cut
265     VTABLE void delete_keyed(PMC *key) {
266         VTABLE_delete_keyed(INTERP,
267             PARROT_PACKFILEDIRECTORY(SELF)->hash, key);
268     }
275 =back
277 =cut
282  * Local variables:
283  *   c-file-style: "parrot"
284  * End:
285  * vim: expandtab shiftwidth=4:
286  */