File Coverage

xs/linear.xs
Criterion Covered Total %
statement 24 90 26.6
branch 12 46 26.0
condition n/a
subroutine n/a
pod n/a
total 36 136 26.4


line stmt bran cond sub pod time code
1             ##############################################################################
2             # xs/linear.xs — XS bindings for PDF linearization (Fast Web View)
3             ##############################################################################
4              
5             MODULE = PDF::Make PACKAGE = PDF::Make::Linearization
6             PROTOTYPES: ENABLE
7              
8             ##############################################################################
9             # Linearization Detection
10             ##############################################################################
11              
12             int
13             _data_is_linearized(data_sv)
14             SV *data_sv
15             PREINIT:
16             STRLEN len;
17             const uint8_t *data;
18             CODE:
19 9 50         if (!SvPOK(data_sv)) {
20 0           RETVAL = 0;
21             } else {
22 9           data = (const uint8_t *)SvPVbyte(data_sv, len);
23 9           RETVAL = pdfmake_data_is_linearized(data, len);
24             }
25             OUTPUT:
26             RETVAL
27              
28             ##############################################################################
29             # Document Methods
30             ##############################################################################
31              
32             MODULE = PDF::Make PACKAGE = PDF::Make::Document
33             PROTOTYPES: ENABLE
34              
35             int
36             _xs_is_linearized(doc)
37             pdfmake_doc_t *doc
38             CODE:
39 7           RETVAL = pdfmake_doc_is_linearized(doc);
40             OUTPUT:
41             RETVAL
42              
43             SV *
44             _xs_linear_params(doc)
45             pdfmake_doc_t *doc
46             PREINIT:
47             pdfmake_linear_params_t params;
48             pdfmake_err_t err;
49             HV *hv;
50             CODE:
51 0           err = pdfmake_doc_linear_params(doc, ¶ms);
52 0 0         if (err != PDFMAKE_OK) {
53 0           XSRETURN_UNDEF;
54             }
55            
56 0           hv = newHV();
57 0           hv_store(hv, "version", 7, newSViv(params.version), 0);
58 0           hv_store(hv, "file_length", 11, newSVuv(params.file_length), 0);
59 0           hv_store(hv, "hint_offset", 11, newSVuv(params.hint_offset), 0);
60 0           hv_store(hv, "hint_length", 11, newSVuv(params.hint_length), 0);
61 0           hv_store(hv, "first_page_obj", 14, newSVuv(params.first_page_obj), 0);
62 0           hv_store(hv, "first_page_end", 14, newSVuv(params.first_page_end), 0);
63 0           hv_store(hv, "page_count", 10, newSVuv(params.page_count), 0);
64 0           hv_store(hv, "main_xref_offset", 16, newSVuv(params.main_xref_offset), 0);
65            
66 0           RETVAL = newRV_noinc((SV *)hv);
67             OUTPUT:
68             RETVAL
69              
70             int
71             _xs_linearize(doc)
72             pdfmake_doc_t *doc
73             CODE:
74 4 100         RETVAL = (pdfmake_doc_linearize(doc) == PDFMAKE_OK) ? 1 : 0;
75             OUTPUT:
76             RETVAL
77              
78             SV *
79             _xs_write_linearized(doc)
80             pdfmake_doc_t *doc
81             PREINIT:
82             pdfmake_buf_t buf;
83             pdfmake_err_t err;
84             CODE:
85 0           pdfmake_buf_init(&buf);
86 0           err = pdfmake_doc_write_linearized(doc, &buf);
87 0 0         if (err != PDFMAKE_OK) {
88 0           pdfmake_buf_free(&buf);
89 0           croak("PDF::Make: linearized write failed: error %d", err);
90             }
91 0           RETVAL = newSVpvn((char *)pdfmake_buf_data(&buf), pdfmake_buf_len(&buf));
92 0           pdfmake_buf_free(&buf);
93             OUTPUT:
94             RETVAL
95              
96             int
97             _xs_write_linearized_to_path(doc, path)
98             pdfmake_doc_t *doc
99             const char *path
100             CODE:
101 2 50         RETVAL = (pdfmake_doc_write_linearized_to_path(doc, path) == PDFMAKE_OK) ? 1 : 0;
102             OUTPUT:
103             RETVAL
104              
105             ##############################################################################
106             # Stream Reader XS wrapper
107             ##############################################################################
108              
109             MODULE = PDF::Make PACKAGE = PDF::Make::StreamReaderXS
110             PROTOTYPES: ENABLE
111              
112             # Note: The StreamReader uses a Perl callback for fetching, so we create
113             # a wrapper that stores the Perl callback SV and calls it from C.
114              
115             # Internal structure definition is handled in the typemap
116              
117             pdfmake_stream_reader_t *
118             _new(class, fetch_sv)
119             const char *class
120             SV *fetch_sv
121             PREINIT:
122             SV *fetch_copy;
123             CODE:
124             PERL_UNUSED_VAR(class);
125            
126 0 0         if (!SvROK(fetch_sv) || SvTYPE(SvRV(fetch_sv)) != SVt_PVCV) {
    0          
127 0           croak("PDF::Make::StreamReaderXS: fetch must be a code reference");
128             }
129            
130             /* For now, return NULL - full implementation would wrap the fetch callback */
131             /* This requires a trampoline function that calls back to Perl */
132 0           RETVAL = NULL;
133 0           croak("PDF::Make::StreamReaderXS: XS stream reader not yet fully implemented");
134             OUTPUT:
135             RETVAL
136              
137             void
138             DESTROY(reader)
139             pdfmake_stream_reader_t *reader
140             CODE:
141 0 0         if (reader) {
142 0           pdfmake_stream_reader_free(reader);
143             }
144              
145             int
146             is_linearized(reader)
147             pdfmake_stream_reader_t *reader
148             CODE:
149 0 0         if (!reader) {
150 0           RETVAL = 0;
151             } else {
152 0           RETVAL = reader->is_linearized;
153             }
154             OUTPUT:
155             RETVAL
156              
157             UV
158             page_count(reader)
159             pdfmake_stream_reader_t *reader
160             CODE:
161 0 0         if (!reader) {
162 0           RETVAL = 0;
163             } else {
164 0           RETVAL = pdfmake_stream_reader_page_count(reader);
165             }
166             OUTPUT:
167             RETVAL
168              
169             int
170             page_available(reader, page_num)
171             pdfmake_stream_reader_t *reader
172             int page_num
173             CODE:
174 0 0         if (!reader) {
175 0           RETVAL = 0;
176             } else {
177 0           RETVAL = pdfmake_stream_reader_page_available(reader, page_num);
178             }
179             OUTPUT:
180             RETVAL
181              
182             SV *
183             params(reader)
184             pdfmake_stream_reader_t *reader
185             PREINIT:
186             HV *hv;
187             CODE:
188 0 0         if (!reader) {
189 0           XSRETURN_UNDEF;
190             }
191            
192 0           hv = newHV();
193 0           hv_store(hv, "version", 7, newSViv(reader->params.version), 0);
194 0           hv_store(hv, "file_length", 11, newSVuv(reader->params.file_length), 0);
195 0           hv_store(hv, "hint_offset", 11, newSVuv(reader->params.hint_offset), 0);
196 0           hv_store(hv, "hint_length", 11, newSVuv(reader->params.hint_length), 0);
197 0           hv_store(hv, "first_page_obj", 14, newSVuv(reader->params.first_page_obj), 0);
198 0           hv_store(hv, "first_page_end", 14, newSVuv(reader->params.first_page_end), 0);
199 0           hv_store(hv, "page_count", 10, newSVuv(reader->params.page_count), 0);
200 0           hv_store(hv, "main_xref_offset", 16, newSVuv(reader->params.main_xref_offset), 0);
201            
202 0           RETVAL = newRV_noinc((SV *)hv);
203             OUTPUT:
204             RETVAL
205              
206             void
207             page_range(reader, page_num)
208             pdfmake_stream_reader_t *reader
209             int page_num
210             PREINIT:
211 0           size_t offset = 0;
212 0           size_t length = 0;
213             pdfmake_err_t err;
214             PPCODE:
215 0 0         if (!reader) {
216 0           XSRETURN_EMPTY;
217             }
218            
219 0           err = pdfmake_stream_reader_page_range(reader, page_num, &offset, &length);
220 0 0         if (err != PDFMAKE_OK) {
221 0           XSRETURN_EMPTY;
222             }
223            
224 0 0         EXTEND(SP, 2);
225 0           PUSHs(sv_2mortal(newSVuv(offset)));
226 0           PUSHs(sv_2mortal(newSVuv(length)));
227              
228             ##############################################################################
229             # Linearization Context (low-level API)
230             ##############################################################################
231              
232             MODULE = PDF::Make PACKAGE = PDF::Make::LinearContext
233             PROTOTYPES: ENABLE
234              
235             pdfmake_linear_t *
236             _new(class, doc)
237             const char *class
238             pdfmake_doc_t *doc
239             CODE:
240             PERL_UNUSED_VAR(class);
241 5           RETVAL = pdfmake_linear_new(doc);
242 5 50         if (!RETVAL) {
243 0           croak("PDF::Make::LinearContext: failed to create context");
244             }
245             OUTPUT:
246             RETVAL
247              
248             void
249             DESTROY(lin)
250             pdfmake_linear_t *lin
251             CODE:
252 5 50         if (lin) {
253 5           pdfmake_linear_free(lin);
254             }
255              
256             int
257             analyze(lin)
258             pdfmake_linear_t *lin
259             CODE:
260 5 50         if (!lin) {
261 0           RETVAL = 0;
262             } else {
263 5           RETVAL = (pdfmake_linear_analyze(lin) == PDFMAKE_OK) ? 1 : 0;
264             }
265             OUTPUT:
266             RETVAL
267              
268             int
269             build_hints(lin)
270             pdfmake_linear_t *lin
271             CODE:
272 5 50         if (!lin) {
273 0           RETVAL = 0;
274             } else {
275 5           RETVAL = (pdfmake_linear_build_hints(lin) == PDFMAKE_OK) ? 1 : 0;
276             }
277             OUTPUT:
278             RETVAL
279              
280             SV *
281             write(lin)
282             pdfmake_linear_t *lin
283             PREINIT:
284             pdfmake_buf_t buf;
285             pdfmake_err_t err;
286             CODE:
287 5 50         if (!lin) {
288 0           croak("PDF::Make::LinearContext: NULL context");
289             }
290            
291 5           pdfmake_buf_init(&buf);
292 5           err = pdfmake_linear_write(lin, &buf);
293 5 50         if (err != PDFMAKE_OK) {
294 0           pdfmake_buf_free(&buf);
295 0           croak("PDF::Make::LinearContext: write failed: error %d", err);
296             }
297            
298 5           RETVAL = newSVpvn((char *)pdfmake_buf_data(&buf), pdfmake_buf_len(&buf));
299 5           pdfmake_buf_free(&buf);
300             OUTPUT:
301             RETVAL
302              
303             UV
304             page_count(lin)
305             pdfmake_linear_t *lin
306             CODE:
307 1 50         if (!lin) {
308 0           RETVAL = 0;
309             } else {
310 1           RETVAL = lin->params.page_count;
311             }
312             OUTPUT:
313             RETVAL
314              
315             UV
316             shared_object_count(lin)
317             pdfmake_linear_t *lin
318             CODE:
319 1 50         if (!lin) {
320 0           RETVAL = 0;
321             } else {
322 1           RETVAL = lin->shared_count;
323             }
324             OUTPUT:
325             RETVAL