| MIME-tools documentation | Contained in the MIME-tools distribution. |
MIME::Decoder::Base64 - encode/decode a "base64" stream
A generic decoder object; see MIME::Decoder for usage.
A MIME::Decoder subclass for the "base64" encoding.
The name was chosen to jibe with the pre-existing MIME::Base64
utility package, which this class actually uses to translate each chunk.
Eryq (eryq@zeegee.com), ZeeGee Software Inc (http://www.zeegee.com).
All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| MIME-tools documentation | Contained in the MIME-tools distribution. |
package MIME::Decoder::Base64;
use vars qw(@ISA $VERSION); use MIME::Decoder; use MIME::Base64 2.04; use MIME::Tools qw(debug); @ISA = qw(MIME::Decoder); ### The package version, both in 1.23 style *and* usable by MakeMaker: $VERSION = "5.502"; ### How many bytes to encode at a time (must be a multiple of 3, and ### less than (76 * 0.75)! my $EncodeChunkLength = 45; ### How many bytes to decode at a time? my $DecodeChunkLength = 32 * 1024; #------------------------------ # # decode_it IN, OUT # sub decode_it { my ($self, $in, $out) = @_; my $len_4xN; ### Create a suitable buffer: my $buffer = ' ' x (120 + $DecodeChunkLength); $buffer = ''; debug "in = $in; out = $out"; ### Get chunks until done: local($_) = ' ' x $DecodeChunkLength; while ($in->read($_, $DecodeChunkLength)) { tr{A-Za-z0-9+/}{}cd; ### get rid of non-base64 chars ### Concat any new input onto any leftover from the last round: $buffer .= $_; length($buffer) >= $DecodeChunkLength or next; ### Extract substring with highest multiple of 4 bytes: ### 0 means not enough to work with... get more data! $len_4xN = length($buffer) & ~3; ### Partition into largest-multiple-of-4 (which we decode), ### and the remainder (which gets handled next time around): $out->print(decode_base64(substr($buffer, 0, $len_4xN))); $buffer = substr($buffer, $len_4xN); } ### No more input remains. Dispose of anything left in buffer: if (length($buffer)) { ### Pad to 4-byte multiple, and decode: $buffer .= "==="; ### need no more than 3 pad chars $len_4xN = length($buffer) & ~3; ### Decode it! $out->print(decode_base64(substr($buffer, 0, $len_4xN))); } 1; } #------------------------------ # # encode_it IN, OUT # sub encode_it { my ($self, $in, $out) = @_; my $encoded; my $nread; my $buf = ''; while ($nread = $in->read($buf, $EncodeChunkLength)) { $encoded = encode_base64($buf); $encoded .= "\n" unless ($encoded =~ /\n\Z/); ### ensure newline! $out->print($encoded); } 1; } #------------------------------ 1;