File Coverage

blib/lib/Dpkg/Compression/Process.pm
Criterion Covered Total %
statement 72 72 100.0
branch 14 22 63.6
condition 5 12 41.6
subroutine 16 16 100.0
pod 8 8 100.0
total 115 130 88.4


line stmt bran cond sub pod time code
1             # Copyright © 2008-2010 Raphaël Hertzog
2             #
3             # This program is free software; you can redistribute it and/or modify
4             # it under the terms of the GNU General Public License as published by
5             # the Free Software Foundation; either version 2 of the License, or
6             # (at your option) any later version.
7             #
8             # This program is distributed in the hope that it will be useful,
9             # but WITHOUT ANY WARRANTY; without even the implied warranty of
10             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11             # GNU General Public License for more details.
12             #
13             # You should have received a copy of the GNU General Public License
14             # along with this program. If not, see .
15              
16             package Dpkg::Compression::Process;
17              
18 19     19   133 use strict;
  19         36  
  19         571  
19 19     19   112 use warnings;
  19         39  
  19         890  
20              
21             our $VERSION = '1.00';
22              
23 19     19   113 use Carp;
  19         58  
  19         1092  
24              
25 19     19   131 use Dpkg::Compression;
  19         36  
  19         2031  
26 19     19   141 use Dpkg::ErrorHandling;
  19         37  
  19         1554  
27 19     19   134 use Dpkg::Gettext;
  19         40  
  19         1150  
28 19     19   5888 use Dpkg::IPC;
  19         50  
  19         15545  
29              
30             =encoding utf8
31              
32             =head1 NAME
33              
34             Dpkg::Compression::Process - run compression/decompression processes
35              
36             =head1 DESCRIPTION
37              
38             This module provides an object oriented interface to run and manage
39             compression/decompression processes.
40              
41             =head1 METHODS
42              
43             =over 4
44              
45             =item $proc = Dpkg::Compression::Process->new(%opts)
46              
47             Create a new instance of the object. Supported options are "compression"
48             and "compression_level" (see corresponding set_* functions).
49              
50             =cut
51              
52             sub new {
53 154     154 1 439 my ($this, %args) = @_;
54 154   33     726 my $class = ref($this) || $this;
55 154         331 my $self = {};
56 154         346 bless $self, $class;
57 154   33     803 $self->set_compression($args{compression} || compression_get_default());
58             $self->set_compression_level($args{compression_level} ||
59 154   33     808 compression_get_default_level());
60 154         583 return $self;
61             }
62              
63             =item $proc->set_compression($comp)
64              
65             Select the compression method to use. It errors out if the method is not
66             supported according to C (of
67             B).
68              
69             =cut
70              
71             sub set_compression {
72 168     168 1 423 my ($self, $method) = @_;
73 168 50       602 error(g_('%s is not a supported compression method'), $method)
74             unless compression_is_supported($method);
75 168         514 $self->{compression} = $method;
76             }
77              
78             =item $proc->set_compression_level($level)
79              
80             Select the compression level to use. It errors out if the level is not
81             valid according to C (of
82             B).
83              
84             =cut
85              
86             sub set_compression_level {
87 154     154 1 334 my ($self, $level) = @_;
88 154 50       466 error(g_('%s is not a compression level'), $level)
89             unless compression_is_valid_level($level);
90 154         556 $self->{compression_level} = $level;
91             }
92              
93             =item @exec = $proc->get_compress_cmdline()
94              
95             =item @exec = $proc->get_uncompress_cmdline()
96              
97             Returns a list ready to be passed to C, its first element is the
98             program name (either for compression or decompression) and the following
99             elements are parameters for the program.
100              
101             When executed the program acts as a filter between its standard input
102             and its standard output.
103              
104             =cut
105              
106             sub get_compress_cmdline {
107 9     9 1 18 my $self = shift;
108 9         13 my @prog = (@{compression_get_property($self->{compression}, 'comp_prog')});
  9         36  
109 9         35 my $level = '-' . $self->{compression_level};
110             $level = '--' . $self->{compression_level}
111 9 50       69 if $self->{compression_level} !~ m/^[1-9]$/;
112 9         36 push @prog, $level;
113 9         31 return @prog;
114             }
115              
116             sub get_uncompress_cmdline {
117 5     5 1 10 my $self = shift;
118 5         10 return (@{compression_get_property($self->{compression}, 'decomp_prog')});
  5         23  
119             }
120              
121             sub _sanity_check {
122 14     14   88 my ($self, %opts) = @_;
123             # Check for proper cleaning before new start
124             error(g_('Dpkg::Compression::Process can only start one subprocess at a time'))
125 14 50       56 if $self->{pid};
126             # Check options
127 14         36 my $to = my $from = 0;
128 14         73 foreach my $thing (qw(file handle string pipe)) {
129 56 100       149 $to++ if $opts{"to_$thing"};
130 56 100       146 $from++ if $opts{"from_$thing"};
131             }
132 14 50       54 croak 'exactly one to_* parameter is needed' if $to != 1;
133 14 50       37 croak 'exactly one from_* parameter is needed' if $from != 1;
134 14         37 return %opts;
135             }
136              
137             =item $proc->compress(%opts)
138              
139             Starts a compressor program. You must indicate where it will read its
140             uncompressed data from and where it will write its compressed data to.
141             This is accomplished by passing one parameter C and one parameter
142             C as accepted by B.
143              
144             You must call C after having called this method to
145             properly close the sub-process (and verify that it exited without error).
146              
147             =cut
148              
149             sub compress {
150 9     9 1 96 my ($self, %opts) = @_;
151              
152 9         64 $self->_sanity_check(%opts);
153 9         51 my @prog = $self->get_compress_cmdline();
154 9         54 $opts{exec} = \@prog;
155 9         76 $self->{cmdline} = "@prog";
156 9         64 $self->{pid} = spawn(%opts);
157 7 50       422 delete $self->{pid} if $opts{to_string}; # wait_child already done
158             }
159              
160             =item $proc->uncompress(%opts)
161              
162             Starts a decompressor program. You must indicate where it will read its
163             compressed data from and where it will write its uncompressed data to.
164             This is accomplished by passing one parameter C and one parameter
165             C as accepted by B.
166              
167             You must call C after having called this method to
168             properly close the sub-process (and verify that it exited without error).
169              
170             =cut
171              
172             sub uncompress {
173 5     5 1 58 my ($self, %opts) = @_;
174              
175 5         75 $self->_sanity_check(%opts);
176 5         23 my @prog = $self->get_uncompress_cmdline();
177 5         33 $opts{exec} = \@prog;
178 5         23 $self->{cmdline} = "@prog";
179 5         56 $self->{pid} = spawn(%opts);
180 3 50       203 delete $self->{pid} if $opts{to_string}; # wait_child already done
181             }
182              
183             =item $proc->wait_end_process(%opts)
184              
185             Call B to wait until the sub-process has exited
186             and verify its return code. Any given option will be forwarded to
187             the C function. Most notably you can use the "nocheck" option
188             to verify the return code yourself instead of letting C do
189             it for you.
190              
191             =cut
192              
193             sub wait_end_process {
194 129     129 1 630 my ($self, %opts) = @_;
195 129   66     999 $opts{cmdline} //= $self->{cmdline};
196 129 100       459 wait_child($self->{pid}, %opts) if $self->{pid};
197 129         271 delete $self->{pid};
198 129         421 delete $self->{cmdline};
199             }
200              
201             =back
202              
203             =head1 CHANGES
204              
205             =head2 Version 1.00 (dpkg 1.15.6)
206              
207             Mark the module as public.
208              
209             =cut
210              
211             1;