File Coverage

lib/Sisimai/Mail/Mbox.pm
Criterion Covered Total %
statement 48 48 100.0
branch 13 20 65.0
condition 5 7 71.4
subroutine 8 8 100.0
pod 2 2 100.0
total 76 85 89.4


line stmt bran cond sub pod time code
1             package Sisimai::Mail::Mbox;
2 77     77   65075 use feature ':5.10';
  77         133  
  77         5830  
3 77     77   385 use strict;
  77         129  
  77         1320  
4 77     77   292 use warnings;
  77         121  
  77         2164  
5 77     77   389 use File::Basename qw(basename dirname);
  77         129  
  77         7190  
6 77     77   31663 use IO::File;
  77         554155  
  77         9714  
7             use Class::Accessor::Lite (
8 77         662 '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 77     77   1178 );
  77         1265  
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 549     549 1 2824 my $class = shift;
27 549   50     1365 my $argv1 = shift // return undef;
28 549         1317 my $param = { 'offset' => 0 };
29 549 50       6957 return undef unless -f $argv1;
30              
31 549         27023 $param->{'dir'} = File::Basename::dirname $argv1;
32 549         1456 $param->{'path'} = $argv1;
33 549         6467 $param->{'size'} = -s $argv1;
34 549         15635 $param->{'file'} = File::Basename::basename $argv1;
35 549 50       4367 $param->{'handle'} = ref $argv1 ? $argv1 : IO::File->new($argv1, 'r');
36 549         55885 binmode $param->{'handle'};
37              
38 549         2886 return bless($param, __PACKAGE__);
39             }
40              
41             sub read {
42             # Mbox reader, works as a iterator.
43             # @return [String] Contents of mbox
44 1317     1317 1 10225392 my $self = shift;
45              
46 1317   50     3904 my $seekoffset = $self->{'offset'} // 0;
47 1317         1903 my $filehandle = $self->{'handle'};
48 1317         1684 my $readbuffer = '';
49              
50 1317 50       2739 return undef unless defined $self->{'path'};
51 1317 50       2717 unless( ref $self->{'path'} ) {
52             # "path" is not IO::File object
53 1317 50       23576 return undef unless -f $self->{'path'};
54 1317 50       71312 return undef unless -T $self->{'path'};
55             }
56 1317 100       6924 return undef unless $self->{'offset'} < $self->{'size'};
57              
58 769         1239 eval {
59 769 50       1647 $seekoffset = 0 if $seekoffset < 0;
60 769         5806 seek($filehandle, $seekoffset, 0);
61              
62 769         10375 while( my $r = <$filehandle> ) {
63             # Read the UNIX mbox file from 'From ' to the next 'From '
64 68465 100 100     129479 last if( $readbuffer && substr($r, 0, 5) eq 'From ' );
65 68244         103556 $readbuffer .= $r;
66             }
67 769         1654 $seekoffset += length $readbuffer;
68 769         1311 $self->{'offset'} = $seekoffset;
69 769 100       4358 $filehandle->close unless $seekoffset < $self->{'size'};
70             };
71 769         12219 return $readbuffer;
72             }
73              
74             1;
75             __END__