File Coverage

lib/Sisimai/Mail/Mbox.pm
Criterion Covered Total %
statement 47 47 100.0
branch 13 20 65.0
condition 6 7 85.7
subroutine 8 8 100.0
pod 2 2 100.0
total 76 84 90.4


line stmt bran cond sub pod time code
1             package Sisimai::Mail::Mbox;
2 88     88   104774 use v5.26;
  88         257  
3 88     88   362 use strict;
  88         138  
  88         1801  
4 88     88   317 use warnings;
  88         179  
  88         4862  
5 88     88   399 use File::Basename qw(basename dirname);
  88         117  
  88         7698  
6 88     88   37765 use IO::File;
  88         637882  
  88         11651  
7             use Class::Accessor::Lite (
8 88         734 'new' => 0,
9             'ro' => [
10             'dir', # [String] Directory name of the mbox
11             'file', # [String] File name of the mbox
12             'path', # [String] Path to mbox
13             'size', # [Integer] File size of the mbox
14             ],
15             'rw' => [
16             'offset', # [Integer] Offset position for seeking
17             'handle', # [IO::File] File handle
18             ]
19 88     88   1141 );
  88         1160  
20              
21             sub new {
22             # Constructor of Sisimai::Mail::Mbox
23             # @param [String] argv1 Path to mbox
24             # @return [Sisimai::Mail::Mbox] Object
25             # [Undef] is not a file or does not exist
26 743     743 1 322747 my $class = shift;
27 743 50 100     2496 my $argv1 = shift // return undef; return undef unless -f $argv1;
  742         10013  
28 742         2739 my $param = {'offset' => 0};
29              
30 742         48529 $param->{'dir'} = File::Basename::dirname $argv1;
31 742         2165 $param->{'path'} = $argv1;
32 742         10241 $param->{'size'} = -s $argv1;
33 742         22522 $param->{'file'} = File::Basename::basename $argv1;
34 742 50       7313 $param->{'handle'} = ref $argv1 ? $argv1 : IO::File->new($argv1, 'r');
35 742         96240 binmode $param->{'handle'};
36              
37 742         5022 return bless($param, __PACKAGE__);
38             }
39              
40             sub read {
41             # Mbox reader, works as an iterator.
42             # @return [String] Contents of mbox
43 1740 50   1740 1 2966193 my $self = shift; return "" unless defined $self->{'path'};
  1740         6586  
44 1740   50     6737 my $seekoffset = $self->{'offset'} // 0;
45 1740         3399 my $filehandle = $self->{'handle'};
46 1740         2861 my $readbuffer = '';
47              
48 1740 50       4660 unless( ref $self->{'path'} ) {
49             # "path" is not IO::File object
50 1740 50       41616 return "" unless -f $self->{'path'};
51 1740 50       121149 return "" unless -T $self->{'path'};
52             }
53 1740 100       12941 return "" unless $self->{'offset'} < $self->{'size'};
54              
55 1000         1909 eval {
56 1000 50       2430 $seekoffset = 0 if $seekoffset < 0;
57 1000         5380 seek($filehandle, $seekoffset, 0);
58              
59 1000         12971 while( my $r = <$filehandle> ) {
60             # Read the UNIX mbox file from 'From ' to the next 'From '
61 93525 100 100     171428 last if( $readbuffer && substr($r, 0, 5) eq 'From ' );
62 93266         136411 $readbuffer .= $r;
63             }
64 1000         1856 $seekoffset += length $readbuffer;
65 1000         1899 $self->{'offset'} = $seekoffset;
66 1000 100       5636 $filehandle->close unless $seekoffset < $self->{'size'};
67             };
68 1000         16539 return $readbuffer;
69             }
70              
71             1;
72             __END__