From 547bd47887d7096e5568c31edb0b1661b1ac23ec Mon Sep 17 00:00:00 2001
From: Daniel Llorens <lloda@sarc.name>
Date: Sun, 15 Jan 2023 22:41:48 +0100
Subject: [PATCH] Document R7RS functions related to bytevectors

* doc/ref/api-data.texi (Bytevectors): Document R7RS bytevector,
  bytevector-copy, bytevector-copy!, bytevector-append.
  Fix typo in (r6:bytevector-copy), index need not be positive.
  Fix typos in bytevector-length, bytevector=, bytevector-fill!.
* doc/ref/api-io.texi (Binary I/O): Document R7RS
  open-output-bytevector, write-u8, read-u8, peek-u8,
  get-output-bytevector, open-input-bytevector, read-bytevector!,
  read-bytevector, write-bytevector.
---
 doc/ref/api-data.texi | 102 ++++++++++++++++++++++++++++++++---
 doc/ref/api-io.texi   | 121 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 216 insertions(+), 7 deletions(-)

diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi
index d332aa997..e4f3978b4 100644
--- a/doc/ref/api-data.texi
+++ b/doc/ref/api-data.texi
@@ -6635,7 +6635,7 @@ and writing.
 @cindex bytevector
 @cindex R6RS
 
-A @dfn{bytevector} is a raw bit string.  The @code{(rnrs bytevectors)}
+A @dfn{bytevector} is a raw byte string.  The @code{(rnrs bytevectors)}
 module provides the programming interface specified by the
 @uref{http://www.r6rs.org/, Revised^6 Report on the Algorithmic Language
 Scheme (R6RS)}.  It contains procedures to manipulate bytevectors and
@@ -6722,6 +6722,7 @@ The objects denoting big- and little-endianness, respectively.
 Bytevectors can be created, copied, and analyzed with the following
 procedures and C functions.
 
+@anchor{x-make-bytevector}
 @deffn {Scheme Procedure} make-bytevector len [fill]
 @deffnx {C Function} scm_make_bytevector (len, fill)
 @deffnx {C Function} scm_c_make_bytevector (size_t len)
@@ -6730,6 +6731,7 @@ is given, fill it with @var{fill}; @var{fill} must be in the range
 [-128,255].
 @end deffn
 
+@anchor{x-bytevector?}
 @deffn {Scheme Procedure} bytevector? obj
 @deffnx {C Function} scm_bytevector_p (obj)
 Return true if @var{obj} is a bytevector.
@@ -6739,6 +6741,7 @@ Return true if @var{obj} is a bytevector.
 Equivalent to @code{scm_is_true (scm_bytevector_p (obj))}.
 @end deftypefn
 
+@anchor{x-bytevector-length}
 @deffn {Scheme Procedure} bytevector-length bv
 @deffnx {C Function} scm_bytevector_length (bv)
 Return the length in bytes of bytevector @var{bv}.
@@ -6750,31 +6753,33 @@ Likewise, return the length in bytes of bytevector @var{bv}.
 
 @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
