Decompress stream based on magic bytes using boost
===

I'd like to be able to pass either compressed or uncompressed streams to (some part of) my application. The application should have a **peek** at the first few bytes, detect whether they match some **magic value** indicate a certain compression scheme, and if so, put a suitable **decompressor** into the **chain**.

My main problem here is that I don't see from the [boost documentation][1] how a `filtering_stream` would react to changes to the chain after the first characters have been read. The FAQ question “[Can I swap Filters or Devices in the middle of a sequence of i/o operations?][2]” only sanctions some output operations, so by default I'd say modifying an input chain is a bad idea. As I'd be popping chain elements starting with the source device, I doubt that any read bytes could be re-read easily.

An acceptable answer to this solution should:

* Result in a complete `filtering_stream` or `filtering_streambuf` from which all the (possibly decompressed) bytes can be read. No special handling for the first byte or similar should be required by the code reading from the stream.
* Avoid unneccessary layers, particularly unneccessary copying between superfluous buffers.
* Be able to deal with different possible sources, in particular an `std::istream` and a `mapped_file_source`.
* Work without seeking, as the input might be unseekable.
* Close the source when the stream goes out of scope.
* Peeking at the first byte only should be enough, if that makes a difference.

I have some ideas how to achieve this, but all of them seem kind of ugly to me, so I'd like to know which of these works best, or if you have better ideas to offer. I must confess that I haven't implemented anything yet, so some of my ideas might fail as well. Here they are:

1. Nest two boost `filtering_streambuf` objects. In other words, use one stream buffer to read the first character off the source device, and based on that, construct a second stream buffer, pushing the first one into that stream as the source. The added layer feels like an overhead one would like to avoid, but most likely this impression comes mainly from the fact that `filtering_stream` already can take care of multiple processing stages without nesting.
1. Peek at the source before adding it to the filter chain. As I intend to use different devices, this would mean different code for each of them. When using `std::istream` as a source I could use `peek`, and for the `mapped_file_source` I could examine the `data` directly. But a solution where I could add other sources without having to add to a case distinction would be preferable.
1. There might be a way to read the first byte, then modify the chain, then put the byte back in place. Or `get` and `unget` more than one byte, perhaps. I'm worried that some buffered data might get lost in this approach, though. And I'm also worried that what might work now might stop working in some other release, as there seem to be no guarantees that things like this are allowed.

When you also would suggest one of the above methods, I'd be interested in the benefits over the other suggestions, and perhaps some reason why my concerns are insubstantial. When you have something new to offer, a comparison to the above would be welcome but not required.

  [1]: http://www.boost.org/doc/libs/1_50_0/libs/iostreams/doc/index.html
  [2]: http://www.boost.org/doc/libs/1_50_0/libs/iostreams/doc/faq.html#auto_close