File Coverage

blib/lib/EBook/Ishmael/EBook/PalmDoc.pm
Criterion Covered Total %
statement 83 99 83.8
branch 14 28 50.0
condition 4 8 50.0
subroutine 19 19 100.0
pod 0 9 0.0
total 120 163 73.6


line stmt bran cond sub pod time code
1             package EBook::Ishmael::EBook::PalmDoc;
2 17     17   317 use 5.016;
  17         65  
3             our $VERSION = '2.03';
4 17     17   91 use strict;
  17         34  
  17         483  
5 17     17   79 use warnings;
  17         47  
  17         1106  
6              
7 17     17   109 use Encode qw(decode);
  17         32  
  17         1137  
8              
9 17     17   10782 use EBook::Ishmael::CharDet;
  17         69  
  17         1609  
10 17     17   145 use EBook::Ishmael::Decode qw(palmdoc_decode);
  17         38  
  17         934  
11 17     17   113 use EBook::Ishmael::EBook::Metadata;
  17         34  
  17         438  
12 17     17   76 use EBook::Ishmael::PDB;
  17         33  
  17         396  
13 17     17   8712 use EBook::Ishmael::TextToHtml;
  17         58  
  17         20462  
14              
15             my $TYPE = 'TEXt';
16             my $CREATOR = 'REAd';
17              
18             my $RECSIZE = 4096;
19              
20             sub heuristic {
21              
22 59     59 0 139 my $class = shift;
23 59         155 my $file = shift;
24 59         127 my $fh = shift;
25              
26 59 50       901 return 0 unless -s $file >= 68;
27              
28 59         381 seek $fh, 32, 0;
29 59         470 read $fh, my ($null), 1;
30              
31             # Last byte in title must be null
32 59 100       225 unless ($null eq "\0") {
33 35         155 return 0;
34             }
35              
36 24         188 seek $fh, 60, 0;
37 24         137 read $fh, my ($type), 4;
38 24         67 read $fh, my ($creator), 4;
39              
40 24   66     216 return $type eq $TYPE && $creator eq $CREATOR;
41              
42             }
43              
44             sub _decode_record {
45              
46 63     63   18320 my $self = shift;
47 63         107 my $rec = shift;
48              
49 63         90 $rec++;
50              
51 63         182 my $encode = $self->{_pdb}->record($rec)->data;
52              
53 63 50       278 if ($self->{_compression} == 1) {
    50          
54 0         0 return $encode;
55             } elsif ($self->{_compression} == 2) {
56 63         171 return palmdoc_decode($encode);
57             }
58              
59             }
60              
61             sub new {
62              
63 11     11 0 52 my $class = shift;
64 11         24 my $file = shift;
65 11         23 my $enc = shift;
66              
67 11         111 my $self = {
68             Source => undef,
69             Metadata => EBook::Ishmael::EBook::Metadata->new,
70             Encoding => $enc,
71             _pdb => undef,
72             _compression => undef,
73             _textlen => undef,
74             _recnum => undef,
75             _recsize => undef,
76             _curpos => undef,
77             };
78              
79 11         24 bless $self, $class;
80              
81 11         443 $self->{Source} = File::Spec->rel2abs($file);
82              
83 11         87 $self->{_pdb} = EBook::Ishmael::PDB->new($file);
84              
85 11         56 my $hdr = $self->{_pdb}->record(0)->data;
86              
87             (
88             $self->{_compression},
89             undef,
90             $self->{_textlen},
91             $self->{_recnum},
92             $self->{_recsize},
93             $self->{_curpos},
94 11         72 ) = unpack "n n N n n N", $hdr;
95              
96 11 50 33     83 if ($self->{_compression} != 1 and $self->{_compression} != 2) {
97 0         0 die "$self->{Source} is not a PalmDoc file\n";
98             }
99              
100 11 50       33 if ($self->{_recsize} != 4096) {
101 0         0 die "$self->{Source} is not a PalmDoc file\n";
102             }
103              
104 11         62 $self->{Metadata}->set_title($self->{_pdb}->name);
105              
106 11 50       43 if ($self->{_pdb}->cdate) {
107 11         33 $self->{Metadata}->set_created($self->{_pdb}->cdate);
108             }
109 11 50       38 if ($self->{_pdb}->mdate) {
110 11         34 $self->{Metadata}->set_modified($self->{_pdb}->mdate);
111             }
112              
113 11 50       34 if ($self->{_pdb}->version) {
114             $self->{Metadata}->set_format(
115             sprintf(
116             "PalmDOC %s.%s",
117             ($self->{_pdb}->version >> 8) & 0xff,
118 0         0 $self->{_pdb}->version & 0xff
119             )
120             );
121             } else {
122 11         39 $self->{Metadata}->set_format('PalmDOC');
123             }
124              
125 11         46 return $self;
126              
127             }
128              
129             sub html {
130              
131 3     3 0 12 my $self = shift;
132 3         8 my $out = shift;
133              
134 3         45 my $html = text2html($self->raw);
135              
136 3 50       20 if (defined $out) {
137 0 0       0 open my $fh, '>', $out
138             or die "Failed to open $out for writing: $!\n";
139 0         0 binmode $fh, ':utf8';
140 0         0 print { $fh } $html;
  0         0  
141 0         0 close $fh;
142 0         0 return $out;
143             } else {
144 3         38 return $html;
145             }
146              
147             }
148              
149             sub raw {
150              
151 6     6 0 17 my $self = shift;
152 6         13 my $out = shift;
153              
154             my $raw = join '',
155 54         163 map { $self->_decode_record($_) }
156 6         36 (0 .. $self->{_recnum} - 1);
157 6 100       77 if (not defined $self->{Encoding}) {
158 5   50     33 $self->{Encoding} = chardet($raw) // 'ASCII';
159             }
160              
161 6         84 $raw = decode($self->{Encoding}, $raw);
162              
163 6 50       1549 if (defined $out) {
164 0 0       0 open my $fh, '>', $out
165             or die "Failed to open $out for writing: $!\n";
166 0         0 binmode $fh, ':utf8';
167 0         0 print { $fh } $raw;
  0         0  
168 0         0 close $fh;
169 0         0 return $out;
170             } else {
171 6         45 return $raw;
172             }
173              
174             }
175              
176             sub metadata {
177              
178 4     4 0 12 my $self = shift;
179              
180 4         28 return $self->{Metadata};
181              
182             }
183              
184 2     2 0 7 sub has_cover { 0 }
185              
186 1     1 0 4 sub cover { (undef, undef) }
187              
188 2     2 0 7 sub image_num { 0 }
189              
190 1     1 0 5 sub image { (undef, undef) }
191              
192             1;