|
#ifndef FS_ARCHIVE_H
#define FS_ARCHIVE_H
/*-----------------------------------------------------------------------------
File : fs_archive.H
Title : File System archive class for calvin persistence library
Owner : Jay Kint
Copyright (C) 2005, Jay Kint, All Rights Reserved
-------------------------------------------------------------------------------
Description:
*/
//-----------------------------------------------------------------------------
// Include Files
//-----------------------------------------------------------------------------
// module includes
// system includes
#include <istream>
#include <ostream>
#include <boost/filesystem/operations.hpp> // includes boost/filesystem/path.hpp
#include <boost/filesystem/fstream.hpp> // ditto
#include <boost/shared_ptr.hpp>
//-----------------------------------------------------------------------------
// Namespace
//-----------------------------------------------------------------------------
namespace calvin {
#if 0
} // namespace indentation hack
#endif
//-----------------------------------------------------------------------------
// Types and Structures
//-----------------------------------------------------------------------------
// forward declarations
namespace fs = boost::filesystem;
// implementation of archives where objects are stored in individual files.
// any data type can be used as the key as long as it can be converted to a
// string using the << operator.
template <typename Key>
class file_archive : public archive<Key> {
public:
// Types and constants
// Constructors
file_archive( const std::string& base_dir );
// Destructor
~file_archive( void );
// Operations
// Accessors
const std::string& base_directory( void ) { return _base_dir; }
// Class Functions
protected:
// Constructors
// Attributes
// Operations
// Class Attributes
// Class Functions
private:
// Attributes
std::string _base_dir;
boost::filesystem::path _root;
boost::shared_ptr<std::ostream> _current_ostream;
boost::shared_ptr<std::istream> _current_istream;
// Operations
virtual boost::shared_ptr<std::ostream> resolve_output( const Key& );
virtual boost::shared_ptr<std::istream> resolve_input( const Key& );
// Class Attributes
// Class Functions
};
// shortcut for conventional file names
typedef class file_archive<std::string> filesys_archive;
//-----------------------------------------------------------------------------
// Constants and Definitions
//-----------------------------------------------------------------------------
// explicit instantiation for filesys_archive in archive.h
// You muse use similar to these if you define persistent classes and archives
// that use other types for keys and put them in a .h file included by
// the application that imports it. See the comments for the defintion
// of CALVIN_EXPORT and CALVIN_DECLSPEC.
#pragma warning(push)
#pragma warning(disable:4231)
CALVIN_EXPORT template CALVIN_DECLSPEC archive<std::string>;
CALVIN_EXPORT template archive<std::string>* archive<std::string>::default_archive_;
CALVIN_EXPORT template archive<std::string>* archive<std::string>::current_archive_;
#pragma warning(pop)
//-----------------------------------------------------------------------------
// Module Functions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Inline functions
//-----------------------------------------------------------------------------
template <typename Key>
file_archive< Key >::file_archive( const std::string& base )
{
_root = boost::filesystem::path( base, fs::native );
}
template <typename Key>
file_archive< Key >::~file_archive( void )
{
_current_ostream.reset();
_current_istream.reset();
}
template <typename Key>
boost::shared_ptr<std::ostream> file_archive< Key >::resolve_output( const Key& key )
{
// if the persistent object doesn't have a name, put it in the same stream
if( key == Key() )
return _current_ostream;
std::ostringstream key_to_string;
key_to_string << key;
boost::shared_ptr<std::ostream> s( static_cast<std::ostream*>( new fs::ofstream( _root / key_to_string.str(), std::ios::out | std::ios::binary )));
if( !s->good() )
CALVIN_ERROR( "failed to open output stream" );
_current_ostream = s;
return s;
}
template <typename Key>
boost::shared_ptr<std::istream> file_archive< Key >::resolve_input( const Key& key )
{
// close off any outstanding output streams
if( _current_ostream != NULL )
_current_ostream.reset();
// if this persistent object doesn't have a name, read it from the same stream
if( key == Key() )
return _current_istream;
std::ostringstream key_to_string;
key_to_string << key;
boost::shared_ptr<std::istream> s( static_cast<std::istream*>( new fs::ifstream( _root / key_to_string.str(), std::ios::in | std::ios::binary )));
if( !s->good() ) {
std::string err( "failed to open file " );
err += key;
CALVIN_ERROR( err );
}
_current_istream = s;
return s;
}
} // namespace calvin
#endif // ARCHIVE_H
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Jay Kint has been a software engineer/hacker for most of his life, starting with 8 bit Ataris. After a lengthy stint in the game industry, he now works at Microsoft in SQL Server.