1:- module(bytes, [bytestream/2, bytestream_int/3, read_all_bytes/2, byte_group/2, byte_groups/2]).    2
    3:- use_module(math).    4:- use_module(utility).    5
    6byte_groups(Stream, Groups) :- apply_each(bytes:byte_group(Stream), Groups).
    7
    8byte_group(Stream, skip(N)) :- byte_group(Stream, bytes(N, _)).
    9byte_group(Stream, bytes(Bytes)) :- byte_group(Stream, bytes(_, Bytes)).
   10byte_group(Stream, atom(A)) :- byte_group(Stream, atom(_, A)).
   11byte_group(Stream, atom(N, A)) :-
   12    ( nonvar(N), var(A) -> length(Bytes, N); true ),
   13    call_or_inverse(nonvar(A),
   14    (
   15        atom_chars(A, Chars),
   16        maplist(char_code, Chars, Bytes),
   17        length(Bytes, N),
   18        bytestream(Stream, Bytes)
   19    )).
   20byte_group(Stream, chars(N, Chars)) :-
   21    length(Chars, N),
   22    same_length(Chars, Bytes),
   23    call_or_inverse(nonvar(Chars),
   24    (
   25        maplist(char_code, Chars, Bytes),
   26        bytestream(Stream, Bytes)
   27    )).
   28byte_group(Stream, bytes(N, Bytes)) :-
   29    nonvar(N) -> integer(N),
   30    length(Bytes, N),
   31    bytestream(Stream, Bytes).
   32byte_group(Stream, int(N, Int)) :- bytestream_int(N, Stream, Int).
   33
   34bytestream(Stream, Bytes) :-
   35    stream_property(Stream, output) -> apply_each(put_byte(Stream), Bytes);
   36    stream_property(Stream, input) ->
   37    (
   38        nonvar(Bytes) -> apply_each(get_byte(Stream), Bytes);
   39
   40        read_all_bytes(Stream, Bytes)
   41    ).
   42
   43bytestream_int(ByteCount, Stream, N) :-
   44    range(0, 255, Digits),
   45    (
   46        nonvar(N) ->
   47            to_digits(256, Digits, N, Temp),
   48            pad_begin(ByteCount, 0, Temp, Padded),
   49            reverse(Padded, Bytes),
   50            bytestream(Stream, Bytes);
   51
   52        length(Temp, ByteCount),
   53        bytestream(Stream, Temp),
   54        reverse(Temp, Bytes),
   55        from_digits(256, Digits, Bytes, N)
   56    ).
   57
   58read_all_bytes(Stream, Bytes) :-
   59    read_string(Stream, _, Str),
   60    string_codes(Str, Bytes)