This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Update IO-Compress to CPAN version 2.096
[perl5.git] / cpan / IO-Compress / lib / IO / Compress / Bzip2.pm
1 package IO::Compress::Bzip2 ;
2
3 use strict ;
4 use warnings;
5 use bytes;
6 require Exporter ;
7
8 use IO::Compress::Base 2.096 ;
9
10 use IO::Compress::Base::Common  2.096 qw();
11 use IO::Compress::Adapter::Bzip2 2.096 ;
12
13
14
15 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $Bzip2Error);
16
17 $VERSION = '2.096';
18 $Bzip2Error = '';
19
20 @ISA    = qw(IO::Compress::Base Exporter);
21 @EXPORT_OK = qw( $Bzip2Error bzip2 ) ;
22 %EXPORT_TAGS = %IO::Compress::Base::EXPORT_TAGS ;
23 push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
24 Exporter::export_ok_tags('all');
25
26
27
28 sub new
29 {
30     my $class = shift ;
31
32     my $obj = IO::Compress::Base::Common::createSelfTiedObject($class, \$Bzip2Error);
33     return $obj->_create(undef, @_);
34 }
35
36 sub bzip2
37 {
38     my $obj = IO::Compress::Base::Common::createSelfTiedObject(undef, \$Bzip2Error);
39     $obj->_def(@_);
40 }
41
42
43 sub mkHeader 
44 {
45     my $self = shift ;
46     return '';
47
48 }
49
50 sub getExtraParams
51 {
52     my $self = shift ;
53
54     use IO::Compress::Base::Common  2.096 qw(:Parse);
55     
56     return (  
57             'blocksize100k' => [IO::Compress::Base::Common::Parse_unsigned,  1],
58             'workfactor'    => [IO::Compress::Base::Common::Parse_unsigned,  0],
59             'verbosity'     => [IO::Compress::Base::Common::Parse_boolean,   0],
60         );
61 }
62
63
64
65 sub ckParams
66 {
67     my $self = shift ;
68     my $got = shift;
69     
70     # check that BlockSize100K is a number between 1 & 9
71     if ($got->parsed('blocksize100k')) {
72         my $value = $got->getValue('blocksize100k');
73         return $self->saveErrorString(undef, "Parameter 'BlockSize100K' not between 1 and 9, got $value")
74             unless defined $value && $value >= 1 && $value <= 9;
75
76     }
77
78     # check that WorkFactor between 0 & 250
79     if ($got->parsed('workfactor')) {
80         my $value = $got->getValue('workfactor');
81         return $self->saveErrorString(undef, "Parameter 'WorkFactor' not between 0 and 250, got $value")
82             unless $value >= 0 && $value <= 250;
83     }
84
85     return 1 ;
86 }
87
88
89 sub mkComp
90 {
91     my $self = shift ;
92     my $got = shift ;
93
94     my $BlockSize100K = $got->getValue('blocksize100k');
95     my $WorkFactor    = $got->getValue('workfactor');
96     my $Verbosity     = $got->getValue('verbosity');
97
98     my ($obj, $errstr, $errno) = IO::Compress::Adapter::Bzip2::mkCompObject(
99                                                $BlockSize100K, $WorkFactor,
100                                                $Verbosity);
101
102     return $self->saveErrorString(undef, $errstr, $errno)
103         if ! defined $obj;
104     
105     return $obj;
106 }
107
108
109 sub mkTrailer
110 {
111     my $self = shift ;
112     return '';
113 }
114
115 sub mkFinalTrailer
116 {
117     return '';
118 }
119
120 #sub newHeader
121 #{
122 #    my $self = shift ;
123 #    return '';
124 #}
125
126 sub getInverseClass
127 {
128     return ('IO::Uncompress::Bunzip2');
129 }
130
131 sub getFileInfo
132 {
133     my $self = shift ;
134     my $params = shift;
135     my $file = shift ;
136     
137 }
138
139 1;
140
141 __END__
142
143 =head1 NAME
144
145 IO::Compress::Bzip2 - Write bzip2 files/buffers
146
147 =head1 SYNOPSIS
148
149     use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error) ;
150
151     my $status = bzip2 $input => $output [,OPTS]
152         or die "bzip2 failed: $Bzip2Error\n";
153
154     my $z = new IO::Compress::Bzip2 $output [,OPTS]
155         or die "bzip2 failed: $Bzip2Error\n";
156
157     $z->print($string);
158     $z->printf($format, $string);
159     $z->write($string);
160     $z->syswrite($string [, $length, $offset]);
161     $z->flush();
162     $z->tell();
163     $z->eof();
164     $z->seek($position, $whence);
165     $z->binmode();
166     $z->fileno();
167     $z->opened();
168     $z->autoflush();
169     $z->input_line_number();
170     $z->newStream( [OPTS] );
171
172     $z->close() ;
173
174     $Bzip2Error ;
175
176     # IO::File mode
177
178     print $z $string;
179     printf $z $format, $string;
180     tell $z
181     eof $z
182     seek $z, $position, $whence
183     binmode $z
184     fileno $z
185     close $z ;
186
187 =head1 DESCRIPTION
188
189 This module provides a Perl interface that allows writing bzip2
190 compressed data to files or buffer.
191
192 For reading bzip2 files/buffers, see the companion module
193 L<IO::Uncompress::Bunzip2|IO::Uncompress::Bunzip2>.
194
195 =head1 Functional Interface
196
197 A top-level function, C<bzip2>, is provided to carry out
198 "one-shot" compression between buffers and/or files. For finer
199 control over the compression process, see the L</"OO Interface">
200 section.
201
202     use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error) ;
203
204     bzip2 $input_filename_or_reference => $output_filename_or_reference [,OPTS]
205         or die "bzip2 failed: $Bzip2Error\n";
206
207 The functional interface needs Perl5.005 or better.
208
209 =head2 bzip2 $input_filename_or_reference => $output_filename_or_reference [, OPTS]
210
211 C<bzip2> expects at least two parameters,
212 C<$input_filename_or_reference> and C<$output_filename_or_reference>
213 and zero or more optional parameters (see L</Optional Parameters>)
214
215 =head3 The C<$input_filename_or_reference> parameter
216
217 The parameter, C<$input_filename_or_reference>, is used to define the
218 source of the uncompressed data.
219
220 It can take one of the following forms:
221
222 =over 5
223
224 =item A filename
225
226 If the C<$input_filename_or_reference> parameter is a simple scalar, it is
227 assumed to be a filename. This file will be opened for reading and the
228 input data will be read from it.
229
230 =item A filehandle
231
232 If the C<$input_filename_or_reference> parameter is a filehandle, the input
233 data will be read from it.  The string '-' can be used as an alias for
234 standard input.
235
236 =item A scalar reference
237
238 If C<$input_filename_or_reference> is a scalar reference, the input data
239 will be read from C<$$input_filename_or_reference>.
240
241 =item An array reference
242
243 If C<$input_filename_or_reference> is an array reference, each element in
244 the array must be a filename.
245
246 The input data will be read from each file in turn.
247
248 The complete array will be walked to ensure that it only
249 contains valid filenames before any data is compressed.
250
251 =item An Input FileGlob string
252
253 If C<$input_filename_or_reference> is a string that is delimited by the
254 characters "<" and ">" C<bzip2> will assume that it is an
255 I<input fileglob string>. The input is the list of files that match the
256 fileglob.
257
258 See L<File::GlobMapper|File::GlobMapper> for more details.
259
260 =back
261
262 If the C<$input_filename_or_reference> parameter is any other type,
263 C<undef> will be returned.
264
265 =head3 The C<$output_filename_or_reference> parameter
266
267 The parameter C<$output_filename_or_reference> is used to control the
268 destination of the compressed data. This parameter can take one of
269 these forms.
270
271 =over 5
272
273 =item A filename
274
275 If the C<$output_filename_or_reference> parameter is a simple scalar, it is
276 assumed to be a filename.  This file will be opened for writing and the
277 compressed data will be written to it.
278
279 =item A filehandle
280
281 If the C<$output_filename_or_reference> parameter is a filehandle, the
282 compressed data will be written to it.  The string '-' can be used as
283 an alias for standard output.
284
285 =item A scalar reference
286
287 If C<$output_filename_or_reference> is a scalar reference, the
288 compressed data will be stored in C<$$output_filename_or_reference>.
289
290 =item An Array Reference
291
292 If C<$output_filename_or_reference> is an array reference,
293 the compressed data will be pushed onto the array.
294
295 =item An Output FileGlob
296
297 If C<$output_filename_or_reference> is a string that is delimited by the
298 characters "<" and ">" C<bzip2> will assume that it is an
299 I<output fileglob string>. The output is the list of files that match the
300 fileglob.
301
302 When C<$output_filename_or_reference> is an fileglob string,
303 C<$input_filename_or_reference> must also be a fileglob string. Anything
304 else is an error.
305
306 See L<File::GlobMapper|File::GlobMapper> for more details.
307
308 =back
309
310 If the C<$output_filename_or_reference> parameter is any other type,
311 C<undef> will be returned.
312
313 =head2 Notes
314
315 When C<$input_filename_or_reference> maps to multiple files/buffers and
316 C<$output_filename_or_reference> is a single
317 file/buffer the input files/buffers will be stored
318 in C<$output_filename_or_reference> as a concatenated series of compressed data streams.
319
320 =head2 Optional Parameters
321
322 The optional parameters for the one-shot function C<bzip2>
323 are (for the most part) identical to those used with the OO interface defined in the
324 L</"Constructor Options"> section. The exceptions are listed below
325
326 =over 5
327
328 =item C<< AutoClose => 0|1 >>
329
330 This option applies to any input or output data streams to
331 C<bzip2> that are filehandles.
332
333 If C<AutoClose> is specified, and the value is true, it will result in all
334 input and/or output filehandles being closed once C<bzip2> has
335 completed.
336
337 This parameter defaults to 0.
338
339 =item C<< BinModeIn => 0|1 >>
340
341 This option is now a no-op. All files will be read in binmode.
342
343 =item C<< Append => 0|1 >>
344
345 The behaviour of this option is dependent on the type of output data
346 stream.
347
348 =over 5
349
350 =item * A Buffer
351
352 If C<Append> is enabled, all compressed data will be append to the end of
353 the output buffer. Otherwise the output buffer will be cleared before any
354 compressed data is written to it.
355
356 =item * A Filename
357
358 If C<Append> is enabled, the file will be opened in append mode. Otherwise
359 the contents of the file, if any, will be truncated before any compressed
360 data is written to it.
361
362 =item * A Filehandle
363
364 If C<Append> is enabled, the filehandle will be positioned to the end of
365 the file via a call to C<seek> before any compressed data is
366 written to it.  Otherwise the file pointer will not be moved.
367
368 =back
369
370 When C<Append> is specified, and set to true, it will I<append> all compressed
371 data to the output data stream.
372
373 So when the output is a filehandle it will carry out a seek to the eof
374 before writing any compressed data. If the output is a filename, it will be opened for
375 appending. If the output is a buffer, all compressed data will be
376 appended to the existing buffer.
377
378 Conversely when C<Append> is not specified, or it is present and is set to
379 false, it will operate as follows.
380
381 When the output is a filename, it will truncate the contents of the file
382 before writing any compressed data. If the output is a filehandle
383 its position will not be changed. If the output is a buffer, it will be
384 wiped before any compressed data is output.
385
386 Defaults to 0.
387
388 =back
389
390 =head2 Examples
391
392 Here are a few example that show the capabilities of the module.
393
394 =head3 Streaming
395
396 This very simple command line example demonstrates the streaming capabilities of the module.
397 The code reads data from STDIN, compresses it, and writes the compressed data to STDOUT.
398
399     $ echo hello world | perl -MIO::Compress::Bzip2=bzip2 -e 'bzip2 \*STDIN => \*STDOUT' >output.bz2
400
401 The special filename "-" can be used as a standin for both C<\*STDIN> and C<\*STDOUT>,
402 so the above can be rewritten as
403
404     $ echo hello world | perl -MIO::Compress::Bzip2=bzip2 -e 'bzip2 "-" => "-"' >output.bz2
405
406 =head3 Compressing a file from the filesystem
407
408 To read the contents of the file C<file1.txt> and write the compressed
409 data to the file C<file1.txt.bz2>.
410
411     use strict ;
412     use warnings ;
413     use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error) ;
414
415     my $input = "file1.txt";
416     bzip2 $input => "$input.bz2"
417         or die "bzip2 failed: $Bzip2Error\n";
418
419 =head3 Reading from a Filehandle and writing to an in-memory buffer
420
421 To read from an existing Perl filehandle, C<$input>, and write the
422 compressed data to a buffer, C<$buffer>.
423
424     use strict ;
425     use warnings ;
426     use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error) ;
427     use IO::File ;
428
429     my $input = new IO::File "<file1.txt"
430         or die "Cannot open 'file1.txt': $!\n" ;
431     my $buffer ;
432     bzip2 $input => \$buffer
433         or die "bzip2 failed: $Bzip2Error\n";
434
435 =head3 Compressing multiple files
436
437 To compress all files in the directory "/my/home" that match "*.txt"
438 and store the compressed data in the same directory
439
440     use strict ;
441     use warnings ;
442     use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error) ;
443
444     bzip2 '</my/home/*.txt>' => '<*.bz2>'
445         or die "bzip2 failed: $Bzip2Error\n";
446
447 and if you want to compress each file one at a time, this will do the trick
448
449     use strict ;
450     use warnings ;
451     use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error) ;
452
453     for my $input ( glob "/my/home/*.txt" )
454     {
455         my $output = "$input.bz2" ;
456         bzip2 $input => $output
457             or die "Error compressing '$input': $Bzip2Error\n";
458     }
459
460 =head1 OO Interface
461
462 =head2 Constructor
463
464 The format of the constructor for C<IO::Compress::Bzip2> is shown below
465
466     my $z = new IO::Compress::Bzip2 $output [,OPTS]
467         or die "IO::Compress::Bzip2 failed: $Bzip2Error\n";
468
469 It returns an C<IO::Compress::Bzip2> object on success and undef on failure.
470 The variable C<$Bzip2Error> will contain an error message on failure.
471
472 If you are running Perl 5.005 or better the object, C<$z>, returned from
473 IO::Compress::Bzip2 can be used exactly like an L<IO::File|IO::File> filehandle.
474 This means that all normal output file operations can be carried out
475 with C<$z>.
476 For example, to write to a compressed file/buffer you can use either of
477 these forms
478
479     $z->print("hello world\n");
480     print $z "hello world\n";
481
482 The mandatory parameter C<$output> is used to control the destination
483 of the compressed data. This parameter can take one of these forms.
484
485 =over 5
486
487 =item A filename
488
489 If the C<$output> parameter is a simple scalar, it is assumed to be a
490 filename. This file will be opened for writing and the compressed data
491 will be written to it.
492
493 =item A filehandle
494
495 If the C<$output> parameter is a filehandle, the compressed data will be
496 written to it.
497 The string '-' can be used as an alias for standard output.
498
499 =item A scalar reference
500
501 If C<$output> is a scalar reference, the compressed data will be stored
502 in C<$$output>.
503
504 =back
505
506 If the C<$output> parameter is any other type, C<IO::Compress::Bzip2>::new will
507 return undef.
508
509 =head2 Constructor Options
510
511 C<OPTS> is any combination of zero or more the following options:
512
513 =over 5
514
515 =item C<< AutoClose => 0|1 >>
516
517 This option is only valid when the C<$output> parameter is a filehandle. If
518 specified, and the value is true, it will result in the C<$output> being
519 closed once either the C<close> method is called or the C<IO::Compress::Bzip2>
520 object is destroyed.
521
522 This parameter defaults to 0.
523
524 =item C<< Append => 0|1 >>
525
526 Opens C<$output> in append mode.
527
528 The behaviour of this option is dependent on the type of C<$output>.
529
530 =over 5
531
532 =item * A Buffer
533
534 If C<$output> is a buffer and C<Append> is enabled, all compressed data
535 will be append to the end of C<$output>. Otherwise C<$output> will be
536 cleared before any data is written to it.
537
538 =item * A Filename
539
540 If C<$output> is a filename and C<Append> is enabled, the file will be
541 opened in append mode. Otherwise the contents of the file, if any, will be
542 truncated before any compressed data is written to it.
543
544 =item * A Filehandle
545
546 If C<$output> is a filehandle, the file pointer will be positioned to the
547 end of the file via a call to C<seek> before any compressed data is written
548 to it.  Otherwise the file pointer will not be moved.
549
550 =back
551
552 This parameter defaults to 0.
553
554 =item C<< BlockSize100K => number >>
555
556 Specify the number of 100K blocks bzip2 uses during compression.
557
558 Valid values are from 1 to 9, where 9 is best compression.
559
560 The default is 1.
561
562 =item C<< WorkFactor => number >>
563
564 Specifies how much effort bzip2 should take before resorting to a slower
565 fallback compression algorithm.
566
567 Valid values range from 0 to 250, where 0 means use the default value 30.
568
569 The default is 0.
570
571 =item C<< Strict => 0|1 >>
572
573 This is a placeholder option.
574
575 =back
576
577 =head2 Examples
578
579 TODO
580
581 =head1 Methods
582
583 =head2 print
584
585 Usage is
586
587     $z->print($data)
588     print $z $data
589
590 Compresses and outputs the contents of the C<$data> parameter. This
591 has the same behaviour as the C<print> built-in.
592
593 Returns true if successful.
594
595 =head2 printf
596
597 Usage is
598
599     $z->printf($format, $data)
600     printf $z $format, $data
601
602 Compresses and outputs the contents of the C<$data> parameter.
603
604 Returns true if successful.
605
606 =head2 syswrite
607
608 Usage is
609
610     $z->syswrite $data
611     $z->syswrite $data, $length
612     $z->syswrite $data, $length, $offset
613
614 Compresses and outputs the contents of the C<$data> parameter.
615
616 Returns the number of uncompressed bytes written, or C<undef> if
617 unsuccessful.
618
619 =head2 write
620
621 Usage is
622
623     $z->write $data
624     $z->write $data, $length
625     $z->write $data, $length, $offset
626
627 Compresses and outputs the contents of the C<$data> parameter.
628
629 Returns the number of uncompressed bytes written, or C<undef> if
630 unsuccessful.
631
632 =head2 flush
633
634 Usage is
635
636     $z->flush;
637
638 Flushes any pending compressed data to the output file/buffer.
639
640 TODO
641
642 Returns true on success.
643
644 =head2 tell
645
646 Usage is
647
648     $z->tell()
649     tell $z
650
651 Returns the uncompressed file offset.
652
653 =head2 eof
654
655 Usage is
656
657     $z->eof();
658     eof($z);
659
660 Returns true if the C<close> method has been called.
661
662 =head2 seek
663
664     $z->seek($position, $whence);
665     seek($z, $position, $whence);
666
667 Provides a sub-set of the C<seek> functionality, with the restriction
668 that it is only legal to seek forward in the output file/buffer.
669 It is a fatal error to attempt to seek backward.
670
671 Empty parts of the file/buffer will have NULL (0x00) bytes written to them.
672
673 The C<$whence> parameter takes one the usual values, namely SEEK_SET,
674 SEEK_CUR or SEEK_END.
675
676 Returns 1 on success, 0 on failure.
677
678 =head2 binmode
679
680 Usage is
681
682     $z->binmode
683     binmode $z ;
684
685 This is a noop provided for completeness.
686
687 =head2 opened
688
689     $z->opened()
690
691 Returns true if the object currently refers to a opened file/buffer.
692
693 =head2 autoflush
694
695     my $prev = $z->autoflush()
696     my $prev = $z->autoflush(EXPR)
697
698 If the C<$z> object is associated with a file or a filehandle, this method
699 returns the current autoflush setting for the underlying filehandle. If
700 C<EXPR> is present, and is non-zero, it will enable flushing after every
701 write/print operation.
702
703 If C<$z> is associated with a buffer, this method has no effect and always
704 returns C<undef>.
705
706 B<Note> that the special variable C<$|> B<cannot> be used to set or
707 retrieve the autoflush setting.
708
709 =head2 input_line_number
710
711     $z->input_line_number()
712     $z->input_line_number(EXPR)
713
714 This method always returns C<undef> when compressing.
715
716 =head2 fileno
717
718     $z->fileno()
719     fileno($z)
720
721 If the C<$z> object is associated with a file or a filehandle, C<fileno>
722 will return the underlying file descriptor. Once the C<close> method is
723 called C<fileno> will return C<undef>.
724
725 If the C<$z> object is associated with a buffer, this method will return
726 C<undef>.
727
728 =head2 close
729
730     $z->close() ;
731     close $z ;
732
733 Flushes any pending compressed data and then closes the output file/buffer.
734
735 For most versions of Perl this method will be automatically invoked if
736 the IO::Compress::Bzip2 object is destroyed (either explicitly or by the
737 variable with the reference to the object going out of scope). The
738 exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In
739 these cases, the C<close> method will be called automatically, but
740 not until global destruction of all live objects when the program is
741 terminating.
742
743 Therefore, if you want your scripts to be able to run on all versions
744 of Perl, you should call C<close> explicitly and not rely on automatic
745 closing.
746
747 Returns true on success, otherwise 0.
748
749 If the C<AutoClose> option has been enabled when the IO::Compress::Bzip2
750 object was created, and the object is associated with a file, the
751 underlying file will also be closed.
752
753 =head2 newStream([OPTS])
754
755 Usage is
756
757     $z->newStream( [OPTS] )
758
759 Closes the current compressed data stream and starts a new one.
760
761 OPTS consists of any of the options that are available when creating
762 the C<$z> object.
763
764 See the L</"Constructor Options"> section for more details.
765
766 =head1 Importing
767
768 No symbolic constants are required by IO::Compress::Bzip2 at present.
769
770 =over 5
771
772 =item :all
773
774 Imports C<bzip2> and C<$Bzip2Error>.
775 Same as doing this
776
777     use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error) ;
778
779 =back
780
781 =head1 EXAMPLES
782
783 =head2 Apache::GZip Revisited
784
785 See L<IO::Compress::FAQ|IO::Compress::FAQ/"Apache::GZip Revisited">
786
787 =head2 Working with Net::FTP
788
789 See L<IO::Compress::FAQ|IO::Compress::FAQ/"Compressed files and Net::FTP">
790
791 =head1 SUPPORT
792
793 General feedback/questions/bug reports should be sent to
794 L<https://github.com/pmqs/IO-Compress/issues> (preferred) or
795 L<https://rt.cpan.org/Public/Dist/Display.html?Name=IO-Compress>.
796
797 =head1 SEE ALSO
798
799 L<Compress::Zlib>, L<IO::Compress::Gzip>, L<IO::Uncompress::Gunzip>, L<IO::Compress::Deflate>, L<IO::Uncompress::Inflate>, L<IO::Compress::RawDeflate>, L<IO::Uncompress::RawInflate>, L<IO::Uncompress::Bunzip2>, L<IO::Compress::Lzma>, L<IO::Uncompress::UnLzma>, L<IO::Compress::Xz>, L<IO::Uncompress::UnXz>, L<IO::Compress::Lzip>, L<IO::Uncompress::UnLzip>, L<IO::Compress::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Compress::Zstd>, L<IO::Uncompress::UnZstd>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress>
800
801 L<IO::Compress::FAQ|IO::Compress::FAQ>
802
803 L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>,
804 L<Archive::Tar|Archive::Tar>,
805 L<IO::Zlib|IO::Zlib>
806
807 The primary site for the bzip2 program is L<https://sourceware.org/bzip2/>.
808
809 See the module L<Compress::Bzip2|Compress::Bzip2>
810
811 =head1 AUTHOR
812
813 This module was written by Paul Marquess, C<pmqs@cpan.org>.
814
815 =head1 MODIFICATION HISTORY
816
817 See the Changes file.
818
819 =head1 COPYRIGHT AND LICENSE
820
821 Copyright (c) 2005-2020 Paul Marquess. All rights reserved.
822
823 This program is free software; you can redistribute it and/or
824 modify it under the same terms as Perl itself.
825