Got some basic functionality working. Still isn't fully functional (only the specifie...
[dbsrgits/DBM-Deep.git] / lib / DBM / Deep / Sector / File / Scalar.pm
CommitLineData
2c70efe1 1package DBM::Deep::Sector::File::Scalar;
f0276afb 2
3use 5.006_000;
4
5use strict;
6use warnings FATAL => 'all';
7
2c70efe1 8use base qw( DBM::Deep::Sector::File::Data );
f0276afb 9
5ae752e2 10my $STALE_SIZE = 2;
11
12# Please refer to the pack() documentation for further information
13my %StP = (
14 1 => 'C', # Unsigned char value (no order needed as it's just one byte)
15 2 => 'n', # Unsigned short in "network" (big-endian) order
16 4 => 'N', # Unsigned long in "network" (big-endian) order
17 8 => 'Q', # Usigned quad (no order specified, presumably machine-dependent)
18);
19
f0276afb 20sub free {
21 my $self = shift;
22
23 my $chain_loc = $self->chain_loc;
24
25 $self->SUPER::free();
26
27 if ( $chain_loc ) {
d6ecf579 28 $self->engine->load_sector( $chain_loc )->free;
f0276afb 29 }
30
31 return;
32}
33
a4d36ff6 34sub clone {
35 my $self = shift;
36 return ref($self)->new({
37 engine => $self->engine,
38 type => $self->type,
39 data => $self->data,
40 });
41}
42
f0276afb 43sub type { $_[0]{engine}->SIG_DATA }
44sub _init {
45 my $self = shift;
46
47 my $engine = $self->engine;
48
49 unless ( $self->offset ) {
50 my $data_section = $self->size - $self->base_size - $engine->byte_size - 1;
51
52 $self->{offset} = $engine->_request_data_sector( $self->size );
53
54 my $data = delete $self->{data};
55 my $dlen = length $data;
56 my $continue = 1;
57 my $curr_offset = $self->offset;
58 while ( $continue ) {
59
60 my $next_offset = 0;
61
62 my ($leftover, $this_len, $chunk);
63 if ( $dlen > $data_section ) {
64 $leftover = 0;
65 $this_len = $data_section;
66 $chunk = substr( $data, 0, $this_len );
67
68 $dlen -= $data_section;
69 $next_offset = $engine->_request_data_sector( $self->size );
70 $data = substr( $data, $this_len );
71 }
72 else {
73 $leftover = $data_section - $dlen;
74 $this_len = $dlen;
75 $chunk = $data;
76
77 $continue = 0;
78 }
79
80 $engine->storage->print_at( $curr_offset, $self->type ); # Sector type
81 # Skip staleness
82 $engine->storage->print_at( $curr_offset + $self->base_size,
83 pack( $StP{$engine->byte_size}, $next_offset ), # Chain loc
84 pack( $StP{1}, $this_len ), # Data length
85 $chunk, # Data to be stored in this sector
86 chr(0) x $leftover, # Zero-fill the rest
87 );
88
89 $curr_offset = $next_offset;
90 }
91
92 return;
93 }
94}
95
96sub data_length {
97 my $self = shift;
98
99 my $buffer = $self->engine->storage->read_at(
100 $self->offset + $self->base_size + $self->engine->byte_size, 1
101 );
102
103 return unpack( $StP{1}, $buffer );
104}
105
106sub chain_loc {
107 my $self = shift;
108 return unpack(
109 $StP{$self->engine->byte_size},
110 $self->engine->storage->read_at(
111 $self->offset + $self->base_size,
112 $self->engine->byte_size,
113 ),
114 );
115}
116
117sub data {
118 my $self = shift;
f0276afb 119
120 my $data;
121 while ( 1 ) {
122 my $chain_loc = $self->chain_loc;
123
124 $data .= $self->engine->storage->read_at(
125 $self->offset + $self->base_size + $self->engine->byte_size + 1, $self->data_length,
126 );
127
128 last unless $chain_loc;
129
d6ecf579 130 $self = $self->engine->load_sector( $chain_loc );
f0276afb 131 }
132
133 return $data;
134}
135
1361;
137__END__