| 1 | package PerlIO::Via; |
| 2 | our $VERSION = '0.01'; |
| 3 | use XSLoader (); |
| 4 | XSLoader::load 'PerlIO::Via'; |
| 5 | 1; |
| 6 | __END__ |
| 7 | |
| 8 | =head1 NAME |
| 9 | |
| 10 | PerlIO::Via - Helper class for PerlIO layers implemented in perl |
| 11 | |
| 12 | =head1 SYNOPSIS |
| 13 | |
| 14 | use PerlIO::Via::Layer; |
| 15 | open($fh,"<:Via(Layer)",...); |
| 16 | |
| 17 | use Some::Other::Package; |
| 18 | open($fh,">:Via(Some::Other::Package)",...); |
| 19 | |
| 20 | =head1 DESCRIPTION |
| 21 | |
| 22 | The PerlIO::Via module allows you to develop PerlIO layers in Perl, without |
| 23 | having to go into the nitty gritty of programming C with XS as the interface |
| 24 | to Perl. |
| 25 | |
| 26 | One example module, L<PerlIO::Via::QuotedPrint>, is include with Perl |
| 27 | 5.8.0, and more example modules are available from CPAN, such as |
| 28 | L<PerlIO::Via::StripHTML> and L<PerlIO::Via::Base64>. The |
| 29 | PerlIO::Via::StripHTML for instance, allows you to say: |
| 30 | |
| 31 | use PerlIO::Via::StripHTML; |
| 32 | open( my $fh, "<:Via(StripHTML)", "index.html" ); |
| 33 | my @line = <$fh>; |
| 34 | |
| 35 | to obtain the text of an HTML-file in an array with all the HTML-tags |
| 36 | automagically removed. |
| 37 | |
| 38 | Please note that if the layer is created in the PerlIO::Via:: namespace, it |
| 39 | does B<not> have to be fully qualified. The PerlIO::Via module will prefix |
| 40 | the PerlIO::Via:: namespace if the specified modulename does not exist as a |
| 41 | fully qualified module name. |
| 42 | |
| 43 | =head1 EXPECTED METHODS |
| 44 | |
| 45 | To create a Perl module that implements a PerlIO layer in Perl (as opposed to |
| 46 | in C using XS as the interface to Perl), you need to supply some of the |
| 47 | following subroutines. It is recommended to create these Perl modules in the |
| 48 | PerlIO::Via:: namespace, so that they can easily be located on CPAN and use |
| 49 | the default namespace feature of the PerlIO::Via module itself. |
| 50 | |
| 51 | Please note that this is an area of recent development in Perl and that the |
| 52 | interface described here is therefor still subject to change (and hopefully |
| 53 | better documentation and more examples). |
| 54 | |
| 55 | In the method descriptions below I<$fh> will be |
| 56 | a reference to a glob which can be treated as a perl file handle. |
| 57 | It refers to the layer below. I<$fh> is not passed if the layer |
| 58 | is at the bottom of the stack, for this reason and to maintain |
| 59 | some level of "compatibility" with TIEHANDLE classes it is passed last. |
| 60 | |
| 61 | =over 4 |
| 62 | |
| 63 | =item $class->PUSHED([$mode[,$fh]]) |
| 64 | |
| 65 | Should return an object or the class, or -1 on failure. (Compare |
| 66 | TIEHANDLE.) The arguments are an optional mode string ("r", "w", |
| 67 | "w+", ...) and a filehandle for the PerlIO layer below. Mandatory. |
| 68 | |
| 69 | When layer is pushed as part of an C<open> call, C<PUSHED> will be called |
| 70 | I<before> the actual open occurs whether than be via C<OPEN>, C<SYSOPEN>, |
| 71 | C<FDOPEN> or by letting lower layer do the open. |
| 72 | |
| 73 | =item $obj->POPPED([$fh]) |
| 74 | |
| 75 | Optional - layer is about to be removed. |
| 76 | |
| 77 | =item $obj->OPEN($path,$mode[,$fh]) |
| 78 | |
| 79 | Optional - if not present lower layer does open. |
| 80 | If present called for normal opens after layer is pushed. |
| 81 | This function is subject to change as there is no easy way |
| 82 | to get lower layer to do open and then regain control. |
| 83 | |
| 84 | =item $obj->BINMODE([,$fh]) |
| 85 | |
| 86 | Optional - if not available layer is popped on binmode($fh) or when C<:raw> |
| 87 | is pushed. If present it should return 0 on success -1 on error and undef |
| 88 | to pop the layer. |
| 89 | |
| 90 | =item $obj->FDOPEN($fd[,$fh]) |
| 91 | |
| 92 | Optional - if not present lower layer does open. |
| 93 | If present called for opens which pass a numeric file |
| 94 | descriptor after layer is pushed. |
| 95 | This function is subject to change as there is no easy way |
| 96 | to get lower layer to do open and then regain control. |
| 97 | |
| 98 | =item $obj->SYSOPEN($path,$imode,$perm,[,$fh]) |
| 99 | |
| 100 | Optional - if not present lower layer does open. |
| 101 | If present called for sysopen style opens which pass a numeric mode |
| 102 | and permissions after layer is pushed. |
| 103 | This function is subject to change as there is no easy way |
| 104 | to get lower layer to do open and then regain control. |
| 105 | |
| 106 | =item $obj->FILENO($fh) |
| 107 | |
| 108 | Returns a numeric value for Unix-like file descriptor. Return -1 if |
| 109 | there isn't one. Optional. Default is fileno($fh). |
| 110 | |
| 111 | =item $obj->READ($buffer,$len,$fh) |
| 112 | |
| 113 | Returns the number of octets placed in $buffer (must be less than or |
| 114 | equal to $len). Optional. Default is to use FILL instead. |
| 115 | |
| 116 | =item $obj->WRITE($buffer,$fh) |
| 117 | |
| 118 | Returns the number of octets from buffer that have been sucessfully written. |
| 119 | |
| 120 | =item $obj->FILL($fh) |
| 121 | |
| 122 | Should return a string to be placed in the buffer. Optional. If not |
| 123 | provided must provide READ or reject handles open for reading in |
| 124 | PUSHED. |
| 125 | |
| 126 | =item $obj->CLOSE($fh) |
| 127 | |
| 128 | Should return 0 on success, -1 on error. |
| 129 | Optional. |
| 130 | |
| 131 | =item $obj->SEEK($posn,$whence,$fh) |
| 132 | |
| 133 | Should return 0 on success, -1 on error. |
| 134 | Optional. Default is to fail, but that is likely to be changed |
| 135 | in future. |
| 136 | |
| 137 | =item $obj->TELL($fh) |
| 138 | |
| 139 | Returns file postion. |
| 140 | Optional. Default to be determined. |
| 141 | |
| 142 | =item $obj->UNREAD($buffer,$fh) |
| 143 | |
| 144 | Returns the number of octets from buffer that have been sucessfully |
| 145 | saved to be returned on future FILL/READ calls. Optional. Default is |
| 146 | to push data into a temporary layer above this one. |
| 147 | |
| 148 | =item $obj->FLUSH($fh) |
| 149 | |
| 150 | Flush any buffered write data. May possibly be called on readable |
| 151 | handles too. Should return 0 on success, -1 on error. |
| 152 | |
| 153 | =item $obj->SETLINEBUF($fh) |
| 154 | |
| 155 | Optional. No return. |
| 156 | |
| 157 | =item $obj->CLEARERR($fh) |
| 158 | |
| 159 | Optional. No return. |
| 160 | |
| 161 | =item $obj->ERROR($fh) |
| 162 | |
| 163 | Optional. Returns error state. Default is no error until a mechanism |
| 164 | to signal error (die?) is worked out. |
| 165 | |
| 166 | =item $obj->EOF($fh) |
| 167 | |
| 168 | Optional. Returns end-of-file state. Default is function of return |
| 169 | value of FILL or READ. |
| 170 | |
| 171 | =back |
| 172 | |
| 173 | =head1 EXAMPLES |
| 174 | |
| 175 | Check the PerlIO::Via:: namespace on CPAN for examples of PerlIO layers |
| 176 | implemented in Perl. To give you an idea how simple the implementation of |
| 177 | a PerlIO layer can look, as simple example is included here. |
| 178 | |
| 179 | =head2 Example - a Hexadecimal Handle |
| 180 | |
| 181 | Given the following module, PerlIO::Via::Hex.pm: |
| 182 | |
| 183 | package PerlIO::Via::Hex; |
| 184 | |
| 185 | sub PUSHED |
| 186 | { |
| 187 | my ($class,$mode,$fh) = @_; |
| 188 | # When writing we buffer the data |
| 189 | my $buf = ''; |
| 190 | return bless \$buf,$class; |
| 191 | } |
| 192 | |
| 193 | sub FILL |
| 194 | { |
| 195 | my ($obj,$fh) = @_; |
| 196 | my $line = <$fh>; |
| 197 | return (defined $line) ? pack("H*", $line) : undef; |
| 198 | } |
| 199 | |
| 200 | sub WRITE |
| 201 | { |
| 202 | my ($obj,$buf,$fh) = @_; |
| 203 | $$obj .= unpack("H*", $buf); |
| 204 | return length($buf); |
| 205 | } |
| 206 | |
| 207 | sub FLUSH |
| 208 | { |
| 209 | my ($obj,$fh) = @_; |
| 210 | print $fh $$obj or return -1; |
| 211 | $$obj = ''; |
| 212 | return 0; |
| 213 | } |
| 214 | |
| 215 | 1; |
| 216 | |
| 217 | the following code opens up an output handle that will convert any |
| 218 | output to hexadecimal dump of the output bytes: for example "A" will |
| 219 | be converted to "41" (on ASCII-based machines, on EBCDIC platforms |
| 220 | the "A" will become "c1") |
| 221 | |
| 222 | use PerlIO::Via::Hex; |
| 223 | open(my $fh, ">:Via(Hex)", "foo.hex"); |
| 224 | |
| 225 | and the following code will read the hexdump in and convert it |
| 226 | on the fly back into bytes: |
| 227 | |
| 228 | open(my $fh, "<:Via(Hex)", "foo.hex"); |
| 229 | |
| 230 | =cut |