File Coverage

blib/lib/File/RoundRobin.pm
Criterion Covered Total %
statement 145 248 58.4
branch 48 96 50.0
condition 16 39 41.0
subroutine 18 33 54.5
pod 14 14 100.0
total 241 430 56.0


line stmt bran cond sub pod time code
1             package File::RoundRobin;
2              
3 5     5   47916 use 5.006;
  5         17  
4 5     5   28 use strict;
  5         6  
  5         89  
5 5     5   18 use warnings;
  5         8  
  5         10803  
6              
7             =head1 NAME
8              
9             File::RoundRobin - Round Robin text files
10              
11             =head1 VERSION
12              
13             Version 0.05
14              
15             =cut
16              
17             our $VERSION = '0.05';
18              
19             local $|=1;
20              
21             =head1 SYNOPSIS
22              
23             This module implements a Round-Robin text file.
24              
25             The text file will not grow beyond the size we specify.
26              
27             The benefit of using this module is that you can log a certain amount of
28             information without having to care about filling your hard drive or setting up a
29             log-rotate mechanism.
30              
31             Example :
32              
33             use File::RoundRobin;
34              
35             my $rrfile = File::RoundRobin->new(
36             path => '/tmp/sample.txt',
37             size => '100M',
38             mode => 'new',
39             ) // die $@;
40              
41             $rrfile->print("foo bar");
42            
43             or
44            
45             my $rrfile = File::RoundRobin->new(path => '/tmp/sample.txt', mode => 'read');
46              
47             while (my $line = $rrfile->readline() ) {
48             print $line;
49             }
50            
51              
52              
53             When you write into the Round-Robin file, if it filled the maximum allowed space it
54             will write over the old data, while always preserving the most recent data.
55              
56             =head1 ERROR HANDLING and DEBUGGING
57              
58             In case an error occures, the error will be stored in $@
59              
60             Starting with version 0.5 the module no longer dies on errors, instead returns
61             undef or 0 (c will return undef, c will return 0) and the actual
62             error message is available in $@.
63              
64             =head1 TIE INTERFACE
65              
66             This module implements the TIEHANDLE interface and the objects an be used as normal
67             file handles.
68              
69             =over 4
70              
71             =item 1. Write example :
72              
73             local *FH;
74             tie *FH, 'File::RoundRobin', path => 'test.txt',size => '10M';
75              
76             my $fh = *FH;
77              
78             ...
79             print $fh "foo bar";
80              
81             ...
82             close($fh);
83            
84             =item 2. Read example :
85              
86             local *FH;
87             tie *FH, 'File::RoundRobin', path => 'test.txt',mode => 'read';
88              
89             $fh = *FH;
90              
91             while ( my $line = readline($fh) ) {
92             print $line;
93             }
94            
95             close($fh);
96            
97             =back
98            
99             =head1 UTILITIES
100              
101             =head2 rrcat
102              
103             The package comes with a simple utility B that let's you create and read RoundRobin files from command line
104              
105             Usage :
106             To print the content of a file :
107             $ rrcat
108              
109             To write into a file (reads from stdin):
110             $ rrcat
111              
112             Size can be specified in any of the forms accepted by File::RoundRobin (see C method)
113              
114             =head2 rrtail
115              
116             The package comes with a simple utility B that let's you tail RoundRobin files from command line
117              
118             Usage :
119             To a file you can run :
120              
121             Print the last 10 lines
122            
123             $ rrtail
124              
125             Print the last 100 lines :
126            
127             $ rrtail -n 100
128              
129             Print the content as it's written :
130              
131             $ rrtail -f
132            
133              
134             =head1 SUBROUTINES/METHODS
135              
136             =head2 new
137              
138             Returns a new File::RoundRobin object.
139              
140             Files can be opened in three ways: I, I, I
141              
142             =head3 write
143              
144             In I mode any existing data will be lost and the file will be overwritten
145             Arguments :
146              
147             =over 4
148              
149             =item * path = path where to create the file
150              
151             =item * size = the maximum size the file is allowed to grow to. Example : 100K or 100Kb, 10M or 10Mb, 1G or 1Gb
152              
153             =back
154              
155             Example :
156              
157             my $rrfile = File::RoundRobin->new(
158             path => '/tmp/sample.txt',
159             size => '100M',
160             );
161              
162             =head3 read
163              
164             Arguments :
165              
166             =over 4
167              
168             =item * path = path where to create the file
169              
170             =item * mode = must be C
171              
172             =back
173              
174             Example :
175              
176             my $rrfile = File::RoundRobin->new(path => '/tmp/sample.txt', mode => 'read') || die $@;
177              
178             =head3 append
179              
180             In I mode all existing data will preserved and we can continue writing the file from where we left off
181              
182             Arguments :
183              
184             =over 4
185              
186             =item * path = path where to create the file
187              
188             =item * mode = must be C
189              
190             =back
191              
192             Example :
193              
194             my $rrfile = File::RoundRobin->new(path => '/tmp/sample.txt', mode => 'append') || die $@;
195              
196             =cut
197              
198             sub new {
199 18     18 1 891 my $class = shift;
200            
201 18         59 my %params = (
202             mode => 'new',
203             @_
204             );
205            
206 18         44 $params{size} = convert_size($params{size});
207              
208 18 50 66     70 if ($params{mode} eq "new" && ! defined $params{size}) {
209 0         0 $@ = "You must specify the file size" ;
210 0         0 return;
211             }
212            
213 18         46 my ($fh,$size,$start_point,$headers_size,$read_only) = open_file(%params);
214            
215 18 50       49 return undef unless $fh;
216            
217             my $self = {
218             _fh_ => $fh,
219             _data_length_ => $size,
220             _file_length_ => $size + $headers_size,
221             _write_start_point_ => $start_point,
222             _read_start_point_ => $start_point,
223             _headers_size_ => $headers_size,
224             _read_only_ => $read_only,
225 18   100     145 _autoflush_ => $params{autoflush} || 1,
226             };
227            
228 18         56 bless $self, $class;
229            
230 18         70 return $self;
231             }
232              
233              
234             =head2 read
235              
236             Reads the $length craracters form the file beginning with $offset and returns the result
237              
238             Usage :
239              
240             #reads the next 10 characted from the file
241             my $buffer = $rrfile->read(10);
242             or
243             #reads the first 10 characters starting with character 90 after the current position
244             my $buffer = $rrfile->read(10,90);
245              
246             Arguments :
247              
248             =over 4
249              
250             =item * I = how many bytes to read
251              
252             =item * I = offset from which to start reading
253              
254             =back
255            
256             =cut
257             sub read {
258 573     573 1 2000935 my $self = shift;
259 573   50     801 my $length = shift || 1;
260 573   50     1030 my $offset = shift || 0;
261            
262 573 100       869 if ($self->{_write_start_point_} == $self->{_read_start_point_}) {
263 13 100       25 if ($self->{_read_started_}) {
264 5         20 return undef;
265             }
266             else {
267 8         12 $self->{_read_started_} = 1;
268             }
269             }
270              
271             my $to_eof = ($self->{_write_start_point_} > $self->{_read_start_point_}) ?
272             $self->{_write_start_point_} - $self->{_read_start_point_} :
273 568 100       874 ($self->{_write_start_point_} - $self->{_headers_size_}) + ($self->{_file_length_} - $self->{_read_start_point_});
274            
275 568 100       698 $length = $to_eof > $length ? $length : $to_eof;
276            
277 568 50       798 return undef unless $length;
278              
279 568 50       712 $self->jump($offset) if ($offset);
280            
281 568         624 my ($buffer1,$buffer2);
282            
283 568         1165 my $bytes = CORE::sysread($self->{_fh_},$buffer1,$length);
284 568         659 $self->{_read_start_point_} += $bytes;
285 568         788 CORE::sysseek($self->{_fh_},$self->{_read_start_point_},0);
286            
287 568 100       822 if ($bytes < $length) {
288 8         11 $length -= $bytes;
289 8 50       21 if ($self->{_write_start_point_} - $self->{_headers_size_} < $length) {
290 0         0 $length = $self->{_write_start_point_} - $self->{_headers_size_};
291             }
292 8         15 CORE::sysseek($self->{_fh_},$self->{_headers_size_},0);
293 8         35 $bytes = CORE::sysread($self->{_fh_},$buffer2,$length);
294 8         14 $self->{_read_start_point_} = $self->{_headers_size_} + $bytes;
295 8         21 CORE::sysseek($self->{_fh_},$self->{_read_start_point_},0);
296             }
297              
298 568 100       1267 return $buffer2 ? $buffer1 . $buffer2 : $buffer1;
299             }
300              
301             =head2 write
302              
303             Writes the given text into the file
304              
305             Usage :
306              
307             $rrfile->write("foo bar");
308            
309             Arguments :
310              
311             =over 4
312              
313             =item * I = the actual content we want to write
314              
315             =item * I = the length of the content we want to write (defaults to C)
316              
317             =item * I = offset from which to start writing
318              
319             =back
320              
321             =cut
322             sub write {
323 11     11 1 1367 my $self = shift;
324 11         15 my $buffer = shift;
325 11   33     36 my $length = shift || length($buffer);
326 11   50     27 my $offset = shift || 0;
327            
328 11 50       28 if ( $self->{_read_only_} ) {
329 0         0 $@ = "File is read only!";
330 0         0 return 0;
331             }
332            
333 11 50       18 $self->jump($offset) if $offset;
334            
335 11         18 $self->{_write_start_point_} = $self->{_read_start_point_};
336            
337 11         17 my $fh = $self->{_fh_};
338            
339 11         13 my $start_pos = 0;
340 11         29 while ($self->{_write_start_point_} + $length > $self->{_file_length_}) {
341 59         72 my $bytes_to_write = $self->{_file_length_} - $self->{_write_start_point_};
342 59         174 CORE::syswrite($fh,substr($buffer,$start_pos,$bytes_to_write));
343 59         65 $start_pos += $bytes_to_write;
344 59         61 $length -= $bytes_to_write;
345 59         67 $self->{_write_start_point_} = $self->{_headers_size_};
346 59         122 CORE::sysseek($fh,$self->{_write_start_point_},0);
347             }
348            
349 11         100 CORE::syswrite($fh,substr($buffer,$start_pos,$length));
350 11         18 $self->{_write_start_point_} += $length;
351 11         18 $self->{_read_start_point_} = $self->{_write_start_point_};
352            
353 11 50       37 $self->update_headers() unless $self->{_autoflush_} == 0;
354            
355 11 50       56 return ($self->{_write_start_point_} == CORE::tell($fh)) ? 1 : 0;
356             }
357              
358              
359             =head2 print
360              
361             Writes the given text into the file
362              
363             Usage :
364              
365             $rrfile->print("foo bar");
366            
367             Arguments :
368              
369             =over 4
370              
371             =item * I = the actual content we want to write
372              
373             =back
374              
375             =cut
376             *print = \&write;
377              
378              
379             =head2 close
380              
381             Close the Round-Robin file
382              
383             Usage :
384              
385             $rrfile->close();
386              
387             =cut
388             sub close {
389 28     28 1 585 my $self = shift;
390            
391 28         47 my $fh = $self->{_fh_};
392            
393 28 100       146 return if $self->{_closed_};
394            
395 18 100       38 if (! $self->{_read_only_}) {
396 10         19 $self->update_headers();
397             }
398            
399 18         34 $self->{_closed_} = 1;
400            
401 18         162 return CORE::close($fh);
402             }
403              
404              
405             =head2 eof
406              
407             Return true if you reached the end of file, false otherwise
408              
409             Usage :
410              
411             my $bool = $rrfile->eof();
412              
413             =cut
414             sub eof {
415 0     0 1 0 my $self = shift;
416            
417 0 0 0     0 return 1 if ($self->{_write_start_point_} == $self->{_read_start_point_} && defined $self->{_read_started_} );
418              
419 0         0 return 0;
420             }
421              
422              
423             =head2 autoflush
424              
425             Turns on/off the autoflush feature
426              
427             Usage :
428             my $autoflush = $rrfile->autoflush();
429            
430             or
431            
432             $rrfile->autoflush(1); #enables autoflush
433             $rrfile->autoflush(0); #disables autoflush
434            
435             =cut
436             sub autoflush {
437 0     0 1 0 my $self = shift;
438            
439 0 0       0 if ( scalar(@_) ) {
440 0         0 $self->{_autoflush_} = $_[0];
441             }
442            
443 0         0 return $self->{_autoflush_};
444             }
445              
446              
447             =head1 Private methods
448              
449             Don't call this methods manually, or you might get unexpected results!
450              
451              
452             =head2 open_file
453              
454             Has two modes :
455              
456             =over 4
457              
458             =item 1. In append mode it opens an existing file
459              
460             =item 2. In new mode it creates a new file
461              
462             =back
463              
464             =cut
465             sub open_file {
466 19     19 1 482 my %params = @_;
467            
468 19 50       39 if (! defined($params{path}) ) {
469 0         0 $@ = "You myst specifi the name of the file!";
470             }
471 19 50       244 if (-d $params{path}) {
472 0         0 $@ = "Path is a directory!";
473             }
474            
475 19         35 my ($fh,$size,$start_point,$version,$headers_size,$read_only);
476 19 100       43 if ($params{mode} eq "new") {
477 10 50       28 if (! defined $params{size} ) {
478 0         0 $! = "You must specify the size of the file!";
479 0         0 return;
480             }
481 10         14 $size = $params{size};
482 10 50       503 if (! open($fh,"+>",$params{path}) ) {
483 0         0 $@ = $!;
484 0         0 return;
485             }
486 10         54 CORE::binmode($fh,":unix");
487             #version number
488 10         235 CORE::syswrite($fh,"1"."\x00");
489             #file size
490 10         67 CORE::syswrite($fh,$params{size} ."\x00");
491             #where is the start of the file
492 10         33 $start_point = length($params{size}) * 2 + 2 + 2;
493 10         58 CORE::syswrite($fh,("0" x (length($params{size}) - length($start_point) )) . $start_point ."\x00");
494 10         34 $headers_size = length($params{size}) * 2 + 2 + 2;
495 10         18 $read_only = 0;
496             }
497             else {
498 9 100       27 if ($params{mode} eq "append") {
    50          
499 1 50       18 if (! open($fh,"+<",$params{path}) ) {
500 0         0 $@ = $!;
501 0         0 return;
502             }
503 1         4 CORE::binmode($fh,":unix");
504 1         3 CORE::sysseek($fh,0,0);
505 1         2 $read_only = 0;
506             }
507             elsif ($params{mode} eq "read") {
508 8 50       142 if (! open($fh,"<",$params{path}) ) {
509 0         0 $@ = $!;
510 0         0 return;
511             }
512 8         41 CORE::binmode($fh,":unix");
513 8         19 $read_only = 1;
514             }
515             else {
516 0         0 $@ = "Invalid open mode! Use one of new,read,append!";
517 0         0 return;
518             }
519            
520 9         15 my $start_section;
521 9         53 CORE::sysread($fh,$start_section,4096);
522            
523 9         64 ($version, $size, $start_point) = split("\x00", $start_section);
524            
525 9         31 CORE::sysseek($fh,0,0);
526            
527             #make sure this looks like a File::RoundRobin file
528 9 50 33     119 if (! $version || $version ne "1" || int($size || '') == 0 || int($start_point || '') == 0 ) {
      50        
      33        
      50        
      33        
529 0         0 $@ = "File does not look like a File::RoundRobin file - missing headers";
530 0         0 return;
531             }
532            
533 9         31 $headers_size = length($version) + length($size) + length($start_point) +3;
534             # +3 because of the 3 \x00 chars we use to separate headder info
535            
536 9         27 CORE::sysseek($fh,$start_point + 0,0);
537             }
538            
539 19         85 return ($fh,$size + 0,$start_point + 0,$headers_size + 0,$read_only);
540             }
541              
542              
543             =head2 update_headers
544              
545             Update the start point in the headers section after a write command
546              
547             =cut
548             sub update_headers {
549 21     21 1 29 my $self = shift;
550            
551 21         26 my $fh = $self->{_fh_};
552            
553 21         66 CORE::sysseek($fh,0, 0);
554            
555 21         38 my $headers = '';
556             #version
557 21         28 $headers .= "1\x00";
558             #file size
559 21         40 $headers .= $self->{_data_length_} ."\x00";
560             #start pos
561 21         54 $headers .= ("0" x (length($self->{_data_length_}) - length($self->{_write_start_point_}) )) . $self->{_write_start_point_} ."\x00";
562            
563 21         120 CORE::syswrite($fh,$headers);
564            
565             #go back to the previous position
566 21         53 CORE::sysseek($fh,$self->{_write_start_point_}, 0);
567             }
568              
569              
570             =head2 refresh
571              
572             Re-reads the headers from the file. Useful for tail
573              
574             =cut
575             sub refresh {
576 0     0 1 0 my $self = shift;
577            
578 0         0 my $fh = $self->{_fh_};
579            
580 0         0 my $pos = $self->tell();
581            
582 0         0 CORE::sysseek($fh,0,0);
583            
584 0         0 local $/ = "\x00";
585            
586             #skip the first part of the header
587 0         0 my $version = <$fh>;
588 0         0 my $size = <$fh>;
589            
590 0         0 my $start_point = <$fh>;
591            
592 0         0 my $headers_size = length($version) + length($size) + length($start_point);
593            
594 0         0 $size =~ s/\x00//g;
595 0         0 $start_point =~ s/\x00//g;
596            
597 0         0 $self->{_headers_size_} = $headers_size;
598 0         0 $self->{_read_start_point_} = $start_point + 0;
599 0         0 $self->{_data_length_} = $size + 0;
600 0         0 $self->{_file_length_} = $size + $headers_size;
601            
602 0         0 CORE::sysseek($fh,$start_point,0);
603             }
604              
605             =head2 sync_markers
606              
607             Sets the write market to the same position as the read marker
608              
609             =cut
610             sub sync_markers {
611 0     0 1 0 my $self = shift;
612            
613 0         0 $self->{_write_start_point_} = $self->{_read_start_point_};
614 0         0 $self->{_read_started_} = 0;
615             }
616              
617              
618             =head2 jump
619              
620             Advance the read start position pointer by $offset bytes
621              
622             =cut
623             sub jump {
624 0     0 1 0 my $self = shift;
625 0   0     0 my $offset = shift || 0;
626            
627 0 0       0 if ($offset) {
628 0 0       0 if ($offset + $self->{_read_start_point_} > $self->{_file_length_}) {
629             $self->{_read_start_point_} = $self->{_headers_size_} + (($offset + $self->{_read_start_point_}) % $self->{_file_length_} )
630 0         0 }
631             else {
632 0         0 $self->{_start_point_} += $offset;
633             }
634             }
635            
636 0         0 CORE::sysseek($self->{_fh_},$self->{_read_start_point_},0);
637             }
638              
639              
640             =head2 seek
641              
642             Move the read/write start position to the given position
643              
644             Arguments :
645              
646             =over 4
647              
648             =item * I = The position to which we want to move to offset
649              
650             =item * I = From where should we start counting the position :
651              
652             =back
653              
654             =over 8
655              
656             =item * 0 = from the beginning of the file
657              
658             =item * 1 = from the current position
659              
660             =item * 2 = from the end of the file (I must be negative)
661              
662             =back
663              
664             Usage :
665              
666             $rrfile->seek(10,0);
667              
668             =cut
669             sub seek {
670 3     3 1 6 my $self = $_[0];
671 3         3 my $position = $_[1];
672 3   50     11 my $whence = $_[2] || 0;
673            
674             #$position = $position % $self->{_data_length_};
675            
676 3 50       6 if ($whence == 0) {
    0          
    0          
677 3         4 my $start_pos = $self->{_write_start_point_};
678 3 50       7 if ($self->{_write_start_point_} + $position > $self->{_file_length_}) {
679 0         0 $position -= $self->{_file_length_} - $self->{_write_start_point_};
680 0         0 $start_pos = $self->{_headers_size_};
681             }
682 3 50       11 if ( CORE::sysseek($self->{_fh_},$start_pos + $position,0) ) {
683 3         4 $self->{_read_start_point_} = $start_pos + $position;
684 3         15 return 1;
685             }
686             }
687             elsif ($whence == 1) {
688 0         0 my $start_pos = $self->{_read_start_point_};
689 0 0       0 if ($self->{_read_start_point_} + $position > $self->{_file_length_}) {
690 0         0 $position -= $self->{_file_length_} - $self->{_read_start_point_};
691 0         0 $start_pos = $self->{_headers_size_};
692             }
693 0 0       0 if ( CORE::sysseek($self->{_fh_},$start_pos + $position,1) ) {
694 0         0 $self->{_read_start_point_} = $start_pos + $position;
695 0         0 return 1;
696             }
697             }
698             elsif ($whence == 2 ) {
699 0 0       0 if ($position > 0) {
700 0         0 $@ = "Attempt to seek beyond the end of file!";
701 0         0 warn $@;
702 0         0 return 0;
703             }
704            
705 0         0 my $start_pos = $self->{_write_start_point_};
706 0 0       0 if ($self->{_write_start_point_} + $position < $self->{_headers_size_}) {
707 0         0 $position = -$position;
708 0         0 $position -= $self->{_write_start_point_} - $self->{_headers_size_};
709 0         0 $start_pos = $self->{_file_length_};
710             }
711            
712             #don't go in cicles
713 0 0 0     0 if ($self->{_read_start_point_} < $self->{_write_start_point_} &&
714             $self->{_read_start_point_} + $position >= $self->{_write_start_point_}){
715 0         0 return 0;
716             }
717            
718 0 0       0 if ( CORE::sysseek($self->{_fh_},$start_pos,0) ) {
719 0 0       0 if ( CORE::sysseek($self->{_fh_},$position,1) ) {
720 0         0 $self->{_read_start_point_} = $start_pos + $position;
721 0         0 return 1;
722             }
723             }
724             }
725             else {
726 0         0 $@ = "Unknown seek mode!";
727 0         0 warn $@;
728             }
729            
730 0         0 return 0;
731             }
732              
733             =head2 tell
734              
735             Return the difference between the current read position and the last write position
736              
737             Example :
738              
739             my $pos = $rrfile->tell();
740              
741             =cut
742             sub tell {
743 0     0 1 0 my $self = shift;
744            
745 0         0 my $offset;
746            
747 0 0       0 if ($self->{_read_start_point_} >= $self->{_write_start_point_}) {
748 0         0 $offset = $self->{_read_start_point_} - $self->{_write_start_point_};
749             }
750             else {
751             $offset = ($self->{_file_length_} - $self->{_write_start_point_}) +
752 0         0 ($self->{_read_start_point_} - $self->{_headers_size_});
753             }
754 0         0 return $offset % $self->{_data_length_};
755             }
756              
757             =head2 convert_size
758              
759             Converts the size from a human readable form into bytes
760              
761             Example of acceptable formats :
762              
763             =over 4
764              
765             =item * 1000
766              
767             =item * 120K or 120Kb
768              
769             =item * 15M or 15Mb
770              
771             =item * 1G or 1Gb
772              
773             =back
774              
775             =cut
776             sub convert_size {
777 24     24 1 541 my $size = shift;
778            
779 24 100       59 return undef unless defined $size;
780            
781 15 100       91 return $size if $size =~ /^\d+$/;
782            
783 10         33 my %sizes = (
784             'K' => 10**3,
785             'M' => 10**6,
786             'G' => 10**9,
787             );
788            
789 10 100       78 if ($size =~ /^(\d+(?:\.\d+)?)(K|M|G)b?$/i ) {
790 9         71 return $1 * $sizes{uc($2)};
791             }
792             else {
793 1         3 $@ = "Broke size format in ".__PACKAGE__."->convert_size(). See pod for accepted formats";
794 1         7 return undef;
795             }
796              
797             }
798              
799              
800             =head1 TIE INTERFACE IMPLEMENTATION
801              
802             This module implements the TIEHANDLE interface and the objects an be used as normal
803             file handles.
804              
805             See SYNOPSYS for more details on this
806              
807             =cut
808              
809             sub TIEHANDLE {
810 8     8   469 my $class = shift;
811 8         18 return $class->new(@_);
812             }
813              
814             sub READ {
815 4     4   1205 my ($self,$buffer,$length,$offet) = @_;
816            
817 4         9 my $content = $self->read($length,$offet);
818 4         6 $_[1] = $content;
819 4   100     13 return length($content || '');
820             }
821              
822             sub READLINE {
823 7     7   2257 my $self = shift;
824            
825 7         8 my $buffer;
826 7         15 while (my $char = $self->read(1)) {
827 558         641 $buffer .= $char;
828 558 100       1215 last if ($char =~ /[\n\r]/);
829             }
830            
831 7         18 return $buffer;
832             }
833              
834             sub GETC {
835 1     1   7 my $self = shift;
836            
837 1         3 return $self->read(1,0);
838             }
839              
840             sub WRITE {
841 0     0   0 my ($self,$buffer,$length,$offet) = @_;
842            
843 0         0 return $self->write($buffer,$length,$offet);
844             }
845              
846             sub PRINT {
847 4     4   68 my ($self,@data) = @_;
848            
849 4         10 return $self->write($_) foreach @data;
850             }
851              
852             sub PRINTF {
853 0     0   0 my ($self,$format,@data) = @_;
854            
855 0         0 return $self->write(sprintf($format,@data));
856             }
857              
858             # binmode does nothing, this is a text file
859             sub BINMODE {
860 0     0   0 my $self = shift;
861 0         0 CORE::binmode($self->{_fh_},@_);
862             }
863              
864             sub EOF {
865 0     0   0 my $self = shift;
866            
867 0         0 return $self->eof();
868             }
869              
870             sub FILENO {
871 0     0   0 my $self = shift;
872            
873 0         0 return CORE::fileno($self->{_fh_});
874             }
875              
876             sub SEEK {
877 0     0   0 my ($self,$position,$whence) = @_;
878            
879 0         0 return $self->seek($position,$whence);
880             }
881              
882             sub TELL {
883 0     0   0 my $self = shift;
884            
885 0         0 return $self->tell();
886             }
887              
888             sub OPEN {
889 0     0   0 my ($self, $mode, @params) = @_;
890              
891 0         0 die "You cannot use the tie interface to open a file, use File::RoundRobin->new() instead!";
892             }
893              
894             sub CLOSE {
895 4     4   21 my $self = shift;
896            
897 4         9 $self->close();
898             }
899              
900              
901             # Does nothing
902             sub UNTIE {
903 0     0   0 my $self = shift;
904 0         0 return 0
905             }
906              
907             DESTROY {
908 18     18   5040 my $self = shift;
909            
910 18         47 $self->close();
911             }
912              
913             =head1 AUTHOR
914              
915             Gligan Calin Horea, C<< >>
916              
917             =head1 BUGS
918              
919             Please report any bugs or feature requests to C, or through
920             the web interface at L. I will be notified, and then you'll
921             automatically be notified of progress on your bug as I make changes.
922              
923              
924              
925              
926             =head1 SUPPORT
927              
928             You can find documentation for this module with the perldoc command.
929              
930             perldoc File::RoundRobin
931              
932              
933             You can also look for information at:
934              
935             =over 4
936              
937             =item * RT: CPAN's request tracker (report bugs here)
938              
939             L
940              
941             =item * AnnoCPAN: Annotated CPAN documentation
942              
943             L
944              
945             =item * CPAN Ratings
946              
947             L
948              
949             =item * Search CPAN
950              
951             L
952              
953             =back
954              
955             =head1 LICENSE AND COPYRIGHT
956              
957             Copyright 2012 Gligan Calin Horea.
958              
959             This program is free software; you can redistribute it and/or modify it
960             under the terms of either: the GNU General Public License as published
961             by the Free Software Foundation; or the Artistic License.
962              
963             See http://dev.perl.org/licenses/ for more information.
964              
965              
966             =cut
967              
968             1; # End of File::RoundRobin