1 package DBM::Deep::Array;
12 eval { tied( @{$_[0]} ) } || $_[0]
17 # Tied array constructor method, called by Perl's tie() function.
23 $class->_throw_error( "Odd number of parameters to TIEARRAY" );
27 elsif ( my $type = Scalar::Util::reftype($_[0]) ) {
28 if ( $type ne 'HASH' ) {
29 $class->_throw_error( "Not a hashref in TIEARRAY" );
34 $args = { file => shift };
37 $args->{type} = $class->TYPE_ARRAY;
39 return $class->_init($args);
43 # The following methods are for arrays only
47 my $self = $_[0]->_get_self;
50 if ( $key =~ /^-?\d+$/ ) {
52 $key += $self->FETCHSIZE;
53 return unless $key >= 0;
56 $key = pack($DBM::Deep::LONG_PACK, $key);
59 return $self->SUPER::FETCH( $key );
64 # Return the length of the array
66 my $self = $_[0]->_get_self;
68 my $SAVE_FILTER = $self->root->{filter_fetch_value};
69 $self->root->{filter_fetch_value} = undef;
71 my $packed_size = $self->FETCH('length');
73 $self->root->{filter_fetch_value} = $SAVE_FILTER;
76 return int(unpack($DBM::Deep::LONG_PACK, $packed_size));
83 # Set the length of the array
85 my $self = $_[0]->_get_self;
86 my $new_length = $_[1];
88 my $SAVE_FILTER = $self->root->{filter_store_value};
89 $self->root->{filter_store_value} = undef;
91 my $result = $self->STORE('length', pack($DBM::Deep::LONG_PACK, $new_length));
93 $self->root->{filter_store_value} = $SAVE_FILTER;
100 # Remove and return the last element on the array
102 my $self = $_[0]->_get_self;
103 my $length = $self->FETCHSIZE();
106 my $content = $self->FETCH( $length - 1 );
107 $self->DELETE( $length - 1 );
117 # Add new element(s) to the end of the array
119 my $self = shift->_get_self;
120 my $length = $self->FETCHSIZE();
122 while (my $content = shift @_) {
123 $self->STORE( $length, $content );
132 # Remove and return first element on the array.
133 # Shift over remaining elements to take up space.
135 my $self = $_[0]->_get_self;
136 my $length = $self->FETCHSIZE();
139 my $content = $self->FETCH( 0 );
142 # Shift elements over and remove last one.
144 for (my $i = 0; $i < $length - 1; $i++) {
145 $self->STORE( $i, $self->FETCH($i + 1) );
147 $self->DELETE( $length - 1 );
158 # Insert new element(s) at beginning of array.
159 # Shift over other elements to make space.
161 my $self = shift->_get_self;
162 my @new_elements = @_;
163 my $length = $self->FETCHSIZE();
164 my $new_size = scalar @new_elements;
167 for (my $i = $length - 1; $i >= 0; $i--) {
168 $self->STORE( $i + $new_size, $self->FETCH($i) );
172 for (my $i = 0; $i < $new_size; $i++) {
173 $self->STORE( $i, $new_elements[$i] );
176 return $length + $new_size;
181 # Splices section of array with optional new section.
182 # Returns deleted section, or last element deleted in scalar context.
184 my $self = shift->_get_self;
185 my $length = $self->FETCHSIZE();
188 # Calculate offset and length of splice
190 my $offset = shift || 0;
191 if ($offset < 0) { $offset += $length; }
194 if (scalar @_) { $splice_length = shift; }
195 else { $splice_length = $length - $offset; }
196 if ($splice_length < 0) { $splice_length += ($length - $offset); }
199 # Setup array with new elements, and copy out old elements for return
201 my @new_elements = @_;
202 my $new_size = scalar @new_elements;
204 my @old_elements = ();
205 for (my $i = $offset; $i < $offset + $splice_length; $i++) {
206 push @old_elements, $self->FETCH( $i );
210 # Adjust array length, and shift elements to accomodate new section.
212 if ( $new_size != $splice_length ) {
213 if ($new_size > $splice_length) {
214 for (my $i = $length - 1; $i >= $offset + $splice_length; $i--) {
215 $self->STORE( $i + ($new_size - $splice_length), $self->FETCH($i) );
219 for (my $i = $offset + $splice_length; $i < $length; $i++) {
220 $self->STORE( $i + ($new_size - $splice_length), $self->FETCH($i) );
222 for (my $i = 0; $i < $splice_length - $new_size; $i++) {
223 $self->DELETE( $length - 1 );
230 # Insert new elements into array
232 for (my $i = $offset; $i < $offset + $new_size; $i++) {
233 $self->STORE( $i, shift @new_elements );
237 # Return deleted section, or last element in scalar context.
239 return wantarray ? @old_elements : $old_elements[-1];
242 #XXX We don't need to define it.
243 #XXX It will be useful, though, when we split out HASH and ARRAY
246 # Perl will call EXTEND() when the array is likely to grow.
247 # We don't care, but include it for compatibility.
252 # Public method aliases
254 *length = *FETCHSIZE;