2 Copyright (C) 2001-2010, Parrot Foundation.
7 src/pmc/fixedbooleanarray.pmc - fixed size array for booleans only
11 The C<FixedBooleanArray> PMC implements an array of fixed size, which
12 stores booleans. It uses the C<Boolean> PMC for all conversions. The
13 C<FixedBooleanArray> PMC is extended by the C<ResizableBooleanArray>
20 =item C<static UINTVAL get_size_in_bytes(UINTVAL size)>
22 Auxiliar function to avoid repeating the size evaluation.
28 #define BITS_PER_CHAR 8
32 get_size_in_bytes(UINTVAL size)
34 return (size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
38 pmclass FixedBooleanArray auto_attrs provides array {
39 ATTR UINTVAL size; /* # of bits this fba holds */
40 ATTR UINTVAL resize_threshold; /* max capacity before resizing */
41 ATTR unsigned char * bit_array; /* where the bits go */
47 =head2 Vtable functions
53 Initializes the array.
60 PObj_custom_destroy_SET(SELF);
65 =item C<void init_int(INTVAL size)>
67 Initializes the array.
73 VTABLE void init_int(INTVAL size) {
74 const size_t size_in_bytes = get_size_in_bytes(size);
77 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_OUT_OF_BOUNDS,
78 _("FixedBooleanArray: Cannot set array size to a negative number (%d)"), size);
80 SET_ATTR_size(INTERP, SELF, size);
81 SET_ATTR_resize_threshold(INTERP, SELF, size_in_bytes * BITS_PER_CHAR);
82 SET_ATTR_bit_array(INTERP, SELF, mem_gc_allocate_n_zeroed_typed(INTERP, size_in_bytes,
84 PObj_custom_destroy_SET(SELF);
90 =item C<void destroy()>
98 VTABLE void destroy() {
99 unsigned char *bit_array;
100 GET_ATTR_bit_array(INTERP, SELF, bit_array);
102 mem_gc_free(INTERP, bit_array);
107 =item C<PMC *clone()>
109 Creates and returns a copy of the array.
115 VTABLE PMC *clone() {
116 unsigned char * my_bit_array, * clone_bit_array;
117 UINTVAL resize_threshold, size;
118 PMC * const dest = Parrot_pmc_new(INTERP, SELF->vtable->base_type);
120 GET_ATTR_bit_array(INTERP, SELF, my_bit_array);
121 GET_ATTR_size(INTERP, SELF, size);
122 GET_ATTR_resize_threshold(INTERP, SELF, resize_threshold);
125 const size_t size_in_bytes = get_size_in_bytes(resize_threshold);
127 SET_ATTR_size(INTERP, dest, size);
128 SET_ATTR_resize_threshold(INTERP, dest, resize_threshold);
130 clone_bit_array = mem_gc_allocate_n_typed(INTERP, size_in_bytes, unsigned char);
131 mem_sys_memcopy(clone_bit_array, my_bit_array, size_in_bytes);
133 SET_ATTR_bit_array(INTERP, dest, clone_bit_array);
136 PObj_custom_destroy_SET(dest);
142 =item C<INTVAL get_bool()>
144 Returns whether the array has any elements (meaning been initialized, for a
150 VTABLE INTVAL get_bool() {
151 return SELF.elements() ? 1 : 0;
156 =item C<INTVAL elements()>
162 VTABLE INTVAL elements() {
164 GET_ATTR_size(INTERP, SELF, size);
170 =item C<INTVAL get_integer()>
172 Returns the number of elements in the array.
178 VTABLE INTVAL get_integer() {
179 return SELF.elements();
184 =item C<INTVAL get_integer_keyed_int(INTVAL key)>
186 Returns the integer value of the element at index C<key>.
192 VTABLE INTVAL get_integer_keyed_int(INTVAL key) {
194 const unsigned char * bit_array;
195 GET_ATTR_bit_array(INTERP, SELF, bit_array);
196 GET_ATTR_size(INTERP, SELF, size);
198 if (key < 0 || (UINTVAL)key >= size)
199 Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
200 "FixedBooleanArray: index out of bounds!");
202 return (bit_array[key / BITS_PER_CHAR] & (1 << (key % BITS_PER_CHAR))) ? 1 : 0;
207 =item C<INTVAL get_integer_keyed(PMC *key)>
209 Returns the integer value of the element at index C<*key>.
215 VTABLE INTVAL get_integer_keyed(PMC *key) {
216 /* simple int keys only */
217 const INTVAL k = VTABLE_get_integer(INTERP, key);
218 return SELF.get_integer_keyed_int(k);
224 =item C<FLOATVAL get_number_keyed_int(INTVAL key)>
226 Returns the floating-point value of the element at index C<key>.
232 VTABLE FLOATVAL get_number_keyed_int(INTVAL key) {
233 const INTVAL i = SELF.get_integer_keyed_int(key);
239 =item C<FLOATVAL get_number_keyed(PMC *key)>
241 Returns the floating-point value of the element at index C<*key>.
247 VTABLE FLOATVAL get_number_keyed(PMC *key) {
248 const INTVAL k = VTABLE_get_integer(INTERP, key);
249 return SELF.get_number_keyed_int(k);
254 =item C<STRING *get_string()>
256 Returns the Parrot string representation of the array.
262 VTABLE STRING *get_string() {
266 UINTVAL elems = SELF.elements();
268 zero = CONST_STRING(INTERP, "0");
269 one = CONST_STRING(INTERP, "1");
271 for (i = 0; i < elems; i++) {
272 if (SELF.get_integer_keyed_int((INTVAL)i))
273 str = Parrot_str_concat(INTERP, str, one, 0);
275 str = Parrot_str_concat(INTERP, str, zero, 0);
284 =item C<STRING *get_string_keyed_int(INTVAL key)>
286 Returns the Parrot string value of the element at index C<key>.
292 VTABLE STRING *get_string_keyed_int(INTVAL key) {
293 PMC * const val = SELF.get_pmc_keyed_int(key);
294 return VTABLE_get_string(INTERP, val);
299 =item C<STRING *get_string_keyed(PMC *key)>
301 Returns the Parrot string value of the element at index C<*key>.
307 VTABLE STRING *get_string_keyed(PMC *key) {
308 const INTVAL k = VTABLE_get_integer(INTERP, key);
309 return SELF.get_string_keyed_int(k);
315 =item C<PMC *get_pmc_keyed_int(INTVAL key)>
317 Returns the PMC value of the element at index C<key>.
323 VTABLE PMC *get_pmc_keyed_int(INTVAL key) {
324 PMC * const ret = Parrot_pmc_new(INTERP, enum_class_Boolean);
325 const INTVAL val = SELF.get_integer_keyed_int(key);
326 VTABLE_set_integer_native(INTERP, ret, val);
332 =item C<PMC *get_pmc_keyed(PMC *key)>
334 Returns the PMC value of the element at index C<*key>.
340 VTABLE PMC *get_pmc_keyed(PMC *key) {
341 const INTVAL k = VTABLE_get_integer(INTERP, key);
342 return SELF.get_pmc_keyed_int(k);
347 =item C<void set_integer_native(INTVAL size)>
349 Resizes the array to C<size> elements.
355 VTABLE void set_integer_native(INTVAL size) {
356 const size_t size_in_bytes = get_size_in_bytes(size);
358 unsigned char *bit_array;
360 GET_ATTR_size(INTERP, SELF, old_size);
362 if (old_size || size < 1)
363 Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
364 "FixedBooleanArray: Can't resize!");
366 SET_ATTR_size(INTERP, SELF, size);
367 SET_ATTR_resize_threshold(INTERP, SELF, size_in_bytes * BITS_PER_CHAR);
368 bit_array = mem_gc_allocate_n_typed(INTERP, size_in_bytes, unsigned char);
369 memset(bit_array, 0, size_in_bytes);
370 SET_ATTR_bit_array(INTERP, SELF, bit_array);
375 =item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>
377 Sets the integer value of the element at index C<key> to C<value>.
383 VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
385 unsigned char * bit_array;
386 GET_ATTR_bit_array(INTERP, SELF, bit_array);
387 GET_ATTR_size(INTERP, SELF, size);
389 if (key < 0 || (UINTVAL)key >= size)
390 Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
391 "FixedBooleanArray: index out of bounds!");
394 bit_array[key/BITS_PER_CHAR] |= (1 << (key % BITS_PER_CHAR));
396 bit_array[key/BITS_PER_CHAR] &= ~(1 << (key % BITS_PER_CHAR));
401 =item C<void set_integer_keyed(PMC *key, INTVAL value)>
403 Sets the integer value of the element at index C<key> to C<value>.
409 VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
410 const INTVAL k = VTABLE_get_integer(INTERP, key);
411 SELF.set_integer_keyed_int(k, value);
416 =item C<void set_number_keyed_int(INTVAL key, FLOATVAL value)>
418 Sets the floating-point value of the element at index C<key> to
425 VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) {
426 SELF.set_integer_keyed_int(key, !FLOAT_IS_ZERO(value));
431 =item C<void set_number_keyed(PMC *key, FLOATVAL value)>
433 Sets the floating-point value of the element at index C<key> to
440 VTABLE void set_number_keyed(PMC *key, FLOATVAL value) {
441 const INTVAL k = VTABLE_get_integer(INTERP, key);
442 SELF.set_number_keyed_int(k, value);
447 =item C<void set_string_keyed_int(INTVAL key, STRING *value)>
449 Sets the Parrot string value of the element at index C<key> to C<value>.
455 VTABLE void set_string_keyed_int(INTVAL key, STRING *value) {
457 PMC * const tempPMC = Parrot_pmc_new(INTERP, enum_class_Boolean);
459 VTABLE_set_string_native(INTERP, tempPMC, value);
460 tempInt = VTABLE_get_integer(INTERP, tempPMC);
462 SELF.set_integer_keyed_int(key, tempInt);
467 =item C<void set_string_keyed(PMC *key, STRING *value)>
469 Sets the string value of the element at index C<key> to
476 VTABLE void set_string_keyed(PMC *key, STRING *value) {
477 const INTVAL k = VTABLE_get_integer(INTERP, key);
478 SELF.set_string_keyed_int(k, value);
483 =item C<void set_pmc_keyed_int(INTVAL key, PMC *src)>
485 Sets the PMC value of the element at index C<key> to C<*src>.
491 VTABLE void set_pmc_keyed_int(INTVAL key, PMC *src) {
492 const INTVAL tempInt = VTABLE_get_integer(INTERP, src);
493 SELF.set_integer_keyed_int(key, tempInt);
498 =item C<void set_pmc_keyed(PMC *key, PMC *value)>
500 Sets the string value of the element at index C<key> to
507 VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
508 const INTVAL k = VTABLE_get_integer(INTERP, key);
509 SELF.set_pmc_keyed_int(k, value);
514 =item C<PMC *get_iter()>
516 Return a new iterator for SELF.
522 VTABLE PMC *get_iter() {
523 return Parrot_pmc_new_init(INTERP, enum_class_ArrayIterator, SELF);
532 =head2 Freeze/thaw Interface
536 =item C<void freeze(PMC *info)>
538 Used to archive the string.
543 VTABLE void freeze(PMC *info) {
544 UINTVAL size, resize_threshold;
545 unsigned char * bit_array;
547 GET_ATTR_size(INTERP, SELF, size);
548 GET_ATTR_resize_threshold(INTERP, SELF, resize_threshold);
549 GET_ATTR_bit_array(INTERP, SELF, bit_array);
551 s = Parrot_str_new(INTERP, (char*)bit_array,
552 (resize_threshold / BITS_PER_CHAR));
554 VTABLE_push_integer(INTERP, info, size);
555 VTABLE_push_string(INTERP, info, s);
560 =item C<void thaw(PMC *info)>
562 Used to unarchive the string.
567 VTABLE void thaw(PMC *info) {
571 unsigned char * bit_array;
573 const INTVAL size = VTABLE_shift_integer(INTERP, info);
574 STRING * const s = VTABLE_shift_string(INTERP, info);
576 bit_array = (unsigned char *)Parrot_str_to_cstring(INTERP, s);
577 threshold = Parrot_str_byte_length(interp, s) * BITS_PER_CHAR;
579 SET_ATTR_size(INTERP, SELF, size);
580 SET_ATTR_resize_threshold(INTERP, SELF, threshold);
581 SET_ATTR_bit_array(INTERP, SELF, bit_array);
593 =item C<METHOD fill(INTVAL fill)>
595 Sets all of the entires to true if fill is a true value, otherwise
596 sets them all to false.
602 METHOD fill(INTVAL fill) {
604 unsigned char * bit_array;
605 size_t size_in_bytes;
607 GET_ATTR_bit_array(INTERP, SELF, bit_array);
608 GET_ATTR_size(INTERP, SELF, size);
609 size_in_bytes = get_size_in_bytes(size);
612 memset(bit_array, fill ? 0xff : 0, size_in_bytes);
622 F<docs/pdds/pdd17_basic_types.pod>.
630 * c-file-style: "parrot"
632 * vim: expandtab shiftwidth=4: