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 79     79   71731 use feature ':5.10';
  79         155  
  79         6014  
3 79     79   461 use strict;
  79         142  
  79         1521  
4 79     79   349 use warnings;
  79         145  
  79         2267  
5 79     79   443 use File::Basename qw(basename dirname);
  79         167  
  79         7095  
6 79     79   36558 use IO::File;
  79         640400  
  79         11432  
7             use Class::Accessor::Lite (
8 79         750 '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 79     79   1093 );
  79         1409  
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 559     559 1 3209 my $class = shift;
27 559   50     1670 my $argv1 = shift // return undef;
28 559         1554 my $param = { 'offset' => 0 };
29 559 50       7282 return undef unless -f $argv1;
30              
31 559         31331 $param->{'dir'} = File::Basename::dirname $argv1;
32 559         1664 $param->{'path'} = $argv1;
33 559         7531 $param->{'size'} = -s $argv1;
34 559         18071 $param->{'file'} = File::Basename::basename $argv1;
35 559 50       5259 $param->{'handle'} = ref $argv1 ? $argv1 : IO::File->new($argv1, 'r');
36 559         64227 binmode $param->{'handle'};
37              
38 559         3418 return bless($param, __PACKAGE__);
39             }
40              
41             sub read {
42             # Mbox reader, works as a iterator.
43             # @return [String] Contents of mbox
44 1337     1337 1 11438237 my $self = shift;
45              
46 1337   50     4425 my $seekoffset = $self->{'offset'} // 0;
47 1337         2118 my $filehandle = $self->{'handle'};
48 1337         2023 my $readbuffer = '';
49              
50 1337 50       3552 return undef unless defined $self->{'path'};
51 1337 50       3128 unless( ref $self->{'path'} ) {
52             # "path" is not IO::File object
53 1337 50       25411 return undef unless -f $self->{'path'};
54 1337 50       79177 return undef unless -T $self->{'path'};
55             }
56 1337 100       8165 return undef unless $self->{'offset'} < $self->{'size'};
57              
58 779         1513 eval {
59 779 50       2068 $seekoffset = 0 if $seekoffset < 0;
60 779         6557 seek($filehandle, $seekoffset, 0);
61              
62 779         11810 while( my $r = <$filehandle> ) {
63             # Read the UNIX mbox file from 'From ' to the next 'From '
64 69281 100 100     152220 last if( $readbuffer && substr($r, 0, 5) eq 'From ' );
65 69060         123650 $readbuffer .= $r;
66             }
67 779         1865 $seekoffset += length $readbuffer;
68 779         1570 $self->{'offset'} = $seekoffset;
69 779 100       4774 $filehandle->close unless $seekoffset < $self->{'size'};
70             };
71 779         13668 return $readbuffer;
72             }
73              
74             1;
75             __END__