File Coverage

lib/App/MtAws/HttpSegmentWriter.pm
Criterion Covered Total %
statement 124 175 70.8
branch 12 40 30.0
condition 2 6 33.3
subroutine 35 49 71.4
pod 0 6 0.0
total 173 276 62.6


line stmt bran cond sub pod time code
1             # mt-aws-glacier - Amazon Glacier sync client
2             # Copyright (C) 2012-2014 Victor Efimov
3             # http://mt-aws.com (also http://vs-dev.com) vs@vs-dev.com
4             # License: GPLv3
5             #
6             # This file is part of "mt-aws-glacier"
7             #
8             # mt-aws-glacier is free software: you can redistribute it and/or modify
9             # it under the terms of the GNU General Public License as published by
10             # the Free Software Foundation, either version 3 of the License, or
11             # (at your option) any later version.
12             #
13             # mt-aws-glacier is distributed in the hope that it will be useful,
14             # but WITHOUT ANY WARRANTY; without even the implied warranty of
15             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16             # GNU General Public License for more details.
17             #
18             # You should have received a copy of the GNU General Public License
19             # along with this program. If not, see <http://www.gnu.org/licenses/>.
20              
21             package App::MtAws::HttpWriter;
22              
23             our $VERSION = '1.114_2';
24              
25 18     18   84 use strict;
  18         30  
  18         572  
26 18     18   94 use warnings;
  18         18  
  18         459  
27 18     18   74 use utf8;
  18         30  
  18         107  
28 18     18   445 use Carp;
  18         18  
  18         1121  
29 18     18   7722 use App::MtAws::TreeHash;
  18         35  
  18         9558  
30              
31              
32             sub new
33             {
34 0     0   0 my ($class, %args) = @_;
35 0         0 my $self = \%args;
36 0         0 bless $self, $class;
37 0         0 $self->initialize();
38 0         0 return $self;
39             }
40              
41             sub initialize
42             {
43 12     12   33 my ($self) = @_;
44 12         41 $self->{write_threshold} = 2*1024*1024;
45             }
46              
47             sub reinit
48             {
49 5     5   11 my ($self, $size) = @_;
50 5         14 $self->{size}=$size;
51 5         13 $self->{totalsize}=0;
52 5         23 $self->{total_commited_length} = $self->{pending_length} = $self->{total_length} = 0;
53 5         21 $self->{buffer} = '';
54             }
55              
56             sub add_data
57             {
58 2933     2933   2619 my $self = $_[0];
59 2933 50       4094 return unless defined($_[1]);
60 2933         2667 my $len = length($_[1]);
61 2933         10207 $self->{buffer} .= $_[1];
62 2933         2663 $self->{pending_length} += $len;
63 2933         2209 $self->{total_length} += $len;
64 2933 100       5027 if ($self->{pending_length} > $self->{write_threshold}) {
65 4         19 $self->_flush();
66             }
67 2933         4316 1;
68             }
69              
70             sub _flush
71             {
72 0     0   0 confess "not implemented";
73             }
74              
75             sub treehash
76             {
77 0     0   0 undef;
78             }
79              
80             sub _flush_buffers
81             {
82 9     9   22 my ($self, @files) = @_;
83 9         21 my $len = length($self->{buffer});
84 9         26 for my $fh (@files) {
85 9 50       20102 print $fh $self->{buffer} or confess "cant write to file $!";
86             }
87 9 50       47 if (my $th = $self->treehash) {
88 9         61 $th->eat_data_any_size($self->{buffer});
89             }
90 9         37 $self->{total_commited_length} += $len;
91 9         17 $self->{buffer} = '';
92 9         18 $self->{pending_length} = 0;
93 9         27 $len;
94             }
95              
96             sub finish
97             {
98 5     5   10 my ($self) = @_;
99 5         19 $self->_flush();
100 5 50       20 $self->{total_commited_length} == $self->{total_length} or confess;
101 5 100 66     64 return ($self->{total_length} && ($self->{total_length} == $self->{size})) ? ('ok') : ('retry', 'Unexpected end of data');
102             }
103              
104             package App::MtAws::HttpSegmentWriter;
105              
106             our $VERSION = '1.114_2';
107              
108 18     18   126 use strict;
  18         31  
  18         10941  
109 18     18   89 use warnings;
  18         19  
  18         543  
110 18     18   93 use utf8;
  18         30  
  18         118  
111 18     18   449 use App::MtAws::Utils;
  18         34  
  18         2335  
112 18     18   77 use Fcntl qw/SEEK_SET LOCK_EX/;
  18         18  
  18         651  
113 18     18   70 use Carp;
  18         20  
  18         760  
114 18     18   67 use base qw/App::MtAws::HttpWriter/;
  18         18  
  18         15130  
