summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2009-06-21 23:16:57 +0200
committerLudovic Courtès <ludo@gnu.org>2009-06-22 01:05:43 +0200
commit404bb5f87b66709206507acdf7b899101185a7a0 (patch)
treee893992fa46a837112c2f69550d4825afbcf12db
parent2d34e9244b8b35f62d086a88db749718a2a1a3b4 (diff)
downloadguile-404bb5f87b66709206507acdf7b899101185a7a0.tar.gz
bytevectors: Add a C-friendly API.
* doc/ref/api-data.texi (Bytevector Manipulation): Add `scm_is_bytevector ()', `scm_c_bytevector_length ()', `scm_c_bytevector_length ()', and `scm_c_bytevector_set_x ()'. * libguile/bytevectors.c (scm_is_bytevector, scm_c_bytevector_length, scm_c_bytevector_ref, scm_c_bytevector_set_x): New functions. (scm_bytevector_p): Use `scm_is_bytevector ()'. (scm_bytevector_length): Use `scm_c_bytevector_length ()'. * libguile/bytevectors.h (scm_is_bytevector, scm_c_bytevector_length, scm_c_bytevector_ref, scm_c_bytevector_set_x): New declarations.
-rwxr-xr-xdoc/ref/api-data.texi18
-rw-r--r--libguile/bytevectors.c61
-rw-r--r--libguile/bytevectors.h7
3 files changed, 79 insertions, 7 deletions
diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi
index eb059d329..4ff738c6b 100755
--- a/doc/ref/api-data.texi
+++ b/doc/ref/api-data.texi
@@ -3833,7 +3833,7 @@ The objects denoting big (resp. little) endianness.
@subsubsection Manipulating Bytevectors
Bytevectors can be created, copied, and analyzed with the following
-procedures.
+procedures and C functions.
@deffn {Scheme Procedure} make-bytevector len [fill]
@deffnx {C Function} scm_make_bytevector (len, fill)
@@ -3848,11 +3848,19 @@ is given, fill it with @var{fill}; @var{fill} must be in the range
Return true if @var{obj} is a bytevector.
@end deffn
+@deftypefn {C Function} int scm_is_bytevector (SCM obj)
+Equivalent to @code{scm_is_true (scm_bytevector_p (obj))}.
+@end deftypefn
+
@deffn {Scheme Procedure} bytevector-length bv
@deffnx {C Function} scm_bytevector_length (bv)
Return the length in bytes of bytevector @var{bv}.
@end deffn
+@deftypefn {C Function} size_t scm_c_bytevector_length (SCM bv)
+Likewise, return the length in bytes of bytevector @var{bv}.
+@end deftypefn
+
@deffn {Scheme Procedure} bytevector=? bv1 bv2
@deffnx {C Function} scm_bytevector_eq_p (bv1, bv2)
Return is @var{bv1} equals to @var{bv2}---i.e., if they have the same
@@ -3876,6 +3884,14 @@ and start writing at @var{target-start}.
Return a newly allocated copy of @var{bv}.
@end deffn
+@deftypefn {C Function} scm_t_uint8 scm_c_bytevector_ref (SCM bv, size_t index)
+Return the byte at @var{index} in bytevector @var{bv}.
+@end deftypefn
+
+@deftypefn {C Function} void scm_c_bytevector_set_x (SCM bv, size_t index, scm_t_uint8 value)
+Set the byte at @var{index} in @var{bv} to @var{value}.
+@end deftypefn
+
Low-level C macros are available. They do not perform any
type-checking; as such they should be used with care.
diff --git a/libguile/bytevectors.c b/libguile/bytevectors.c
index 83058ba0b..4dd66970d 100644
--- a/libguile/bytevectors.c
+++ b/libguile/bytevectors.c
@@ -274,6 +274,60 @@ scm_i_shrink_bytevector (SCM bv, size_t c_new_len)
return bv;
}
+int
+scm_is_bytevector (SCM obj)
+{
+ return SCM_SMOB_PREDICATE (scm_tc16_bytevector, obj);
+}
+
+size_t
+scm_c_bytevector_length (SCM bv)
+#define FUNC_NAME "scm_c_bytevector_length"
+{
+ SCM_VALIDATE_BYTEVECTOR (1, bv);
+
+ return SCM_BYTEVECTOR_LENGTH (bv);
+}
+#undef FUNC_NAME
+
+scm_t_uint8
+scm_c_bytevector_ref (SCM bv, size_t index)
+#define FUNC_NAME "scm_c_bytevector_ref"
+{
+ size_t c_len;
+ const scm_t_uint8 *c_bv;
+
+ SCM_VALIDATE_BYTEVECTOR (1, bv);
+
+ c_len = SCM_BYTEVECTOR_LENGTH (bv);
+ c_bv = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (bv);
+
+ if (SCM_UNLIKELY (index >= c_len))
+ scm_out_of_range (FUNC_NAME, scm_from_size_t (index));
+
+ return c_bv[index];
+}
+#undef FUNC_NAME
+
+void
+scm_c_bytevector_set_x (SCM bv, size_t index, scm_t_uint8 value)
+#define FUNC_NAME "scm_c_bytevector_set_x"
+{
+ size_t c_len;
+ scm_t_uint8 *c_bv;
+
+ SCM_VALIDATE_BYTEVECTOR (1, bv);
+
+ c_len = SCM_BYTEVECTOR_LENGTH (bv);
+ c_bv = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (bv);
+
+ if (SCM_UNLIKELY (index >= c_len))
+ scm_out_of_range (FUNC_NAME, scm_from_size_t (index));
+
+ c_bv[index] = value;
+}
+#undef FUNC_NAME
+
SCM_SMOB_PRINT (scm_tc16_bytevector, print_bytevector,
bv, port, pstate)
{
@@ -357,8 +411,7 @@ SCM_DEFINE (scm_bytevector_p, "bytevector?", 1, 0, 0,
"Return true if @var{obj} is a bytevector.")
#define FUNC_NAME s_scm_bytevector_p
{
- return (scm_from_bool (SCM_SMOB_PREDICATE (scm_tc16_bytevector,
- obj)));
+ return scm_from_bool (scm_is_bytevector (obj));
}
#undef FUNC_NAME
@@ -403,9 +456,7 @@ SCM_DEFINE (scm_bytevector_length, "bytevector-length", 1, 0, 0,
"Return the length (in bytes) of @var{bv}.")
#define FUNC_NAME s_scm_bytevector_length
{
- SCM_VALIDATE_BYTEVECTOR (1, bv);
-
- return (scm_from_uint (SCM_BYTEVECTOR_LENGTH (bv)));
+ return scm_from_uint (scm_c_bytevector_length (bv));
}
#undef FUNC_NAME
diff --git a/libguile/bytevectors.h b/libguile/bytevectors.h
index 208147627..df1ad2dfe 100644
--- a/libguile/bytevectors.h
+++ b/libguile/bytevectors.h
@@ -37,8 +37,13 @@
SCM_API SCM scm_endianness_big;
SCM_API SCM scm_endianness_little;
-SCM_API SCM scm_make_bytevector (SCM, SCM);
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);