fix codetest failure - trailing whitespace
[parrot.git] / src / pmc / fixedbooleanarray.pmc
blob597bb1f72b968f99bdf5e6283865a764adb904ae
1 /*
2 Copyright (C) 2001-2010, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc/fixedbooleanarray.pmc - fixed size array for booleans only
9 =head1 DESCRIPTION
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>
14 PMC.
16 =head2 Functions
18 =over 4
20 =item C<static UINTVAL get_size_in_bytes(UINTVAL size)>
22 Auxiliar function to avoid repeating the size evaluation.
24 =cut
28 #define BITS_PER_CHAR 8
30 PARROT_INLINE
31 static UINTVAL
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 */
45 =back
47 =head2 Vtable functions
49 =over 4
51 =item C<void init()>
53 Initializes the array.
55 =cut
59     VTABLE void init() {
60         PObj_custom_destroy_SET(SELF);
61     }
65 =item C<void init_int(INTVAL size)>
67 Initializes the array.
69 =cut
73     VTABLE void init_int(INTVAL size) {
74         const size_t size_in_bytes = get_size_in_bytes(size);
76         if (size < 0)
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,
83                                                                         unsigned char));
84         PObj_custom_destroy_SET(SELF);
85     }
90 =item C<void destroy()>
92 Destroys the array.
94 =cut
98     VTABLE void destroy() {
99         unsigned char *bit_array;
100         GET_ATTR_bit_array(INTERP, SELF, bit_array);
101         if (bit_array)
102             mem_gc_free(INTERP, bit_array);
103     }
107 =item C<PMC *clone()>
109 Creates and returns a copy of the array.
111 =cut
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);
124         if (my_bit_array) {
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);
134         }
136         PObj_custom_destroy_SET(dest);
137         return dest;
138     }
142 =item C<INTVAL get_bool()>
144 Returns whether the array has any elements (meaning been initialized, for a
145 fixed sized array).
147 =cut
150     VTABLE INTVAL get_bool() {
151         return SELF.elements() ? 1 : 0;
152     }
156 =item C<INTVAL elements()>
158 =cut
162     VTABLE INTVAL elements() {
163         UINTVAL size;
164         GET_ATTR_size(INTERP, SELF, size);
165         return size;
166     }
170 =item C<INTVAL get_integer()>
172 Returns the number of elements in the array.
174 =cut
178     VTABLE INTVAL get_integer() {
179         return SELF.elements();
180     }
184 =item C<INTVAL get_integer_keyed_int(INTVAL key)>
186 Returns the integer value of the element at index C<key>.
188 =cut
192     VTABLE INTVAL get_integer_keyed_int(INTVAL key) {
193         UINTVAL               size;
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;
203     }
207 =item C<INTVAL get_integer_keyed(PMC *key)>
209 Returns the integer value of the element at index C<*key>.
211 =cut
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);
219     }
224 =item C<FLOATVAL get_number_keyed_int(INTVAL key)>
226 Returns the floating-point value of the element at index C<key>.
228 =cut
232     VTABLE FLOATVAL get_number_keyed_int(INTVAL key) {
233         const INTVAL i = SELF.get_integer_keyed_int(key);
234         return (FLOATVAL)i;
235     }
239 =item C<FLOATVAL get_number_keyed(PMC *key)>
241 Returns the floating-point value of the element at index C<*key>.
243 =cut
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);
250     }
254 =item C<STRING *get_string()>
256 Returns the Parrot string representation of the array.
258 =cut
262     VTABLE STRING *get_string() {
263         STRING *zero, *one;
264         STRING *str   = NULL;
265         UINTVAL i;
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);
274             else
275                 str = Parrot_str_concat(INTERP, str, zero, 0);
276         }
278         return str;
280     }
284 =item C<STRING *get_string_keyed_int(INTVAL key)>
286 Returns the Parrot string value of the element at index C<key>.
288 =cut
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);
295     }
299 =item C<STRING *get_string_keyed(PMC *key)>
301 Returns the Parrot string value of the element at index C<*key>.
303 =cut
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);
310     }
315 =item C<PMC *get_pmc_keyed_int(INTVAL key)>
317 Returns the PMC value of the element at index C<key>.
319 =cut
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);
327         return ret;
328     }
332 =item C<PMC *get_pmc_keyed(PMC *key)>
334 Returns the PMC value of the element at index C<*key>.
336 =cut
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);
343     }
347 =item C<void set_integer_native(INTVAL size)>
349 Resizes the array to C<size> elements.
351 =cut
355     VTABLE void set_integer_native(INTVAL size) {
356         const size_t size_in_bytes = get_size_in_bytes(size);
357         UINTVAL old_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);
371     }
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>.
379 =cut
383     VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
384         UINTVAL size;
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!");
393         if (value)
394             bit_array[key/BITS_PER_CHAR] |=  (1 << (key % BITS_PER_CHAR));
395         else
396             bit_array[key/BITS_PER_CHAR] &= ~(1 << (key % BITS_PER_CHAR));
397     }
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>.
405 =cut
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);
412     }
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
419 C<value>.
421 =cut
425     VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) {
426         SELF.set_integer_keyed_int(key, !FLOAT_IS_ZERO(value));
427     }
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
434 C<value>.
436 =cut
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);
443     }
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>.
451 =cut
455     VTABLE void set_string_keyed_int(INTVAL key, STRING *value) {
456         INTVAL tempInt;
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);
463     }
467 =item C<void set_string_keyed(PMC *key, STRING *value)>
469 Sets the string value of the element at index C<key> to
470 C<value>.
472 =cut
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);
479     }
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>.
487 =cut
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);
494     }
498 =item C<void set_pmc_keyed(PMC *key, PMC *value)>
500 Sets the string value of the element at index C<key> to
501 C<value>.
503 =cut
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);
510     }
514 =item C<PMC *get_iter()>
516 Return a new iterator for SELF.
518 =cut
522     VTABLE PMC *get_iter() {
523         return Parrot_pmc_new_init(INTERP, enum_class_ArrayIterator, SELF);
524     }
530 =back
532 =head2 Freeze/thaw Interface
534 =over 4
536 =item C<void freeze(PMC *info)>
538 Used to archive the string.
540 =cut
543     VTABLE void freeze(PMC *info) {
544         UINTVAL          size, resize_threshold;
545         unsigned char  * bit_array;
546         STRING   *       s;
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);
556     }
560 =item C<void thaw(PMC *info)>
562 Used to unarchive the string.
564 =cut
567     VTABLE void thaw(PMC *info) {
568         SUPER(info);
570         {
571             unsigned char * bit_array;
572             UINTVAL         threshold;
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);
582         }
583     }
587 =back
589 =head2 Methods
591 =over 4
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.
598 =cut
602     METHOD fill(INTVAL fill) {
603         UINTVAL         size;
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);
611         if (size_in_bytes)
612             memset(bit_array, fill ? 0xff : 0, size_in_bytes);
613     }
618 =back
620 =head1 SEE ALSO
622 F<docs/pdds/pdd17_basic_types.pod>.
624 =cut
629  * Local variables:
630  *   c-file-style: "parrot"
631  * End:
632  * vim: expandtab shiftwidth=4:
633  */