File Coverage

blib/lib/DBM/Deep/Sector/File/Scalar.pm
Criterion Covered Total %
statement 71 73 97.2
branch 12 14 85.7
condition n/a
subroutine 11 11 100.0
pod 0 4 0.0
total 94 102 92.1


line stmt bran cond sub pod time code
1             package DBM::Deep::Sector::File::Scalar;
2              
3 50     50   935 use 5.008_004;
  50         197  
4              
5 50     50   300 use strict;
  50         101  
  50         1323  
6 50     50   269 use warnings FATAL => 'all';
  50         100  
  50         1859  
7 50     50   315 no warnings 'recursion';
  50         122  
  50         2001  
8              
9 50     50   342 use base qw( DBM::Deep::Sector::File::Data );
  50         114  
  50         13241  
10              
11             my $STALE_SIZE = 2;
12              
13             # Please refer to the pack() documentation for further information
14             my %StP = (
15             1 => 'C', # Unsigned char value (no order needed as it's just one byte)
16             2 => 'n', # Unsigned short in "network" (big-endian) order
17             4 => 'N', # Unsigned long in "network" (big-endian) order
18             8 => 'Q', # Usigned quad (no order specified, presumably machine-dependent)
19             );
20              
21             sub free {
22 382     382 0 682 my $self = shift;
23              
24 382         812 my $chain_loc = $self->chain_loc;
25              
26 382         1799 $self->SUPER::free();
27              
28 382 50       927 if ( $chain_loc ) {
29 0         0 $self->engine->load_sector( $chain_loc )->free;
30             }
31              
32 382         936 return;
33             }
34              
35             sub _init {
36 6346     6346   10069 my $self = shift;
37              
38 6346         12564 my $engine = $self->engine;
39              
40 6346 100       13224 unless ( $self->offset ) {
41 2179         6019 my $data_section = $self->size - $self->base_size - $engine->byte_size - 1;
42              
43 2179         5274 $self->{offset} = $engine->_request_data_sector( $self->size );
44              
45 2179         5746 my $data = delete $self->{data};
46 50     50   399 my $utf8 = do { no warnings 'utf8'; $data !~ /^[\0-\xff]*\z/ };
  50         116  
  50         29492  
  2179         3656  
  2179         12717  
47 2179 100       5263 if($utf8){
48 7 50       56 if($engine->{v} < 4) {
49 0         0 DBM::Deep->_throw_error(
50             "This database format version is too old for Unicode"
51             );
52             }
53 7         24 utf8::encode $data;
54 7         23 $self->{type} = $engine->SIG_UNIDATA;
55             }
56 2172         6632 else { $self->{type} = $engine->SIG_DATA; }
57              
58 2179         3557 my $dlen = length $data;
59 2179         3305 my $continue = 1;
60 2179         5780 my $curr_offset = $self->offset;
61 2179         5131 while ( $continue ) {
62              
63 4695         6910 my $next_offset = 0;
64              
65 4695         7461 my ($leftover, $this_len, $chunk);
66 4695 100       8936 if ( $dlen > $data_section ) {
67 2516         3294 $leftover = 0;
68 2516         3255 $this_len = $data_section;
69 2516         4943 $chunk = substr( $data, 0, $this_len );
70              
71 2516         3541 $dlen -= $data_section;
72 2516         6391 $next_offset = $engine->_request_data_sector( $self->size );
73 2516         18645 $data = substr( $data, $this_len );
74             }
75             else {
76 2179         3255 $leftover = $data_section - $dlen;
77 2179         3111 $this_len = $dlen;
78 2179         3357 $chunk = $data;
79              
80 2179         3289 $continue = 0;
81             }
82              
83 4695         13720 $engine->storage->print_at( $curr_offset, $self->type ); # Sector type
84             # Skip staleness
85             $engine->storage->print_at( $curr_offset + $self->base_size,
86             pack( $StP{$engine->byte_size}, $next_offset ), # Chain loc
87 4695         14522 pack( $StP{1}, $this_len ), # Data length
88             $chunk, # Data to be stored in this sector
89             chr(0) x $leftover, # Zero-fill the rest
90             );
91              
92 4695         15216 $curr_offset = $next_offset;
93             }
94              
95 2179         5880 return;
96             }
97             }
98              
99             sub data_length {
100 3733     3733 0 5842 my $self = shift;
101              
102 3733         7251 my $buffer = $self->engine->storage->read_at(
103             $self->offset + $self->base_size + $self->engine->byte_size, 1
104             );
105              
106 3733         16762 return unpack( $StP{1}, $buffer );
107             }
108              
109             sub chain_loc {
110 4115     4115 0 6209 my $self = shift;
111             return unpack(
112 4115         8050 $StP{$self->engine->byte_size},
113             $self->engine->storage->read_at(
114             $self->offset + $self->base_size,
115             $self->engine->byte_size,
116             ),
117             );
118             }
119              
120             sub data {
121 1200     1200 0 1955 my $self = shift;
122 1200         2343 my $engine = $self->engine;
123              
124 1200         1920 my $data;
125 1200         2031 while ( 1 ) {
126 3733         7501 my $chain_loc = $self->chain_loc;
127              
128 3733         12901 $data .= $engine->storage->read_at(
129             $self->offset + $self->base_size + $engine->byte_size + 1, $self->data_length,
130             );
131              
132 3733 100       11530 last unless $chain_loc;
133              
134 2533         6845 $self = $engine->load_sector( $chain_loc );
135             }
136              
137 1200 100       3483 utf8::decode $data if $self->type eq $engine->SIG_UNIDATA;
138              
139 1200         5751 return $data;
140             }
141              
142             1;
143             __END__