shell bypass 403
use strict;
use warnings;
package Mixin::Linewise::Writers;
# ABSTRACT: get linewise writers for strings and filenames
$Mixin::Linewise::Writers::VERSION = '0.108';
use 5.008001; # PerlIO
use Carp ();
use IO::File;
use Sub::Exporter -setup => {
exports => { map {; "write_$_" => \"_mk_write_$_" } qw(file string) },
groups => {
default => [ qw(write_file write_string) ],
writers => [ qw(write_file write_string) ],
},
};
#pod =head1 SYNOPSIS
#pod
#pod package Your::Pkg;
#pod use Mixin::Linewise::Writers -writers;
#pod
#pod sub write_handle {
#pod my ($self, $data, $handle) = @_;
#pod
#pod $handle->print("datum: $_\n") for @$data;
#pod }
#pod
#pod Then:
#pod
#pod use Your::Pkg;
#pod
#pod Your::Pkg->write_file($data, $filename);
#pod
#pod Your::Pkg->write_string($data, $string);
#pod
#pod Your::Pkg->write_handle($data, $fh);
#pod
#pod =head1 EXPORTS
#pod
#pod C<write_file> and C<write_string> are exported by default. Either can be
#pod requested individually, or renamed. They are generated by
#pod L<Sub::Exporter|Sub::Exporter>, so consult its documentation for more
#pod information.
#pod
#pod Both can be generated with the option "method" which requests that a method
#pod other than "write_handle" is called with the created IO::Handle.
#pod
#pod If given a "binmode" option, any C<write_file> type functions will use
#pod that as an IO layer, otherwise, the default is C<encoding(UTF-8)>.
#pod
#pod use Mixin::Linewise::Writers -writers => { binmode => "raw" };
#pod use Mixin::Linewise::Writers -writers => { binmode => "encoding(iso-8859-1)" };
#pod
#pod =head2 write_file
#pod
#pod Your::Pkg->write_file($data, $filename);
#pod Your::Pkg->write_file($data, $options, $filename);
#pod
#pod This method will try to open a new file with the given name. It will then call
#pod C<write_handle> with that handle.
#pod
#pod An optional hash reference may be passed before C<$filename> with options.
#pod The only valid option currently is C<binmode>, which overrides any
#pod default set from C<use> or the built-in C<encoding(UTF-8)>.
#pod
#pod Any arguments after C<$filename> are passed along after to C<write_handle>.
#pod
#pod =cut
sub _mk_write_file {
my ($self, $name, $arg) = @_;
my $method = defined $arg->{method} ? $arg->{method} : 'write_handle';
my $dflt_enc = defined $arg->{binmode} ? $arg->{binmode} : 'encoding(UTF-8)';
sub {
my ($invocant, $data, $options, $filename);
if ( ref $_[2] eq 'HASH' ) {
# got options before filename
($invocant, $data, $options, $filename) = splice @_, 0, 4;
}
else {
($invocant, $data, $filename) = splice @_, 0, 3;
}
my $binmode = defined $options->{binmode} ? $options->{binmode} : $dflt_enc;
$binmode =~ s/^://; # we add it later
# Check the file
Carp::croak "no filename specified" unless $filename;
Carp::croak "'$filename' is not a plain file" if -e $filename && ! -f _;
# Write out the file
my $handle = IO::File->new($filename, ">:$binmode")
or Carp::croak "couldn't write to file '$filename': $!";
$invocant->write_handle($data, $handle, @_);
}
}
#pod =head2 write_string
#pod
#pod my $string = Your::Pkg->write_string($data);
#pod my $string = Your::Pkg->write_string(\%option, $data);
#pod
#pod C<write_string> will create a new handle on the given string, then call
#pod C<write_handle> to write to that handle, and return the resulting string.
#pod Because handles on strings must be octet-oriented, the string B<will contain
#pod octets>. It will be opened in the default binmode established by importing.
#pod (See L</EXPORTS>, above, and the options, below.)
#pod
#pod Any arguments after C<$data> are passed along after to C<write_handle>.
#pod
#pod Like C<write_file>, this method can take a leading hashref with one valid
#pod argument: C<binmode>.
#pod
#pod =cut
sub _mk_write_string {
my ($self, $name, $arg) = @_;
my $method = defined $arg->{method} ? $arg->{method} : 'write_handle';
my $dflt_enc = defined $arg->{binmode} ? $arg->{binmode} : 'encoding(UTF-8)';
sub {
my ($opt) = @_ > 2 && ref $_[1] ? splice(@_, 1, 1) : undef;
my ($invocant, $data) = splice @_, 0, 2;
my $binmode = ($opt && $opt->{binmode}) ? $opt->{binmode} : $dflt_enc;
$binmode =~ s/^://; # we add it later
my $string = '';
open my $handle, ">:$binmode", \$string
or die "error opening string for output: $!";
$invocant->write_handle($data, $handle, @_);
close $handle or die "error closing string after output: $!";
return $string;
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Mixin::Linewise::Writers - get linewise writers for strings and filenames
=head1 VERSION
version 0.108
=head1 SYNOPSIS
package Your::Pkg;
use Mixin::Linewise::Writers -writers;
sub write_handle {
my ($self, $data, $handle) = @_;
$handle->print("datum: $_\n") for @$data;
}
Then:
use Your::Pkg;
Your::Pkg->write_file($data, $filename);
Your::Pkg->write_string($data, $string);
Your::Pkg->write_handle($data, $fh);
=head1 EXPORTS
C<write_file> and C<write_string> are exported by default. Either can be
requested individually, or renamed. They are generated by
L<Sub::Exporter|Sub::Exporter>, so consult its documentation for more
information.
Both can be generated with the option "method" which requests that a method
other than "write_handle" is called with the created IO::Handle.
If given a "binmode" option, any C<write_file> type functions will use
that as an IO layer, otherwise, the default is C<encoding(UTF-8)>.
use Mixin::Linewise::Writers -writers => { binmode => "raw" };
use Mixin::Linewise::Writers -writers => { binmode => "encoding(iso-8859-1)" };
=head2 write_file
Your::Pkg->write_file($data, $filename);
Your::Pkg->write_file($data, $options, $filename);
This method will try to open a new file with the given name. It will then call
C<write_handle> with that handle.
An optional hash reference may be passed before C<$filename> with options.
The only valid option currently is C<binmode>, which overrides any
default set from C<use> or the built-in C<encoding(UTF-8)>.
Any arguments after C<$filename> are passed along after to C<write_handle>.
=head2 write_string
my $string = Your::Pkg->write_string($data);
my $string = Your::Pkg->write_string(\%option, $data);
C<write_string> will create a new handle on the given string, then call
C<write_handle> to write to that handle, and return the resulting string.
Because handles on strings must be octet-oriented, the string B<will contain
octets>. It will be opened in the default binmode established by importing.
(See L</EXPORTS>, above, and the options, below.)
Any arguments after C<$data> are passed along after to C<write_handle>.
Like C<write_file>, this method can take a leading hashref with one valid
argument: C<binmode>.
=head1 AUTHOR
Ricardo SIGNES <rjbs@cpan.org>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2008 by Ricardo SIGNES.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut