mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
Bytevectors have a very close relationship to other forms of uniform vectors. Often you want to view a u64vector as a series of bytes, for writing over a socket; or to process an incoming stream using the convenient and less error-prone s16vector-ref API rather than bytevector-s16-native-ref. The essential needs of the representation of a bytevector and an s64vector are the same, so we take advantage of that and extend the bytevector implementation to have a "native type" field, which defaults to VU8. This commit doesn't actually expose any user-noticeable changes, however. * libguile/bytevectors.h (SCM_BYTEVECTOR_ELEMENT_TYPE): New internal defines. (scm_i_make_typed_bytevector, scm_c_take_typed_bytevector): New internal functions. * libguile/bytevectors.c (SCM_BYTEVECTOR_SET_ELEMENT_TYPE): (SCM_BYTEVECTOR_TYPE_SIZE): (SCM_BYTEVECTOR_TYPED_LENGTH): New internal macros. (make_bytevector, make_bytevector_from_buffer): Take an extra argument, the element type. The length argument is interpreted as being the number of elements, which corresponds to the number of bytes in the default VU8 case. Doing it this way eliminates a class of bugs -- e.g. a u32vector of length 3 bytes doesn't make sense. We do have to check for another class of bugs: overflow. The length stored on the bytevector itself is still the byte length, though. (scm_i_make_typed_bytevector): (scm_c_take_typed_bytevector): New internal functions. (scm_i_shrink_bytevector): Make sure the new size is valid for the bytevector's type. (scm_i_bytevector_generalized_set_x): Remove this function, the array-handle infrastructure takes care of this for us. (print_bytevector): Print the bytevector according to its type. (scm_make_bytevector, scm_bytevector_copy) (scm_uniform_array_to_bytevector) (scm_u8_list_to_bytevector, scm_bytevector_to_uint_list): Adapt to make_bytevector extra arg. (bv_handle_ref, bv_handle_set_x): Adapt to ref and set based on the type of the bytevector, e.g. f64 or u8. (bytevector_get_handle): Set the typed length of the vector, not the byte length. Conflicts: libguile/bytevectors.c
150 lines
6.1 KiB
C
150 lines
6.1 KiB
C
#ifndef SCM_BYTEVECTORS_H
|
||
#define SCM_BYTEVECTORS_H
|
||
|
||
/* Copyright (C) 2009 Free Software Foundation, Inc.
|
||
*
|
||
* This library is free software; you can redistribute it and/or
|
||
* modify it under the terms of the GNU Lesser General Public License
|
||
* as published by the Free Software Foundation; either version 3 of
|
||
* the License, or (at your option) any later version.
|
||
*
|
||
* This library is distributed in the hope that it will be useful, but
|
||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
* Lesser General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU Lesser General Public
|
||
* License along with this library; if not, write to the Free Software
|
||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||
* 02110-1301 USA
|
||
*/
|
||
|
||
|
||
|
||
#include "libguile/__scm.h"
|
||
|
||
|
||
/* R6RS bytevectors. */
|
||
|
||
#define SCM_BYTEVECTOR_LENGTH(_bv) \
|
||
((size_t) SCM_SMOB_DATA (_bv))
|
||
#define SCM_BYTEVECTOR_CONTENTS(_bv) \
|
||
(SCM_BYTEVECTOR_INLINE_P (_bv) \
|
||
? (signed char *) SCM_SMOB_OBJECT_2_LOC (_bv) \
|
||
: (signed char *) SCM_SMOB_DATA_2 (_bv))
|
||
|
||
|
||
SCM_API SCM scm_endianness_big;
|
||
SCM_API SCM scm_endianness_little;
|
||
|
||
SCM_API SCM scm_c_make_bytevector (size_t);
|
||
SCM_API int scm_is_bytevector (SCM);
|
||
SCM_API size_t scm_c_bytevector_length (SCM);
|
||
SCM_API scm_t_uint8 scm_c_bytevector_ref (SCM, size_t);
|
||
SCM_API void scm_c_bytevector_set_x (SCM, size_t, scm_t_uint8);
|
||
|
||
SCM_API SCM scm_make_bytevector (SCM, SCM);
|
||
SCM_API SCM scm_native_endianness (void);
|
||
SCM_API SCM scm_bytevector_p (SCM);
|
||
SCM_API SCM scm_bytevector_length (SCM);
|
||
SCM_API SCM scm_bytevector_eq_p (SCM, SCM);
|
||
SCM_API SCM scm_bytevector_fill_x (SCM, SCM);
|
||
SCM_API SCM scm_bytevector_copy_x (SCM, SCM, SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_copy (SCM);
|
||
|
||
SCM_API SCM scm_uniform_array_to_bytevector (SCM);
|
||
|
||
SCM_API SCM scm_bytevector_to_u8_list (SCM);
|
||
SCM_API SCM scm_u8_list_to_bytevector (SCM);
|
||
SCM_API SCM scm_uint_list_to_bytevector (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_to_uint_list (SCM, SCM, SCM);
|
||
SCM_API SCM scm_sint_list_to_bytevector (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_to_sint_list (SCM, SCM, SCM);
|
||
|
||
SCM_API SCM scm_bytevector_u16_native_ref (SCM, SCM);
|
||
SCM_API SCM scm_bytevector_s16_native_ref (SCM, SCM);
|
||
SCM_API SCM scm_bytevector_u32_native_ref (SCM, SCM);
|
||
SCM_API SCM scm_bytevector_s32_native_ref (SCM, SCM);
|
||
SCM_API SCM scm_bytevector_u64_native_ref (SCM, SCM);
|
||
SCM_API SCM scm_bytevector_s64_native_ref (SCM, SCM);
|
||
SCM_API SCM scm_bytevector_u8_ref (SCM, SCM);
|
||
SCM_API SCM scm_bytevector_s8_ref (SCM, SCM);
|
||
SCM_API SCM scm_bytevector_uint_ref (SCM, SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_sint_ref (SCM, SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_u16_ref (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_s16_ref (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_u32_ref (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_s32_ref (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_u64_ref (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_s64_ref (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_u16_native_set_x (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_s16_native_set_x (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_u32_native_set_x (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_s32_native_set_x (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_u64_native_set_x (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_s64_native_set_x (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_u8_set_x (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_s8_set_x (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_uint_set_x (SCM, SCM, SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_sint_set_x (SCM, SCM, SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_u16_set_x (SCM, SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_s16_set_x (SCM, SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_u32_set_x (SCM, SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_s32_set_x (SCM, SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_u64_set_x (SCM, SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_s64_set_x (SCM, SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_ieee_single_ref (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_ieee_single_native_ref (SCM, SCM);
|
||
SCM_API SCM scm_bytevector_ieee_single_set_x (SCM, SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_ieee_single_native_set_x (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_ieee_double_ref (SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_ieee_double_native_ref (SCM, SCM);
|
||
SCM_API SCM scm_bytevector_ieee_double_set_x (SCM, SCM, SCM, SCM);
|
||
SCM_API SCM scm_bytevector_ieee_double_native_set_x (SCM, SCM, SCM);
|
||
SCM_API SCM scm_string_to_utf8 (SCM);
|
||
SCM_API SCM scm_string_to_utf16 (SCM, SCM);
|
||
SCM_API SCM scm_string_to_utf32 (SCM, SCM);
|
||
SCM_API SCM scm_utf8_to_string (SCM);
|
||
SCM_API SCM scm_utf16_to_string (SCM, SCM);
|
||
SCM_API SCM scm_utf32_to_string (SCM, SCM);
|
||
|
||
|
||
|
||
/* Internal API. */
|
||
|
||
/* The threshold (in octets) under which bytevectors are stored "in-line",
|
||
i.e., without allocating memory beside the SMOB itself (a double cell).
|
||
This optimization is necessary since small bytevectors are expected to be
|
||
common. */
|
||
#define SCM_BYTEVECTOR_P(_bv) \
|
||
SCM_SMOB_PREDICATE (scm_tc16_bytevector, _bv)
|
||
#define SCM_F_BYTEVECTOR_INLINE 0x1
|
||
#define SCM_BYTEVECTOR_INLINE_P(_bv) \
|
||
(SCM_SMOB_FLAGS (_bv) & SCM_F_BYTEVECTOR_INLINE)
|
||
#define SCM_BYTEVECTOR_ELEMENT_TYPE(_bv) \
|
||
(SCM_SMOB_FLAGS (_bv) >> 8)
|
||
|
||
/* Hint that is passed to `scm_gc_malloc ()' and friends. */
|
||
#define SCM_GC_BYTEVECTOR "bytevector"
|
||
|
||
SCM_INTERNAL SCM scm_i_make_typed_bytevector (size_t, scm_t_array_element_type);
|
||
SCM_INTERNAL SCM scm_c_take_typed_bytevector (signed char *, size_t,
|
||
scm_t_array_element_type);
|
||
|
||
SCM_INTERNAL void scm_bootstrap_bytevectors (void);
|
||
SCM_INTERNAL void scm_init_bytevectors (void);
|
||
|
||
SCM_INTERNAL scm_t_bits scm_tc16_bytevector;
|
||
SCM_INTERNAL SCM scm_i_native_endianness;
|
||
SCM_INTERNAL SCM scm_c_take_bytevector (signed char *, size_t);
|
||
|
||
#define scm_c_shrink_bytevector(_bv, _len) \
|
||
(SCM_BYTEVECTOR_INLINE_P (_bv) \
|
||
? (_bv) \
|
||
: scm_i_shrink_bytevector ((_bv), (_len)))
|
||
|
||
SCM_INTERNAL SCM scm_i_shrink_bytevector (SCM, size_t);
|
||
SCM_INTERNAL void scm_i_bytevector_generalized_set_x (SCM, size_t, SCM);
|
||
SCM_INTERNAL SCM scm_null_bytevector;
|
||
|
||
#endif /* SCM_BYTEVECTORS_H */
|