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'; # VERSION
4             # ABSTRACT: Reference a path and optional range of bytes and load it on demand
5              
6 11     11   139 use v5.26;
  11         33  
7 11     11   47 use warnings;
  11         19  
  11         645  
8 11     11   49 use experimental qw( signatures );
  11         16  
  11         113  
9 11     11   1546 use Carp;
  11         16  
  11         1008  
10 11     11   61 use overload q{""} => \&as_string, q{${}} => \&as_scalarref;
  11         16  
  11         102  
11 11     11   766 use Cwd ();
  11         16  
  11         176  
12 11     11   39 use Sys::Export ();
  11         37  
  11         6183  
13              
14              
15 13     13 1 23 sub new($class, $src, $offset=0, $size=undef) {
  13         21  
  13         15  
  13         16  
  13         16  
  13         14  
16 13         19 my ($abs, $actual_size);
17 13 100       33 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     15 return bless [ $src, $src, 0, length $$src ], $class
      66        
23             if !$offset && (!$size || $size == length $$src);
24 2         4 $actual_size= length $$src;
25             } else {
26 10   33     285 $abs= Cwd::abs_path($src) // croak "Can't resolve '$src' to a real file";
27 10         128 $actual_size= -s $abs;
28             }
29 12   66     60 $size //= $actual_size - $offset;
30 12 50       57 croak "Requested size ($src, $offset+$size) exceeds actual size ($actual_size)"
31             if $offset+$size > $actual_size;
32 12         126 return bless [ undef, $src, $offset, $size, $abs ], $class;
33             }
34              
35              
36 0     0 1 0 sub source { $_[0][1] }
37 6     6 1 6653 sub offset { $_[0][2] }
38 7     7 1 2289 sub size { $_[0][3] }
39 2     2 1 10 sub abs_path { $_[0][4] }
40              
41             sub as_scalarref {
42 21 50 66 21 1 150 $_[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__