File Coverage

gunzip.xs
Criterion Covered Total %
statement 17 25 68.0
branch 10 22 45.4
condition n/a
subroutine n/a
pod n/a
total 27 47 57.4


line stmt bran cond sub pod time code
1             /* Copyright 2007, 2008, 2009, 2010, 2011, 2019 Kevin Ryde
2              
3             This file is part of Filter-gunzip.
4              
5             Filter-gunzip is free software; you can redistribute it and/or modify it
6             under the terms of the GNU General Public License as published by the
7             Free Software Foundation; either version 3, or (at your option) any later
8             version.
9              
10             Filter-gunzip is distributed in the hope that it will be useful, but
11             WITHOUT ANY WARRANTY; without even the implied warranty of
12             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13             Public License for more details.
14              
15             You should have received a copy of the GNU General Public License along
16             with Filter-gunzip. If not, see . */
17              
18             #include "EXTERN.h"
19             #include "perl.h"
20             #include "XSUB.h"
21              
22             #define NEED_PL_parser
23             #define DPPP_PL_parser_NO_DUMMY /* code below checks PL_parser != NULL */
24             #include "ppport.h"
25              
26              
27             /* set this to 1 for some debug prints to stderr */
28             #define MY_DEBUG 0
29              
30              
31             #if MY_DEBUG >= 1
32             #define MY_DEBUG1(code) do { code; } while (0)
33             #else
34             #define MY_DEBUG1(code)
35             #endif
36              
37             #if MY_DEBUG >= 1
38             #define MY_SHOW_LAYERS(location) \
39             do { \
40             PerlIO *f = PL_rsfp; \
41             AV *av = PerlIO_get_layers(aTHX_ f); \
42             if (!av) { \
43             fprintf(stderr, "%s: get_layers NULL\n", location); \
44             } else { \
45             int i, lastidx = av_len(av); \
46             fprintf(stderr, "%s: get_layers lastidx %d (ref count %d)\n", \
47             location, lastidx, SvREFCNT(av)); \
48             for (i = 0; i <= lastidx; i+=3) { \
49             SV **svp = av_fetch(av, i, FALSE); \
50             fprintf(stderr, " i=%d %s\n", i, SvPVX_const(*svp)); \
51             } \
52             SvREFCNT_dec(av); \
53             } \
54             } while (0)
55             #else
56             #define MY_SHOW_LAYERS(location) do {} while (0)
57             #endif
58              
59              
60             MODULE = Filter::gunzip PACKAGE = Filter::gunzip
61              
62             int
63             _filter_by_layer ()
64             CODE:
65             /* Return 1 if successful, or 0 if cannot use a layer (for any reason). */
66 1 50         if (PL_parser == NULL) {
67             MY_DEBUG1(fprintf(stderr, "PL_parser == NULL, no rsfp\n"));
68 0           RETVAL = 0;
69              
70             } else {
71 1           int other_filters = 0;
72             {
73             /* PL_rsfp_filters is NULL if never used.
74             Believe can be an empty arrayref if used then the filter popped off.
75             */
76 1 50         AV *av = PL_rsfp_filters;
77 1 50         if (av) {
78 0 0         if (av_len(av) >= 0) { /* $# style last index */
79             MY_DEBUG1(fprintf(stderr, "rsfp_filters lastidx %d is other filters, so don't mangle rsfp\n",
80             av_len(av)));
81 0           other_filters = 1;
82             } else {
83             MY_DEBUG1(fprintf(stderr, "rsfp_filters lastidx %d, good\n", av_len(av)));
84             }
85             } else {
86             MY_DEBUG1(fprintf(stderr, "rsfp_filters NULL, good\n"));
87             }
88             }
89 1 50         if (other_filters) {
90 0           RETVAL = 0;
91              
92             } else {
93 1 50         PerlIO *f = PL_rsfp;
94 1           int crlf = 0;
95             int gzip_apply;
96              
97             MY_SHOW_LAYERS("initial");
98             {
99 1           AV *av = PerlIO_get_layers(aTHX_ f);
100             MY_DEBUG1(fprintf(stderr, "PL_rsfp get_layers length %d (ref count %d)\n",
101             av_len(av), SvREFCNT(av)));
102 1 50         if (av_len(av)) {
103 1           SV **svp = av_fetch(av, 0, FALSE);
104             MY_DEBUG1(fprintf(stderr, " top layer name: %s\n", SvPVX_const(*svp)));
105 1 50         if (strEQ(SvPVX_const(*svp), "crlf")) {
106             MY_DEBUG1(fprintf(stderr, " set flag crlf = 1\n"));
107 0           crlf = 1;
108             }
109             }
110 1           SvREFCNT_dec(av);
111             }
112              
113 1 50         if (crlf) {
114 0           PerlIO_apply_layers(aTHX_ f, NULL, "pop");
115             MY_SHOW_LAYERS("popped crlf");
116             }
117              
118 1           gzip_apply = PerlIO_apply_layers(aTHX_ f, NULL, "gzip");
119             MY_DEBUG1(fprintf(stderr, "gzip_apply result %d\n", gzip_apply));
120             MY_SHOW_LAYERS("pushed gzip");
121              
122             /* PerlIO_apply_layers(aTHX_ f, NULL, "pop"); */
123             /* MY_SHOW_LAYERS("popped gzip"); */
124              
125 1 50         if (crlf) {
126 0           PerlIO_apply_layers(aTHX_ f, NULL, "crlf");
127             MY_SHOW_LAYERS("pushed back crlf");
128             }
129 1 50         if (gzip_apply == 0) {
130             /* success */
131 1           RETVAL = 1;
132             } else {
133             /* cannot push ":gzip" for some reason */
134 0           RETVAL = 0;
135             }
136             MY_DEBUG1(fprintf(stderr, "RETVAL %d\n", RETVAL));
137              
138             /* for (;;) { */
139             /* int c = PerlIO_getc(f); */
140             /* fprintf(stderr, "c = %d\n", c); */
141             /* if (c == '\n') break; */
142             /* } */
143             }
144             }
145             OUTPUT:
146             RETVAL