1 package DBM::Deep::Array;
8 eval { tied( @{$_[0]} ) } || $_[0]
13 # Tied array constructor method, called by Perl's tie() function.
17 if (scalar(@_) > 1) { $args = {@_}; }
18 #XXX This use of ref() is bad and is a bug
19 elsif (ref($_[0])) { $args = $_[0]; }
20 else { $args = { file => shift }; }
22 $args->{type} = $class->TYPE_ARRAY;
24 return $class->_init($args);
28 # The following methods are for arrays only
33 # Return the length of the array
35 my $self = $_[0]->_get_self;
37 my $SAVE_FILTER = $self->root->{filter_fetch_value};
38 $self->root->{filter_fetch_value} = undef;
40 my $packed_size = $self->FETCH('length');
42 $self->root->{filter_fetch_value} = $SAVE_FILTER;
44 if ($packed_size) { return int(unpack($DBM::Deep::LONG_PACK, $packed_size)); }
50 # Set the length of the array
52 my $self = $_[0]->_get_self;
53 my $new_length = $_[1];
55 my $SAVE_FILTER = $self->root->{filter_store_value};
56 $self->root->{filter_store_value} = undef;
58 my $result = $self->STORE('length', pack($DBM::Deep::LONG_PACK, $new_length));
60 $self->root->{filter_store_value} = $SAVE_FILTER;
67 # Remove and return the last element on the array
69 my $self = $_[0]->_get_self;
70 my $length = $self->FETCHSIZE();
73 my $content = $self->FETCH( $length - 1 );
74 $self->DELETE( $length - 1 );
84 # Add new element(s) to the end of the array
86 my $self = shift->_get_self;
87 my $length = $self->FETCHSIZE();
89 while (my $content = shift @_) {
90 $self->STORE( $length, $content );
99 # Remove and return first element on the array.
100 # Shift over remaining elements to take up space.
102 my $self = $_[0]->_get_self;
103 my $length = $self->FETCHSIZE();
106 my $content = $self->FETCH( 0 );
109 # Shift elements over and remove last one.
111 for (my $i = 0; $i < $length - 1; $i++) {
112 $self->STORE( $i, $self->FETCH($i + 1) );
114 $self->DELETE( $length - 1 );
125 # Insert new element(s) at beginning of array.
126 # Shift over other elements to make space.
128 my $self = shift->_get_self;
129 my @new_elements = @_;
130 my $length = $self->FETCHSIZE();
131 my $new_size = scalar @new_elements;
134 for (my $i = $length - 1; $i >= 0; $i--) {
135 $self->STORE( $i + $new_size, $self->FETCH($i) );
139 for (my $i = 0; $i < $new_size; $i++) {
140 $self->STORE( $i, $new_elements[$i] );
143 return $length + $new_size;
148 # Splices section of array with optional new section.
149 # Returns deleted section, or last element deleted in scalar context.
151 my $self = shift->_get_self;
152 my $length = $self->FETCHSIZE();
155 # Calculate offset and length of splice
157 my $offset = shift || 0;
158 if ($offset < 0) { $offset += $length; }
161 if (scalar @_) { $splice_length = shift; }
162 else { $splice_length = $length - $offset; }
163 if ($splice_length < 0) { $splice_length += ($length - $offset); }
166 # Setup array with new elements, and copy out old elements for return
168 my @new_elements = @_;
169 my $new_size = scalar @new_elements;
171 my @old_elements = ();
172 for (my $i = $offset; $i < $offset + $splice_length; $i++) {
173 push @old_elements, $self->FETCH( $i );
177 # Adjust array length, and shift elements to accomodate new section.
179 if ( $new_size != $splice_length ) {
180 if ($new_size > $splice_length) {
181 for (my $i = $length - 1; $i >= $offset + $splice_length; $i--) {
182 $self->STORE( $i + ($new_size - $splice_length), $self->FETCH($i) );
186 for (my $i = $offset + $splice_length; $i < $length; $i++) {
187 $self->STORE( $i + ($new_size - $splice_length), $self->FETCH($i) );
189 for (my $i = 0; $i < $splice_length - $new_size; $i++) {
190 $self->DELETE( $length - 1 );
197 # Insert new elements into array
199 for (my $i = $offset; $i < $offset + $new_size; $i++) {
200 $self->STORE( $i, shift @new_elements );
204 # Return deleted section, or last element in scalar context.
206 return wantarray ? @old_elements : $old_elements[-1];
209 #XXX We don't need to define it.
210 #XXX It will be useful, though, when we split out HASH and ARRAY
213 # Perl will call EXTEND() when the array is likely to grow.
214 # We don't care, but include it for compatibility.
219 # Public method aliases
221 *length = *FETCHSIZE;