115              
116              
117             # when file not found/etc error happen, it can mean Temp file deleted by another process, so we
118             # don't need to throw error, most likelly signal will arrive in a few milliseconds
119             sub delayed_confess(@)
120             {
121 0     0 0 0 sleep 2;
122 0         0 confess @_;
123             }
124              
125              
126             sub new
127             {
128 0     0 0 0 my ($class, %args) = @_;
129 0         0 my $self = \%args;
130 0         0 bless $self, $class;
131 0         0 $self->SUPER::initialize();
132 0         0 $self->initialize();
133 0         0 return $self;
134             }
135              
136             sub initialize
137             {
138 0     0 0 0 my ($self) = @_;
139 0 0       0 defined($self->{filename}) or confess;
140 0 0       0 defined($self->{tempfile}) or confess;
141 0 0       0 defined($self->{position}) or confess;
142             }
143              
144             sub reinit
145             {
146 0     0 0 0 my $self = shift;
147 0         0 $self->{incr_position} = 0;
148 0         0 $self->{treehash} = App::MtAws::TreeHash->new();
149 0         0 $self->SUPER::reinit(@_);
150             }
151              
152 0     0 0 0 sub treehash { shift->{treehash} }
153              
154             sub _flush
155             {
156 0     0   0 my ($self) = @_;
157 0 0       0 if ($self->{pending_length}) {
158 0 0       0 open_file(my $fh, $self->{tempfile}, mode => '+<', binary => 1) or delayed_confess "cant open file $self->{tempfile} $!";
159 0 0       0 flock $fh, LOCK_EX or delayed_confess;
160 0         0 $fh->flush();
161 0         0 $fh->autoflush(1);
162 0 0       0 seek $fh, $self->{position}+$self->{incr_position}, SEEK_SET or delayed_confess "cannot seek() $!";
163 0         0 $self->{incr_position} += $self->_flush_buffers($fh);
164 0 0       0 close $fh or delayed_confess; # close will unlock
165             }
166             }
167              
168             sub finish
169             {
170 0     0 0 0 my ($self) = @_;
171 0         0 my @r = $self->SUPER::finish();
172 0         0 return @r;
173             }
174              
175              
176             package App::MtAws::HttpFileWriter;
177              
178             our $VERSION = '1.114_2';
179              
180 18     18   110 use strict;
  18         34  
  18         516  
181 18     18   67 use warnings;
  18         25  
  18         401  
182 18     18   60 use utf8;
  18         18  
  18         56  
183 18     18   499 use App::MtAws::Utils;
  18         78  
  18         2042  
184 18     18   71 use Carp;
  18         29  
  18         729  
185 18     18   57 use base qw/App::MtAws::HttpWriter/;
  18         19  
  18         12626  
186              
187              
188             sub new
189             {
190 12     12   324344 my ($class, %args) = @_;
191 12         38 my $self = \%args;
192 12         39 bless $self, $class;
193 12         81 $self->SUPER::initialize();
194 12         46 $self->initialize();
195 12         40 return $self;
196             }
197              
198             sub initialize
199             {
200 12     12   21 my ($self) = @_;
201 12 50       49 defined($self->{tempfile}) or confess;
202             }
203              
204             sub reinit
205             {
206 5     5   43 my $self = shift;
207 5         16 undef $self->{fh};
208 5 50       39 open_file($self->{fh}, $self->{tempfile}, mode => '+<', binary => 1) or confess "cant open file $self->{tempfile} $!";
209 5         13 binmode $self->{fh};
210 5         47 $self->{treehash} = App::MtAws::TreeHash->new();
211 5         35 $self->SUPER::reinit(@_);
212             }
213              
214 11     11   60 sub treehash { shift->{treehash} }
215              
216             sub _flush
217             {
218 9     9   17 my ($self) = @_;
219 9 50       31 if ($self->{pending_length}) {
220 9         51 $self->_flush_buffers($self->{fh});
221             }
222             }
223              
224             sub finish
225             {
226 5     5   13 my ($self) = @_;
227 5         27 my @r = $self->SUPER::finish();
228 5 50       154 close $self->{fh} or confess;
229 5         21 return @r;
230             }
231              
232              
233             package App::MtAws::HttpMemoryWriter;
234              
235             our $VERSION = '1.114_2';
236              
237 18     18   166 use strict;
  18         29  
  18         564  
238 18     18   90 use warnings;
  18         28  
  18         496  
239 18     18   70 use utf8;
  18         20  
  18         66  
240 18     18   294 use App::MtAws::Utils;
  18         18  
  18         1886  
241 18     18   64 use Carp;
  18         20  
  18         838  
242 18     18   62 use base qw/App::MtAws::HttpWriter/;
  18         19  
  18         9632  
243              
244              
245             sub new
246             {
247 0     0     my ($class, %args) = @_;
248 0           my $self = {};
249 0           bless $self, $class;
250 0           return $self;
251             }
252              
253             sub reinit
254             {
255 0     0     my $self = shift;
256 0           $self->{size} = shift;
257 0           $self->{buffer} = '';
258 0           $self->{total_length} = 0;
259             }
260              
261             sub add_data
262             {
263 0     0     my $self = $_[0];
264 0 0         return unless defined($_[1]);
265 0           $self->{buffer} .= $_[1];
266 0           $self->{total_length} += length($_[1]);
267 0           1;
268             }
269              
270             sub finish
271             {
272 0     0     my ($self) = @_;
273 0 0 0       return ($self->{total_length} && ($self->{total_length} == $self->{size})) ? ('ok') : ('retry', 'Unexpected end of data');
274             }
275              
276             1;