d86c7a5f749896f1b9ffee38fe0b6f69a39af0b9
[dbsrgits/DBM-Deep.git] / lib / DBM / Deep / Engine / Sector.pm
1 package DBM::Deep::Engine::Sector;
2
3 use 5.006_000;
4
5 use strict;
6 use warnings FATAL => 'all';
7
8 use Scalar::Util ();
9
10 sub new {
11     my $self = bless $_[1], $_[0];
12     Scalar::Util::weaken( $self->{engine} );
13
14     $self->_init;
15
16     return $self;
17 }
18
19 #sub _init {}
20 #sub clone { DBM::Deep->_throw_error( "Must be implemented in the child class" ); }
21
22 sub engine { $_[0]{engine} }
23 sub offset { $_[0]{offset} }
24 sub type   { $_[0]{type}   }
25
26 sub base_size {
27     my $self = shift;
28     if ( ref($self) ) {
29         return $self->engine->SIG_SIZE + $DBM::Deep::Engine::STALE_SIZE;
30     }
31     else {
32         return $_[0]->SIG_SIZE + $DBM::Deep::Engine::STALE_SIZE;
33     }
34 }
35
36 sub free {
37     my $self = shift;
38
39     my $e = $self->engine;
40
41     $self->write( 0, $e->SIG_FREE );
42     $self->write( $self->base_size, chr(0) x ($self->size - $self->base_size) );
43
44     my $free_meth = $self->free_meth;
45     $e->$free_meth( $self );
46
47     return;
48 }
49
50 sub read {
51     my $self = shift;
52
53     if ( @_ == 1 ) {
54         die "read(): Start ($_[0]) is too large" if $_[0] > $self->size;
55         return substr( ${$self->engine->get_data( $self->offset, $self->size )}, $_[0] );
56     }
57     elsif ( @_ == 2 ) {
58         die "read(): Start ($_[0]) is too large" if $_[0] > $self->size;
59         die "read(): Length ($_[1]) is too large" if $_[1] > $self->size;
60         return substr( ${$self->engine->get_data( $self->offset, $self->size )}, $_[0], $_[1] );
61     }
62     elsif ( @_ < 1 ) {
63         die "read( start [, length ]): No parameters found.";
64     }
65     else {
66         die "read( start [, length ]): Too many parameters found (@_).";
67     }
68 }
69
70 sub write {
71     my $self = shift;
72     my ($start, $text) = @_;
73
74     die "write(): Start ($start) is too large" if $start > $self->size;
75     die "write(): length(\$text) (@{[length($text)]}) is too large" if length($text) > $self->size;
76     substr( ${$self->engine->get_data( $self->offset, $self->size )}, $start, length($text) ) = $text;
77
78     $self->mark_dirty;
79 }
80
81 sub mark_dirty {
82     my $self = shift;
83     $self->engine->add_dirty_sector( $self->offset );
84 }
85
86 1;
87 __END__