File Coverage

blib/lib/File/RoundRobin.pm
Criterion Covered Total %
statement 145 248 58.4
branch 48 96 50.0
condition 20 45 44.4
subroutine 18 33 54.5
pod 14 14 100.0
total 245 436 56.1


line stmt bran cond sub pod time code
1             package File::RoundRobin;
2              
3 5     5   71594 use 5.006;
  5         17  
4 5     5   28 use strict;
  5         9  
  5         117  
5 5     5   71 use warnings;
  5         9  
  5         15109  
6              
7             =head1 NAME
8              
9             File::RoundRobin - Round Robin text files
10              
11             =head1 VERSION
12              
13             Version 0.06
14              
15             =cut
16              
17             our $VERSION = '0.07';
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 occurs, 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 1156 my $class = shift;
200              
201 18         82 my %params = (
202             mode => 'new',
203             @_
204             );
205              
206 18         51 $params{size} = convert_size($params{size});
207              
208 18 50 66     86 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         57 my ($fh,$size,$start_point,$headers_size,$read_only) = open_file(%params);
214              
215 18 50       67 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     152 _autoflush_ => $params{autoflush} || 1,
226             };
227              
228 18         71 bless $self, $class;
229              
230 18         83 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 2001288 my $self = shift;
259 573   50     989 my $length = shift || 1;
260 573   50     1327 my $offset = shift || 0;
261              
262 573 100       1131 if ($self->{_write_start_point_} == $self->{_read_start_point_}) {
263 13 100       35 if ($self->{_read_started_}) {
264 5         27 return undef;
265             }
266             else {
267 8         17 $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       1076 ($self->{_write_start_point_} - $self->{_headers_size_}) + ($self->{_file_length_} - $self->{_read_start_point_});
274              
275 568 100       870 $length = $to_eof > $length ? $length : $to_eof;
276              
277 568 50       923 return undef unless $length;
278              
279 568 50       879 $self->jump($offset) if ($offset);
280              
281 568         739 my ($buffer1,$buffer2);
282              
283 568         3947 my $bytes = CORE::sysread($self->{_fh_},$buffer1,$length);
284 568         1271 $self->{_read_start_point_} += $bytes;
285 568         2749 CORE::sysseek($self->{_fh_},$self->{_read_start_point_},0);
286              
287 568 100       1569 if ($bytes < $length) {
288 8         65 $length -= $bytes;
289 8 50       26 if ($self->{_write_start_point_} - $self->{_headers_size_} < $length) {
290 0         0 $length = $self->{_write_start_point_} - $self->{_headers_size_};
291             }
292 8         47 CORE::sysseek($self->{_fh_},$self->{_headers_size_},0);
293 8         100 $bytes = CORE::sysread($self->{_fh_},$buffer2,$length);
294 8         26 $self->{_read_start_point_} = $self->{_headers_size_} + $bytes;
295 8         45 CORE::sysseek($self->{_fh_},$self->{_read_start_point_},0);
296             }
297              
298 568 100       2271 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 1597 my $self = shift;
324 11         20 my $buffer = shift;
325 11   33     48 my $length = shift || length($buffer);
326 11   50     42 my $offset = shift || 0;
327              
328 11 50       37 if ( $self->{_read_only_} ) {
329 0         0 $@ = "File is read only!";
330 0         0 return 0;
331             }
332              
333 11 50       24 $self->jump($offset) if $offset;
334              
335 11         27 $self->{_write_start_point_} = $self->{_read_start_point_};
336              
337 11         26 my $fh = $self->{_fh_};
338              
339 11         15 my $start_pos = 0;
340 11         33 while ($self->{_write_start_point_} + $length > $self->{_file_length_}) {
341 61         124 my $bytes_to_write = $self->{_file_length_} - $self->{_write_start_point_};
342 61         512 CORE::syswrite($fh,substr($buffer,$start_pos,$bytes_to_write));
343 61         131 $start_pos += $bytes_to_write;
344 61         78 $length -= $bytes_to_write;
345 61         95 $self->{_write_start_point_} = $self->{_headers_size_};
346 61         397 CORE::sysseek($fh,$self->{_write_start_point_},0);
347             }
348              
349 11         211 CORE::syswrite($fh,substr($buffer,$start_pos,$length));
350 11         33 $self->{_write_start_point_} += $length;
351 11         27 $self->{_read_start_point_} = $self->{_write_start_point_};
352              
353 11 50       50 $self->update_headers() unless $self->{_autoflush_} == 0;
354              
355 11 50       140 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 726 my $self = shift;
390              
391 28         52 my $fh = $self->{_fh_};
392              
393 28 100       359 return if $self->{_closed_};
394              
395 18 100       47 if (! $self->{_read_only_}) {
396 10         26 $self->update_headers();
397             }
398              
399 18         49 $self->{_closed_} = 1;
400              
401 18         414 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 555 my %params = @_;
467              
468 19 50       50 if (! defined($params{path}) ) {
469 0         0 $@ = "Missing file name in call to open_file()!";
470             }
471 19 50       385 if (-d $params{path}) {
472 0         0 $@ = "Path is a directory!";
473             }
474              
475 19         54 my ($fh,$size,$start_point,$version,$headers_size,$read_only);
476 19 100 66     111 if ($params{mode} eq "new" || ( $params{mode} eq 'append' && ! -f $params{path} ) ) {
      66        
477 10 50       27 if (! defined $params{size} ) {
478 0         0 $! = "File size is mandatory for new files ('append' mode will create a new file if it doesn't exist)!";
479 0         0 return;
480             }
481 10         21 $size = $params{size};
482 10 50       792 if (! open($fh,"+>",$params{path}) ) {
483 0         0 $@ = $!;
484 0         0 return;
485             }
486 10         79 CORE::binmode($fh,":unix");
487             #version number
488 10         397 CORE::syswrite($fh,"1"."\x00");
489             #file size
490 10         154 CORE::syswrite($fh,$params{size} ."\x00");
491             #where is the start of the file
492 10         47 $start_point = length($params{size}) * 2 + 2 + 2;
493 10         122 CORE::syswrite($fh,("0" x (length($params{size}) - length($start_point) )) . $start_point ."\x00");
494 10         63 $headers_size = length($params{size}) * 2 + 2 + 2;
495 10         28 $read_only = 0;
496             }
497             else {
498 9 100       31 if ($params{mode} eq "append") {
    50          
499 1 50       36 if (! open($fh,"+<",$params{path}) ) {
500 0         0 $@ = $!;
501 0         0 return;
502             }
503 1         6 CORE::binmode($fh,":unix");
504 1         7 CORE::sysseek($fh,0,0);
505 1         3 $read_only = 0;
506             }
507             elsif ($params{mode} eq "read") {
508 8 50       269 if (! open($fh,"<",$params{path}) ) {
509 0         0 $@ = $!;
510 0         0 return;
511             }
512 8         50 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         14 my $start_section;
521 9         109 CORE::sysread($fh,$start_section,4096);
522              
523 9         77 ($version, $size, $start_point) = split("\x00", $start_section);
524              
525 9         60 CORE::sysseek($fh,0,0);
526              
527             #make sure this looks like a File::RoundRobin file
528 9 50 33     131 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         26 $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         65 CORE::sysseek($fh,$start_point + 0,0);
537             }
538              
539 19         136 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 36 my $self = shift;
550              
551 21         31 my $fh = $self->{_fh_};
552              
553 21         149 CORE::sysseek($fh,0, 0);
554              
555 21         64 my $headers = '';
556             #version
557 21         40 $headers .= "1\x00";
558             #file size
559 21         61 $headers .= $self->{_data_length_} ."\x00";
560             #start pos
561 21         78 $headers .= ("0" x (length($self->{_data_length_}) - length($self->{_write_start_point_}) )) . $self->{_write_start_point_} ."\x00";
562              
563 21         278 CORE::syswrite($fh,$headers);
564              
565             #go back to the previous position
566 21         162 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 7 my $self = $_[0];
671 3         4 my $position = $_[1];
672 3   50     11 my $whence = $_[2] || 0;
673              
674 3 50       17 if ($whence == 0) {
    0          
    0          
675 3         7 my $start_pos = $self->{_write_start_point_};
676 3 50       8 if ($self->{_write_start_point_} + $position > $self->{_file_length_}) {
677 0         0 $position -= $self->{_file_length_} - $self->{_write_start_point_};
678 0         0 $start_pos = $self->{_headers_size_};
679             }
680 3 50       26 if ( CORE::sysseek($self->{_fh_},$start_pos + $position,0) ) {
681 3         8 $self->{_read_start_point_} = $start_pos + $position;
682 3         19 return 1;
683             }
684             }
685             elsif ($whence == 1) {
686 0         0 my $start_pos = $self->{_read_start_point_};
687 0 0       0 if ($self->{_read_start_point_} + $position > $self->{_file_length_}) {
688 0         0 $position -= $self->{_file_length_} - $self->{_read_start_point_};
689 0         0 $start_pos = $self->{_headers_size_};
690             }
691 0 0       0 if ( CORE::sysseek($self->{_fh_},$start_pos + $position,1) ) {
692 0         0 $self->{_read_start_point_} = $start_pos + $position;
693 0         0 return 1;
694             }
695             }
696             elsif ($whence == 2 ) {
697 0 0       0 if ($position > 0) {
698 0         0 $@ = "Attempt to seek beyond the end of file!";
699 0         0 warn $@;
700 0         0 return 0;
701             }
702              
703 0         0 my $start_pos = $self->{_write_start_point_};
704 0 0       0 if ($self->{_write_start_point_} + $position < $self->{_headers_size_}) {
705 0         0 $position = -$position;
706 0         0 $position -= $self->{_write_start_point_} - $self->{_headers_size_};
707 0         0 $start_pos = $self->{_file_length_};
708             }
709              
710             #don't go in cicles
711 0 0 0     0 if ($self->{_read_start_point_} < $self->{_write_start_point_} &&
712             $self->{_read_start_point_} + $position >= $self->{_write_start_point_}){
713 0         0 return 0;
714             }
715              
716 0 0       0 if ( CORE::sysseek($self->{_fh_},$start_pos,0) ) {
717 0 0       0 if ( CORE::sysseek($self->{_fh_},$position,1) ) {
718 0         0 $self->{_read_start_point_} = $start_pos + $position;
719 0         0 return 1;
720             }
721             }
722             }
723             else {
724 0         0 $@ = "Unknown seek mode!";
725 0         0 warn $@;
726             }
727              
728 0         0 return 0;
729             }
730              
731             =head2 tell
732              
733             Return the difference between the current read position and the last write position
734              
735             Example :
736              
737             my $pos = $rrfile->tell();
738              
739             =cut
740             sub tell {
741 0     0 1 0 my $self = shift;
742              
743 0         0 my $offset;
744              
745 0 0       0 if ($self->{_read_start_point_} >= $self->{_write_start_point_}) {
746 0         0 $offset = $self->{_read_start_point_} - $self->{_write_start_point_};
747             }
748             else {
749             $offset = ($self->{_file_length_} - $self->{_write_start_point_}) +
750 0         0 ($self->{_read_start_point_} - $self->{_headers_size_});
751             }
752 0         0 return $offset % $self->{_data_length_};
753             }
754              
755             =head2 convert_size
756              
757             Converts the size from a human readable form into bytes
758              
759             Example of acceptable formats :
760              
761             =over 4
762              
763             =item * 1000
764              
765             =item * 120K or 120Kb
766              
767             =item * 15M or 15Mb
768              
769             =item * 1G or 1Gb
770              
771             =back
772              
773             =cut
774             sub convert_size {
775 24     24 1 539 my $size = shift;
776              
777 24 100       72 return undef unless defined $size;
778              
779 15 100       97 return $size if $size =~ /^\d+$/;
780              
781 10         33 my %sizes = (
782             'K' => 10**3,
783             'M' => 10**6,
784             'G' => 10**9,
785             );
786              
787 10 100       66 if ($size =~ /^(\d+(?:\.\d+)?)(K|M|G)b?$/i ) {
788 9         73 return $1 * $sizes{uc($2)};
789             }
790             else {
791 1         3 $@ = "Broke size format in ".__PACKAGE__."->convert_size(). See pod for accepted formats";
792 1         5 return undef;
793             }
794              
795             }
796              
797              
798             =head1 TIE INTERFACE IMPLEMENTATION
799              
800             This module implements the TIEHANDLE interface and the objects an be used as normal
801             file handles.
802              
803             See SYNOPSYS for more details on this
804              
805             =cut
806              
807             sub TIEHANDLE {
808 8     8   739 my $class = shift;
809 8         19 return $class->new(@_);
810             }
811              
812             sub READ {
813 4     4   1627 my ($self,$buffer,$length,$offet) = @_;
814              
815 4         9 my $content = $self->read($length,$offet);
816 4         8 $_[1] = $content;
817 4   100     17 return length($content || '');
818             }
819              
820             sub READLINE {
821 7     7   2910 my $self = shift;
822              
823 7         21 my $buffer;
824 7         17 while (my $char = $self->read(1)) {
825 558         890 $buffer .= $char;
826 558 100       1860 last if ($char =~ /[\n\r]/);
827             }
828              
829 7         26 return $buffer;
830             }
831              
832             sub GETC {
833 1     1   10 my $self = shift;
834              
835 1         2 return $self->read(1,0);
836             }
837              
838             sub WRITE {
839 0     0   0 my ($self,$buffer,$length,$offet) = @_;
840              
841 0         0 return $self->write($buffer,$length,$offet);
842             }
843              
844             sub PRINT {
845 4     4   129 my ($self,@data) = @_;
846              
847 4         16 return $self->write($_) foreach @data;
848             }
849              
850             sub PRINTF {
851 0     0   0 my ($self,$format,@data) = @_;
852              
853 0         0 return $self->write(sprintf($format,@data));
854             }
855              
856             # binmode does nothing, this is a text file
857             sub BINMODE {
858 0     0   0 my $self = shift;
859 0         0 CORE::binmode($self->{_fh_},@_);
860             }
861              
862             sub EOF {
863 0     0   0 my $self = shift;
864              
865 0         0 return $self->eof();
866             }
867              
868             sub FILENO {
869 0     0   0 my $self = shift;
870              
871 0         0 return CORE::fileno($self->{_fh_});
872             }
873              
874             sub SEEK {
875 0     0   0 my ($self,$position,$whence) = @_;
876              
877 0         0 return $self->seek($position,$whence);
878             }
879              
880             sub TELL {
881 0     0   0 my $self = shift;
882              
883 0         0 return $self->tell();
884             }
885              
886             sub OPEN {
887 0     0   0 my ($self, $mode, @params) = @_;
888              
889 0         0 die "You cannot use the tie interface to open a file, use File::RoundRobin->new() instead!";
890             }
891              
892             sub CLOSE {
893 4     4   33 my $self = shift;
894              
895 4         20 $self->close();
896             }
897              
898              
899             # Does nothing
900             sub UNTIE {
901 0     0   0 my $self = shift;
902 0         0 return 0
903             }
904              
905             DESTROY {
906 18     18   6692 my $self = shift;
907              
908 18         64 $self->close();
909             }
910              
911             =head1 AUTHOR
912              
913             Gligan Calin Horea, C<< >>
914              
915             =head1 BUGS
916              
917             Please report any bugs or feature requests to C, or through
918             the web interface at L. I will be notified, and then you'll
919             automatically be notified of progress on your bug as I make changes.
920              
921              
922              
923              
924             =head1 SUPPORT
925              
926             You can find documentation for this module with the perldoc command.
927              
928             perldoc File::RoundRobin
929              
930              
931             You can also look for information at:
932              
933             =over 4
934              
935             =item * RT: CPAN's request tracker (report bugs here)
936              
937             L
938              
939             =back
940              
941             =head1 LICENSE AND COPYRIGHT
942              
943             Copyright 2012 Gligan Calin Horea.
944              
945             This program is free software; you can redistribute it and/or modify it
946             under the terms of either: the GNU General Public License as published
947             by the Free Software Foundation; or the Artistic License.
948              
949             See http://dev.perl.org/licenses/ for more information.
950              
951              
952             =cut
953              
954             1; # End of File::RoundRobin