# LispKit Bytevector

Bytevectors represent blocks of binary data. They are fixed-length sequences of bytes, where a byte is a fixnum in the range from 0 to 255 inclusive. A bytevector is typically more space-efficient than a vector containing the same values.

The length of a bytevector is the number of elements that it contains. The length is a non-negative integer that is fixed when the bytevector is created. The valid indexes of a bytevector are the exact non-negative integers less than the length of the bytevector, starting at index zero as with vectors.

Bytevectors are written using the notation `#u8(byte ...)`. For example, a bytevector of length 3 containing the byte 0 in element 0, the byte 10 in element 1, and the byte 5 in element 2 can be written as follows: `#u8(0 10 5)`. Bytevector constants are self-evaluating, so they do not need to be quoted.

## Basic

(bytevector? obj) [procedure]

Returns `#t` if obj is a bytevector; otherwise, `#f` is returned.

(bytevector byte …) [procedure]

Returns a newly allocated bytevector containing its arguments as bytes in the given order.

    (bytevector 1 3 5 1 3 5)  ⇒  #u8(1 3 5 1 3 5)
    (bytevector)              ⇒  #u8()

(make-bytevector k) [procedure]
(make-bytevector k byte)

The `make-bytevector` procedure returns a newly allocated bytevector of length k. If byte is given, then all elements of the bytevector are initialized to byte, otherwise the contents of each element are unspecified.

    (make-bytevector 3 12)  ⇒  #u8(12 12 12)

(bytevector=? bytevector …) [procedure]

Returns `#t` if all bytevector … contain the same sequence of bytes, otherwise `#f` is returned.

(bytevector-length bytevector) [procedure]

Returns the length of bytevector in bytes as an exact integer.

(bytevector-u8-ref bytevector k) [procedure]

