Skip to content

HTTPS clone URL

Subversion checkout URL

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

Cannot retrieve contributors at this time

623 lines (406 sloc) 12.902 kB
/*
Copyright (C) 2001-2008, The Perl Foundation.
$Id$
=head1 NAME
src/pmc/fixedintegerarray.pmc - fixed size array for integers only
=head1 DESCRIPTION
This class, FixedIntegerArray, implements an array of fixed size which stores
INTVALs. It uses Integer PMCs for all of the conversions.
=head2 Functions
=over 4
=cut
*/
#include "parrot/parrot.h"
pmclass FixedIntegerArray need_ext provides array {
/*
=back
=head2 Methods
=over 4
=item C<void init()>
Initializes the array.
=cut
*/
VTABLE void init() {
PMC_int_val(SELF) = 0;
PMC_data(SELF) = NULL;
}
/*
=item C<PMC new_from_string(STRING *rep, INTVAL flags)>
Class method to construct an array from the string representation C<rep>,
which is a string I<"(el0, el1, ...)">. C<flags> may have the
C<PObj_constant_FLAG> bit set, which will be honored to create a PMC
in the constant PMC pool.
=cut
*/
VTABLE PMC *new_from_string(STRING *rep, INTVAL flags) {
const INTVAL type = SELF->vtable->base_type;
INTVAL n, elem, i, l;
char *p, *start;
int base;
if (flags & PObj_constant_FLAG)
SELF = constant_pmc_new(INTERP, type);
else
SELF = pmc_new(INTERP, type);
l = string_length(INTERP, rep);
if (!l)
return SELF;
if (rep->encoding != Parrot_fixed_8_encoding_ptr)
real_exception(INTERP, NULL, E_ValueError,
"unhandled string encoding in constructor");
/* "()" - no args */
if (l <= 2 && ((char *)rep->strstart)[0] == '(')
return SELF;
/* count commas */
p = rep->strstart;
for (i = l, n = 0; i; --i, ++p) {
if (*p == ',')
++n;
}
/* presize the array */
SELF.set_integer_native(n + 1);
/* parse string */
p = rep->strstart;
for (i = l, n = 0; i; --i, ++p) {
switch (*p) {
case ' ': continue;
case '\t': continue;
case '(': continue;
case ')': break;
case ',':
n++;
break;
default:
base = 10;
if (*p == '0') {
++p;
--i;
if (*p == 'b' || *p == 'B') {
base = 2;
++p;
--i;
}
else if (*p == 'x' || *p == 'X') {
base = 16;
++p;
--i;
}
}
start = p;
elem = strtoul(p, &p, base);
--p;
i -= (p - start);
SELF.set_integer_keyed_int(n, elem);
break;
}
}
return SELF;
}
/*
=item C<void destroy()>
Destroys the array.
=cut
*/
VTABLE void destroy() {
if (PMC_data(SELF))
mem_sys_free(PMC_data(SELF));
PMC_data(SELF) = NULL;
PMC_int_val(SELF) = 0;
}
/*
=item C<PMC *clone()>
Creates and returns a copy of the array.
=cut
*/
VTABLE PMC *clone() {
/* a quick hack to create a clone in the constant PMC arena
* this is needed for the call signatures
*
* a better way would be probably to supply a flag to the clone
* vtable
*/
PMC * const dest =
PObj_constant_TEST(SELF)
? constant_pmc_new(INTERP, SELF->vtable->base_type)
: pmc_new(INTERP, SELF->vtable->base_type);
if (PMC_data(SELF)) {
const INTVAL size = PMC_int_val(SELF);
PMC_int_val(dest) = size;
PMC_data(dest) = mem_allocate_n_typed(size, INTVAL);
mem_sys_memcopy(PMC_data(dest), PMC_data(SELF), size * sizeof (INTVAL));
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() {
const INTVAL size = SELF.elements();
return (INTVAL)(size != 0);
}
/*
=item C<INTVAL elements()>
=cut
*/
VTABLE INTVAL elements() {
return PMC_int_val(SELF);
}
/*
=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) {
INTVAL *data;
if (key < 0 || key >= PMC_int_val(SELF))
real_exception(interp, NULL, E_IndexError,
"FixedIntegerArray: index out of bounds!");
data = (INTVAL *)PMC_data(SELF);
return data[key];
}
/*
=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 = key_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 = key_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) {
PMC * const temp = SELF.get_pmc_keyed_int(key);
return VTABLE_get_string(INTERP, temp);
}
/*
=item C<STRING *get_repr()>
Returns the Parrot string representation C<key>.
=cut
*/
VTABLE STRING *get_repr() {
STRING *res = CONST_STRING(INTERP, "[ ");
const INTVAL n = VTABLE_elements(INTERP, SELF);
INTVAL j;
for (j = 0; j < n; ++j) {
PMC * const val = SELF.get_pmc_keyed_int(j);
res = string_append(INTERP, res, VTABLE_get_repr(INTERP, val));
if (j < n - 1)
res = string_append(INTERP, res, CONST_STRING(INTERP, ", "));
}
res = string_append(INTERP, res, CONST_STRING(INTERP, " ]"));
return res;
}
/*
=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 = key_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_Integer);
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 = key_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) {
if (PMC_int_val(SELF) || size < 1)
real_exception(INTERP, NULL, E_IndexError,
"FixedIntegerArray: Can't resize!");
PMC_int_val(SELF) = size;
PMC_data(SELF) = mem_sys_allocate_zeroed(size * sizeof (INTVAL));
PObj_active_destroy_SET(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) {
INTVAL *data;
if (key < 0 || key >= PMC_int_val(SELF))
real_exception(interp, NULL, E_IndexError,
"FixedIntegerArray: index out of bounds!");
data = (INTVAL *)PMC_data(SELF);
data[key] = value;
}
/*
=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 = key_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, (INTVAL)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 = key_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_Integer);
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 = key_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 = key_integer(INTERP, key);
SELF.set_pmc_keyed_int(k, value);
}
METHOD sort(PMC *cmp_func) {
UINTVAL n = (UINTVAL)PMC_int_val(SELF);
if (n > 1)
Parrot_quicksort(interp, PMC_data_typed(SELF, void **), n, cmp_func);
}
/*
=item C<void visit(visit_info *info)>
This is used by freeze/thaw to visit the contents of the array.
C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
=item C<void freeze(visit_info *info)>
Used to archive the array.
=item C<void thaw(visit_info *info)>
Used to unarchive the array.
=cut
*/
VTABLE void visit(visit_info *info) {
SUPER(info);
}
VTABLE void freeze(visit_info *info) {
IMAGE_IO *io = info->image_io;
INTVAL *ar;
INTVAL i, n;
SUPER(info);
n = VTABLE_elements(INTERP, SELF);
VTABLE_push_integer(INTERP, io, n);
ar = (INTVAL *)PMC_data(SELF);
for (i = 0; i < n; ++i)
VTABLE_push_integer(INTERP, io, ar[i]);
}
VTABLE void thaw(visit_info *info) {
if (info->extra_flags == EXTRA_IS_NULL) {
IMAGE_IO * const io = info->image_io;
const INTVAL n = VTABLE_shift_integer(INTERP, io);
PMC_int_val(SELF) = 0;
PMC_data(SELF) = NULL;
if (n) {
INTVAL i;
INTVAL *ar;
SELF.set_integer_native(n);
ar = (INTVAL *)PMC_data(SELF);
for (i = 0; i < n; ++i)
ar[i] = VTABLE_shift_integer(INTERP, io);
}
}
else
SUPER(info);
}
}
/*
=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.