# BidirectionalDevice

## Definition

An BidirectionalDevice is a Device whose mode refines bidirectional.

## Description

An BidirectionalDevice provides read-access to a sequence of characters of a given type and write-access to a separate sequence of characters of the same type. An BidirectionalDevice may expose these sequences in three ways:[1]

1. by defining member functions `read` and `write` , invoked indirectly by the Iostreams Library through the functions `boost::iostreams::read` and `boost::iostreams::write`;
2. by overloading or specializing `boost::iostreams::read` and `boost::iostreams::write`; or
3. by defining member functions `input_sequence` and `output_sequence` returning pairs of pointers delimiting the two sequences in their entirety.

The i/o mode of a BidirectionalDevice is bidirectional or bidirectional-seekable.

## Example

A model of BidirectionalDevice can be defined as follows:

    struct BidirectionalDevice {
        typedef char                char_type;
        typedef bidirectional_device_tag    category;
        std::streamsize read(char* s, std::streamsize n)
            {
                // Reads up to n characters from the input
                // sequence into the buffer s, returning the number
                // of characters read. Returning a value less than n
                // indicates end-of-sequence.
            }
        std::streamsize write(const char* s, std::streamsize n)
            {
                // Write up to n characters from the buffer
                // s to the output sequence, returning the
                // number of characters written
            }
    };

Here `category` is a tag `struct` identifying the containing type as a model of BidirectionalDevice. When defining a new BidirectionalDevice, it suffices to use the tag `bidirectional_device_tag`. One can also derive from the helper classes `device<bidirectional>` or `wdevice<bidirectional>`.

## Refinement of

Source, Sink.

## Associated Types

Same as Device, with the following additional requirements:

Category | A type convertible to device_tag and to `bidirectional`

## Notation

`D` | - A type which is a model of BidirectionalDevice
`Ch` | - The character type of `D`
`dev` | - Object of type `D`
`s1` | - Object of type `Ch*`
`s2` | - Object of type `const Ch*`
`n` | - Object of type `std::streamsize`

## Valid Expressions / Semantics

Same as Device, with the following additional requirements:

Expression | Expression Type | Category Precondition | Semantics
--- | --- | --- | ---
    boost::iostreams::read(dev, s1, n)
| `std::streamsize` | Not convertible to `direct_tag` | Reads up to `n` characters from the input sequence controlled by `dev` into `s1`, returning the number of characters read; returning a value less than n indicates end-of-sequence
    boost::iostreams::write(dev, s2, n)
| `std::streamsize` | Writes up to `n` characters from the sequence beginning at `s2` to the sequence controlled by `dev`, returning the number of characters written
    dev.input_sequence()
    std::pair<Ch*,Ch*>
| Convertible to `direct_tag` | Returns a pair of pointers delimiting the input sequence controlled by `dev`
    dev.output_sequence()
    std::pair<Ch*,Ch*>
| Returns a pair of pointers delimiting the output sequence controlled by `dev`

## Exceptions

Errors which occur during the execution of member functions `read`, `write`, `input_sequence` or `output_sequence` are indicated by throwing exceptions. Reaching the end of the input sequence is not an error, but attempting to write past the end of the output sequence is.

After an exception is thrown, an BidirectionalDevice must be in a consistent state; further i/o operations may throw exceptions but must have well-defined behaviour.

## Models

[1]Strictly speaking, (i) and (ii) can be varied independently for input and output, so there are actually five possibilities.

Revised 20 May, 2004

© Copyright Jonathan Turkanis, 2004

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)