Next: , Previous: bit_buffer.read, Up: Top


9 bit_buffer.write

     %--------------------------------------------------%
     % vim: ts=4 sw=4 et tw=0 wm=0 ft=mercury
     %--------------------------------------------------%
     % Copyright (C) 2007, 2011 The University of Melbourne
     % This file may only be copied under the terms of the GNU Library General
     % Public License - see the file COPYING.LIB in the Mercury distribution.
     %--------------------------------------------------%
     % File: bit_buffer.write.m.
     % Main author: stayl.
     % Stability: low.
     %
     % A bit buffer provides an interface between bit-oriented output requests
     % and byte-array-oriented streams, storing bits until there are enough bytes
     % to make calling the `put' method on the stream worthwhile.
     %
     % CAVEAT: the user is referred to the documentation in the header
     % of array.m regarding programming with unique objects (the compiler
     % does not currently recognise them, hence we are forced to use
     % non-unique modes until the situation is rectified; this places
     % a small burden on the programmer to ensure the correctness of his
     % code that would otherwise be assured by the compiler.)
     %
     %--------------------------------------------------%
     %--------------------------------------------------%
     
     :- module bit_buffer.write.
     :- interface.
     
     :- import_module io.
     
     :- type write_buffer(Stream, State).
             % <= stream.writer(Stream, bitmap.slice, State).
     
     :- type write_buffer == write_buffer(error_stream, error_state).
     :- type io_write_buffer == write_buffer(io.binary_output_stream, io.state).
     
     :- inst uniq_write_buffer == ground.   % XXX Should be unique.
     :- mode write_buffer_di == in(uniq_write_buffer).
     :- mode write_buffer_ui == in(uniq_write_buffer).
     :- mode write_buffer_uo == out(uniq_write_buffer).
     
         % new(NumBytes, Stream, State) creates a buffer which will write to
         % the stream specified by Stream and State in chunks of NumBytes bytes.
         % If NumBytes is less than the size of an integer (given by
         % int.bits_per_int), the size of an integer will be used instead.
         %
     :- func new(num_bytes, Stream, State) = write_buffer(Stream, State)
         <= stream.writer(Stream, byte_index, State).
     :- mode new(in, in, di) = write_buffer_uo is det.
     
         % new(NumBytes)
         % Create a buffer which collects all of the bits written, and does
         % not write them to a stream.  The bits are collected in chunks of
         % size NumBytes bytes, and are written to a bitmap by
         % `finalize_to_bitmap/1'.
     :- func new_bitmap_builder(num_bytes) = write_buffer.
     :- mode new_bitmap_builder(in) = out is det.
     
         % How many bits to be written does the buffer contain.
         %
     :- func num_buffered_bits(write_buffer(_, _)) = num_bits.
     :- mode num_buffered_bits(write_buffer_ui) = out is det.
     
         % Return how many bits need to be written to get to a byte boundary
         % in the output stream.
         %
     :- func num_bits_to_byte_boundary(write_buffer(_, _)) = num_bits.
     :- mode num_bits_to_byte_boundary(write_buffer_ui) = out is det.
     
         % Write a bit to the buffer.
         %
     :- pred put_bit(bool, write_buffer(Stream, State), write_buffer(Stream, State))
         <= stream.writer(Stream, bitmap.slice, State).
     :- mode put_bit(in, write_buffer_di, write_buffer_uo) is det.
     
         % Write the given number of low-order bits from an int to the buffer.
         % The number of bits must be less than int.bits_per_int.
         %
     :- pred put_bits(word, num_bits, write_buffer(Stream, State),
         write_buffer(Stream, State))
         <= stream.writer(Stream, bitmap.slice, State).
     :- mode put_bits(in, in, write_buffer_di, write_buffer_uo) is det.
     
         % Write the eight low-order bits from an int to the buffer.
         % The number of bits must be less than int.bits_per_int.
         %
     :- pred put_byte(word, write_buffer(Stream, State),
         write_buffer(Stream, State))
         <= stream.writer(Stream, bitmap.slice, State).
     :- mode put_byte(in, write_buffer_di, write_buffer_uo) is det.
     
         % Write bits from a bitmap to the buffer.
         % The buffer does not keep a reference to the bitmap.
         %
     :- pred put_bitmap(bitmap, write_buffer(Stream, State),
         write_buffer(Stream, State))
         <= stream.writer(Stream, bitmap.slice, State).
     :- mode put_bitmap(bitmap_ui, write_buffer_di, write_buffer_uo) is det.
     
     :- pred put_bitmap(bitmap, bit_index, num_bits,
         write_buffer(Stream, State), write_buffer(Stream, State))
         <= stream.writer(Stream, bitmap.slice, State).
     :- mode put_bitmap(bitmap_ui, in, in, write_buffer_di, write_buffer_uo) is det.
     
         % Flush all complete bytes in the buffer to the output stream.
         % If there is an incomplete final byte it will remain unwritten
         % in the buffer.
         %
     :- pred flush(write_buffer(Stream, State), write_buffer(Stream, State))
         <= stream.writer(Stream, bitmap.slice, State).
     :- mode flush(write_buffer_di, write_buffer_uo) is det.
     
         % Pad the buffered data out to a byte boundary, flush it to
         % the output stream, then return the Stream and State.
         %
     :- pred finalize(write_buffer(Stream, State), Stream, State)
         <= stream.writer(Stream, bitmap.slice, State).
     :- mode finalize(write_buffer_di, out, uo) is det.
     
         % Copy the data from a non-streamed write_buffer to a bitmap.
         % The output is not padded to an even number of bits.
         %
     :- func finalize_to_bitmap(write_buffer) = bitmap.
     :- mode finalize_to_bitmap(write_buffer_di) = bitmap_uo is det.
     
     %--------------------------------------------------%