From: Jeff Flinn (TriumphSprint2000_at_[hidden])
Date: 2004-08-31 09:39:30


I've tried to replace a couple of existing derived stream/streambuf classes
that are used with boost::serialization i/o archives to support
Drag/Drop/Copy/Paste in an MFC application.

The Drop/Paste side works great and significantly simplifies and reduces the
amount of code req'd:

class CSharedFileIStream
: public boost::io::stream_facade< boost::io::array_source >
{
   typedef boost::io::array_source tSource;
   typedef boost::io::stream_facade< tSource > tBase;

   HGLOBAL mMemHdl;

public:
  ~CSharedFileIStream( ){ ::GlobalUnlock(mMemHdl); }
   CSharedFileIStream( HGLOBAL aMemHdl )
   : tBase( (LPTSTR)::GlobalLock(aMemHdl), ::GlobalSize(aMemHdl) )
   , mMemHdl( aMemHdl )
   {}
};

Used like so:

CSharedFileIStream lIn( lMemHdl );

boost::archive::binary_iarchive ia( lIn );

ia >> aVal;

Unfortunately, the Drag/Copy side produces a access violation in the
std::locale copy constructor, when
boost::io::detail::indirect_streambuf::imbue calls
std::basic_streambuf::pbuimbue. I've tried the following with both
binary/text archive types:

struct CSharedFileSink : public boost::io::sink
{
   CSharedFile& mSharedFile;

   CSharedFileSink( CSharedFile& aSharedFile )
   : boost::io::sink()
   , mSharedFile(aSharedFile)
   {}

   void write( const char* s, std::streamsize n ){ mSharedFile.Write( s,
n ); }
};

class CSharedFileOStream : public boost::io::stream_facade<CSharedFileSink>
{
  typedef boost::io::stream_facade<CSharedFileSink> tBase;

  public:
    CSharedFileOStream( CSharedFile& aSharedFile )
    : tBase( CSharedFileSink( aSharedFile ) )
    {}
};

Used like so:

CSharedFile lOutFile;
CSharedFileOStream lOut( lOutFile );

 boost::archive::text_oarchive oa( lOut );

Am I doing anything obviously wrong? I love the source/sink approach and
would love to take advantage of it's conceptual simplification in dealing
with streams.

Thanks, Jeff