Commit | Line | Data |
---|---|---|
e38f8ec4 TC |
1 | #include "EXTERN.h" |
2 | #include "perl.h" | |
3 | #include "XSUB.h" | |
4 | #include <string.h> /* for memmove() mostly */ | |
5 | #include <errno.h> /* errno values */ | |
a0e4f61f | 6 | #include "queue.h" |
1bbcbbe4 | 7 | #include "alloc.h" |
e38f8ec4 TC |
8 | |
9 | /* this typedef lets the standard T_PTROBJ typemap handle the | |
10 | conversion between perl class and C type and back again */ | |
11 | typedef poe_queue *POE__XS__Queue__Array; | |
12 | ||
13 | /* This gives us our new method and correct destruction */ | |
14 | #define pq_new(class) pq_create() | |
15 | #define pq_DESTROY(pq) pq_delete(pq) | |
16 | ||
17 | MODULE = POE::XS::Queue::Array PACKAGE = POE::XS::Queue::Array PREFIX = pq_ | |
18 | ||
19 | PROTOTYPES: DISABLE | |
20 | ||
21 | POE::XS::Queue::Array | |
22 | pq_new(class) | |
23 | ||
24 | void | |
25 | pq_DESTROY(pq) | |
26 | POE::XS::Queue::Array pq | |
27 | ||
28 | int | |
29 | pq_enqueue(pq, priority, payload) | |
30 | POE::XS::Queue::Array pq | |
31 | double priority | |
32 | SV *payload | |
33 | ||
34 | void | |
35 | pq_dequeue_next(pq) | |
36 | POE::XS::Queue::Array pq | |
37 | PREINIT: | |
38 | pq_priority_t priority; | |
39 | pq_id_t id; | |
40 | SV *payload; | |
41 | PPCODE: | |
42 | if (pq_dequeue_next(pq, &priority, &id, &payload)) { | |
43 | EXTEND(SP, 3); | |
44 | PUSHs(sv_2mortal(newSVnv(priority))); | |
45 | PUSHs(sv_2mortal(newSViv(id))); | |
46 | PUSHs(sv_2mortal(payload)); | |
47 | } | |
48 | ||
49 | SV * | |
50 | pq_get_next_priority(pq) | |
51 | POE::XS::Queue::Array pq | |
52 | PREINIT: | |
53 | pq_priority_t priority; | |
54 | CODE: | |
55 | if (pq_get_next_priority(pq, &priority)) { | |
56 | RETVAL = newSVnv(priority); /* XS will mortalize this for us */ | |
57 | } | |
58 | else { | |
59 | RETVAL = &PL_sv_undef; | |
60 | } | |
61 | OUTPUT: | |
62 | RETVAL | |
63 | ||
64 | int | |
65 | pq_get_item_count(pq) | |
66 | POE::XS::Queue::Array pq | |
67 | ||
68 | void | |
69 | pq_remove_item(pq, id, filter) | |
70 | POE::XS::Queue::Array pq | |
71 | int id | |
72 | SV *filter | |
73 | PREINIT: | |
74 | pq_entry removed; | |
75 | PPCODE: | |
76 | if (pq_remove_item(pq, id, filter, &removed)) { | |
77 | EXTEND(SP, 3); | |
78 | PUSHs(sv_2mortal(newSVnv(removed.priority))); | |
79 | PUSHs(sv_2mortal(newSViv(removed.id))); | |
80 | PUSHs(sv_2mortal(removed.payload)); | |
81 | } | |
82 | ||
83 | void | |
84 | pq_remove_items(pq, filter, ...) | |
85 | POE::XS::Queue::Array pq | |
86 | SV *filter | |
87 | PREINIT: | |
88 | int max_count; | |
89 | pq_entry *removed_entries = NULL; | |
90 | int removed_count; | |
91 | int i; | |
92 | PPCODE: | |
93 | if (items > 2) | |
94 | max_count = SvIV(ST(2)); | |
95 | else | |
96 | max_count = pq_get_item_count(pq); | |
97 | removed_count = pq_remove_items(pq, filter, max_count, | |
98 | &removed_entries); | |
99 | if (removed_count) { | |
100 | EXTEND(SP, removed_count); | |
101 | for (i = 0; i < removed_count; ++i) { | |
102 | pq_entry *entry = removed_entries + i; | |
103 | AV *av = newAV(); | |
104 | SV *rv; | |
105 | av_extend(av, 2); | |
106 | av_store(av, 0, newSVnv(entry->priority)); | |
107 | av_store(av, 1, newSViv(entry->id)); | |
108 | av_store(av, 2, entry->payload); | |
109 | rv = newRV_noinc((SV *)av); | |
110 | PUSHs(sv_2mortal(rv)); | |
111 | } | |
112 | } | |
113 | if (removed_entries) | |
1bbcbbe4 | 114 | myfree(removed_entries); |
e38f8ec4 TC |
115 | |
116 | void | |
117 | pq_adjust_priority(pq, id, filter, delta) | |
118 | POE::XS::Queue::Array pq | |
119 | int id | |
120 | SV *filter | |
121 | double delta | |
122 | PREINIT: | |
123 | pq_priority_t new_priority; | |
124 | PPCODE: | |
125 | if (pq_adjust_priority(pq, id, filter, delta, &new_priority)) { | |
126 | EXTEND(SP, 1); | |
127 | PUSHs(sv_2mortal(newSVnv(new_priority))); | |
128 | } | |
129 | ||
130 | void | |
131 | pq_set_priority(pq, id, filter, new_priority) | |
132 | POE::XS::Queue::Array pq | |
133 | int id | |
134 | SV *filter | |
135 | double new_priority | |
136 | PPCODE: | |
137 | if (pq_set_priority(pq, id, filter, new_priority)) { | |
138 | EXTEND(SP, 1); | |
139 | PUSHs(sv_2mortal(newSVnv(new_priority))); | |
140 | } | |
141 | ||
142 | void | |
143 | pq_peek_items(pq, filter, ...) | |
144 | POE::XS::Queue::Array pq | |
145 | SV *filter | |
146 | PREINIT: | |
147 | pq_entry *ret_items; | |
148 | int count, i; | |
149 | int max_count; | |
150 | PPCODE: | |
151 | if (items == 3) | |
152 | max_count = SvIV(ST(2)); | |
153 | else | |
154 | max_count = pq_get_item_count(pq); | |
155 | count = pq_peek_items(pq, filter, max_count, &ret_items); | |
156 | if (count) { | |
157 | EXTEND(SP, count); | |
158 | for (i = 0; i < count; ++i) { | |
159 | pq_entry *entry = ret_items + i; | |
160 | AV *av = newAV(); | |
161 | SV *rv; | |
162 | av_extend(av, 2); | |
163 | av_store(av, 0, newSVnv(entry->priority)); | |
164 | av_store(av, 1, newSViv(entry->id)); | |
165 | av_store(av, 2, newSVsv(entry->payload)); | |
166 | rv = newRV_noinc((SV *)av); | |
167 | PUSHs(sv_2mortal(rv)); | |
168 | } | |
1bbcbbe4 | 169 | myfree(ret_items); |
e38f8ec4 TC |
170 | } |
171 | ||
172 | void | |
173 | pq_dump(pq) | |
174 | POE::XS::Queue::Array pq | |
d5e34ea9 TC |
175 | |
176 | void | |
177 | pq_verify(pq) | |
178 | POE::XS::Queue::Array pq | |
70aaf253 TC |
179 | |
180 | # these are for testing errno is being set correctly for perl when | |
181 | # set from XS | |
182 | void | |
183 | pq__set_errno_xs(value) | |
184 | int value | |
185 | CODE: | |
186 | errno = value; | |
187 | ||
188 | void | |
189 | pq__set_errno_queue(value) | |
190 | int value |