Next: bitmap, Previous: bit_buffer.read, Up: Top [Contents]
%--------------------------------------------------% % vim: ts=4 sw=4 et ft=mercury %--------------------------------------------------% % Copyright (C) 2007, 2011 The University of Melbourne % Copyright (C) 2014-2016, 2018 The Mercury team. % This file is distributed under the terms specified in COPYING.LIB. %--------------------------------------------------% % 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. %--------------------------------------------------%
Next: bitmap, Previous: bit_buffer.read, Up: Top [Contents]