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   71108 use feature ':5.10';
  79         164  
  79         6058  
3 79     79   475 use strict;
  79         240  
  79         1683  
4 79     79   360 use warnings;
  79         163  
  79         2548  
5 79     79   498 use File::Basename qw(basename dirname);
  79         182  
  79         7227  
6 79     79   39058 use IO::File;
  79         675178  
  79         11729  
7             use Class::Accessor::Lite (
8 79         771 '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   1149 );
  79         1477  
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 3004 my $class = shift;
27 559   50     1542 my $argv1 = shift // return undef;
28 559         1513 my $param = { 'offset' => 0 };
29 559 50       7036 return undef unless -f $argv1;
30              
31 559         28925 $param->{'dir'} = File::Basename::dirname $argv1;
32 559         1714 $param->{'path'} = $argv1;
33 559         7445 $param->{'size'} = -s $argv1;
34 559         18510 $param->{'file'} = File::Basename::basename $argv1;
35 559 50       4784 $param->{'handle'} = ref $argv1 ? $argv1 : IO::File->new($argv1, 'r');
36 559         64692 binmode $param->{'handle'};
37              
38 559         3343 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 12429291 my $self = shift;
45              
46 1337   50     4862 my $seekoffset = $self->{'offset'} // 0;
47 1337         2065 my $filehandle = $self->{'handle'};
48 1337         1939 my $readbuffer = '';
49              
50 1337 50       3064 return undef unless defined $self->{'path'};
51 1337 50       3014 unless( ref $self->{'path'} ) {
52             # "path" is not IO::File object
53 1337 50       24085 return undef unless -f $self->{'path'};
54 1337 50       82462 return undef unless -T $self->{'path'};
55             }
56 1337 100       7860 return undef unless $self->{'offset'} < $self->{'size'};
57              
58 779         1400 eval {
59 779 50       1805 $seekoffset = 0 if $seekoffset < 0;
60 779         6700 seek($filehandle, $seekoffset, 0);
61              
62 779         12411 while( my $r = <$filehandle> ) {
63             # Read the UNIX mbox file from 'From ' to the next 'From '
64 69281 100 100     157482 last if( $readbuffer && substr($r, 0, 5) eq 'From ' );
65 69060         126099 $readbuffer .= $r;
66             }
67 779         1889 $seekoffset += length $readbuffer;
68 779         1567 $self->{'offset'} = $seekoffset;
69 779 100       4512 $filehandle->close unless $seekoffset < $self->{'size'};
70             };
71 779         14001 return $readbuffer;
72             }
73              
74             1;
75             __END__