File Coverage

blib/lib/MIME/Decoder/Base64.pm
Criterion Covered Total %
statement 45 45 100.0
branch 4 6 66.6
condition 2 2 100.0
subroutine 8 8 100.0
pod 2 2 100.0
total 61 63 96.8


line stmt bran cond sub pod time code
1             package MIME::Decoder::Base64;
2 12     12   80 use strict;
  12         26  
  12         610  
3 12     12   70 use warnings;
  12         22  
  12         920  
4              
5              
6             =head1 NAME
7              
8             MIME::Decoder::Base64 - encode/decode a "base64" stream
9              
10              
11             =head1 SYNOPSIS
12              
13             A generic decoder object; see L for usage.
14              
15              
16             =head1 DESCRIPTION
17              
18             A L subclass for the C<"base64"> encoding.
19             The name was chosen to jibe with the pre-existing MIME::Base64
20             utility package, which this class actually uses to translate each chunk.
21              
22             =over 4
23              
24             =item *
25              
26             When B, the input is read one line at a time.
27             The input accumulates in an internal buffer, which is decoded in
28             multiple-of-4-sized chunks (plus a possible "leftover" input chunk,
29             of course).
30              
31             =item *
32              
33             When B, the input is read 6840 (120 * 57) bytes at a time.
34             Each section of 57 bytes is encoded as a line containing 76 Base64
35             characters.
36              
37             =back
38              
39             =head1 SEE ALSO
40              
41             L
42              
43             =head1 AUTHOR
44              
45             Eryq (F), ZeeGee Software Inc (F).
46              
47             All rights reserved. This program is free software; you can redistribute
48             it and/or modify it under the same terms as Perl itself.
49              
50             =cut
51              
52 12     12   80 use vars qw(@ISA $VERSION);
  12         20  
  12         756  
53 12     12   83 use MIME::Decoder;
  12         19  
  12         727  
54 12     12   85 use MIME::Base64 2.04;
  12         331  
  12         1055  
55 12     12   80 use MIME::Tools qw(debug);
  12         22  
  12         10253  
56              
57             @ISA = qw(MIME::Decoder);
58              
59             ### The package version, both in 1.23 style *and* usable by MakeMaker:
60             $VERSION = "5.517";
61              
62             ### How many bytes to encode at a time (must be a multiple of 3)
63             my $EncodeChunkLength = 120 * 57;
64              
65             ### How many bytes to decode at a time?
66             my $DecodeChunkLength = 32 * 1024;
67              
68             #------------------------------
69             #
70             # decode_it IN, OUT
71             #
72             sub decode_it {
73 46     46 1 116 my ($self, $in, $out) = @_;
74 46         88 my $len_4xN;
75            
76             ### Create a suitable buffer:
77 46         2015 my $buffer = ' ' x (120 + $DecodeChunkLength); $buffer = '';
  46         130  
78 46         308 debug "in = $in; out = $out";
79              
80             ### Get chunks until done:
81 46         825 local($_) = ' ' x $DecodeChunkLength;
82 46         230 while ($in->read($_, $DecodeChunkLength)) {
83 47         1903 tr{A-Za-z0-9+/}{}cd; ### get rid of non-base64 chars
84              
85             ### Concat any new input onto any leftover from the last round:
86 47         182 $buffer .= $_;
87 47 100       225 length($buffer) >= $DecodeChunkLength or next;
88            
89             ### Extract substring with highest multiple of 4 bytes:
90             ### 0 means not enough to work with... get more data!
91 1         3 $len_4xN = length($buffer) & ~3;
92              
93             ### Partition into largest-multiple-of-4 (which we decode),
94             ### and the remainder (which gets handled next time around):
95 1         237 $out->print(decode_base64(substr($buffer, 0, $len_4xN)));
96 1         72 $buffer = substr($buffer, $len_4xN);
97             }
98            
99             ### No more input remains. Dispose of anything left in buffer:
100 46 50       403 if (length($buffer)) {
101              
102             ### Pad to 4-byte multiple, and decode:
103 46         112 $buffer .= "==="; ### need no more than 3 pad chars
104 46         116 $len_4xN = length($buffer) & ~3;
105              
106             ### Decode it!
107 46         711 $out->print(decode_base64(substr($buffer, 0, $len_4xN)));
108             }
109 46         779 1;
110             }
111              
112             #------------------------------
113             #
114             # encode_it IN, OUT
115             #
116             sub encode_it {
117 10     10 1 24 my ($self, $in, $out) = @_;
118 10         17 my $encoded;
119              
120             my $nread;
121 10         21 my $buf = '';
122 10   100     39 my $nl = $MIME::Entity::BOUNDARY_DELIMITER || "\n";
123 10         64 while ($nread = $in->read($buf, $EncodeChunkLength)) {
124 10         494 $encoded = encode_base64($buf, $nl);
125 10 50       125 $encoded .= $nl unless ($encoded =~ /$nl\Z/); ### ensure newline!
126 10         42 $out->print($encoded);
127             }
128 10         271 1;
129             }
130              
131             #------------------------------
132             1;
133