File Coverage

blib/lib/Convert/yEnc/Decoder.pm
Criterion Covered Total %
statement 112 112 100.0
branch 24 34 70.5
condition 2 2 100.0
subroutine 20 20 100.0
pod 9 9 100.0
total 167 177 94.3


line stmt bran cond sub pod time code
1             package Convert::yEnc::Decoder;
2              
3 2     2   107040 use strict;
  2         6  
  2         75  
4 2     2   1346 use IO::File;
  2         15652  
  2         275  
5 2     2   18 use warnings;
  2         9  
  2         85  
6              
7 2     2   13 use constant yEncBrainDamage => 1;
  2         3  
  2         4312  
8              
9              
10             sub new
11             {
12 11     11 1 69961 my($class, $dir) = @_;
13              
14 11   100     100 my $decoder = { dir => $dir || '.' };
15              
16 11         98 bless $decoder, $class
17             }
18              
19             sub out_dir
20             {
21 9     9 1 24 my($decoder, $dir) = @_;
22              
23 9         31 $decoder->{dir} = $dir;
24             }
25              
26              
27             sub decode
28             {
29 14     14 1 1825 my($decoder, $in) = @_;
30              
31 14         113 delete $decoder->{temp};
32              
33 14         50 $decoder->_in($in);
34 12         42 $decoder->_begin;
35 12         39 $decoder->_out;
36 12 100       63 $decoder->_part if $decoder->{temp}{begin}{part};
37 12         48 $decoder->_body;
38 12         43 $decoder->_end;
39             }
40              
41             sub _in
42             {
43 14     14   26 my($decoder, $in) = @_;
44              
45 14 50       161 my $IN = ref $in ? $in :
    100          
46             defined $in ? (new IO::File $in) : \*STDIN;
47              
48 14 100       1251 $IN or die ref $decoder, "::decode: Can't open $in: $!\n";
49 12         98 $decoder->{temp}{IN} = $IN;
50             }
51              
52             sub _begin
53             {
54 12     12   21 my $decoder = shift;
55 12         23 my $temp = $decoder->{temp};
56 12         20 my $IN = $temp->{IN};
57              
58 12         17 my $begin;
59 12         329 while ($begin = <$IN>)
60             {
61 128 100       429 $begin =~ /^=ybegin/ and last;
62             }
63              
64 12 50       36 $begin or die ref $decoder, "::_begin: Can't find =ybegin line\n";
65            
66 12         72 my @begin = split ' ', $begin;
67              
68 12         33 for my $field (@begin)
69             {
70 56         131 my($key, $val) = split /=/, $field;
71 56         171 $temp->{begin}{$key} = $val;
72             }
73              
74 12         78 my($name) = $begin =~ /name=(.*)/; # Horrid Martian.
75 12         95 $name =~ s/^\s+|\s+$//g;
76 12         32 $temp->{begin}{name} = $name;
77              
78 12         57 $temp->{line}{ybegin} = $begin;
79             }
80              
81             sub _out
82             {
83 12     12   31 my $decoder = shift;
84 12         28 my $dir = $decoder->{dir};
85 12         22 my $temp = $decoder->{temp};
86 12         30 my $name = $temp->{begin}{name};
87 12         28 my $file = "$dir/$name";
88 12         20 my $mode = O_CREAT | O_WRONLY;
89 12 50       63 my $OUT = new IO::File $file, $mode or
90             die ref $decoder, "::_out: Can't open $file: $!\n";
91            
92 12 50       1521 binmode $OUT or
93             die ref $decoder, "::_out: Can't binmode $file: $!\n";
94              
95 12         28 $temp->{name} = $name;
96 12         28 $temp->{file} = $file;
97 12         39 $temp->{OUT } = $OUT;
98             }
99              
100             sub _part
101             {
102 4     4   13 my $decoder = shift;
103 4         12 my $temp = $decoder->{temp};
104 4         9 my $IN = $temp->{IN };
105 4         10 my $OUT = $temp->{OUT};
106 4         12 my $part = <$IN>;
107 4 50       25 $part =~ /^=ypart/ or die ref $decoder, "::_part: No =ypart line\n";
108 4         15 my @part = split ' ', $part;
109              
110 4         14 for my $field (@part)
111             {
112 12         31 my($key, $val) = split /=/, $field;
113 12         35 $temp->{part}{$key} = $val;
114             }
115              
116 4         14 my $begin = $temp->{part}{begin};
117 4         10 my $end = $temp->{part}{end };
118 4         15 my $offset = $begin - yEncBrainDamage;
119 4         13 my $size = $end - $offset;
120              
121 4 50       33 seek $OUT, $offset, 0 or
122             die ref $decoder, "::_part: Can't seek to $begin: $!\n";
123              
124 4         14 $temp->{part}{size } = $size;
125 4         17 $temp->{line}{ypart} = $part;
126             }
127              
128             sub _body
129             {
130 12     12   19 my $decoder = shift;
131 12         21 my $temp = $decoder->{temp};
132 12         24 my $file = $temp->{file};
133 12         19 my $IN = $temp->{IN};
134 12         19 my $OUT = $temp->{OUT};
135 12         13 my $line;
136              
137 12         62 while ($line = <$IN>)
138             {
139 364 100       728 $line =~ /^=yend/ and last;
140 352         396 chomp $line;
141              
142 352         846 $decoder->_line($line);
143              
144 352 50       1971 print $OUT $line or
145             die "can't print to $file: $!\n";
146             }
147              
148 12         683 close $OUT;
149 12         60 $temp->{line}{yend} = $line;
150             }
151              
152             sub _line
153             {
154 352     352   1128 $_[1] =~ s/=(.)/chr(ord($1)+256-64 & 255)/egosx;
  986         3378  
155 352         614 $_[1] =~ tr[\000-\377][\326-\377\000-\325];
156            
157             }
158              
159             sub _end
160             {
161 12     12   34 my $decoder = shift;
162 12         25 my $temp = $decoder->{temp};
163 12         32 my $end = $temp->{line}{yend};
164 12 50       51 $end =~ /^=yend/ or die ref $decoder, "::end: No =yend line\n";
165              
166 12         60 my @end = split ' ', $end;
167              
168 12         35 for my $field (@end)
169             {
170 40         102 my($key, $val) = split /=/, $field;
171 40         135 $temp->{end}{$key} = $val;
172             }
173              
174 12         39 my $beginSize = $temp->{begin}{size};
175 12         34 my $partSize = $temp->{part }{size};
176 12         25 my $endSize = $temp->{end }{size};
177 12 100       36 my $decodeSize = defined $partSize ? $partSize : $beginSize;
178              
179 12 50       45 $decodeSize == $endSize or
180             die ref $decoder,
181             "::_end: Begin/PartSize $decodeSize != EndSize $endSize\n";
182              
183 12 100       32 if (not defined $partSize)
184             {
185 8         18 my $file = $temp->{file};
186 8         159 my $fileSize = (stat $file)[7];
187 8 50       33 $beginSize == $fileSize or
188             die ref $decoder,
189             "::_end: BeginSize $beginSize != FileSize $fileSize\n";
190             }
191              
192 12         66 $temp->{size} = $decodeSize;
193             }
194              
195 8     8 1 3935 sub name { shift->{temp}{name} }
196 2     2 1 14 sub file { shift->{temp}{file} }
197 2     2 1 15 sub size { shift->{temp}{size} }
198 8     8 1 35 sub ybegin { shift->{temp}{line}{ybegin} }
199 8     8 1 36 sub ypart { shift->{temp}{line}{ypart } }
200 8     8 1 34 sub yend { shift->{temp}{line}{yend } }
201              
202              
203             1
204              
205             __END__