1

I have defined a boost Device called ZipFileDevice, that takes in an archive path, and a path to a file within that archive.

The Device defines read, write, seek, a costructor that takes the two paths, and a destructor.

I am opening the zip file in the constructor of ZipFileDevice, and closing it in the destructor.

This is how I am using the Device:

boost::iostreams::stream_buffer<ZipFileDevice> kBuff("path/to/archive", "path/to/file");
std::iostream kStream(&kBuff);
kStream.read(...);

My problem is that the ZipFileDevice is copied twice when creating the stream_buffer, and the copies are destroyed, closing the zip file. When I read from the stream, the file has been closed.

How do I correctly handle opening and closing a Device?

1 Answers1

0

From the design rationale page:

Filters and Devices must either be CopyConstructible or be passed to streams and stream buffers using boost::ref.

This requirement can complicate the design of Filters and Devices, since some components that could otherwise be non-copyable must use reference counting.

The template basic_file is a good illustration. A pre-release version of Boost.Iostreams allowed dynamically allocated Filters and Devices to be passed to streams and stream buffers as pointers that would become owned by the Iostreams library at the user's option. This design was rejected for two reasons: it was not exception safe, and it required an extra function parameter to indicate whether an object was to become owned by the library.

So, either pass boost::ref to your device, or implement a Handle/Body idiom e.g. with a shared_ptr<DeviceImpl> inside your Device type

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633