Commit 0495cd57 authored by claes's avatar claes

Adding functionality for adef, bdef and cdef

parent a4cfdf9e
......@@ -4,14 +4,33 @@ wb_adef::wb_adef() : wb_status(LDH__NOSUCHATTR), m_adrep(0)
{
}
wb_adef::wb_adef(const wb_adef& x)
wb_adef::wb_adef( wb_adrep *adrep) : wb_status(LDH__SUCCESS), m_adrep(adrep)
{
//m_adrep = x.m_adrep->ref();
m_adrep->ref();
}
wb_adef::wb_adef(const wb_adef& x) : wb_status(x.m_sts), m_adrep(x.m_adrep)
{
if ( m_adrep)
m_adrep->ref();
}
wb_adef& wb_adef::operator=(const wb_adef& x)
{
if ( x.m_adrep)
x.m_adrep->ref();
if ( m_adrep)
m_adrep->unref();
m_adrep = x.m_adrep;
m_sts = x.m_sts;
return *this;
}
wb_adef::~wb_adef()
{
//m_adrep->unref();
if ( m_adrep)
m_adrep->unref();
}
void wb_adef::check()
......
......@@ -6,27 +6,32 @@
#include "wb_orep.h"
#include "wb_name.h"
#include "wb_ldh.h"
#include "wb_cdef.h"
#include "wb_bdef.h"
class wb_orep;
class wb_adrep;
class wb_adef : public wb_status
{
public:
wb_adrep *m_adrep;
public:
wb_adef();
wb_adef(const wb_adef&); // x = other_object
wb_adef(const wb_adrep*); //
wb_adef(wb_adrep*);
wb_adef(const wb_orep&); // x = other orep
wb_adef& operator=(const wb_adef&) { return *this;}; // Fix
wb_adef& operator=(const wb_adef&);
~wb_adef();
operator bool() const { return (m_adrep != 0);}
operator wb_adrep*() const;
operator wb_adrep*() const { return m_adrep;}
bool operator==(wb_adef&);
wb_bdef bdef();
wb_cdef cdef();
pwr_sAttrRef aref();
size_t size(); // get objects runtime body size
int offset();
......
#include "wb_adrep.h"
#include "wb_vrep.h"
#include "wb_cdef.h"
#include "wb_orepdbs.h"
wb_adrep::wb_adrep(const wb_adrep& x)
void wb_adrep::unref()
{
if ( --m_nRef == 0)
delete this;
}
wb_adrep *wb_adrep::ref()
{
m_nRef++;
return this;
}
wb_adrep::wb_adrep( wb_orepdbs& o): m_nRef(0), m_orep(&o), m_sts(LDH__SUCCESS)
{
m_orep->ref();
}
wb_adrep::~wb_adrep()
{
//m_adrep->unref();
m_orep->unref();
}
wb_cdrep *wb_adrep::cdrep()
{
return new wb_cdrep( this);
}
wb_bdrep *wb_adrep::bdrep()
{
return new wb_bdrep( this);
}
pwr_tOid wb_adrep::aoid()
......
......@@ -6,21 +6,26 @@
#include "wb_cdrep.h"
#include "wb_bdrep.h"
class wb_orepdbs;
class wb_adrep
{
public:
wb_mvrepdbs *m_vrep;
dbs_sObject *m_ao;
wb_adrep();
wb_adrep(wb_mvrepdbs *vrep, dbs_sObject *ao);
wb_adrep(const wb_adrep&); // x = other_object
wb_adrep& operator=(const wb_adrep&);
int m_nRef;
wb_orepdbs *m_orep;
pwr_tStatus m_sts;
friend class wb_bdrep;
friend class wb_cdrep;
public:
wb_adrep(wb_orepdbs& );
~wb_adrep();
wb_bdrep *bdef();
wb_cdrep *cdef();
void unref();
wb_adrep *ref();
wb_bdrep *bdrep();
wb_cdrep *cdrep();
pwr_sAttrRef aref();
size_t size(); // get objects runtime body size
......@@ -37,7 +42,6 @@ public:
wb_name name() { wb_name n; return n;} // Fix // get attribute name
wb_name name(ldh_eName type) { wb_name n; return n; } // Fix
};
#endif
......
#include "wb_bdef.h"
#include "wb_adef.h"
wb_bdef::wb_bdef()
{
}
wb_bdef::wb_bdef(wb_bdrep *b, pwr_tStatus sts) :
wb_status(sts), m_bdrep(b)
wb_bdef::wb_bdef(wb_bdrep *b) :
wb_status(b->sts()), m_bdrep(b)
{
m_bdrep->ref();
}
wb_bdef::wb_bdef(const wb_bdef&)
wb_bdef::wb_bdef(const wb_bdef& x) : wb_status(x.m_sts), m_bdrep(x.m_bdrep)
{
if ( m_bdrep)
m_bdrep->ref();
}
wb_bdef& wb_bdef::operator=(const wb_bdef &b)
wb_bdef& wb_bdef::operator=(const wb_bdef &x)
{
return *this;
if ( x.m_bdrep)
x.m_bdrep->ref();
if ( m_bdrep)
m_bdrep->unref();
m_bdrep = x.m_bdrep;
m_sts = x.m_sts;
return *this;
}
......
......@@ -4,18 +4,20 @@
#include "pwr.h"
#include "wb_bdrep.h"
#include "wb_orep.h"
#include "wb_adef.h"
#include "wb_object.h"
#include "wb_name.h"
class wb_bdrep;
class wb_adef;
class wb_bdef : public wb_status
{
public:
int m_nRef;
wb_bdrep *m_bdrep;
public:
wb_bdef();
wb_bdef(wb_bdrep*, pwr_tStatus);
wb_bdef(wb_bdrep* bdrep);
wb_bdef(const wb_bdef&);
wb_bdef& operator=(const wb_bdef&);
......
#include "wb_bdrep.h"
#include "wb_adrep.h"
#include "wb_orepdbs.h"
void wb_bdrep::unref()
{
if ( --m_nRef == 0)
delete this;
}
wb_bdrep *wb_bdrep::ref()
{
m_nRef++;
return this;
}
wb_bdrep::wb_bdrep(wb_orepdbs& o) : m_nRef(0), m_orep(&o), m_sts(LDH__SUCCESS)
{
m_orep->ref();
}
wb_bdrep::wb_bdrep( wb_adrep *adrep) : m_nRef(0)
{
pwr_tStatus sts;
m_orep = (wb_orepdbs *) adrep->m_orep->parent( &sts);
if ( EVEN(sts)) throw wb_error(sts);
m_sts = LDH__SUCCESS;
}
wb_bdrep::~wb_bdrep()
{
m_orep->unref();
}
wb_adrep *wb_bdrep::adrep( pwr_tStatus *sts)
{
wb_orepdbs *orep = (wb_orepdbs *)m_orep->m_vrep->first( sts, m_orep);
if ( EVEN(*sts)) return 0;
return new wb_adrep(*orep);
}
wb_adrep *wb_bdrep::adrep( pwr_tStatus *sts, char *aname)
{
wb_orepdbs *orep = (wb_orepdbs *)m_orep->m_vrep->child( sts, m_orep, aname);
if ( EVEN(*sts))
return 0;
wb_adrep *adrep = new wb_adrep( *orep);
return adrep;
}
......@@ -3,22 +3,28 @@
#include "pwr.h"
#include "wb_orep.h"
#include "wb_adef.h"
#include "wb_object.h"
#include "co_dbs.h"
#include "wb_name.h"
class wb_adef;
class wb_adrep;
class wb_orepdbs;
class wb_bdrep
{
public:
int m_nRef;
wb_orepdbs *m_orep;
pwr_tStatus m_sts;
public:
wb_bdrep();
wb_bdrep(const wb_adef&);
wb_bdrep(const wb_orep&);
wb_bdrep& operator=(const wb_bdrep&);
wb_bdrep(wb_orepdbs& o); // own orep
wb_bdrep( wb_adrep *adrep);
~wb_bdrep();
void unref();
wb_bdrep *ref();
pwr_sAttrRef aref() { pwr_sAttrRef a; return a;} // Fix
size_t size() { return 0;} // Fix // get objects runtime body size
......@@ -30,6 +36,9 @@ public:
wb_name name() { wb_name n; return n;} // Fix // get attribute name
wb_name name(ldh_eName type) { wb_name n; return n;} // Fix
wb_adrep *adrep( pwr_tStatus *sts); // Get first attribute
wb_adrep *adrep( pwr_tStatus *sts, char *aname);
pwr_tStatus sts() { return m_sts;}
......
#include "wb_cdef.h"
#include "wb_adef.h"
wb_cdef::wb_cdef()
wb_cdef::wb_cdef() : wb_status(LDH__NOCLASS), m_cdrep(0)
{
}
wb_cdef::wb_cdef(const wb_adef&)
wb_cdef::wb_cdef( wb_cdrep *cdrep) : wb_status(cdrep->sts()), m_cdrep(cdrep)
{
cdrep->ref();
}
wb_cdef::wb_cdef(const wb_orep&)
wb_cdef::wb_cdef( wb_adef& a)
{
wb_adrep *adrep = a;
m_cdrep = new wb_cdrep( adrep);
m_cdrep->ref();
m_sts = m_cdrep->sts();
}
wb_cdef& wb_cdef::operator=(const wb_cdef&)
wb_cdef::wb_cdef(const wb_orep& x)
{
return *this;
m_cdrep = new wb_cdrep( x);
m_cdrep->ref();
m_sts = m_cdrep->sts();
}
wb_cdef::wb_cdef(wb_mvrep *mvrep, pwr_tCid cid)
{
m_cdrep = new wb_cdrep( mvrep, cid);
m_cdrep->ref();
m_sts = m_cdrep->sts();
}
wb_cdef::~wb_cdef()
{
if ( m_cdrep)
m_cdrep->unref();
}
wb_cdef::wb_cdef(const wb_cdef& x) : wb_status(x.sts()), m_cdrep(x.m_cdrep)
{
if ( m_cdrep)
m_cdrep->ref();
}
wb_cdef& wb_cdef::operator=(const wb_cdef& x)
{
if ( x.m_cdrep)
x.m_cdrep->ref();
if ( m_cdrep)
m_cdrep->unref();
m_cdrep = x.m_cdrep;
m_sts = x.m_sts;
return *this;
}
......@@ -41,8 +79,15 @@ wb_name wb_cdef::name(ldh_eName type)
wb_bdef wb_cdef::bdef( char *bname) // Fix
{
wb_bdef b;
return b;
pwr_tStatus sts;
wb_bdrep *bdrep = m_cdrep->bdrep( &sts, bname);
if ( ODD(sts))
return wb_bdef( bdrep);
else {
delete bdrep;
return wb_bdef();
}
}
......
......@@ -4,7 +4,6 @@
#include "pwr.h"
#include "pwr_class.h"
#include "co_dbs.h"
#include "wb_adef.h"
#include "wb_bdef.h"
#include "wb_orep.h"
#include "wb_cdrep.h"
......@@ -12,6 +11,9 @@
class wb_bdef;
class wb_adef;
class wb_cdrep;
class wb_mvrep;
class wb_cdef : public wb_status
{
......@@ -20,8 +22,12 @@ public:
wb_cdrep *m_cdrep;
wb_cdef();
wb_cdef(const wb_adef&); // x = other_object
wb_cdef( wb_cdrep *cdrep);
wb_cdef( wb_adef&); // x = other_object
wb_cdef(const wb_orep&); // x = other orep
wb_cdef(wb_mvrep *, pwr_tCid);
wb_cdef(const wb_cdef&);
~wb_cdef();
wb_cdef& operator=(const wb_cdef&);
operator bool() const { return (m_cdrep != 0);}
......
extern "C" {
#include "co_cdh.h"
}
#include "wb_cdrep.h"
#include "wb_merep.h"
#include "wb_ldh_msg.h"
#include "co_dbs.h"
#include "wb_orepdbs.h"
#include "wb_bdrep.h"
void wb_cdrep::unref()
{
if ( --m_nRef == 0)
delete this;
}
wb_cdrep *wb_cdrep::ref()
{
m_nRef++;
return this;
}
wb_cdrep::wb_cdrep() : m_nRef(0), m_orep(0), m_sts(LDH__NOCLASS)
{
}
wb_cdrep::wb_cdrep( wb_mvrep *mvrep, pwr_tCid cid) : m_nRef(0)
{
pwr_tOid oid = cdh_ClassIdToObjid( cid);
m_orep = (wb_orepdbs *) mvrep->object( &m_sts, oid);
m_orep->ref();
if ( EVEN(m_sts)) throw wb_error( m_sts);
m_sts = LDH__SUCCESS;
}
wb_cdrep::wb_cdrep( wb_mvrep *mvrep, const wb_orep& o) : m_nRef(0)
{
pwr_tOid oid = cdh_ClassIdToObjid( o.vid());
m_orep = (wb_orepdbs *) mvrep->object( &m_sts, oid);
if ( EVEN(m_sts)) throw wb_error( m_sts);
m_sts = LDH__SUCCESS;
}
wb_cdrep::wb_cdrep( const wb_orep& o) : m_nRef(0)
{
pwr_tStatus sts;
wb_cdrep *cdrep = o.vrep()->merep()->cdrep( &sts, o);
m_sts = sts;
m_orep = cdrep->m_orep;
m_orep->ref();
delete cdrep;
}
wb_cdrep::wb_cdrep( wb_adrep *adrep) : m_nRef(0)
{
pwr_tStatus sts;
wb_orepdbs *orep = (wb_orepdbs *) adrep->m_orep->parent( &sts);
if ( EVEN(sts)) throw wb_error(sts);
orep->ref();
m_orep = (wb_orepdbs *)orep->parent( &sts);
if ( EVEN(sts)) throw wb_error(sts);
m_sts = LDH__SUCCESS;
orep->unref();
}
wb_bdrep *wb_cdrep::bdrep( pwr_tStatus *sts, char *bname)
{
wb_orepdbs *orep = (wb_orepdbs *)m_orep->m_vrep->child( sts, m_orep, bname);
if ( EVEN(*sts))
return 0;
wb_bdrep *bdrep = new wb_bdrep( *orep);
return bdrep;
}
......@@ -4,24 +4,31 @@
#include "pwr.h"
#include "pwr_class.h"
#include "co_dbs.h"
#include "wb_adef.h"
#include "wb_name.h"
#include "wb_orep.h"
class wb_adef;
class wb_orep;
class wb_mvrep;
class wb_bdrep;
class wb_orepdbs;
class wb_adrep;
class wb_cdrep
{
public:
dbs_sObject *m_coh;
int m_nRef;
wb_orepdbs *m_orep;
pwr_tStatus m_sts;
wb_cdrep() {} // Fix
wb_cdrep(const wb_adef&); // x = other_object
wb_cdrep(const wb_orep&) {} // Fix x = other orep
wb_cdrep& operator=(const wb_cdrep&);
public:
wb_cdrep();
wb_cdrep(wb_adrep *); // x = other_object
wb_cdrep(const wb_orep&); // x = other orep
wb_cdrep(wb_mvrep *, const wb_orep&);
wb_cdrep(wb_mvrep *, pwr_tCid);
void unref();
wb_cdrep *ref();
//wb_object& operator=(const wb_orep&);
......@@ -30,10 +37,11 @@ public:
wb_name name() { wb_name n; return n;} // Fix get class name
wb_name name(ldh_eName type) { wb_name n; return n;} // Fix
wb_name name(ldh_eName type) { wb_name n; return n;} // Fix
void name(const char *name);
void name(wb_name *name);
wb_bdrep *bdrep( pwr_tStatus *sts, char *bname);
pwr_tStatus sts() { return m_sts;}
};
......
#include <iostream.h>
#include <fstream.h>
#include "pwr.h"
#include "wb_erep.h"
#include "wb_merep.h"
#include "wb_vrepwbl.h" // Should be wb_vrepdbs.h ...
#include "wb_cdrep.h"
#include "wb_orep.h"
#include "wb_ldh_msg.h"
extern "C" {
......@@ -384,7 +387,13 @@ void wb_erep::loadMeta( pwr_tStatus *status)
*status = LDH__SUCCESS;
}
wb_cdrep *wb_erep::cdrep( pwr_tStatus *sts, const wb_orep& o)
{
wb_vrep *vrep = volume(sts, o.vid());
if ( EVEN(*sts)) return 0;
return vrep->merep()->cdrep( sts, o);
}
......
......@@ -8,6 +8,8 @@ using namespace std;
class wb_merep;
class wb_vrep;
class wb_cdrep;
class wb_orep;
class wb_erep
{
......@@ -43,6 +45,8 @@ public:
void removeExtern( pwr_tStatus *sts, wb_vrep *vrep);
void load( pwr_tStatus *sts);
wb_cdrep *cdrep( pwr_tStatus *sts, const wb_orep& o);
private:
void loadDirList( pwr_tStatus *status);
void loadCommonMeta( pwr_tStatus *status);
......
......@@ -16,7 +16,7 @@ wb_mvrep *wb_merep::volume( pwr_tStatus *sts)
wb_mvrep *wb_merep::volume(pwr_tStatus *sts, pwr_tVid vid)
{
map<pwr_tVid, wb_mvrep*>::iterator it = m_mvrepdbs.find( vid);
map<pwr_tVid, wb_mvrep*>::iterator it = m_mvrepdbs.find( vid);
if ( it == m_mvrepdbs.end()) {
*sts = LDH__NOSUCHVOL;
return 0;
......@@ -55,10 +55,25 @@ void wb_merep::removeDbs(pwr_tStatus *sts, wb_mvrep *mvrep)
wb_cdrep *wb_merep::cdrep( pwr_tStatus *sts, const wb_orep& o)
{
if ( o.vrep() != m_vrep)
// Fetch from other meta environment
return m_erep->cdrep( sts, o);
map<pwr_tVid, wb_mvrep*>::iterator it = m_mvrepdbs.find( cdh_CidToVid(o.cid()));
if ( it == m_mvrepdbs.end()) {
*sts = LDH__NOSUCHVOL;
return 0;
}
*sts = LDH__SUCCESS;
return it->second->cdrep( o);
}
wb_cdrep *wb_merep::cdrep( pwr_tStatus *sts, pwr_tCid cid)
{
map<pwr_tVid, wb_mvrep*>::iterator it = m_mvrepdbs.find( cdh_CidToVid( cid));
if ( it == m_mvrepdbs.end()) {
*sts = LDH__NOSUCHVOL;
return 0;
}
return it->second->cdrep( cid);
}
......@@ -13,15 +13,17 @@ class wb_merep {
map<pwr_tVid, wb_mvrep*> m_mvrepdbs;
wb_erep *m_erep;
wb_vrep *m_vrep;
public:
wb_merep( wb_erep *erep) : m_erep(erep) {}
wb_merep( wb_erep *erep, wb_vrep *vrep = 0) : m_erep(erep), m_vrep(vrep) {}
wb_mvrep *volume(pwr_tStatus *sts);
wb_mvrep *volume(pwr_tStatus *sts, pwr_tVid vid);
void addDbs( pwr_tStatus *sts, wb_mvrep *mvrep);
void removeDbs( pwr_tStatus *sts, wb_mvrep *mvrep);
wb_cdrep *cdrep( pwr_tStatus *sts, const wb_orep& o);
wb_cdrep *cdrep( pwr_tStatus *sts, pwr_tCid cid);
};
#endif
#include "wb_mvrep.h"
wb_cdrep *wb_mvrep::cdrep( pwr_tCid cid)
{
return new wb_cdrep( this, cid);
}
wb_cdrep *wb_mvrep::cdrep( const wb_orep& o)
{
return new wb_cdrep( this, o);
}
......@@ -8,9 +8,8 @@
class wb_mvrep : public wb_vrep {
public:
wb_cdrep *cdrep( const wb_orep& o) { return 0;} // Fix
wb_bdrep *bdrep( const wb_orep& o) { return 0;} // Fix
wb_adrep *adrep( const wb_orep& o) { return 0;} // Fix
wb_cdrep *cdrep( const wb_orep& o);
wb_cdrep *cdrep( pwr_tCid cid);
};
#endif
......@@ -9,6 +9,7 @@
#include "wb_adrep.h"
class wb_vrep;
class wb_erep;
class wb_orep
{
......@@ -59,6 +60,8 @@ public:
virtual wb_adrep *attribute(pwr_tStatus*, const char *aname) = 0;
virtual wb_adrep *attribute(pwr_tStatus*) = 0;
virtual wb_erep *erep() const = 0;
virtual wb_vrep *vrep() const = 0;
};
#endif
......@@ -78,6 +78,8 @@ public:
virtual wb_adrep *attribute(pwr_tStatus*, const char *aname);
virtual wb_adrep *attribute(pwr_tStatus*);
wb_erep *erep() const { return m_vrep->erep();}
wb_vrep *vrep() const { return m_vrep;}
};
#endif
......@@ -11,6 +11,8 @@ class wb_orepdbs : public wb_orep
wb_vrepdbs *m_vrep;
unsigned int m_refCount;
friend class wb_cdrep;
friend class wb_bdrep;
public:
......@@ -55,6 +57,9 @@ public:
virtual wb_adrep *attribute(pwr_tStatus*, const char *aname);
virtual wb_adrep *attribute(pwr_tStatus*);
wb_erep *erep() const { return m_vrep->erep();}
wb_vrep *vrep() const { return m_vrep;}
};
#endif
......@@ -56,6 +56,9 @@ public:
virtual wb_adrep *attribute(pwr_tStatus*);
wb_wblnode *wblNode() { return m_wblnode;}
wb_erep *erep() const { return m_vrep->erep();}
wb_vrep *vrep() const { return m_vrep;}
};
#endif
......
#include "wb_volume.h"
#include "wb_merep.h"
wb_volume::wb_volume() : wb_status(LDH__NOSUCHVOL), m_vrep(0), m_vid(0)
{
......@@ -122,7 +123,11 @@ wb_object wb_volume::object(pwr_tOid oid) const
return o;
}
wb_cdef wb_volume::cdef(wb_object o)
{
pwr_tStatus sts;
return wb_cdef(m_vrep->erep()->merep()->cdrep( &sts, o.cid()));
}
......
......@@ -65,7 +65,7 @@ public:
wb_bdef bdef(wb_cdef cdef, char *bname) { wb_bdef b; return b;}; // Fix
wb_bdef bdef(wb_object o, char *bname) { wb_bdef b; return b;}; // Fix
wb_cdef cdef(wb_object o) { wb_cdef c; return c;}; // Fix
wb_cdef cdef(wb_object o);
wb_cdef cdef(pwr_tCid cid) { wb_cdef c; return c;}; // Fix
wb_cdef cdef(pwr_tOid coid) { wb_cdef c; return c;}; // Fix
wb_cdef cdef(wb_name n) { wb_cdef c; return c;}; // Fix
......
......@@ -12,6 +12,7 @@
#include <map>
class wb_erep;
class wb_merep;
class wb_srep;
class wb_cdef;
class wb_destination;
......@@ -86,6 +87,7 @@ public:
virtual pwr_tCid cid() const = 0;
virtual void name( char *n) { strcpy( m_name, n);}
virtual char *name() { return m_name;}
virtual wb_merep *merep() const = 0;
virtual bool createSnapshot(char *fileName) = 0;
......
......@@ -3,6 +3,7 @@
#include "co_dbs.h"
#include "wb_vrep.h"
#include "wb_cdef.h"
class wb_vrepdbs : public wb_vrep
{
......
......@@ -26,6 +26,7 @@ class wb_vrepwbl : public wb_vrep
//wb_session m_wsession;
wb_erep *m_erep;
wb_merep *m_merep;
unsigned int m_nSession;
unsigned int m_nRef;
......@@ -43,11 +44,11 @@ class wb_vrepwbl : public wb_vrep
public:
wb_vrepwbl( wb_erep *erep) :
m_erep(erep), root_object(0), error_cnt(0), file_cnt(0), next_oix(0),
volume_node(0) {}
m_erep(erep), m_merep(erep->merep()), root_object(0), error_cnt(0),
file_cnt(0), next_oix(0), volume_node(0) {}
wb_vrepwbl( wb_erep *erep, pwr_tVid vid) :
m_vid(vid), m_erep(erep), root_object(0), error_cnt(0), file_cnt(0), next_oix(0),
volume_node(0) {}
m_vid(vid), m_erep(erep), m_merep(erep->merep()), root_object(0),
error_cnt(0), file_cnt(0), next_oix(0), volume_node(0) {}
~wb_vrepwbl();
pwr_tVid vid() const { return m_vid;}
......@@ -112,6 +113,7 @@ public:
virtual wb_vrep *ref();
wb_erep *erep() const {return m_erep;};
wb_merep *merep() const { return m_merep;}
wb_orep *object(pwr_tStatus *sts);
wb_orep *object(pwr_tStatus *sts, pwr_tOid oid) {return 0;};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment