|
/*-----------------------------------------------------------------------------
File : test_resource.CPP
Title : Test the resource loading and saving module
Owner : Jay Kint
Tabs : column 5 every 4
Copyright (C) 2004, Jay Kint, All Rights Reserved
-------------------------------------------------------------------------------
Description:
Test harness for the Calvin persistent library
*/
//-----------------------------------------------------------------------------
// Include Files
//-----------------------------------------------------------------------------
// module includes
#include "calvin.h"
#include "fs_archive.h"
#include "cmdline.h"
// system includes
#include <crtdbg.h>
#include <string>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <cstdio>
#include <windows.h>
//-----------------------------------------------------------------------------
// Namespaces
//-----------------------------------------------------------------------------
using namespace calvin;
using namespace std;
using namespace boost;
//-----------------------------------------------------------------------------
// Internal Types and Structures
//-----------------------------------------------------------------------------
#define INT_KEY
#if defined(INT_KEY)
#define KEY int
#define A1_NAME 0xa1
#define A2_NAME 0xa2
#define A3_NAME 0xa3
#define A4_NAME 0xa4
#define A5_NAME 0xa5
#define A6_NAME 0xa6
#define B_NAME 0x0b
#define C_NAME 0x0c
#define Q_NAME 0xff
#else
#define KEY std::string
#define A1_NAME "a1"
#define A2_NAME "a2"
#define A3_NAME "a3"
#define A4_NAME "a4"
#define A5_NAME "a5"
#define A6_NAME "a6"
#define B_NAME "b"
#define C_NAME "c"
#define Q_NAME "q"
#endif
struct made_of_prims {
int i;
float f;
double d;
};
class persistent_void_test : public calvin::persistent<void> {
std::string* msg;
friend struct calvin::allow_persistence<void>;
public:
persistent_void_test( void ) : msg( new std::string( "I'm a calvin::persistent<void>" )) {}
~persistent_void_test( void )
{
delete msg;
msg = NULL;
}
template<typename Stream>
Stream& serialize( Stream& s, unsigned int version )
{
return s ^ msg;
}
void print( void )
{
cout << *msg << endl;
}
};
class A : public calvin::persistent<KEY> {
int a;
float a2;
double a3;
struct Aa {
int a4;
int a5;
Aa(void) : a4(4), a5(5) {}
};
Aa a6;
public:
typedef char stupid;
void print( void ) { std::cout << a << ' ' << a2 << ' ' << a3 << ' ' << a6.a4 << ' ' << a6.a5 << std::endl; }
A( void ) : a(1), a2(2.0f), a3(3.0), a6(Aa()) {}
A( const KEY& name ) : persistent<KEY>(name), a(1), a2(2.0f), a3(3.0), a6(Aa()) {
return;
}
virtual ~A( void ) {
// memset( this, 0, sizeof(A) );
return;
}
protected:
template <typename Stream>
Stream& serialize( Stream& s, const unsigned int version ) { return s ^ a ^ a2 ^ a3 ^ a6.a4 ^ a6.a5; }
private:
friend calvin::allow_persistence<A>;
};
class B : public A {
public:
B( void ) : A(), b1(0), b2(1), stupid(NULL) {}
B( const KEY& name ) : A(name), b1(0), b2(1), stupid(NULL) {}
B( const KEY& name, const char* stupid ) : A(name), b1(0), b2(1), stupid(stupid) {
return;
}
virtual ~B( void ) { /*memset( this, 0, sizeof(B) );*/ }
void print( void ) { A::print(); sm.print(); std::cout << b1 << ' ' << b2 << std::endl; }
void set_b1( int b1 ) { this->b1 = b1; }
void set_b2( unsigned int b2 ) { this->b2 = b2; }
void add( made_of_prims& p)
{
vec_of_prims.push_back( p );
}
private:
int b1;
unsigned int b2;
std::vector<made_of_prims> vec_of_prims;
persistent_void_test sm;
const stupid* stupid;
template <typename Stream>
Stream& serialize( Stream& s, const unsigned int version )
{
return A::serialize( s, version ) ^
b1 ^
b2 ^
vec_of_prims ^
sm ^
PtrArray<const char>( stupid, (stupid == NULL) ? 0 : (unsigned int) strlen(stupid)+1 /*null terminator*/);
}
friend calvin::allow_persistence<B>;
};
class C : public calvin::persistent<KEY> {
struct deleter {
boost::shared_ptr<A> operator()( boost::shared_ptr<A> a )
{
a.reset();
return a;
}
};
public:
C( void ) : persistent<KEY>() { b.reset(); ppint = new int*; *ppint = new int; }
C( const KEY& name ) : persistent<KEY>( name ) /*, b(NULL)*/ { b.reset(); ppint = new int*; *ppint = new int; }
C( const KEY& name, B* b, char* strz ) : persistent<KEY>(name), b(b)
{
strcpy( reinterpret_cast<char*>(this->strz), strz );
mpc = 10;
mp = new made_of_prims[10];
ppint = new int*;
*ppint = new int;
**ppint = 0xbaadface;
}
virtual ~C( void )
{
//delete b;
b.reset();
transform( list_of_a.begin(), list_of_a.end(), list_of_a.begin(), deleter() );
list_of_a.clear();
delete *ppint;
delete ppint;
ppint = NULL;
//memset( this, 0, sizeof(C) );
}
void print(void) { b->print(); printf( "%08x\n", **ppint );}
void add( boost::shared_ptr<A> a ) { list_of_a.push_back( a ); }
private:
boost::shared_ptr<B> b;
std::list<boost::shared_ptr<A> > list_of_a;
char strz[10];
unsigned int mpc;
made_of_prims* mp;
int ** ppint;
template <typename Stream>
Stream& serialize( Stream& s, const unsigned int version ) { return s ^ b ^ list_of_a ^ strz ^ ppint ^ mpc ^ PtrArray<made_of_prims>( mp, mpc ); }
friend calvin::allow_persistence<C>;
};
template <typename T>
struct test_self {
int a;
float b;
long c;
test_self( void ) { a = 1; b = 2.0f; c = 3; }
static const test_self& get( void );
static std::string self_name_;
};
template <typename T>
const test_self<T>& test_self<T>::get( void )
{
static test_self<T> self_;
return self_;
}
template <typename T>
std::string test_self<T>::self_name_ = "This is me!";
//-----------------------------------------------------------------------------
// Internal Constants
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Internal Function Prototypes
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Internal Globals
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Exported Globals
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Functions - Internal and External
// All kept alphabetically ordered.
//-----------------------------------------------------------------------------
int main(void)
{
const test_self<int>& self2 = test_self<int>::get();
file_archive<KEY> ar( "." );
file_archive<KEY>::set_default_archive( &ar );
command_line_parser cmd_parser;
std::string cmdline( GetCommandLine() );
if( !cmd_parser.parse( cmdline )) {
cerr << "Command line didn't parse correctly.";
exit(-1);
}
// test loading instead of saving if the "load=true" is on the command line. We do this so that
// there is no way that the save/load can succeed based on residual pointers or anything
// still being around.
if( cmd_parser.get_value( "load" ) == "true" || cmd_parser.get_value( "load" ) == "1" ) {
shared_ptr<C> c;
c = ar.load<C>( C_NAME );
c->print();
return 0;
}
made_of_prims p1, p2, p3;
p1.i = 0;
p1.f = 1.0f;
p1.d = 2.0;
p2.i = 100;
p2.f = 101.0f;
p2.d = 102.0;
p3.i = 200;
p3.f = 201.0f;
p3.d = 202.0;
B *b = new B( B_NAME, "more stupid" );
shared_ptr<C> c( new C( C_NAME, b, "stupid" ));
b->set_b1( 100 );
b->set_b2( 200 );
b->add( p1 );
b->add( p2 );
b->add( p3 );
c->add( boost::shared_ptr<A>( new A(A1_NAME)));
c->add( boost::shared_ptr<A>( new A(A2_NAME)));
c->add( boost::shared_ptr<A>( new A(A3_NAME)));
c->add( boost::shared_ptr<A>( new A(A4_NAME)));
c->add( boost::shared_ptr<A>( new A(A5_NAME)));
c->add( boost::shared_ptr<A>( new A(A6_NAME)));
ar.save( c );
#if defined(NO_CALVIN_EXCEPTIONS)
shared_ptr<C> c_too( new C( C_NAME, NULL, "not as stupid" ));
#else
try {
shared_ptr<C> c_too( new C( C_NAME, b, "not as stupid" ));
}
catch( calvin_exception& e ) {
cerr << e.what() << endl;
cout << "Duplicate name test passed" << endl;
}
#endif
c.reset();
// test for errors
#if defined(NO_CALVIN_EXCEPTIONS)
c = ar.load<C>( Q_NAME ); // no object named q should exist
#else
try {
// no object named q should exist
c = ar.load<C>( Q_NAME );
}
catch( calvin_exception& c ) {
cerr << c.what() << endl;
cout << "Non existent object test passed" << endl;
}
#endif
}
namespace calvin {
void throw_exception( const calvin_exception& e )
{
cerr << e.what() << endl;
exit(-1);
}
}
|
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.