home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / Decoder.pm < prev    next >
Encoding:
Perl POD Document  |  2002-06-14  |  16.3 KB  |  641 lines

  1. package MIME::Decoder;
  2.  
  3.  
  4. =head1 NAME
  5.  
  6. MIME::Decoder - an object for decoding the body part of a MIME stream
  7.  
  8.  
  9. =head1 SYNOPSIS
  10.  
  11. Before reading further, you should see L<MIME::Tools> to make sure that
  12. you understand where this module fits into the grand scheme of things.
  13. Go on, do it now.  I'll wait.
  14.  
  15. Ready?  Ok...
  16.  
  17.  
  18. =head2 Decoding a data stream
  19.  
  20. Here's a simple filter program to read quoted-printable data from STDIN
  21. (until EOF) and write the decoded data to STDOUT:
  22.  
  23.     use MIME::Decoder;
  24.  
  25.     $decoder = new MIME::Decoder 'quoted-printable' or die "unsupported";
  26.     $decoder->decode(\*STDIN, \*STDOUT);
  27.  
  28.  
  29. =head2 Encoding a data stream
  30.  
  31. Here's a simple filter program to read binary data from STDIN
  32. (until EOF) and write base64-encoded data to STDOUT:
  33.  
  34.     use MIME::Decoder;
  35.  
  36.     $decoder = new MIME::Decoder 'base64' or die "unsupported";
  37.     $decoder->encode(\*STDIN, \*STDOUT);
  38.  
  39.  
  40. =head2 Non-standard encodings
  41.  
  42. You can B<write and install> your own decoders so that
  43. MIME::Decoder will know about them:
  44.  
  45.     use MyBase64Decoder;
  46.  
  47.     install MyBase64Decoder 'base64';
  48.  
  49. You can also B<test> if a given encoding is supported:
  50.  
  51.     if (supported MIME::Decoder 'x-uuencode') {
  52.         ### we can uuencode!
  53.     }
  54.  
  55.  
  56. =head1 DESCRIPTION
  57.  
  58. This abstract class, and its private concrete subclasses (see below)
  59. provide an OO front end to the actions of...
  60.  
  61. =over 4
  62.  
  63. =item *
  64.  
  65. Decoding a MIME-encoded stream
  66.  
  67. =item *
  68.  
  69. Encoding a raw data stream into a MIME-encoded stream.
  70.  
  71. =back
  72.  
  73. The constructor for MIME::Decoder takes the name of an encoding
  74. (C<base64>, C<7bit>, etc.), and returns an instance of a I<subclass>
  75. of MIME::Decoder whose C<decode()> method will perform the appropriate
  76. decoding action, and whose C<encode()> method will perform the appropriate
  77. encoding action.
  78.  
  79.  
  80. =cut
  81.  
  82.  
  83. ### Pragmas:
  84. use strict;
  85. use vars qw($VERSION %DecoderFor);
  86.  
  87. ### System modules:
  88. use FileHandle;
  89. use IPC::Open2;
  90.  
  91. ### Kit modules:
  92. use MIME::Tools qw(:config :msgs);
  93. use IO::Wrap;
  94. use Carp;
  95.  
  96. #------------------------------
  97. #
  98. # Globals
  99. #------------------------------
  100.  
  101. ### The stream decoders:
  102. %DecoderFor = (
  103.  
  104.   ### Standard...
  105.     '7bit'       => 'MIME::Decoder::NBit',
  106.     '8bit'       => 'MIME::Decoder::NBit',
  107.     'base64'     => 'MIME::Decoder::Base64',
  108.     'binary'     => 'MIME::Decoder::Binary',
  109.     'none'       => 'MIME::Decoder::Binary',
  110.     'quoted-printable' => 'MIME::Decoder::QuotedPrint',
  111.  
  112.   ### Non-standard...
  113.     'x-uu'       => 'MIME::Decoder::UU',
  114.     'x-uuencode' => 'MIME::Decoder::UU',
  115.  
  116.   ### This was removed, since I fear that x-gzip != x-gzip64...
  117. ### 'x-gzip'     => 'MIME::Decoder::Gzip64',
  118.  
  119.   ### This is no longer installed by default, since not all folks have gzip:
  120. ### 'x-gzip64'   => 'MIME::Decoder::Gzip64',
  121. );
  122.  
  123. ### The package version, both in 1.23 style *and* usable by MakeMaker:
  124. $VERSION = substr q$Revision: 5.403 $, 10;
  125.  
  126. ### Me:
  127. my $ME = 'MIME::Decoder';
  128.  
  129.  
  130. #------------------------------
  131.  
  132. =head1 PUBLIC INTERFACE
  133.  
  134. =head2 Standard interface
  135.  
  136. If all you are doing is I<using> this class, here's all you'll need...
  137.  
  138. =over 4
  139.  
  140. =cut
  141.  
  142. #------------------------------
  143.  
  144. =item new ENCODING
  145.  
  146. I<Class method, constructor.>
  147. Create and return a new decoder object which can handle the
  148. given ENCODING.
  149.  
  150.     my $decoder = new MIME::Decoder "7bit";
  151.  
  152. Returns the undefined value if no known decoders are appropriate.
  153.  
  154. =cut
  155.  
  156. sub new {
  157.     my ($class, @args) = @_;
  158.     my ($encoding) = @args;
  159.     my ($concrete_name, $concrete_path);
  160.  
  161.     ### Coerce the type to be legit:
  162.     $encoding = lc($encoding || '');
  163.  
  164.     ### Get the class:
  165.     ($concrete_name = $DecoderFor{$encoding}) or return undef;
  166.     ($concrete_path = $concrete_name.'.pm') =~ s{::}{/}g;
  167.  
  168.     ### Create the new object (if we can):
  169.     my $self = { MD_Encoding => lc($encoding) };
  170.     require $concrete_path;
  171.     bless $self, $concrete_name;
  172.     $self->init(@args);
  173. }
  174.  
  175. #------------------------------
  176.  
  177. =item best ENCODING
  178.  
  179. I<Class method, constructor.>
  180. Exactly like new(), except that this defaults any unsupported encoding to
  181. "binary", after raising a suitable warning (it's a fatal error if there's
  182. no binary decoder).
  183.  
  184.     my $decoder = best MIME::Decoder "x-gzip64";
  185.  
  186. Will either return a decoder, or a raise a fatal exception.
  187.  
  188. =cut
  189.  
  190. sub best {
  191.     my ($class, $enc, @args) = @_;
  192.     my $self = $class->new($enc, @args);
  193.     if (!$self) {
  194.     usage "unsupported encoding '$enc': using 'binary'";
  195.     $self = $class->new('binary') || croak "ack! no binary decoder!";
  196.     }
  197.     $self;
  198. }
  199.  
  200. #------------------------------
  201.  
  202. =item decode INSTREAM,OUTSTREAM
  203.  
  204. I<Instance method.>
  205. Decode the document waiting in the input handle INSTREAM,
  206. writing the decoded information to the output handle OUTSTREAM.
  207.  
  208. Read the section in this document on I/O handles for more information
  209. about the arguments.  Note that you can still supply old-style
  210. unblessed filehandles for INSTREAM and OUTSTREAM.
  211.  
  212. Returns true on success, throws exception on failure.
  213.  
  214. =cut
  215.  
  216. sub decode {
  217.     my ($self, $in, $out) = @_;
  218.     
  219.     ### Set up the default input record separator to be CRLF:
  220.     ### $in->input_record_separator("\012\015");
  221.  
  222.     ### Coerce old-style filehandles to legit objects, and do it!
  223.     $in  = wraphandle($in);
  224.     $out = wraphandle($out);
  225.  
  226.     ### Invoke back-end method to do the work:
  227.     $self->decode_it($in, $out) ||
  228.     die "$ME: ".$self->encoding." decoding failed\n";
  229.     1;
  230. }
  231.  
  232. #------------------------------
  233.  
  234. =item encode INSTREAM,OUTSTREAM
  235.  
  236. I<Instance method.>
  237. Encode the document waiting in the input filehandle INSTREAM,
  238. writing the encoded information to the output stream OUTSTREAM.
  239.  
  240. Read the section in this document on I/O handles for more information
  241. about the arguments.  Note that you can still supply old-style
  242. unblessed filehandles for INSTREAM and OUTSTREAM.
  243.  
  244. Returns true on success, throws exception on failure.
  245.  
  246. =cut
  247.  
  248. sub encode {
  249.     my ($self, $in, $out) = @_;
  250.     
  251.     ### Coerce old-style filehandles to legit objects, and do it!
  252.     $in  = wraphandle($in);
  253.     $out = wraphandle($out);
  254.  
  255.     ### Invoke back-end method to do the work:
  256.     $self->encode_it($in, $out) || 
  257.     die "$ME: ".$self->encoding." encoding failed\n";
  258. }
  259.  
  260. #------------------------------
  261.  
  262. =item encoding
  263.  
  264. I<Instance method.>
  265. Return the encoding that this object was created to handle,
  266. coerced to all lowercase (e.g., C<"base64">).
  267.  
  268. =cut
  269.  
  270. sub encoding {
  271.     shift->{MD_Encoding};
  272. }
  273.  
  274. #------------------------------
  275.  
  276. =item head [HEAD]
  277.  
  278. I<Instance method.>
  279. Completely optional: some decoders need to know a little about the file
  280. they are encoding/decoding; e.g., x-uu likes to have the filename.
  281. The HEAD is any object which responds to messages like:
  282.  
  283.     $head->mime_attr('content-disposition.filename');
  284.  
  285. =cut
  286.  
  287. sub head {
  288.     my ($self, $head) = @_;
  289.     $self->{MD_Head} = $head if @_ > 1;
  290.     $self->{MD_Head};
  291. }
  292.  
  293. #------------------------------
  294.  
  295. =item supported [ENCODING]
  296.  
  297. I<Class method.>
  298. With one arg (an ENCODING name), returns truth if that encoding
  299. is currently handled, and falsity otherwise.  The ENCODING will
  300. be automatically coerced to lowercase:
  301.  
  302.     if (supported MIME::Decoder '7BIT') {
  303.         ### yes, we can handle it...
  304.     }
  305.     else {
  306.         ### drop back six and punt...
  307.     }
  308.  
  309. With no args, returns a reference to a hash of all available decoders,
  310. where the key is the encoding name (all lowercase, like '7bit'),
  311. and the value is true (it happens to be the name of the class
  312. that handles the decoding, but you probably shouldn't rely on that).
  313. You may safely modify this hash; it will I<not> change the way the
  314. module performs its lookups.  Only C<install> can do that.
  315.  
  316. I<Thanks to Achim Bohnet for suggesting this method.>
  317.  
  318. =cut
  319.  
  320. sub supported {
  321.     my ($class, $decoder) = @_;
  322.     defined($decoder) ? $DecoderFor{lc($decoder)}: { %DecoderFor };
  323. }
  324.  
  325. #------------------------------
  326.  
  327. =back
  328.  
  329. =head2 Subclass interface
  330.  
  331. If you are writing (or installing) a new decoder subclass, there
  332. are some other methods you'll need to know about:
  333.  
  334. =over 4
  335.  
  336. =cut
  337.  
  338. #------------------------------
  339.  
  340. =item decode_it INSTREAM,OUTSTREAM
  341.  
  342. I<Abstract instance method.>
  343. The back-end of the B<decode> method.  It takes an input handle
  344. opened for reading (INSTREAM), and an output handle opened for
  345. writing (OUTSTREAM).
  346.  
  347. If you are writing your own decoder subclass, you must override this
  348. method in your class.  Your method should read from the input
  349. handle via C<getline()> or C<read()>, decode this input, and print the
  350. decoded data to the output handle via C<print()>.  You may do this
  351. however you see fit, so long as the end result is the same.
  352.  
  353. Note that unblessed references and globrefs are automatically turned
  354. into I/O handles for you by C<decode()>, so you don't need to worry
  355. about it.
  356.  
  357. Your method must return either C<undef> (to indicate failure),
  358. or C<1> (to indicate success).
  359. It may also throw an exception to indicate failure.
  360.  
  361. =cut
  362.  
  363. sub decode_it {
  364.     die "attempted to use abstract 'decode_it' method!";
  365. }
  366.  
  367. #------------------------------
  368.  
  369. =item encode_it INSTREAM,OUTSTREAM
  370.  
  371. I<Abstract instance method.>
  372. The back-end of the B<encode> method.  It takes an input handle
  373. opened for reading (INSTREAM), and an output handle opened for
  374. writing (OUTSTREAM).
  375.  
  376. If you are writing your own decoder subclass, you must override this
  377. method in your class.  Your method should read from the input
  378. handle via C<getline()> or C<read()>, encode this input, and print the
  379. encoded data to the output handle via C<print()>.  You may do this
  380. however you see fit, so long as the end result is the same.
  381.  
  382. Note that unblessed references and globrefs are automatically turned
  383. into I/O handles for you by C<encode()>, so you don't need to worry
  384. about it.
  385.  
  386. Your method must return either C<undef> (to indicate failure),
  387. or C<1> (to indicate success).
  388. It may also throw an exception to indicate failure.
  389.  
  390. =cut
  391.  
  392. sub encode_it {
  393.     die "attempted to use abstract 'encode_it' method!";
  394. }
  395.  
  396. #------------------------------
  397.  
  398. =item filter IN, OUT, COMMAND...
  399.  
  400. I<Class method, utility.>
  401. If your decoder involves an external program, you can invoke
  402. them easily through this method.  The command must be a "filter": a
  403. command that reads input from its STDIN (which will come from the IN argument)
  404. and writes output to its STDOUT (which will go to the OUT argument).
  405.  
  406. For example, here's a decoder that un-gzips its data:
  407.  
  408.     sub decode_it {
  409.         my ($self, $in, $out) = @_;
  410.         $self->filter($in, $out, "gzip -d -");
  411.     }
  412.  
  413. The usage is similar to IPC::Open2::open2 (which it uses internally),
  414. so you can specify COMMAND as a single argument or as an array.
  415.  
  416. =cut
  417.  
  418. sub filter {
  419.     my ($self, $in, $out, @cmd) = @_;
  420.     my $buf = '';
  421.  
  422.     ### Make sure we've got MIME::IO-compliant objects:
  423.     $in  = wraphandle($in);
  424.     $out = wraphandle($out);
  425.    
  426.     ### Open pipe:
  427.     STDOUT->flush;       ### very important, or else we get duplicate output!
  428.     my $kidpid = open2(\*CHILDOUT, \*CHILDIN, @cmd) || die "open2 failed: $!";
  429.  
  430.     ### Write all:
  431.     while ($in->read($buf, 2048)) { print CHILDIN $buf }
  432.     close \*CHILDIN;
  433.  
  434.     ### Read all:
  435.     while (read(\*CHILDOUT, $buf, 2048)) { $out->print($buf) }
  436.     close \*CHILDOUT;
  437.     
  438.     ### Wait for it:
  439.     waitpid($kidpid,0) or die "couldn't reap child $kidpid";
  440.     1;
  441. }
  442.  
  443.  
  444. #------------------------------
  445.  
  446. =item init ARGS...
  447.  
  448. I<Instance method.>
  449. Do any necessary initialization of the new instance,
  450. taking whatever arguments were given to C<new()>.
  451. Should return the self object on success, undef on failure.
  452.  
  453. =cut
  454.  
  455. sub init {
  456.     $_[0];
  457. }
  458.  
  459. #------------------------------
  460.  
  461. =item install ENCODINGS...
  462.  
  463. I<Class method>.
  464. Install this class so that each encoding in ENCODINGS is handled by it:
  465.  
  466.     install MyBase64Decoder 'base64', 'x-base64super';
  467.  
  468. You should not override this method.
  469.  
  470. =cut
  471.  
  472. sub install {
  473.     my $class = shift;
  474.     $DecoderFor{lc(shift @_)} = $class while (@_);
  475. }
  476.  
  477. #------------------------------
  478.  
  479. =item uninstall ENCODINGS...
  480.  
  481. I<Class method>.
  482. Uninstall support for encodings.  This is a way to turn off the decoding
  483. of "experimental" encodings.  For safety, always use MIME::Decoder directly:
  484.  
  485.     uninstall MIME::Decoder 'x-uu', 'x-uuencode';
  486.  
  487. You should not override this method.
  488.  
  489. =cut
  490.  
  491. sub uninstall {
  492.     shift;
  493.     $DecoderFor{lc(shift @_)} = undef while (@_);
  494. }
  495.  
  496. 1;
  497.  
  498. __END__
  499.  
  500. #------------------------------
  501.  
  502. =back
  503.  
  504. =head1 DECODER SUBCLASSES
  505.  
  506. You don't need to C<"use"> any other Perl modules; the
  507. following "standard" subclasses are included as part of MIME::Decoder:
  508.  
  509.      Class:                         Handles encodings:
  510.      ------------------------------------------------------------
  511.      MIME::Decoder::Binary          binary
  512.      MIME::Decoder::NBit            7bit, 8bit
  513.      MIME::Decoder::Base64          base64
  514.      MIME::Decoder::QuotedPrint     quoted-printable
  515.  
  516. The following "non-standard" subclasses are also included:
  517.  
  518.      Class:                         Handles encodings:
  519.      ------------------------------------------------------------
  520.      MIME::Decoder::UU              x-uu, x-uuencode
  521.      MIME::Decoder::Gzip64          x-gzip64            ** requires gzip!
  522.  
  523.  
  524.  
  525. =head1 NOTES
  526.  
  527. =head2 Input/Output handles
  528.  
  529. As of MIME-tools 2.0, this class has to play nice with the new MIME::Body
  530. class... which means that input and output routines cannot just assume that
  531. they are dealing with filehandles.
  532.  
  533. Therefore, all that MIME::Decoder and its subclasses require (and, thus,
  534. all that they can assume) is that INSTREAMs and OUTSTREAMs are objects
  535. which respond to a subset of the messages defined in the IO::Handle
  536. interface; minimally:
  537.  
  538.       print
  539.       getline
  540.       read(BUF,NBYTES)
  541.  
  542. For backwards compatibilty, if you supply a scalar filehandle name
  543. (like C<"STDOUT">) or an unblessed glob reference (like C<\*STDOUT>)
  544. where an INSTREAM or OUTSTREAM is expected, this package will
  545. automatically wrap it in an object that fits these criteria, via IO::Wrap.
  546.  
  547. I<Thanks to Achim Bohnet for suggesting this more-generic I/O model.>
  548.  
  549.  
  550. =head2 Writing a decoder
  551.  
  552. If you're experimenting with your own encodings, you'll probably want
  553. to write a decoder.  Here are the basics:
  554.  
  555. =over 4
  556.  
  557. =item 1.
  558.  
  559. Create a module, like "MyDecoder::", for your decoder.
  560. Declare it to be a subclass of MIME::Decoder.
  561.  
  562. =item 2.
  563.  
  564. Create the following instance methods in your class, as described above:
  565.  
  566.     decode_it
  567.     encode_it
  568.     init
  569.  
  570. =item 3.
  571.  
  572. In your application program, activate your decoder for one or
  573. more encodings like this:
  574.  
  575.     require MyDecoder;
  576.  
  577.     install MyDecoder "7bit";   ### use MyDecoder to decode "7bit"
  578.     install MyDecoder "x-foo";  ### also use MyDecoder to decode "x-foo"
  579.  
  580. =back
  581.  
  582. To illustrate, here's a custom decoder class for the C<quoted-printable>
  583. encoding:
  584.  
  585.     package MyQPDecoder;
  586.  
  587.     @ISA = qw(MIME::Decoder);
  588.     use MIME::Decoder;
  589.     use MIME::QuotedPrint;
  590.  
  591.     ### decode_it - the private decoding method
  592.     sub decode_it {
  593.         my ($self, $in, $out) = @_;
  594.  
  595.         while (defined($_ = $in->getline)) {
  596.             my $decoded = decode_qp($_);
  597.         $out->print($decoded);
  598.         }
  599.         1;
  600.     }
  601.  
  602.     ### encode_it - the private encoding method
  603.     sub encode_it {
  604.         my ($self, $in, $out) = @_;
  605.  
  606.         my ($buf, $nread) = ('', 0);
  607.         while ($in->read($buf, 60)) {
  608.             my $encoded = encode_qp($buf);
  609.         $out->print($encoded);
  610.         }
  611.         1;
  612.     }
  613.  
  614. That's it.  The task was pretty simple because the C<"quoted-printable">
  615. encoding can easily be converted line-by-line... as can
  616. even C<"7bit"> and C<"8bit"> (since all these encodings guarantee
  617. short lines, with a max of 1000 characters).
  618. The good news is: it is very likely that it will be similarly-easy to
  619. write a MIME::Decoder for any future standard encodings.
  620.  
  621. The C<"binary"> decoder, however, really required block reads and writes:
  622. see L<"MIME::Decoder::Binary"> for details.
  623.  
  624.  
  625. =head1 AUTHOR
  626.  
  627. Eryq (F<eryq@zeegee.com>), ZeeGee Software Inc (F<http://www.zeegee.com>).
  628.  
  629. All rights reserved.  This program is free software; you can redistribute
  630. it and/or modify it under the same terms as Perl itself.
  631.  
  632.  
  633. =head1 VERSION
  634.  
  635. $Revision: 5.403 $ $Date: 2000/11/04 19:54:46 $
  636.  
  637. =cut
  638.  
  639. 1;
  640.