Click here to Skip to main content
11,639,305 members (68,995 online)
Click here to Skip to main content
Add your own
alternative version

Persistence is the Key

, 24 Jan 2013 Ms-PL 50K 490 40
Tutorial for using the Calvin C++ persistence library.
calvin.zip
calvin
calvin
calvin
calvin.h.bak
doc
BandCandAonDisk.GIF
BandConDisk.GIF
BandCownA.GIF
BandCshareA.gif
calvin.jpg
test
a1
a2
a3
a4
a5
a6
b
c
Debug
libboost_filesystem-vc71-sgd-1_31.lib
#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.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

Jay Kint
Web Developer
United States United States
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.

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150728.1 | Last Updated 24 Jan 2013
Article Copyright 2005 by Jay Kint
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid