File Coverage

blib/lib/Mail/Box/Dir/Message.pm
Criterion Covered Total %
statement 77 89 86.5
branch 21 38 55.2
condition 6 11 54.5
subroutine 15 16 93.7
pod 9 10 90.0
total 128 164 78.0


line stmt bran cond sub pod time code
1             # This code is part of Perl distribution Mail-Box version 4.01.
2             # The POD got stripped from this file by OODoc version 3.05.
3             # For contributors see file ChangeLog.
4              
5             # This software is copyright (c) 2001-2025 by Mark Overmeer.
6              
7             # This is free software; you can redistribute it and/or modify it under
8             # the same terms as the Perl 5 programming language system itself.
9             # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later
10              
11              
12             package Mail::Box::Dir::Message;{
13             our $VERSION = '4.01';
14             }
15              
16 14     14   2096 use parent 'Mail::Box::Message';
  14         96  
  14         122  
17              
18 14     14   1312 use strict;
  14         34  
  14         510  
19 14     14   76 use warnings;
  14         32  
  14         978  
20              
21 14     14   84 use Log::Report 'mail-box', import => [ qw/__x error fault trace/ ];
  14         25  
  14         141  
22              
23 14     14   2915 use File::Copy qw/move/;
  14         34  
  14         6018  
24              
25             #--------------------
26              
27             sub init($)
28 737     737 0 7932 { my ($self, $args) = @_;
29 737         3288 $self->SUPER::init($args);
30              
31 737 50       3092 $self->filename($args->{filename}) if $args->{filename};
32 737         1586 $self->{MBDM_fix_header} = $args->{fix_header};
33 737         2162 $self;
34             }
35              
36             #--------------------
37              
38             sub filename(;$)
39 4095     4095 1 9760 { my $self = shift;
40 4095 100       13623 @_ ? ($self->{MBDM_filename} = shift) : $self->{MBDM_filename};
41             }
42              
43              
44 289     289 1 2711 sub fixHeader() { $_[0]->{MBDM_fix_header} }
45              
46             #--------------------
47              
48             sub print(;$)
49 226     226 1 455 { my $self = shift;
50 226   33     514 my $out = shift || select;
51              
52 226 100       843 return $self->SUPER::print($out)
53             if $self->isModified;
54              
55 181         561 my $filename = $self->filename;
56 181 50 33     3816 if($filename && -r $filename)
57 181 50       5172 { if(open my $in, '<:raw', $filename)
58 181         327 { local $_;
59 181         13371 print $out $_ while <$in>;
60 181         1707 close $in;
61 181         1010 return $self;
62             }
63             }
64              
65 0         0 $self->SUPER::print($out);
66 0         0 1;
67             }
68              
69 14     14   11571 BEGIN { *write = \&print } # simply alias
70              
71             #--------------------
72              
73             # Asking the filesystem for the size is faster counting (in
74             # many situations. It even may be lazy.
75              
76             sub size()
77 0     0 1 0 { my $self = shift;
78              
79 0 0       0 unless($self->isModified)
80 0         0 { my $filename = $self->filename;
81 0 0       0 if(defined $filename)
82 0         0 { my $size = -s $filename;
83 0 0       0 return $size if defined $size;
84             }
85             }
86              
87 0         0 $self->SUPER::size;
88             }
89              
90             sub diskDelete()
91 24     24 1 48 { my $self = shift;
92 24         174 $self->SUPER::diskDelete;
93              
94 24         79 my $filename = $self->filename;
95 24 50       4612 unlink $filename if $filename;
96 24         161 $self;
97             }
98              
99              
100             sub parser()
101 289     289 1 520 { my $self = shift;
102              
103 289         919 Mail::Box::Parser->new(
104             filename => $self->filename,
105             mode => 'r',
106             fix_header_errors => $self->fixHeader,
107             );
108             }
109              
110              
111             sub loadHead()
112 408     408 1 3760 { my $self = shift;
113 408         1411 my $head = $self->head;
114 408 100       3428 $head->isDelayed or return $head;
115              
116 281         1002 my $folder = $self->folder;
117 281         1161 $folder->lazyPermitted(1);
118              
119 281 50       914 my $parser = $self->parser or return;
120 281         108676 $self->readFromParser($parser);
121 281         5233 $parser->stop;
122              
123 281         37997 $folder->lazyPermitted(0);
124              
125 281         1046 trace "Loaded delayed head.";
126 281         8802 $self->head;
127             }
128              
129              
130             sub loadBody()
131 150     150 1 305 { my $self = shift;
132              
133 150         553 my $body = $self->body;
134 150 100       1673 $body->isDelayed or return $body;
135              
136 8         42 my $parser = $self->parser;
137 8         4526 my $msgid = $self->messageId;
138              
139 8         338 my $head = $self->head;
140 8 50       83 if($head->isDelayed)
141 0 0       0 { $head = $self->readHead($parser)
142             or error __x"unable to read delayed head for message {msgid}.", msgid => $msgid;
143              
144 0         0 trace "Loaded delayed head for $msgid.";
145 0         0 $self->head($head);
146             }
147             else
148 8         47 { my ($begin, $end) = $body->fileLocation;
149 8         46 $parser->filePosition($begin);
150             }
151              
152 8 50       222 my $newbody = $self->readBody($parser, $head)
153             or error __x"unable to read delayed body for message {msgid}.", msgid => $msgid;
154              
155 8         11257 $parser->stop;
156 8         816 trace "Loaded delayed body for $msgid";
157 8         253 $self->storeBody($newbody->contentInfoFrom($head));
158             }
159              
160              
161             sub create($)
162 316     316 1 673 { my ($self, $filename) = @_;
163              
164 316   100     665 my $old = $self->filename || '';
165 316 100 66     1370 return $self if $filename eq $old && !$self->isModified;
166              
167             # Write the new data to a new file.
168              
169 225         370 my $new = $filename . '.new';
170 225 50       40770 open my $newfh, '>:raw', $new
171             or fault __x"cannot write message to {file}", file => $new;
172              
173 225         1480 $self->write($newfh);
174 225         15263 $newfh->close;
175              
176 225 100       29511 unlink $old if $old;
177              
178 225 50       1204 move $new, $filename
179             or error __x"failed to rename file {from} to {to}", from => $new, to => $filename;
180              
181 225         34352 $self->modified(0);
182              
183             # Do not affect flags for Maildir (and some other) which keep it
184             # in there. Flags will be processed later.
185 225         3520 $self->Mail::Box::Dir::Message::filename($filename);
186 225         1523 $self;
187             }
188              
189             1;