[m-rev.] for review: bit buffers

Julien Fischer juliensf at csse.unimelb.edu.au
Mon May 14 17:43:10 AEST 2007


On Mon, 14 May 2007, Simon Taylor wrote:

> NEWS:
> library/bit_buffer.m:
> library/bit_buffer.read.m:
> library/bit_buffer.write.m:
> 	Add bit_buffers to the standard library.  A bit_buffer
> 	provides a bit-oriented interface to byte streams.
> 	These will be used as a base for write_binary and read_binary.
>
> library/stream.m:
> 	Add classes bulk_writer and bulk_reader, which support
> 	reading and writing multiple items at once into a store.
>
> 	Clarify the blocking behaviour of `put' and `get'.
>
> 	Document the behaviour of subsequent calls to `get'
> 	after a call returns eof or an error.
>
> library/bitmap.m:
> 	Add a shorthand for `new(N, no)'.
>
> 	Add `shrink_without_copying' to destructively shrink a bitmap
> 	without copying the data.
>
> 	Add a function `append_list' to condense a list of bitmaps.

I think it should be called `condense_list' rather than `append_list'.
(For symmetry with list.condense/2).

> 	Improve bounds error messages.
>
> library/io.m:
> 	Change the interface of io.read_bitmap to conform to
> 	the stream.bulk_reader interface, by not returning the
> 	bitmap inside the return code.  The bitmap is still
> 	valid (although maybe not completely filled) no matter
> 	what result is returned.
>
> 	Add io.read_binary_file_as_bitmap/N.

...

> Index: library/bit_buffer.m
> ===================================================================
> RCS file: library/bit_buffer.m
> diff -N library/bit_buffer.m
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ library/bit_buffer.m	14 May 2007 04:10:37 -0000

...

> +:- module bit_buffer.
> +
> +:- interface.

For consistency with the other library modules remove the blank line
between the module and interface declarations.

> +:- import_module bitmap.
> +:- import_module stream.
> +
> +:- include_module bit_buffer.read.
> +:- include_module bit_buffer.write.
> +
> +    % An error_stream throws an `error_stream_error' exception if any of
> +    % its output methods are called, or returns an `error_stream_error'
> +    % if any of its input methods are called.
> +    %
> +:- type error_stream ---> error_stream.
> +:- type error_state ---> error_state.
> +:- type error_stream_error
> +        ---> error_stream_error.
> +:- instance stream.error(error_stream_error).
> +:- instance stream.stream(error_stream, error_state).
> +:- instance stream.input(error_stream, error_state).
> +:- instance stream.bulk_reader(error_stream, byte_index, bitmap,
> +        error_state, error_stream_error).
> +
> +:- instance stream.output(error_stream, error_state).
> +:- instance stream.bulk_writer(error_stream, byte_index, bitmap, error_state).
> +
> +%-----------------------------------------------------------------------------%
> +
> +:- implementation.
> +
> +:- import_module bool.
> +:- import_module exception.
> +:- import_module int.
> +:- import_module list.
> +
> +:- instance stream.error(error_stream_error) where
> +[
> +    error_message(_) = "method called for error_stream"
> +].
> +
> +:- instance stream.stream(error_stream, error_state) where
> +[
> +    name(_Stream, "error_stream", !State)
> +].
> +
> +:- instance stream.input(error_stream, error_state) where
> +[].
> +
> +:- instance stream.bulk_reader(error_stream, byte_index, bitmap,
> +    error_state, error_stream_error) where
> +[
> +    bulk_get(_, _, _, !BM, 0, error(error_stream_error), !State)
> +].
> +
> +:- instance stream.output(error_stream, error_state) where
> +[
> +    flush(_, !State) :- throw(error_stream_error)
> +].
> +
> +:- instance stream.bulk_writer(error_stream, byte_index, bitmap, error_state)
> +    where
> +[
> +    bulk_put(_, _, _, _, !State) :- throw(error_stream_error)
> +].
> +
> +    % The bitmap has room for the chunk size given as an argument
> +    % to `new', plus a word.
> +    %
> +    % This means that a for a write buffer a word can always
> +    % be written to the buffer, and the buffer will be flushed
> +    % if the position is greater than the chunk size.
> +    %
> +    % For a read_buffer, bits will be read from the input stream
> +    % and placed starting at bit number `bits_per_int'.  When the
> +    % buffer is nearly exhausted (less than a word left), the last
> +    % word is copied to the start of the buffer and the buffer is
> +    % refilled.
> +    %
> +:- type bit_buffer(Stream, State, Error)
> +        ---> bit_buffer(
> +                mer_bitmap :: bitmap,
> +                mer_pos :: bit_index,
> +                mer_size :: num_bits,
> +
> +                mer_use_stream :: bool,
> +
> +                mer_stream :: Stream,
> +                mer_state :: State,
> +
> +                % For write buffers only.
> +                % If we're not writing to a stream, keep a list of filled
> +                % bitmaps in reverse order.  These will be concatenated
> +                % into a single bitmap by finalize_to_bitmap.
> +                %
> +                mer_filled_bitmaps :: list(bitmap),
> +
> +                % For read buffers only.  The first error found
> +                % when reading from a stream.  Subsequent calls
> +                % will return this error.
> +                %
> +                mer_read_status :: stream.res(Error)
> +        ).
> +
> +:- type bit_buffer(Stream, State) == bit_buffer(Stream, State, {}).
> +
> +    % XXX These should be unique.
> +:- mode bit_buffer_ui == in.
> +:- mode bit_buffer_di == in.
> +:- mode bit_buffer_uo == out.
> +
> +    % Allocating memory for every read or write would be bad, so
> +    % we manually perform destructive update in C.
> +    %
> +:- pragma foreign_decl("C", "
> +typedef struct {
> +    MR_BitmapPtr    ML_bit_buffer_bitmap;
> +    MR_Integer      ML_bit_buffer_pos;
> +    MR_Integer      ML_bit_buffer_size;
> +    MR_Word         ML_bit_buffer_use_stream;
> +    MR_Word         ML_bit_buffer_stream;
> +    MR_Word         ML_bit_buffer_state;
> +    MR_Word         ML_bit_buffer_filled_bitmaps;
> +    MR_Word         ML_bit_buffer_read_status;
> +} ML_BitBuffer;
> +
> +typedef ML_BitBuffer *ML_BitBufferPtr;
> +").
> +
> +:- pragma foreign_type("C", bit_buffer(Stream, State, Error),
> +    "ML_BitBufferPtr").

That can have an `can_pass_as_mercury_type' annotation attached to it.

The rest looks okay.

Julien.
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list