File Coverage

blib/lib/Safe/World/stdout.pm
Criterion Covered Total %
statement 12 192 6.2
branch 0 122 0.0
condition 0 60 0.0
subroutine 4 29 13.7
pod 0 14 0.0
total 16 417 3.8


line stmt bran cond sub pod time code
1             #############################################################################
2             ## Name: stdout.pm
3             ## Purpose: Safe::World::stdout
4             ## Author: Graciliano M. P.
5             ## Modified by:
6             ## Created: 08/09/2003
7             ## RCS-ID:
8             ## Copyright: (c) 2003 Graciliano M. P.
9             ## Licence: This program is free software; you can redistribute it and/or
10             ## modify it under the same terms as Perl itself
11             #############################################################################
12              
13             package Safe::World::stdout ;
14              
15 1     1   5 use strict qw(vars);
  1         2  
  1         33  
16              
17 1     1   5 use vars qw($VERSION @ISA) ;
  1         3  
  1         52  
18             $VERSION = '0.02' ;
19              
20 1     1   5 no warnings ;
  1         1  
  1         69  
21              
22             ##########
23             # SCOPES #
24             ##########
25              
26 1     1   5 use vars qw($Safe_World_NOW) ;
  1         2  
  1         2893  
27            
28             *Safe_World_NOW = \$Safe::World::NOW ;
29              
30             ######################
31             # CHECK_HEADSPLITTER #
32             ######################
33              
34             sub check_headsplitter {
35 0     0 0   my $this = shift ;
36              
37 0           $this->{AUTOHEAD_DATA} .= shift ;
38              
39 0           my $headsplitter = $this->{HEADSPLITTER} ;
40              
41 0           my ($headers , $end) ;
42            
43 0 0         if ( ref($headsplitter) eq 'CODE' ) {
    0          
44 0           ($headers , $end) = &$headsplitter( $Safe_World_NOW , $this->{AUTOHEAD_DATA} ) ;
45             }
46             elsif ( $this->{AUTOHEAD_DATA} =~ /^(.*?$headsplitter)(.*)/s ) {
47 0           $headers = $1 ;
48 0           $end = $2 ;
49             }
50            
51 0 0 0       delete $this->{AUTOHEAD_DATA} if $headers ne '' || $end ne '' ;
52            
53 0           return ($headers , $end) ;
54             }
55              
56             #####################
57             # HEADSPLITTER_HTML #
58             #####################
59              
60             sub headsplitter_html {
61 0     0 0   shift ;
62 0           my $headsplitter ;
63            
64 0 0         if ( $_[0] =~ /Content-Type:\s*\S+(.*?)(\015?\012\015?\012|\r?\n\r?\n)/si ) {
65 0 0         if ($1 !~ /<[^>]+>/s) { $headsplitter = $2 ;}
  0            
66             }
67            
68             ## Try to fix wrong headers:
69              
70 0 0 0       if ( !$headsplitter && $_[0] =~ /^(.*?)(?:\015?\012|\r?\n)([ \t]*<[^>]+>[ \t]*)(?:\015?\012|\r?\n)/s ) {
71 0 0         if ($1 !~ /<[^>]+>/s) { $headsplitter = $2 ;}
  0            
72             }
73            
74 0 0 0       if ( !$headsplitter && $_[0] =~ /^(.*?)(\s*<[^>]+>)/si ) {
75 0 0         if ($1 !~ /<[^>]+>/s) { $headsplitter = $2 ;}
  0            
76             }
77            
78 0 0 0       if ( !$headsplitter && $_[0] =~ /^(.*?)(<[^>]+>\s*<[^>]+>)/s ) {
79 0           my ($s1 , $s2) = ($1,$2) ;
80 0 0 0       if ($s1 !~ /<[^>]+>/s && $s1 !~ /(?:^|[\r\n\015\012])[^\s:]+:[^\r\n\015\012]+$/s) {
81 0           my ($line) = ( $s1 =~ /([^\r\n\015\012]+)$/s );
82 0           $headsplitter = $line . $s2 ;
83             }
84             }
85            
86 0 0 0       if ( !$headsplitter && $_[0] =~ /^(.*?)(\015?\012\015?\012|\r?\n\r?\n)/s ) {
87 0 0         if ($1 !~ /<[^>]+>/s) { $headsplitter = $2 ;}
  0            
88             }
89            
90 0           my $is_all_content ;
91 0 0 0       if ( !$headsplitter && $_[0] =~ /^(?:<[^>]+>|>)+(?:\015?\012|\r?\n)/s ) { $headsplitter = $is_all_content = 1 ;}
  0            
92            
93 0 0 0       if ( !$headsplitter && $_[0] =~ /(?:\015?\012|\r?\n)([ \t]*(?:<[^>]+>|>)+\s)/s ) { $headsplitter = $1 ;}
  0            
94            
95 0           my ($headers , $end) ;
96            
97 0 0 0       if ( $is_all_content ) {
    0          
98 0           $end = $_[0] ;
99             }
100             elsif ( $headsplitter ne '' && $_[0] =~ /^(.*?)\Q$headsplitter\E(.*)/s ) {
101 0           $headers = $1 ;
102 0           $end = $2 ;
103            
104 0 0         if ($headsplitter !~ /^\s+$/s) { $end = "$headsplitter$end" ;}
  0            
105 0           else { $headers .= $headsplitter ;}
106             }
107              
108 0           return ($headers , $end) ;
109             }
110              
111             ###########
112             # HEADERS #
113             ###########
114              
115             sub headers {
116 0 0   0 0   return '' if ref($_[0]->{HEADOUT}) ne 'SCALAR' ;
117 0 0         if ($#_ >= 1) { ${$_[0]->{HEADOUT}} = $_[1] ;}
  0            
  0            
118 0           my $headers = ${ $_[0]->{HEADOUT} } ;
  0            
119 0           return $headers ;
120             }
121              
122             ###############
123             # STDOUT_DATA #
124             ###############
125              
126             sub stdout_data {
127 0 0   0 0   if ( ref($_[0]->{STDOUT}) eq 'SCALAR' ) {
128 0 0         if ($#_ >= 1) { ${$_[0]->{STDOUT}} = $_[1] ;}
  0            
  0            
129 0           my $stdout = ${ $_[0]->{STDOUT} } ;
  0            
130 0           return $stdout ;
131             }
132 0           else { return '' ;}
133             }
134              
135             ###############
136             # BUFFER_DATA #
137             ###############
138              
139             sub buffer_data {
140 0 0   0 0   if ($#_ >= 1) { $_[0]->{BUFFER} = $_[1] ;}
  0            
141 0           my $buf = $_[0]->{BUFFER} ;
142 0           return $buf ;
143             }
144              
145             #########
146             # BLOCK #
147             #########
148              
149             sub block {
150 0     0 0   my $this = shift ;
151 0           $this->{BLOCKED} = 1 ;
152             }
153              
154             ###########
155             # UNBLOCK #
156             ###########
157              
158             sub unblock {
159 0     0 0   my $this = shift ;
160 0           $this->{BLOCKED} = undef ;
161             }
162              
163             #########
164             # PRINT #
165             #########
166              
167 0     0 0   sub print { &PRINT ;}
168              
169             ################
170             # PRINT_STDOUT #
171             ################
172              
173             sub print_stdout {
174             #print main::STDOUT "std>> $| [[$_[1]]] [[$_[0]->{BUFFER}]]\n" ;
175 0 0   0 0   my $this = shift ; return 1 if $_[0] eq '' ;
  0            
176            
177 0 0         return if $this->{BLOCKED} ;
178            
179 0           my $stdout = $this->{STDOUT} ;
180            
181 0 0 0       if ( $this->{AUTOHEAD} && !$_[1] ) {
182 0           my ($headers , $end) = $this->check_headsplitter($_[0]) ;
183 0 0 0       if ($headers ne '' || $end ne '') {
184 0           $this->{AUTOHEAD} = undef ;
185 0 0         $this->print_headout($headers,1) if $headers ne '' ;
186 0 0         $this->print($end) if $end ne '' ;
187 0           return 1 ;
188             }
189             }
190             else {
191 0 0         if ( !$_[1] ) {
192 0 0 0       if ( !$this->{HEADER_CLOSED} && $this->{ONCLOSEHEADERS} ) {
193             #print main::STDOUT "**>> $this->{HEADER_CLOSED} && $this->{ONCLOSEHEADERS}\n" ;
194 0           $this->{HEADER_CLOSED} = 1 ;
195 0           $this->call_oncloseheaders ;
196             }
197 0           else { $this->{HEADER_CLOSED} = 1 ;}
198             }
199            
200 0 0         if ( ref($stdout) eq 'SCALAR' ) { $$stdout .= $_[0] ;}
  0 0          
201             elsif ( ref($stdout) eq 'CODE' ) {
202 0 0         my $sel = $Safe_World_NOW->{SELECT}{PREVSTDOUT} ? &Safe::World::SELECT( $Safe_World_NOW->{SELECT}{PREVSTDOUT} ) : undef ;
203 0           &$stdout($Safe_World_NOW , $_[0]) ;
204 0 0         &Safe::World::SELECT($sel) if $sel ;
205             }
206 0           else { print $stdout $_[0] ;}
207             }
208              
209 0           return 1 ;
210             }
211              
212             #################
213             # PRINT_HEADOUT #
214             #################
215              
216             sub print_headout {
217 0 0   0 0   my $this = shift ; return 1 if $_[0] eq '' ;
  0            
218            
219 0           my $headout = $this->{HEADOUT} ;
220              
221 0 0         return $this->print_stdout($_[0]) if !$headout ;
222            
223 0 0 0       if ( !$_[1] && $this->{AUTOHEAD} ) {
224 0           my ($headers , $end) = $this->check_headsplitter($_[0]) ;
225 0 0 0       if ($headers ne '' || $end ne '') {
226 0           $this->{AUTOHEAD} = undef ;
227 0 0         $this->print_headout($headers,1) if $headers ne '' ;
228 0 0         $this->print($end) if $end ne '' ;
229 0           return 1 ;
230             }
231 0           return ;
232             }
233              
234 0 0         if ( ref($headout) eq 'SCALAR' ) { $$headout .= $_[0] ;}
  0 0          
235             elsif ( ref($headout) eq 'CODE' ) {
236 0 0         my $sel = $Safe_World_NOW->{SELECT}{PREVSTDOUT} ? &Safe::World::SELECT( $Safe_World_NOW->{SELECT}{PREVSTDOUT} ) : undef ;
237 0           &$headout($Safe_World_NOW , $_[0]) ;
238 0 0         &Safe::World::SELECT($sel) if $sel ;
239             }
240 0           else { print $headout $_[0] ;}
241              
242 0           return 1 ;
243             }
244              
245             #################
246             # CLOSE_HEADERS #
247             #################
248              
249             sub close_headers {
250 0     0 0   my $this = shift ;
251            
252             ##print main::STDOUT ">> $this->{AUTOHEAD} && $this->{HEADER_CLOSED} [[$this->{AUTOHEAD_DATA}]] [[$this->{BUFFER}]]\n" ;
253              
254             ##return if !$this->{AUTOHEAD} ;
255 0 0 0       return if (!$this->{AUTOHEAD} && $this->{HEADER_CLOSED}) || $this->{BUFFER} ne '' ;
      0        
256            
257 0           $this->{AUTOHEAD} = undef ;
258              
259 0 0         if ( $this->{AUTOHEAD_DATA} ne '' ) {
260 0           my ($headers , $end) = $this->check_headsplitter() ;
261 0 0 0       if ($headers ne '' || $end ne '') {
262 0 0         $this->print_headout($headers,1) if $headers ne '' ;
263 0 0         $this->print($end) if $end ne '' ;
264             }
265             else {
266 0           $this->print( delete $this->{AUTOHEAD_DATA} ) ;
267             }
268             }
269            
270 0 0 0       if ( !$this->{HEADER_CLOSED} && $this->{ONCLOSEHEADERS} ) {
271 0           $this->{HEADER_CLOSED} = 1 ;
272 0           $this->call_oncloseheaders ;
273             }
274              
275 0           $this->{HEADER_CLOSED} = 1 ;
276            
277 0           return 1 ;
278             }
279              
280             #######################
281             # CALL_ONCLOSEHEADERS #
282             #######################
283              
284             sub call_oncloseheaders {
285 0     0 0   my $this = shift ;
286            
287 0 0         return if !$this->{ONCLOSEHEADERS} ;
288            
289 0 0         my $sel = $Safe_World_NOW->{SELECT}{PREVSTDOUT} ? &Safe::World::SELECT( $Safe_World_NOW->{SELECT}{PREVSTDOUT} ) : undef ;
290              
291 0           my $autoflush = $this->{AUTO_FLUSH} ;
292            
293 0           $this->{AUTO_FLUSH} = 1 ;
294              
295 0           my $oncloseheaders = $this->{ONCLOSEHEADERS} ;
296 0           &$oncloseheaders( $Safe_World_NOW , $this->headers ) ;
297            
298 0           $this->{AUTO_FLUSH} = $autoflush ;
299              
300 0 0         &Safe::World::SELECT($sel) if $sel ;
301              
302 0           return 1 ;
303             }
304              
305             #########
306             # FLUSH #
307             #########
308              
309             sub flush {
310 0     0 0   my $this = shift ;
311              
312 0 0         if ( $this->{BUFFER} ne '' ) {
313 0           $this->print_stdout( delete $this->{BUFFER} ) ;
314 0           return 1 ;
315             }
316            
317 0           return ;
318             }
319              
320             #######################
321             # GET_AUTOFLUSH_VALUE #
322             #######################
323              
324             sub get_autoflush_value {
325 0     0 0   my $this = shift ;
326 0           my $sel = select ;
327            
328 0           my $reset ;
329 0 0 0       if ( $sel ne $this->{IO} && $sel ne 'main::STDOUT' ) { &Safe::World::SELECT($this->{IO}) ; $reset = 1 ;}
  0            
  0            
330            
331 0           my $val = $| ;
332            
333 0 0         if ($reset) { &Safe::World::SELECT($sel) ;}
  0            
334            
335 0           return $val ;
336             }
337              
338             #############
339             # TIEHANDLE #
340             #############
341              
342             sub TIEHANDLE {
343 0     0     my $class = shift ;
344 0           my ($root , $stdout , $flush , $headout , $autohead , $headsplitter , $oncloseheaders) = @_ ;
345              
346 0           my $this = {
347             ROOT => $root ,
348             STDOUT => $stdout ,
349             HEADOUT => $headout ,
350             AUTOHEAD => $autohead ,
351             HEADSPLITTER => $headsplitter ,
352             ONCLOSEHEADERS => $oncloseheaders ,
353             AUTO_FLUSH => $flush ,
354             IO => "$root\::STDOUT" ,
355             } ;
356              
357 0           bless($this , $class) ;
358 0           return( $this ) ;
359             }
360              
361             sub PRINT {
362 0     0     my $this = shift ;
363            
364 0 0         if ( $this->{REDIRECT} ) {
365 0           ${$this->{REDIRECT}} .= join("", (@_[0..$#_])) ;
  0            
366             }
367             else {
368 0 0 0       if ( !$this->{AUTO_FLUSH} && !$this->{AUTOHEAD} && !$| ) {
369             #print main::STDOUT "BUF>> !$autoflus_val && !$this->{AUTO_FLUSH} && !$this->{AUTOHEAD} \n" ;
370 0           $this->{BUFFER} .= join("", (@_[0..$#_])) ;
371             }
372             else {
373             #print main::STDOUT "PRT>> !$autoflus_val && !$this->{AUTO_FLUSH} && !$this->{AUTOHEAD} [[$_[0]]]\n" ;
374 0 0         $this->flush if $this->{BUFFER} ne '' ;
375 0           $this->print_stdout( join("", (@_[0..$#_])) ) ;
376             }
377             }
378              
379 0           return 1 ;
380             }
381              
382 0     0     sub PRINTF { &PRINT($_[0],sprintf($_[1],@_[2..$#_])) ;}
383              
384 0     0     sub READ {}
385 0     0     sub READLINE {}
386 0     0     sub GETC {}
387 0     0     sub WRITE {}
388              
389 0     0     sub FILENO {
390             #my $this = shift ;
391             #my $n = $this + 1 ;
392             #return $n ;
393             }
394              
395             sub CLOSE {
396 0     0     my $this = shift ;
397 0           $this->{AUTO_FLUSH} = 1 ;
398 0           $this->close_headers ;
399 0           $this->flush ;
400             }
401              
402             sub STORE {
403 0     0     my $this = shift ;
404 0           my $stdout = shift ;
405 0 0         if ( !ref($stdout) ) {
406 0           $stdout =~ s/^\*// ;
407 0           $stdout = \*{$stdout} ;
  0            
408             }
409 0           $this->{STDOUT} = $stdout ;
410             }
411              
412 0     0     sub FETCH {}
413              
414             sub DESTROY {
415             &CLOSE ;
416             }
417              
418             #######
419             # END #
420             #######
421              
422             1;
423              
424