+Return @code{#t} if @var{bv1} equals @var{bv2}---i.e., if they have the same
 length and contents.
 @end deffn
 
 @deffn {Scheme Procedure} bytevector-fill! bv fill [start [end]]
 @deffnx {C Function} scm_bytevector_fill_x (bv, fill)
 Fill positions [@var{start} ... @var{end}) of bytevector @var{bv} with
-byte @var{fill}. @var{start} defaults to 0 and @var{end} defaults to the
-length of @var{bv}.@footnote{R6RS defines @code{(bytevector-fill! bv
-fill)}. Arguments @var{start} and @var{end} are a Guile extension
+byte @var{fill}.  @var{start} defaults to 0 and @var{end} defaults to the
+length of @var{bv}.@footnote{R6RS only defines @code{(bytevector-fill! bv
+fill)}.  Arguments @var{start} and @var{end} are a Guile extension
 (cf. @ref{x-vector-fill!,@code{vector-fill!}},
 @ref{x-string-fill!,@code{string-fill!}}).}
 @end deffn
 
+@anchor{x-r6:bytevector-copy!}
 @deffn {Scheme Procedure} bytevector-copy! source source-start target target-start len
 @deffnx {C Function} scm_bytevector_copy_x (source, source_start, target, target_start, len)
 Copy @var{len} bytes from @var{source} into @var{target}, starting
-reading from @var{source-start} (a positive index within @var{source})
+reading from @var{source-start} (an index index within @var{source})
 and writing at @var{target-start}.
 
 It is permitted for the @var{source} and @var{target} regions to
-overlap. In that case, copying takes place as if the source is first
+overlap.  In that case, copying takes place as if the source is first
 copied into a temporary bytevector and then into the destination.
 @end deffn
 
+@anchor{x-r6:bytevector-copy}
 @deffn {Scheme Procedure} bytevector-copy bv
 @deffnx {C Function} scm_bytevector_copy (bv)
 Return a newly allocated copy of @var{bv}.
@@ -6799,6 +6804,86 @@ Return the length in bytes of bytevector @var{bv}.
 Return a pointer to the contents of bytevector @var{bv}.
 @end deftypefn
 
+@subsubheading Bytevector Procedures in R7RS
+
+@ref{R7RS Standard Libraries,R7RS} defines a set of bytevector
+manipulation procedures, accessible with
+
+@example
+(use-modules (scheme base))
+@end example
+
+Of these, @ref{x-make-bytevector,@code{make-bytevector}},
+@ref{x-bytevector?,@code{bytevector?}},
+@ref{x-bytevector-length,@code{bytevector-length}},
+@ref{x-bytevector-u8-ref,@code{bytevector-u8-ref}} and
+@ref{x-bytevector-u8-set!,@code{bytevector-u8-set!}} have the same
+definition as in R6RS.  The procedures listed below either have a
+different definition in R7RS and R6RS, or are not defined in R6RS.
+
+@deffn {Scheme Procedure} bytevector arg @dots{}
+Return a newly allocated bytevector composed of the given arguments.
+Analogous to @code{list}.
+
+@lisp
+(bytevector 2 3 4) @result{} #vu8(2 3 4)
+@end lisp
+
+See also @ref{x-u8-list->bytevector,@code{u8-list->bytevector}}.
+@end deffn
+
+@anchor{x-r7:bytevector-copy}
+@deffn {Scheme Procedure} bytevector-copy bv [start [end]]
+Returns a newly allocated bytevector containing the elements of @var{bv}
+in the range [@var{start} ... @var{end}).  @var{start} defaults to 0 and
+@var{end} defaults to the length of @var{bv}.
+
+@lisp
+(define bv #vu8(0 1 2 3 4 5))
+(bytevector-copy bv) @result{} #vu8(0 1 2 3 4 5)
+(bytevector-copy bv 2) @result{} #vu8(2 3 4 5)
+(bytevector-copy bv 2 4) @result{} #vu8(2 3)
+@end lisp
+
+See also @ref{x-r6:bytevector-copy,the R6RS version}.
+@end deffn
+
+@anchor{x-r7:bytevector-copy!}
+@deffn {Scheme Procedure} bytevector-copy! dst at src [start [end]]
+Copy the block of elements from bytevector @var{src} in the range
+[@var{start} ... @var{end}) into bytevector @var{dst}, starting at
+position @var{at}.  @var{start} defaults to 0 and @var{end} defaults to
+the length of @var{src}.  It is an error for @var{dst}
+to have a length less than @var{at} + (@var{end} - @var{start}).
+
+See also @ref{x-r6:bytevector-copy!,the R6RS version}.  With
+
+@lisp
+(use-modules ((rnrs bytevectors) #:prefix r6:)
+             ((scheme base) #:prefix r7:))
+@end lisp
+
+the following calls are equivalent:
+
+@lisp
+(r6:bytevector-copy! source source-start target target-start len)
+(r7:bytevector-copy! target target-start source source-start (+ source-start len))
+@end lisp
+
+@end deffn
+
+@rnindex bytevector-append
+@deffn {Scheme Procedure} bytevector-append arg @dots{}
+Return a newly allocated bytevector whose characters form the
+concatenation of the given bytevectors @var{arg} @enddots{}
+
+@lisp
+(bytevector-append #vu8(0 1 2) #vu8(3 4 5))
+@result{} #vu8(0 1 2 3 4 5)
+@end lisp
+@end deffn
+
+
 
 @node Bytevectors as Integers
 @subsubsection Interpreting Bytevector Contents as Integers
@@ -6852,6 +6937,7 @@ Set the @var{size}-byte long signed integer at @var{index} to
 The following procedures are similar to the ones above, but specialized
 to a given integer size:
 
+@anchor{x-bytevector-u8-ref}
 @deffn {Scheme Procedure} bytevector-u8-ref bv index
 @deffnx {Scheme Procedure} bytevector-s8-ref bv index
 @deffnx {Scheme Procedure} bytevector-u16-ref bv index endianness
@@ -6873,6 +6959,7 @@ Return the unsigned @var{n}-bit (signed) integer (where @var{n} is 8,
 @var{endianness}.
 @end deffn
 
+@anchor{x-bytevector-u8-set!}
 @deffn {Scheme Procedure} bytevector-u8-set! bv index value
 @deffnx {Scheme Procedure} bytevector-s8-set! bv index value
 @deffnx {Scheme Procedure} bytevector-u16-set! bv index value endianness
@@ -6952,6 +7039,7 @@ Return a newly allocated list of unsigned 8-bit integers from the
 contents of @var{bv}.
 @end deffn
 
+@anchor{x-u8-list->bytevector}
 @deffn {Scheme Procedure} u8-list->bytevector lst
 @deffnx {C Function} scm_u8_list_to_bytevector (lst)
 Return a newly allocated bytevector consisting of the unsigned 8-bit
diff --git a/doc/ref/api-io.texi b/doc/ref/api-io.texi
index a0be2dd57..86f83e85e 100644
--- a/doc/ref/api-io.texi
+++ b/doc/ref/api-io.texi
@@ -150,12 +150,14 @@ some different kind of port, that's not the case: all ports in Guile are
 both binary and textual ports.
 
 @cindex binary input
+@anchor{x-get-u8}
 @deffn {Scheme Procedure} get-u8 port
 @deffnx {C Function} scm_get_u8 (port)
 Return an octet read from @var{port}, an input port, blocking as
 necessary, or the end-of-file object.
 @end deffn
 
+@anchor{x-lookahead-u8}
 @deffn {Scheme Procedure} lookahead-u8 port
 @deffnx {C Function} scm_lookahead_u8 (port)
 Like @code{get-u8} but does not update @var{port}'s position to point
@@ -227,6 +229,7 @@ will be read again in last-in first-out order.
 To perform binary output on a port, use @code{put-u8} or
 @code{put-bytevector}.
 
+@anchor{x-put-u8}
 @deffn {Scheme Procedure} put-u8 port octet
 @deffnx {C Function} scm_put_u8 (port, octet)
 Write @var{octet}, an integer in the 0--255 range, to @var{port}, a
@@ -239,6 +242,124 @@ Write the contents of @var{bv} to @var{port}, optionally starting at
 index @var{start} and limiting to @var{count} octets.
 @end deffn
 
+@subsubheading Binary I/O in R7RS
+
+@ref{R7RS Standard Libraries,R7RS} defines the following binary I/O
+procedures.  Access them with
+
+@example
+(use-modules (scheme base))
+@end example
+
+@anchor{x-open-output-bytevector}
+@deffn {Scheme Procedure} open-output-bytevector
+Returns a binary output port that will accumulate bytes
+for retrieval by @ref{x-get-output-bytevector,@code{get-output-bytevector}}.
+@end deffn
+
+@deffn {Scheme Procedure} write-u8 byte [out]
+Writes @var{byte} to the given binary output port @var{out} and returns
+an unspecified value.  @var{out} defaults to @code{(current-output-port)}.
+
+See also @ref{x-put-u8,@code{put-u8}}.
+@end deffn
+
+@deffn {Scheme Procedure} read-u8 [in]
+Returns the next byte available from the binary input port @var{in},
+updating the port to point to the following byte.  If no more bytes are
+available, an end-of-file object is returned.  @var{in} defaults to
+@code{(current-input-port)}.
+
+See also @ref{x-get-u8,@code{get-u8}}.
+@end deffn
+
+@deffn {Scheme Procedure} peek-u8 [in]
+Returns the next byte available from the binary input port @var{in},
+but without updating the port to point to the following
+byte.  If no more bytes are available, an end-of-file object
+is returned.  @var{in} defaults to @code{(current-input-port)}.
+
+See also @ref{x-lookahead-u8,@code{lookahead-u8}}.
+@end deffn
+
+@anchor{x-get-output-bytevector}
+@deffn {Scheme Procedure} get-output-bytevector port
+Returns a bytevector consisting of the bytes that have been output to
+@var{port} so far in the order they were output.  It is an error if
+@var{port} was not created with
+@ref{x-open-output-bytevector,@code{open-output-bytevector}}.
+
+@example
+(define out (open-output-bytevector))
+(write-u8 1 out)
+(write-u8 2 out)
+(write-u8 3 out)
+(get-output-bytevector out) @result{} #vu8(1 2 3)
+@end example
+@end deffn
+
+@deffn {Scheme Procedure} open-input-bytevector bv
+Takes a bytevector @var{bv} and returns a binary input port that
+delivers bytes from @var{bv}.
+
+@example
+(define in (open-input-bytevector #vu8(1 2 3)))
+(read-u8 in) @result{} 1
+(peek-u8 in) @result{} 2
+(read-u8 in) @result{} 2
+(read-u8 in) @result{} 3
+(read-u8 in) @result{} #<eof>
+@end example
+@end deffn
+
+@deffn {Scheme Procedure} read-bytevector! bv [port [start [end]]]
+Reads the next @var{end} - @var{start} bytes, or as many as are
+available before the end of file, from the binary input port into the
+bytevector @var{bv} in left-to-right order beginning at the @var{start}
+position.  If @var{end} is not supplied, reads until the end of @var{bv}
+has been reached.  If @var{start} is not supplied, reads beginning at
+position 0.
+
+Returns the number of bytes read.  If no bytes are available, an
+end-of-file object is returned.
+
+@example
+(define in (open-input-bytevector #vu8(1 2 3)))
+(define bv (make-bytevector 5 0))
+(read-bytevector! bv in 1 3) @result{} 2
+bv @result{} #vu8(0 1 2 0 0 0)
+@end example
+
+@end deffn
+
+@deffn {Scheme Procedure} read-bytevector k in
+Reads the next @var{k} bytes, or as many as are available before the end
+of file if that is less than @var{k}, from the binary input port
+@var{in} into a newly allocated bytevector in left-to-right order, and
+returns the bytevector.  If no bytes are available before the end of
+file, an end-of-file object is returned.
+
+@example
+(define bv #vu8(1 2 3))
+(read-bytevector 2 (open-input-bytevector bv)) @result{} #vu8(1 2)
+(read-bytevector 10 (open-input-bytevector bv)) @result{} #vu8(1 2 3)
+@end example
+
+@end deffn
+
+@deffn {Scheme Procedure} write-bytevector bv [port [start [end]]]
+Writes the bytes of bytevector @var{bv} from @var{start} to @var{end} in
+left-to-right order to the binary output @var{port}.  @var{start}
+defaults to 0 and @var{end} defaults to the length of @var{bv}.
+
+@example
+(define out (open-output-bytevector))
+(write-bytevector #vu8(0 1 2 3 4) out 2 4)
+(get-output-bytevector out) @result{} #vu8(2 3)
+@end example
+
+@end deffn
+
 @node Encoding
 @subsection Encoding
 
-- 
2.39.0