Returns the k-th byte of bytevector. It is an error if k is not a valid index of bytevector.

    (bytevector-u8-ref #u8(1 1 2 3 5 8 13 21) 5)  ⇒  8

(bytevector-u8-set! bytevector k byte) [procedure]

Stores byte as the k-th byte of bytevector. It is an error if k is not a valid index of bytevector.

    (let ((bv (bytevector 1 2 3 4)))
      (bytevector-u8-set! bv 1 3)
      bv)
    ⇒  #u8(1 3 3 4)

(bytevector-copy bytevector) [procedure]
(bytevector-copy bytevector start)
(bytevector-copy bytevector start end)

Returns a newly allocated bytevector containing the bytes in bytevector between start and end. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

    (define a #u8(1 2 3 4 5))
    (bytevector-copy a 2 4))   ⇒  #u8(3 4)

(bytevector-copy! to at from) [procedure]
(bytevector-copy! to at from start)
(bytevector-copy! to at from start end)

Copies the bytes of bytevector from between start and end to bytevector to, starting at at. The order in which bytes are copied is unspecified, except that if the source and destination overlap, copying takes place as if the source is first copied into a temporary bytevector and then into the destination. This can be achieved without allocating storage by making sure to copy in the correct direction in such circumstances.

It is an error if at is less than zero or greater than the length of to. It is also an error if `(- (bytevector-length to) at)` is less than `(- end start)`.

    (define a (bytevector 1 2 3 4 5))
    (define b (bytevector 10 20 30 40 50))
    (bytevector-copy! b 1 a 0 2)
    b  ⇒  #u8(10 1 2 40 50)

(bytevector-append bytevector …) [procedure]

Returns a newly allocated bytevector whose elements are the concatenation of the elements in the given bytevectors.

    (bytevector-append #u8(0 1 2) #u8(3 4 5))
      ⇒  #u8(0 1 2 3 4 5)

## Input/Output

(read-binary-file path) [procedure]

Reads the file at path and stores its content in a new bytevector which gets returned by `read-binary-file`.

(write-binary-file path bytevector) [procedure]
(write-binary-file path bytevector start)
(write-binary-file path bytevector start end)

Writes the bytes of bytevector between start and end into a new binary file at path. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

## Compression

(bytevector-deflate bytevector) [procedure]
(bytevector-deflate bytevector start)
(bytevector-deflate bytevector start end)

`bytevector-deflate` encodes bytevector between start and end using the Deflate data compression alogrithm returning a new compressed bytevector. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(bytevector-inflate bytevector) [procedure]
(bytevector-inflate bytevector start)
(bytevector-inflate bytevector start end)

`bytevector-inflate` assumes bytevector is encoded using the Deflate data compression alogrithm between start and end. The procedure returns a corresponding new decoded bytevector.

If is an error if bytevector, between start and end, is not encoded using Deflate. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(bytevector-zip bytevector) [procedure]
(bytevector-zip bytevector start)
(bytevector-zip bytevector start end)

`bytevector-zip` encodes bytevector between start and end using the Deflate data compression alogrithm returning a new compressed bytevector which is using a zlib wrapper. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(bytevector-unzip bytevector) [procedure]
(bytevector-unzip bytevector start)
(bytevector-unzip bytevector start end)

`bytevector-unzip` assumes bytevector is using a zlib wrapper for data encoded using the Deflate data compression alogrithm between start and end. The procedure returns a corresponding new decoded bytevector.

If is an error if bytevector, between start and end, is not encoded using Deflate or is not using the zlib wrapper format. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(bytevector-zip-header? bytevector) [procedure]
(bytevector-zip-header? bytevector start)
(bytevector-zip-header? bytevector start end)

`bytevector-zip-header?` returns `#t` if the bytevector is using a zlib wrapper for data encoded using the Deflate data compression alogrithm between start and end. The procedure returns `#f` otherwise. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(bytevector-gzip bytevector) [procedure]
(bytevector-gzip bytevector start)
(bytevector-gzip bytevector start end)

`bytevector-gzip` encodes bytevector between start and end using the Deflate data compression alogrithm returning a new compressed bytevector which is using a gzip wrapper. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(bytevector-gunzip bytevector) [procedure]
(bytevector-gunzip bytevector start)
(bytevector-gunzip bytevector start end)

`bytevector-gunzip` assumes bytevector is using a gzip wrapper for data encoded using the Deflate data compression alogrithm between start and end. The procedure returns a corresponding new decoded bytevector.

If is an error if bytevector, between start and end, is not encoded using Deflate or is not using the gzip wrapper format. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(bytevector-gzip-header? bytevector) [procedure]
(bytevector-gzip-header? bytevector start)
(bytevector-gzip-header? bytevector start end)

`bytevector-gzip-header?` returns `#t` if the bytevector is using a gzip wrapper for data encoded using the Deflate data compression alogrithm between start and end. The procedure returns `#f` otherwise. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

## Advanced

(utf8->string bytevector) [procedure]
(utf8->string bytevector start)
(utf8->string bytevector start end)
(string->utf8 string)
(string->utf8 string start)
(string->utf8 string start end)

These procedures translate between strings and bytevectors that encode those strings using the UTF-8 encoding. The `utf8->string` procedure decodes the bytes of a bytevector between start and end and returns the corresponding string. The `string->utf8` procedure encodes the characters of a string between start and end and returns the corresponding bytevector.

It is an error for bytevector to contain invalid UTF-8 byte sequences.

    (utf8->string #u8(#x41))  ⇒  "A"
    (string->utf8 "λ")        ⇒  #u8(#xCE #xBB)

(bytevector->base64 bytevector) [procedure]
(bytevector->base64 bytevector start)
(bytevector->base64 bytevector start end)

`bytevector->base64` encodes bytevector between start and end as a string consisting of ASCII characters using the Base64 encoding scheme. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(base64->bytevector str) [procedure]
(base64->bytevector str start)
(base64->bytevector str start end)

`base64->bytevector` assumes string str is encoded using Base64 between start and end and returns a corresponding new decoded bytevector.

If is an error if str between start and end is not a valid Base64-encoded string. If end is not provided, it is assumed to be the length of str. If start is not provided, it is assumed to be 0.

(bytevector->hex bytevector) [procedure]
(bytevector->hex bytevector start)
(bytevector->hex bytevector start end)

Returns a string representation of bytevector in which every byte between start and end is represented by two characters denoting the value of the byte in hexadecimal form. The characters representing the individual bytes are concatenated such that a bytevector is represented by a hex string of length end - start. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

    (bytevector->hex #u8(7 8 9 10 11 12)) ⇒ "0708090a0b0c"

(hex->bytevector str) [procedure]
(hex->bytevector str start)
(hex->bytevector str start end)

Returns a bytevector for a given hex string between start and end. Such strings encode every byte with two characters representing the value of the byte in hexadecimal form.

If is an error if str between start and end is not a valid hex string. If end is not provided, it is assumed to be the length of str. If start is not provided, it is assumed to be 0.

    (hex->bytevector "1718090a0b0c") ⇒ #u8(23 24 9 10 11 12)

(bytevector-adler32 bytevector) [procedure]
(bytevector-adler32 bytevector start)
(bytevector-adler32 bytevector start end)

`bytevector-adler32` computes the Adler32 checksum for bytevector between start and end. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(bytevector-crc32 bytevector) [procedure]
(bytevector-crc32 bytevector start)
(bytevector-crc32 bytevector start end)

`bytevector-crc32` computes the CRC32 checksum for bytevector between start and end. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.