Add methods for converting between Collections (asBag, asSet, etc)
[panda.git] / src / st-array.c
blob0722d6f0cfd99e48f78721f45ecbf736ddbfa158
1 /*
2 * st-array.c
4 * Copyright (c) 2008 Vincent Geddes
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
24 #include "st-array.h"
25 #include "st-universe.h"
26 #include "st-utils.h"
27 #include "st-behavior.h"
28 #include <string.h>
30 st_oop
31 st_array_allocate (st_oop class, st_uint size)
33 st_oop array;
34 st_oop *elements;
36 st_assert (size >= 0);
38 array = st_memory_allocate (ST_SIZE_OOPS (struct st_array) + size);
39 if (array == 0) {
40 st_memory_perform_gc ();
41 class = st_memory_remap_reference (class);
42 array = st_memory_allocate (ST_SIZE_OOPS (struct st_array) + size);
43 st_assert (array != 0);
45 st_object_initialize_header (array, class);
47 ST_ARRAYED_OBJECT (array)->size = st_smi_new (size);
48 elements = ST_ARRAY (array)->elements;
49 for (st_uint i = 0; i < size; i++)
50 elements[i] = ST_NIL;
52 return array;
56 /* ByteArray */
58 st_oop
59 st_byte_array_allocate (st_oop class, int size)
61 st_uint size_oops;
62 st_oop array;
64 st_assert (size >= 0);
66 /* add 1 byte for NULL terminator. Allows toll-free bridging with C string function */
67 size_oops = ST_ROUNDED_UP_OOPS (size + 1);
69 array = st_memory_allocate (ST_SIZE_OOPS (struct st_byte_array) + size_oops);
70 if (array == 0) {
71 st_memory_perform_gc ();
72 class = st_memory_remap_reference (class);
73 array = st_memory_allocate (ST_SIZE_OOPS (struct st_array) + size_oops);
74 st_assert (array != 0);
77 st_object_initialize_header (array, class);
79 ST_ARRAYED_OBJECT (array)->size = st_smi_new (size);
80 memset (st_byte_array_bytes (array), 0, ST_OOPS_TO_BYTES (size_oops));
82 return array;
85 bool
86 st_byte_array_equal (st_oop object, st_oop other)
88 int size, size_other;
90 if (st_object_class (other) != ST_BYTE_ARRAY_CLASS &&
91 st_object_class (other) != ST_STRING_CLASS &&
92 st_object_class (other) != ST_SYMBOL_CLASS)
93 return false;
95 size = st_smi_value (ST_ARRAYED_OBJECT (object)->size);
96 size_other = st_smi_value (ST_ARRAYED_OBJECT (other)->size);
98 if (size != size_other)
99 return false;
101 return memcmp (st_byte_array_bytes (object), st_byte_array_bytes (other), size) == 0;
104 st_uint
105 st_byte_array_hash (st_oop object)
107 return st_string_hash ((char *) st_byte_array_bytes (object));
110 /* WordArray */
112 st_oop
113 st_word_array_allocate (st_oop class, int size)
115 st_oop array;
116 int size_oops;
117 st_uint *elements;
119 st_assert (size >= 0);
121 size_oops = size / (sizeof (st_oop) / sizeof (st_uint));
123 array = st_memory_allocate (ST_SIZE_OOPS (struct st_word_array) + size_oops);
124 if (array == 0) {
125 st_memory_perform_gc ();
126 class = st_memory_remap_reference (class);
127 array = st_memory_allocate (ST_SIZE_OOPS (struct st_array) + size_oops);
128 st_assert (array != 0);
130 st_object_initialize_header (array, class);
132 ST_ARRAYED_OBJECT (array)->size = st_smi_new (size);
133 elements = st_word_array_elements (array);
134 for (int i = 0; i < size; i++)
135 elements[i] = 0;
137 return array;
140 /* FloatArray */
142 st_oop
143 st_float_array_allocate (st_oop class, int size)
145 st_oop object;
146 double *elements;
147 int size_oops;
149 st_assert (size >= 0);
151 /* get actual size in oops (dependent on whether system is 64bit or 32bit) */
152 size_oops = size * (sizeof (double) / sizeof (st_oop));
154 object = st_memory_allocate (ST_SIZE_OOPS (struct st_float_array) + size_oops);
155 if (object == 0) {
156 st_memory_perform_gc ();
157 class = st_memory_remap_reference (class);
158 object = st_memory_allocate (ST_SIZE_OOPS (struct st_array) + size_oops);
159 st_assert (object != 0);
161 st_object_initialize_header (object, class);
163 ST_ARRAYED_OBJECT (object)->size = st_smi_new (size);
165 elements = ST_FLOAT_ARRAY (object)->elements;
166 for (int i = 0; i < size; i++)
167 elements[i] = (double) 0;
169 return object;