| 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__ |