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.006'; # VERSION
4             # ABSTRACT: Reference a path and optional range of bytes and load it on demand
5              
6 12     12   131 use v5.26;
  12         34  
7 12     12   51 use warnings;
  12         19  
  12         633  
8 12     12   51 use experimental qw( signatures );
  12         16  
  12         79  
9 12     12   1518 use Carp;
  12         16  
  12         986  
10 12     12   61 use overload q{""} => \&as_string, q{${}} => \&as_scalarref;
  12         38  
  12         121  
11 12     12   814 use Cwd ();
  12         14  
  12         141  
12 12     12   44 use Sys::Export ();
  12         30  
  12         6483  
13              
14              
15 32     32 1 44 sub new($class, $src, $offset=0, $size=undef) {
  32         40  
  32         32  
  32         34  
  32         39  
  32         30  
16 32         36 my ($abs, $actual_size);
17 32 100       100 if (ref $src eq 'SCALAR') {
18             # Ensure is only bytes
19 3 50 33     15 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     26 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 29   33     759 $abs= Cwd::abs_path($src) // croak "Can't resolve '$src' to a real file";
27 29         214 $actual_size= -s $abs;
28             }
29 31   66     140 $size //= $actual_size - $offset;
30 31 50       82 croak "Requested size ($src, $offset+$size) exceeds actual size ($actual_size)"
31             if $offset+$size > $actual_size;
32 31         180 return bless [ undef, $src, $offset, $size, $abs ], $class;
33             }
34              
35              
36 0     0 1 0 sub source { $_[0][1] }
37 6     6 1 7099 sub offset { $_[0][2] }
38 7     7 1 2322 sub size { $_[0][3] }
39 2     2 1 8 sub abs_path { $_[0][4] }
40              
41             sub as_scalarref {
42 43 50 66 43 1 208 $_[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__