File Coverage

blib/lib/Sys/Export/LazyFileData.pm
Criterion Covered Total %
statement 40 44 90.9
branch 6 10 60.0
condition 9 21 42.8
subroutine 12 14 85.7
pod 7 7 100.0
total 74 96 77.0


line stmt bran cond sub pod time code
1             package Sys::Export::LazyFileData;
2              
3             our $VERSION = '0.005_002'; # TRIAL VERSION
4             # ABSTRACT: Reference a path and optional range of bytes and load it on demand
5              
6 12     12   154 use v5.26;
  12         39  
7 12     12   48 use warnings;
  12         19  
  12         613  
8 12     12   45 use experimental qw( signatures );
  12         52  
  12         124  
9 12     12   1679 use Carp;
  12         17  
  12         991  
10 12     12   61 use overload q{""} => \&as_string, q{${}} => \&as_scalarref;
  12         17  
  12         136  
11 12     12   844 use Cwd ();
  12         24  
  12         187  
12 12     12   36 use Sys::Export ();
  12         20  
  12         5904  
13              
14              
15 27     27 1 46 sub new($class, $src, $offset=0, $size=undef) {
  27         31  
  27         55  
  27         32  
  27         45  
  27         29  
16 27         39 my ($abs, $actual_size);
17 27 100       54 if (ref $src eq 'SCALAR') {
18             # Ensure is only bytes
19 3 50 33     11 croak "Wide character in file data scalar ref"
20             if utf8::is_utf8($src) && !utf8::downgrade($src, 1);
21             # If given a scalar-ref, and size and offset are the defaults, then we can just cache that directly.
22 3 50 33     19 return bless [ $src, $src, 0, length $$src ], $class
      66        
23             if !$offset && (!$size || $size == length $$src);
24 2         3 $actual_size= length $$src;
25             } else {
26 24   33     682 $abs= Cwd::abs_path($src) // croak "Can't resolve '$src' to a real file";
27 24         185 $actual_size= -s $abs;
28             }
29 26   66     105 $size //= $actual_size - $offset;
30 26 50       52 croak "Requested size ($src, $offset+$size) exceeds actual size ($actual_size)"
31             if $offset+$size > $actual_size;
32 26         129 return bless [ undef, $src, $offset, $size, $abs ], $class;
33             }
34              
35              
36 0     0 1 0 sub source { $_[0][1] }
37 6     6 1 6629 sub offset { $_[0][2] }
38 7     7 1 2136 sub size { $_[0][3] }
39 2     2 1 9 sub abs_path { $_[0][4] }
40              
41             sub as_scalarref {
42 35 50 66 35 1 181 $_[0][0] //= ref $_[0][1] eq 'SCALAR'? \substr(${$_[0][1]}, $_[0][2], $_[0][3])
  0            
43             : Sys::Export::map_or_load_file($_[0][1], $_[0][2], $_[0][3]);
44             }
45              
46             sub as_string {
47 0   0 0 1   ${ $_[0][0] // $_[0]->as_scalarref }
  0            
48             }
49              
50             # Avoiding dependency on namespace::clean
51             delete @{Sys::Export::LazyFileData::}{qw( carp croak confess )};
52             1;
53              
54             __END__