1 /* Copyright (C) 1995,1996,1997,1998,2000,2001,2002,2003,2004, 2005, 2006, 2009 Free Software Foundation, Inc.
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public License
5 * as published by the Free Software Foundation; either version 3 of
6 * the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 #include "libguile/_scm.h"
27 #include "libguile/__scm.h"
29 #include "libguile/array-handle.h"
30 #include "libguile/unif.h"
31 #include "libguile/strings.h"
32 #include "libguile/vectors.h"
33 #include "libguile/srfi-4.h"
34 #include "libguile/bytevectors.h"
38 enclosed_ref (scm_t_array_handle
*h
, ssize_t pos
)
40 return scm_i_cvref (SCM_I_ARRAY_V (h
->array
), pos
+ h
->base
, 1);
44 vector_ref (scm_t_array_handle
*h
, ssize_t pos
)
46 return ((const SCM
*)h
->elements
)[pos
];
50 string_ref (scm_t_array_handle
*h
, ssize_t pos
)
53 if (SCM_I_ARRAYP (h
->array
))
54 return scm_c_string_ref (SCM_I_ARRAY_V (h
->array
), pos
);
56 return scm_c_string_ref (h
->array
, pos
);
60 bitvector_ref (scm_t_array_handle
*h
, ssize_t pos
)
62 pos
+= scm_array_handle_bit_elements_offset (h
);
64 scm_from_bool (((scm_t_uint32
*)h
->elements
)[pos
/32] & (1l << (pos
% 32)));
68 bytevector_ref (scm_t_array_handle
*h
, ssize_t pos
)
70 return scm_from_uint8 (((scm_t_uint8
*) h
->elements
)[pos
]);
74 memoize_ref (scm_t_array_handle
*h
, ssize_t pos
)
78 if (SCM_I_ENCLOSED_ARRAYP (v
))
80 h
->ref
= enclosed_ref
;
81 return enclosed_ref (h
, pos
);
85 v
= SCM_I_ARRAY_V (v
);
87 if (scm_is_vector (v
))
89 h
->elements
= scm_array_handle_elements (h
);
92 else if (scm_is_uniform_vector (v
))
94 h
->elements
= scm_array_handle_uniform_elements (h
);
95 h
->ref
= scm_i_uniform_vector_ref_proc (v
);
97 else if (scm_is_string (v
))
101 else if (scm_is_bitvector (v
))
103 h
->elements
= scm_array_handle_bit_elements (h
);
104 h
->ref
= bitvector_ref
;
106 else if (scm_is_bytevector (v
))
108 h
->elements
= scm_array_handle_uniform_elements (h
);
109 h
->ref
= bytevector_ref
;
112 scm_misc_error (NULL
, "unknown array type: ~a", scm_list_1 (h
->array
));
114 return h
->ref (h
, pos
);
118 enclosed_set (scm_t_array_handle
*h
, ssize_t pos
, SCM val
)
120 scm_wrong_type_arg_msg (NULL
, 0, h
->array
, "non-enclosed array");
124 vector_set (scm_t_array_handle
*h
, ssize_t pos
, SCM val
)
126 ((SCM
*)h
->writable_elements
)[pos
] = val
;
130 string_set (scm_t_array_handle
*h
, ssize_t pos
, SCM val
)
133 if (SCM_I_ARRAYP (h
->array
))
134 scm_c_string_set_x (SCM_I_ARRAY_V (h
->array
), pos
, val
);
136 scm_c_string_set_x (h
->array
, pos
, val
);
140 bitvector_set (scm_t_array_handle
*h
, ssize_t pos
, SCM val
)
143 pos
+= scm_array_handle_bit_elements_offset (h
);
144 mask
= 1l << (pos
% 32);
145 if (scm_to_bool (val
))
146 ((scm_t_uint32
*)h
->writable_elements
)[pos
/32] |= mask
;
148 ((scm_t_uint32
*)h
->writable_elements
)[pos
/32] &= ~mask
;
152 bytevector_set (scm_t_array_handle
*h
, ssize_t pos
, SCM val
)
155 scm_t_uint8
*elements
;
157 c_value
= scm_to_uint8 (val
);
158 elements
= (scm_t_uint8
*) h
->elements
;
159 elements
[pos
] = (scm_t_uint8
) c_value
;
163 memoize_set (scm_t_array_handle
*h
, ssize_t pos
, SCM val
)
167 if (SCM_I_ENCLOSED_ARRAYP (v
))
169 h
->set
= enclosed_set
;
170 enclosed_set (h
, pos
, val
);
174 if (SCM_I_ARRAYP (v
))
175 v
= SCM_I_ARRAY_V (v
);
177 if (scm_is_vector (v
))
179 h
->writable_elements
= scm_array_handle_writable_elements (h
);
182 else if (scm_is_uniform_vector (v
))
184 h
->writable_elements
= scm_array_handle_uniform_writable_elements (h
);
185 h
->set
= scm_i_uniform_vector_set_proc (v
);
187 else if (scm_is_string (v
))
191 else if (scm_is_bitvector (v
))
193 h
->writable_elements
= scm_array_handle_bit_writable_elements (h
);
194 h
->set
= bitvector_set
;
196 else if (scm_is_bytevector (v
))
198 h
->elements
= scm_array_handle_uniform_writable_elements (h
);
199 h
->set
= bytevector_set
;
202 scm_misc_error (NULL
, "unknown array type: ~a", scm_list_1 (h
->array
));
204 h
->set (h
, pos
, val
);
208 scm_array_get_handle (SCM array
, scm_t_array_handle
*h
)
211 h
->ref
= memoize_ref
;
212 h
->set
= memoize_set
;
214 if (SCM_I_ARRAYP (array
) || SCM_I_ENCLOSED_ARRAYP (array
))
216 h
->dims
= SCM_I_ARRAY_DIMS (array
);
217 h
->base
= SCM_I_ARRAY_BASE (array
);
219 else if (scm_is_generalized_vector (array
))
222 h
->dim0
.ubnd
= scm_c_generalized_vector_length (array
) - 1;
228 scm_wrong_type_arg_msg (NULL
, 0, array
, "array");
232 scm_array_handle_release (scm_t_array_handle
*h
)
234 /* Nothing to do here until arrays need to be reserved for real.
239 scm_array_handle_rank (scm_t_array_handle
*h
)
241 if (SCM_I_ARRAYP (h
->array
) || SCM_I_ENCLOSED_ARRAYP (h
->array
))
242 return SCM_I_ARRAY_NDIM (h
->array
);
248 scm_array_handle_dims (scm_t_array_handle
*h
)
254 scm_array_handle_elements (scm_t_array_handle
*h
)
257 if (SCM_I_ARRAYP (vec
))
258 vec
= SCM_I_ARRAY_V (vec
);
259 if (SCM_I_IS_VECTOR (vec
))
260 return SCM_I_VECTOR_ELTS (vec
) + h
->base
;
261 scm_wrong_type_arg_msg (NULL
, 0, h
->array
, "non-uniform array");
265 scm_array_handle_writable_elements (scm_t_array_handle
*h
)
268 if (SCM_I_ARRAYP (vec
))
269 vec
= SCM_I_ARRAY_V (vec
);
270 if (SCM_I_IS_VECTOR (vec
))
271 return SCM_I_VECTOR_WELTS (vec
) + h
->base
;
272 scm_wrong_type_arg_msg (NULL
, 0, h
->array
, "non-uniform array");
277 scm_init_array_handle (void)
279 #include "libguile/array-handle.x"