1/*
2Copyright (C) 2010-2014, Parrot Foundation.
3
4=head1 NAME
5
6src/pmc/imageiostrings.pmc - ImageIOStrings PMC
7
8=head1 DESCRIPTION
9
10Get a list of strings in an object graph. Used in packfile creation.
11
12=cut
13
14*/
15
16/* HEADERIZER HFILE: none */
17/* HEADERIZER BEGIN: static */
18/* HEADERIZER END: static */
19
20pmclass ImageIOStrings auto_attrs {
21    ATTR PMC *seen; /* seen hash */
22    ATTR PMC *todo; /* todo list */
23    ATTR PMC *list; /* list of strings seen */
24
25/*
26
27=head1 VTABLES
28
29=over 4
30
31=cut
32
33*/
34
35/*
36
37=item C<void init()>
38
39Initializes the PMC.
40
41=cut
42
43*/
44    VTABLE void init() {
45        PARROT_IMAGEIOSTRINGS(SELF)->todo = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
46
47        PARROT_IMAGEIOSTRINGS(SELF)->seen = Parrot_pmc_new(INTERP, enum_class_Hash);
48        VTABLE_set_pointer(INTERP, PARROT_IMAGEIOSTRINGS(SELF)->seen,
49            Parrot_hash_new_intval_hash(INTERP));
50
51        PARROT_IMAGEIOSTRINGS(SELF)->list = Parrot_pmc_new(INTERP, enum_class_ResizableStringArray);
52
53        PObj_custom_mark_SET(SELF);
54    }
55
56/*
57
58=item C<void mark()>
59
60Marks the PMC as alive.
61
62=cut
63
64*/
65    VTABLE void mark() :no_wb {
66        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOSTRINGS(SELF)->todo);
67        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOSTRINGS(SELF)->seen);
68        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOSTRINGS(SELF)->list);
69    }
70
71/*
72
73=item C<VTABLE PMC *get_pmc()>
74
75Gets the result PMC after a thaw.
76
77=cut
78
79*/
80
81    VTABLE PMC *get_pmc() :no_wb {
82        UNUSED(INTERP)
83        return PARROT_IMAGEIOSTRINGS(SELF)->list;
84    }
85
86/*
87
88=item C<VTABLE INTVAL get_integer()>
89
90Returns the flags describing the visit action
91
92=cut
93
94*/
95
96    VTABLE INTVAL get_integer() :no_wb {
97        UNUSED(INTERP)
98        UNUSED(SELF)
99        return VISIT_FREEZE_NORMAL;
100    }
101
102
103/*
104
105=item C<VTABLE void push_integer(INTVAL v)>
106
107Do nothing.
108
109=cut
110
111*/
112
113    VTABLE void push_integer(INTVAL v) :no_wb {
114        UNUSED(INTERP)
115        UNUSED(SELF)
116        UNUSED(v)
117    }
118
119
120/*
121
122=item C<VTABLE void push_float(FLOATVAL v)>
123
124Do nothing.
125
126=cut
127
128*/
129
130    VTABLE void push_float(FLOATVAL v) :no_wb {
131        UNUSED(INTERP)
132        UNUSED(SELF)
133        UNUSED(v)
134    }
135
136
137/*
138
139=item C<VTABLE void push_string(STRING *v)>
140
141Adds the string to the list of strings.
142
143=cut
144
145*/
146
147    VTABLE void push_string(STRING *v) :manual_wb {
148        VTABLE_push_string(INTERP, PARROT_IMAGEIOSTRINGS(SELF)->list, v);
149    }
150
151/*
152
153=item C<VTABLE void push_pmc(PMC *v)>
154
155Checks new pmcs for strings.
156
157=cut
158
159*/
160
161    VTABLE void push_pmc(PMC *v) :manual_wb {
162        if (!PMC_IS_NULL(v)) {
163            Hash * const hash    = (Hash *)VTABLE_get_pointer(INTERP,
164                                                PARROT_IMAGEIOSTRINGS(SELF)->seen);
165            HashBucket * const b = Parrot_hash_get_bucket(INTERP, hash, v);
166            if (!b) {
167                /* not yet seen */
168                Parrot_hash_put(INTERP, hash, v, v);
169                VTABLE_push_pmc(INTERP, PARROT_IMAGEIOSTRINGS(SELF)->todo, v);
170            }
171            else
172                PARROT_GC_WRITE_BARRIER(INTERP, SELF);
173        }
174    }
175
176    VTABLE void set_pmc(PMC *p) :manual_wb {
177        PMC * const todo = PARROT_IMAGEIOSTRINGS(SELF)->todo;
178        STATICSELF.push_pmc(p);
179        while (VTABLE_elements(INTERP, todo)) {
180            PMC * const current = VTABLE_shift_pmc(INTERP, todo);
181            VTABLE_freeze(INTERP, current, SELF);
182            VTABLE_visit(INTERP,  current, SELF);
183            SELF.push_pmc(PMC_metadata(current));
184        }
185    }
186
187/*
188
189=back
190
191=cut
192
193*/
194
195}
196
197/*
198 * Local variables:
199 *   c-file-style: "parrot"
200 * End:
201 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
202 */
203