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   144 use strict;
  19         39  
  19         519  
19 19     19   91 use warnings;
  19         33  
  19         752  
20              
21             our $VERSION = '1.00';
22              
23 19     19   93 use Carp;
  19         36  
  19         1031  
24              
25 19     19   167 use Dpkg::Compression;
  19         32  
  19         1530  
26 19     19   142 use Dpkg::ErrorHandling;
  19         43  
  19         1369  
27 19     19   116 use Dpkg::Gettext;
  19         34  
  19         1001  
28 19     19   5093 use Dpkg::IPC;
  19         40  
  19         14488  
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 369 my ($this, %args) = @_;
54 154   33     724 my $class = ref($this) || $this;
55 154         289 my $self = {};
56 154         339 bless $self, $class;
57 154   33     791 $self->set_compression($args{compression} || compression_get_default());
58             $self->set_compression_level($args{compression_level} ||
59 154   33     699 compression_get_default_level());
60 154         550 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 389 my ($self, $method) = @_;
73 168 50       487 error(g_('%s is not a supported compression method'), $method)
74             unless compression_is_supported($method);
75 168         530 $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 302 my ($self, $level) = @_;
88 154 50       460 error(g_('%s is not a compression level'), $level)
89             unless compression_is_valid_level($level);
90 154         459 $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         9 my @prog = (@{compression_get_property($self->{compression}, 'comp_prog')});
  9         27  
109 9         22 my $level = '-' . $self->{compression_level};
110             $level = '--' . $self->{compression_level}
111 9 50       56 if $self->{compression_level} !~ m/^[1-9]$/;
112 9         27 push @prog, $level;
113 9         27 return @prog;
114             }
115              
116             sub get_uncompress_cmdline {
117 5     5 1 25 my $self = shift;
118 5         10 return (@{compression_get_property($self->{compression}, 'decomp_prog')});
  5         13  
119             }
120              
121             sub _sanity_check {
122 14     14   62 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       43 if $self->{pid};
126             # Check options
127 14         28 my $to = my $from = 0;
128 14         61 foreach my $thing (qw(file handle string pipe)) {
129 56 100       114 $to++ if $opts{"to_$thing"};
130 56 100       120 $from++ if $opts{"from_$thing"};
131             }
132 14 50       39 croak 'exactly one to_* parameter is needed' if $to != 1;
133 14 50       30 croak 'exactly one from_* parameter is needed' if $from != 1;
134 14         32 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 59 my ($self, %opts) = @_;
151              
152 9         35 $self->_sanity_check(%opts);
153 9         26 my @prog = $self->get_compress_cmdline();
154 9         38 $opts{exec} = \@prog;
155 9         54 $self->{cmdline} = "@prog";
156 9         40 $self->{pid} = spawn(%opts);
157 7 50       321 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 32 my ($self, %opts) = @_;
174              
175 5         31 $self->_sanity_check(%opts);
176 5         20 my @prog = $self->get_uncompress_cmdline();
177 5         27 $opts{exec} = \@prog;
178 5         19 $self->{cmdline} = "@prog";
179 5         26 $self->{pid} = spawn(%opts);
180 3 50       187 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 543 my ($self, %opts) = @_;
195 129   66     871 $opts{cmdline} //= $self->{cmdline};
196 129 100       397 wait_child($self->{pid}, %opts) if $self->{pid};
197 129         257 delete $self->{pid};
198 129         402 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;