Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
tag: RELEASE_1_2_0
Fetching contributors…

Cannot retrieve contributors at this time

628 lines (400 sloc) 13.022 kb
/*
Copyright (C) 2001-2009, Parrot Foundation.
$Id$
=head1 NAME
src/pmc/fixedbooleanarray.pmc - fixed size array for booleans only
=head1 DESCRIPTION
The C<FixedBooleanArray> PMC implements an array of fixed size, which
stores booleans. It uses the C<Boolean> PMC for all conversions. The
C<FixedBooleanArray> PMC is extended by the C<ResizableBooleanArray>
PMC.
=head2 Functions
=over 4
=cut
*/
#define BITS_PER_CHAR 8
pmclass FixedBooleanArray need_ext provides array {
ATTR UINTVAL size; /* # of bits this fba holds */
ATTR UINTVAL resize_threshold; /* max capacity before resizing */
ATTR unsigned char * bit_array; /* where the bits go */
/*
=back
=head2 Methods
=over 4
=item C<void init()>
Initializes the array.
=cut
*/
VTABLE void init() {
Parrot_FixedBooleanArray_attributes* attrs =
mem_allocate_zeroed_typed(Parrot_FixedBooleanArray_attributes);
PMC_data(SELF) = attrs;
PObj_active_destroy_SET(SELF);
}
/*
=item C<void destroy()>
Destroys the array.
=cut
*/
VTABLE void destroy() {
unsigned char *bit_array;
GET_ATTR_bit_array(INTERP, SELF, bit_array);
if (bit_array)
mem_sys_free(bit_array);
mem_sys_free(PMC_data(SELF));
}
/*
=item C<PMC *clone()>
Creates and returns a copy of the array.
=cut
*/
VTABLE PMC *clone() {
unsigned char * my_bit_array, * clone_bit_array;
UINTVAL resize_threshold, size;
PMC * const dest = pmc_new(INTERP, SELF->vtable->base_type);
GET_ATTR_bit_array(INTERP, SELF, my_bit_array);
GET_ATTR_size(INTERP, SELF, size);
GET_ATTR_resize_threshold(INTERP, SELF, resize_threshold);
if (my_bit_array) {
size_t size_in_bytes;
SET_ATTR_size(INTERP, dest, size);
SET_ATTR_resize_threshold(INTERP, dest, resize_threshold);
size_in_bytes = resize_threshold / BITS_PER_CHAR;
clone_bit_array = (unsigned char*)mem_sys_allocate(size_in_bytes);
mem_sys_memcopy(clone_bit_array, my_bit_array, size_in_bytes);
SET_ATTR_bit_array(INTERP, dest, clone_bit_array);
}
PObj_active_destroy_SET(dest);
return dest;
}
/*
=item C<INTVAL get_bool()>
Returns whether the array has any elements (meaning been initialized, for a
fixed sized array).
=cut
*/
VTABLE INTVAL get_bool() {
return SELF.elements() ? 1 : 0;
}
/*
=item C<INTVAL elements()>
=cut
*/
VTABLE INTVAL elements() {
UINTVAL size;
GET_ATTR_size(INTERP, SELF, size);
return size;
}
/*
=item C<INTVAL get_integer()>
Returns the number of elements in the array.
=cut
*/
VTABLE INTVAL get_integer() {
return SELF.elements();
}
/*
=item C<INTVAL get_integer_keyed_int(INTVAL key)>
Returns the integer value of the element at index C<key>.
=cut
*/
VTABLE INTVAL get_integer_keyed_int(INTVAL key) {
UINTVAL size;
const unsigned char * bit_array;
GET_ATTR_bit_array(INTERP, SELF, bit_array);
GET_ATTR_size(INTERP, SELF, size);
if (key < 0 || (UINTVAL)key >= size)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
"FixedBooleanArray: index out of bounds!");
return (bit_array[key / BITS_PER_CHAR] & (1 << (key % BITS_PER_CHAR))) ? 1 : 0;
}
/*
=item C<INTVAL get_integer_keyed(PMC *key)>
Returns the integer value of the element at index C<*key>.
=cut
*/
VTABLE INTVAL get_integer_keyed(PMC *key) {
/* simple int keys only */
const INTVAL k = VTABLE_get_integer(INTERP, key);
return SELF.get_integer_keyed_int(k);
}
/*
=item C<FLOATVAL get_number_keyed_int(INTVAL key)>
Returns the floating-point value of the element at index C<key>.
=cut
*/
VTABLE FLOATVAL get_number_keyed_int(INTVAL key) {
const INTVAL i = SELF.get_integer_keyed_int(key);
return (FLOATVAL)i;
}
/*
=item C<FLOATVAL get_number_keyed(PMC *key)>
Returns the floating-point value of the element at index C<*key>.
=cut
*/
VTABLE FLOATVAL get_number_keyed(PMC *key) {
const INTVAL k = VTABLE_get_integer(INTERP, key);
return SELF.get_number_keyed_int(k);
}
/*
=item C<STRING *get_string()>
Returns the Parrot string representation of the array.
=cut
*/
VTABLE STRING *get_string() {
STRING *zero, *one;
STRING *str = NULL;
UINTVAL i;
UINTVAL elems = SELF.elements();
zero = CONST_STRING(INTERP, "0");
one = CONST_STRING(INTERP, "1");
for (i = 0; i < elems; i++) {
if (SELF.get_integer_keyed_int((INTVAL)i))
str = Parrot_str_concat(INTERP, str, one, 0);
else
str = Parrot_str_concat(INTERP, str, zero, 0);
}
return str;
}
/*
=item C<STRING *get_string_keyed_int(INTVAL key)>
Returns the Parrot string value of the element at index C<key>.
=cut
*/
VTABLE STRING *get_string_keyed_int(INTVAL key) {
PMC * const val = SELF.get_pmc_keyed_int(key);
return VTABLE_get_string(INTERP, val);
}
/*
=item C<STRING *get_string_keyed(PMC *key)>
Returns the Parrot string value of the element at index C<*key>.
=cut
*/
VTABLE STRING *get_string_keyed(PMC *key) {
const INTVAL k = VTABLE_get_integer(INTERP, key);
return SELF.get_string_keyed_int(k);
}
/*
=item C<PMC *get_pmc_keyed_int(INTVAL key)>
Returns the PMC value of the element at index C<key>.
=cut
*/
VTABLE PMC *get_pmc_keyed_int(INTVAL key) {
PMC * const ret = pmc_new(INTERP, enum_class_Boolean);
const INTVAL val = SELF.get_integer_keyed_int(key);
VTABLE_set_integer_native(INTERP, ret, val);
return ret;
}
/*
=item C<PMC *get_pmc_keyed(PMC *key)>
Returns the PMC value of the element at index C<*key>.
=cut
*/
VTABLE PMC *get_pmc_keyed(PMC *key) {
const INTVAL k = VTABLE_get_integer(INTERP, key);
return SELF.get_pmc_keyed_int(k);
}
/*
=item C<void set_integer_native(INTVAL size)>
Resizes the array to C<size> elements.
=cut
*/
VTABLE void set_integer_native(INTVAL size) {
size_t size_in_bytes;
UINTVAL old_size;
GET_ATTR_size(INTERP, SELF, old_size);
if (old_size || size < 1)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
"FixedBooleanArray: Can't resize!");
size_in_bytes = size / BITS_PER_CHAR + 1;
SET_ATTR_size(INTERP, SELF, size);
SET_ATTR_resize_threshold(INTERP, SELF, size_in_bytes * BITS_PER_CHAR);
SET_ATTR_bit_array(INTERP, SELF,
(unsigned char*)mem_sys_allocate_zeroed(size_in_bytes));
}
/*
=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>
Sets the integer value of the element at index C<key> to C<value>.
=cut
*/
VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
UINTVAL size;
unsigned char * bit_array;
GET_ATTR_bit_array(INTERP, SELF, bit_array);
GET_ATTR_size(INTERP, SELF, size);
if (key < 0 || (UINTVAL)key >= size)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
"FixedBooleanArray: index out of bounds!");
if (value)
bit_array[key/BITS_PER_CHAR] |= (1 << (key % BITS_PER_CHAR));
else
bit_array[key/BITS_PER_CHAR] &= ~(1 << (key % BITS_PER_CHAR));
}
/*
=item C<void set_integer_keyed(PMC *key, INTVAL value)>
Sets the integer value of the element at index C<key> to C<value>.
=cut
*/
VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
const INTVAL k = VTABLE_get_integer(INTERP, key);
SELF.set_integer_keyed_int(k, value);
}
/*
=item C<void set_number_keyed_int(INTVAL key, FLOATVAL value)>
Sets the floating-point value of the element at index C<key> to
C<value>.
=cut
*/
VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) {
SELF.set_integer_keyed_int(key, !FLOAT_IS_ZERO(value));
}
/*
=item C<void set_number_keyed(PMC *key, FLOATVAL value)>
Sets the floating-point value of the element at index C<key> to
C<value>.
=cut
*/
VTABLE void set_number_keyed(PMC *key, FLOATVAL value) {
const INTVAL k = VTABLE_get_integer(INTERP, key);
SELF.set_number_keyed_int(k, value);
}
/*
=item C<void set_string_keyed_int(INTVAL key, STRING *value)>
Sets the Parrot string value of the element at index C<key> to C<value>.
=cut
*/
VTABLE void set_string_keyed_int(INTVAL key, STRING *value) {
INTVAL tempInt;
PMC * const tempPMC = pmc_new(INTERP, enum_class_Boolean);
VTABLE_set_string_native(INTERP, tempPMC, value);
tempInt = VTABLE_get_integer(INTERP, tempPMC);
SELF.set_integer_keyed_int(key, tempInt);
}
/*
=item C<void set_string_keyed(PMC *key, STRING *value)>
Sets the string value of the element at index C<key> to
C<value>.
=cut
*/
VTABLE void set_string_keyed(PMC *key, STRING *value) {
const INTVAL k = VTABLE_get_integer(INTERP, key);
SELF.set_string_keyed_int(k, value);
}
/*
=item C<void set_pmc_keyed_int(INTVAL key, PMC *src)>
Sets the PMC value of the element at index C<key> to C<*src>.
=cut
*/
VTABLE void set_pmc_keyed_int(INTVAL key, PMC *src) {
const INTVAL tempInt = VTABLE_get_integer(INTERP, src);
SELF.set_integer_keyed_int(key, tempInt);
}
/*
=item C<void set_pmc_keyed(PMC *key, PMC *value)>
Sets the string value of the element at index C<key> to
C<value>.
=cut
*/
VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
const INTVAL k = VTABLE_get_integer(INTERP, key);
SELF.set_pmc_keyed_int(k, value);
}
/*
=item C<void push_integer(INTVAL value)>
Extends the array by adding an element of value C<value> to the end of
the array.
=cut
*/
VTABLE void push_integer(INTVAL value) {
const INTVAL nextix = SELF.elements();
SELF.set_integer_keyed_int(nextix, value);
}
/*
=item C<PMC *get_iter()>
Return a new iterator for SELF.
=cut
*/
VTABLE PMC *get_iter() {
STRING *name = CONST_STRING(interp, "set_key");
PMC * const iter = pmc_new_init(INTERP, enum_class_Iterator, SELF);
PMC * const key = pmc_new(INTERP, enum_class_Key);
Parrot_PCCINVOKE(interp, iter, name, "P->", key);
PObj_get_FLAGS(key) |= KEY_integer_FLAG;
if (SELF.get_integer() == 0)
VTABLE_set_integer_native(INTERP, key, -1);
else
VTABLE_set_integer_native(INTERP, key, 0);
return iter;
}
/*
=back
=head2 Freeze/thaw Interface
=over 4
=item C<void freeze(visit_info *info)>
Used to archive the string.
=cut
*/
VTABLE void freeze(visit_info *info) {
UINTVAL size, resize_threshold;
unsigned char * bit_array;
IMAGE_IO * const io = info->image_io;
STRING * s;
GET_ATTR_size(INTERP, SELF, size);
GET_ATTR_resize_threshold(INTERP, SELF, resize_threshold);
GET_ATTR_bit_array(INTERP, SELF, bit_array);
s = Parrot_str_new(INTERP, (char*)bit_array,
(resize_threshold / BITS_PER_CHAR));
VTABLE_push_integer(INTERP, io, size);
VTABLE_push_string(INTERP, io, s);
}
/*
=item C<void thaw(visit_info *info)>
Used to unarchive the string.
=cut
*/
VTABLE void thaw(visit_info *info) {
IMAGE_IO * const io = info->image_io;
SUPER(info);
if (info->extra_flags == EXTRA_IS_NULL) {
unsigned char * bit_array;
const INTVAL size = VTABLE_shift_integer(INTERP, io);
STRING * const s = VTABLE_shift_string(INTERP, io);
bit_array = (unsigned char*)mem_sys_allocate_zeroed(s->bufused);
mem_sys_memcopy(bit_array, s->strstart, s->bufused);
SET_ATTR_size(INTERP, SELF, size);
SET_ATTR_resize_threshold(INTERP, SELF,
s->bufused * BITS_PER_CHAR);
SET_ATTR_bit_array(INTERP, SELF, bit_array);
}
}
/*
=item C<METHOD fill(INTVAL fill)>
Sets all of the entires to true if fill is a true value, otherwise
sets them all to false.
=cut
*/
METHOD fill(INTVAL fill) {
UINTVAL size;
unsigned char * bit_array;
size_t j;
GET_ATTR_bit_array(INTERP, SELF, bit_array);
GET_ATTR_size(INTERP, SELF, size);
j = size / BITS_PER_CHAR + 1;
if (fill)
memset(bit_array, 0xff, j);
else
memset(bit_array, 0, j);
}
}
/*
=back
=head1 SEE ALSO
F<docs/pdds/pdd17_basic_types.pod>.
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4:
*/
Jump to Line
Something went wrong with that request. Please try again.