Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tag: RELEASE_3_7_0
Fetching contributors…

Cannot retrieve contributors at this time

649 lines (406 sloc) 12.776 kb
/*
Copyright (C) 2001-2011, Parrot Foundation.
=head1 NAME
src/pmc/fixedstringarray.pmc - fixed size array for strings only
=head1 DESCRIPTION
This class, FixedStringArray, implements an array of fixed size which
stores Parrot strings.
=head2 Functions
=over 4
=cut
*/
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */
pmclass FixedStringArray auto_attrs provides array {
ATTR STRING **str_array; /* where the STRINGs are stored */
ATTR UINTVAL size; /* element count */
/*
=back
=head2 Methods
=over 4
=item C<void init_int(INTVAL size)>
Initializes the array.
=cut
*/
VTABLE void init_int(INTVAL size) {
if (size < 0)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
_("FixedStringArray: Cannot set array size to a negative number (%d)"), size);
if (size) {
SET_ATTR_size(INTERP, SELF, size);
SET_ATTR_str_array(INTERP,
SELF, mem_gc_allocate_n_zeroed_typed(INTERP, size, STRING *));
PObj_custom_mark_destroy_SETALL(SELF);
}
}
/*
=item C<void destroy()>
Destroys the array.
=cut
*/
VTABLE void destroy() {
STRING **str_array;
GET_ATTR_str_array(INTERP, SELF, str_array);
if (str_array)
mem_gc_free(INTERP, str_array);
}
/*
=item C<PMC *clone()>
Creates and returns a copy of the array.
=cut
*/
VTABLE PMC *clone() {
STRING **my_str_array;
PMC *const dest = Parrot_pmc_new(INTERP, SELF->vtable->base_type);
GET_ATTR_str_array(INTERP, SELF, my_str_array);
if (my_str_array) {
STRING **dest_str_array;
INTVAL size;
size_t mem_size;
GET_ATTR_size(INTERP, SELF, size);
mem_size = size * sizeof (STRING *);
dest_str_array = mem_gc_allocate_n_zeroed_typed(INTERP, size, STRING *);
mem_sys_memcopy(dest_str_array, my_str_array, mem_size);
SET_ATTR_str_array(INTERP, dest, dest_str_array);
SET_ATTR_size(INTERP, dest, size);
PObj_custom_mark_destroy_SETALL(dest);
}
return dest;
}
/*
=item C<void mark()>
Marks the array as live.
=cut
*/
VTABLE void mark() {
STRING **str_array;
GET_ATTR_str_array(INTERP, SELF, str_array);
if (str_array) {
UINTVAL size, i;
GET_ATTR_size(INTERP, SELF, size);
for (i = 0; i < size; ++i) {
Parrot_gc_mark_STRING_alive(INTERP, str_array[i]);
}
}
}
/*
=item C<INTVAL get_bool()>
Returns 1 if the array has any elements; otherwise, returns 0.
Since this is a fixed size array, C<get_bool> will always
return true once the array has been initialized and had its
size set by C<set_integer_native>.
=cut
*/
VTABLE INTVAL get_bool() {
const INTVAL size = SELF.elements();
return (INTVAL)(size != 0);
}
/*
=item C<PMC *get_iter()>
Gets an iterator for the array.
=cut
*/
VTABLE PMC *get_iter() {
return Parrot_pmc_new_init(INTERP, enum_class_ArrayIterator, SELF);
}
/*
=item C<INTVAL elements()>
Returns the number of elements in the array.
=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<FLOATVAL get_number()>
Returns the number of elements in the array.
=cut
*/
VTABLE FLOATVAL get_number() {
const INTVAL e = SELF.elements();
return (FLOATVAL)e;
}
/*
=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) {
STRING * const element = SELF.get_string_keyed_int(key);
return Parrot_str_to_int(INTERP, element);
}
/*
=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) {
STRING * const element = SELF.get_string_keyed_int(key);
return Parrot_str_to_num(INTERP, element);
}
/*
=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_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) {
STRING **str_array;
UINTVAL size;
GET_ATTR_size(INTERP, SELF, size);
if (key < 0 || (UINTVAL)key >= size)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
"FixedStringArray: index out of bounds!");
GET_ATTR_str_array(INTERP, SELF, str_array);
return str_array[key];
}
/*
=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 = Parrot_pmc_new(INTERP, enum_class_String);
STRING * const val = SELF.get_string_keyed_int(key);
VTABLE_set_string_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)>
Sets the size of the array to C<size> elements. Once the array
has been given an initial size, attempts to resize it will
cause an exception to be thrown.
=cut
*/
VTABLE void set_integer_native(INTVAL new_size) {
UINTVAL old_size;
GET_ATTR_size(INTERP, SELF, old_size);
if (old_size || new_size < 1)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
"FixedStringArray: Can't resize!");
SET_ATTR_size(INTERP, SELF, new_size);
SET_ATTR_str_array(INTERP, SELF,
mem_gc_allocate_n_zeroed_typed(INTERP, new_size, STRING*));
PObj_custom_mark_destroy_SETALL(SELF);
}
/*
=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) {
STRING *val = Parrot_str_from_int(INTERP, value);
SELF.set_string_keyed_int(key, val);
}
/*
=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) {
STRING * const val = Parrot_str_from_num(INTERP, value);
SELF.set_string_keyed_int(key, val);
}
/*
=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) {
STRING **str_array;
if (key < 0 || key >= SELF.elements())
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
"FixedStringArray: index out of bounds!");
GET_ATTR_str_array(INTERP, SELF, str_array);
str_array[key] = value;
}
/*
=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) {
STRING * const temp = VTABLE_get_string(INTERP, src);
SELF.set_string_keyed_int(key, temp);
}
/*
=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<STRING *get_string()>
=item C<STRING *get_repr()>
Returns the Parrot string representation C<key>.
=cut
*/
VTABLE STRING *get_string() {
return STATICSELF.get_repr();
}
VTABLE STRING *get_repr() {
STRING *res = CONST_STRING(INTERP, "[ ");
const INTVAL n = SELF.get_integer();
INTVAL j;
for (j = 0; j < n; ++j) {
STRING * const val = SELF.get_string_keyed_int(j);
res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, "\""));
res = Parrot_str_concat(INTERP, res, val);
res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, "\""));
if (j < n - 1)
res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, ", "));
}
res = Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, " ]"));
return res;
}
/*
=item C<INTVAL is_equal(PMC *value)>
The C<==> operation. Compares two array to hold equal elements.
=cut
*/
VTABLE INTVAL is_equal(PMC *value) {
INTVAL j, n;
if (value->vtable->base_type != SELF->vtable->base_type)
return 0;
n = SELF.elements();
if (VTABLE_elements(INTERP, value) != n)
return 0;
for (j = 0; j < n; ++j) {
STRING * const item1 = SELF.get_string_keyed_int(j);
STRING * const item2 = VTABLE_get_string_keyed_int(INTERP, value, j);
if (item1 == item2)
continue;
if (STRING_IS_NULL(item1) || STRING_IS_NULL(item2))
return 0;
if (!STRING_equal(INTERP, item1, item2))
return 0;
}
return 1;
}
/*
=back
=head2 Freeze/thaw Interface
=over 4
=item C<void freeze(PMC *info)>
Used to archive the string.
=cut
*/
VTABLE void freeze(PMC *info) {
STRING **str_array;
UINTVAL size, i;
GET_ATTR_size(INTERP, SELF, size);
GET_ATTR_str_array(INTERP, SELF, str_array);
VTABLE_push_integer(INTERP, info, size);
for (i = 0; i < size; ++i)
VTABLE_push_string(INTERP, info, str_array[i]);
}
/*
=item C<void thaw(PMC *info)>
Used to unarchive the string.
=cut
*/
VTABLE void thaw(PMC *info) {
const UINTVAL size = VTABLE_shift_integer(INTERP, info);
SELF.init_int(size);
if (size > 0) {
UINTVAL i;
STRING **str_array;
GET_ATTR_str_array(INTERP, SELF, str_array);
for (i = 0; i < size; ++i)
str_array[i] = VTABLE_shift_string(INTERP, info);
}
}
}
/*
=back
=head1 SEE ALSO
F<docs/pdds/pdd17_basic_types.pod>.
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/
Jump to Line
Something went wrong with that request. Please try again.