📄 gacatalogue.h
字号:
#ifndef __GA_CATALOGUE_H__
#define __GA_CATALOGUE_H__
#include <utility>
#include <hash_map>
#include "..\ExportImport.h"
#include "..\CallConvention.h"
#include "..\Threading\GaThreading.h"
using namespace stdext;
using namespace std;
namespace Common
{
template <typename T>
class GaCatalogue;
// Entry of catalogue
template <typename T>
class GaCatalogueEntry
{
friend class GaCatalogue<T>;
private:
// Name of entry
char* _name;
// Length of name
int _nameLength;
// Pointer to the data
T* _data;
public:
// Initialization of the entry
GaCatalogueEntry(const char* name,
T& data)
{
if( name )
{
_nameLength = (int)strlen( name );
// copy name
_name = new char[ _nameLength + 1 ];
strcpy( _name, name );
_data = &data;
return;
}
_name = NULL;
_nameLength = 0;
_data = NULL;
};
// Frees aquired resources
~GaCatalogueEntry()
{
if( _name )
delete[] _name;
if( _data )
delete _data;
};
// Returns name of entry
const char* GACALL GetName() const
{
return _name;
};
// Sets name of entry
void GACALL SetName(const char* name)
{
if( name )
{
if( _name )
delete[] _name;
_nameLength = strlen( name );
// copy name
_name = new char[ _nameLength + 1 ];
strcpy( _name, name );
}
};
// Returns length of entry's name
int GACALL GetNameLength() const
{
return _nameLength;
};
// Returns pointer to data
T& GACALL GetData() const
{
return *_data;
};
// Sets pointer to data
void GACALL SetData(T& data)
{
_data = &data;
};
};// END CLASS DEFINITION GaCatalogueEntry
// Manages catalogues and their entries
template <typename T>
class GaCatalogue
{
DEFINE_SYNC_CLASS
private:
// String comparator
struct GaStringComparator
{
public:
// comapration
bool GACALL operator()(const char* left, const char* right) const
{
return strcmp( left, right ) == -1;
}
};
// comarator for catalogue's hash map
class GaCataolgueHashMapComparator
{
public:
// parameters for hash table
enum
{
bucket_size = 4,
min_buckets = 8
};
// construct with default comparator
GaCataolgueHashMapComparator() : _comparator() { }
// construct with _Pred comparator
GaCataolgueHashMapComparator(GaStringComparator pred) : _comparator( pred ) { }
// Hash function
size_t GACALL operator()(const char* key) const
{
if( key == NULL )
return 0;
size_t t = 0;
while( *key )
t += *( key++ );
ldiv_t rem = ldiv((long)t, 127773);
rem.rem = 16807 * rem.rem - 2836 * rem.quot;
if (rem.rem < 0)
rem.rem += 2147483647;
return ((size_t)rem.rem);
}
// Comparation
bool GACALL operator()(const char* value1, const char* value2) const
{
return _comparator( value1, value2 );
}
private:
// String comparator
GaStringComparator _comparator;
};
typedef hash_map<const char*, GaCatalogueEntry<T>*, GaCataolgueHashMapComparator> GaCataolgueHashMap;
// Global instance of the catalogue
DLL_EXPORT
static GaCatalogue<T>* _instance;
// Catalogue's entries
GaCataolgueHashMap _entries;
public:
// Returns global instance of the catalogue
static GaCatalogue<T>& GACALL Instance()
{
return *_instance;
}
// Makes global instance of catalogue
static void GACALL MakeInstance()
{
if( !_instance )
_instance = new GaCatalogue();
}
// Frees memory used by global instance of catalogue
static void GACALL FreeInstance()
{
if( _instance )
delete _instance;
}
// Initialization of the catalgoue
GaCatalogue() { }
// Frees aquired resources
~GaCatalogue()
{
for( GaCataolgueHashMap::const_iterator it = _entries.begin(); it != _entries.end(); it++ )
delete it->second;
_entries.clear();
}
// Adds entry to catalogue
bool GACALL Register(const char* name,
T& data,
bool replace = false)
{
// no name - error?
if( !name )
return false;
LOCK_THIS_OBJECT( lock );
// does it exist?
GaCataolgueHashMap::const_iterator it = _entries.find( name );
bool exists = it != _entries.end();
if( exists && !replace )
// exists and no replacing - error
return false;
// erease if entry exists and replace is enabled
if( exists && replace )
{
delete it->second;
_entries.erase( name );
}
// make entry for data and insert to catalogue
GaCatalogueEntry<T>* new_entry = new GaCatalogueEntry<T>( name, data );
return _entries.insert( pair<const char*, GaCatalogueEntry<T>*>( name, new_entry ) ).second;
}
// Remove entry from the catalgoue
bool GACALL Unregister(const char* name)
{
LOCK_THIS_OBJECT( lock );
bool removed = false;
// exists?
GaCataolgueHashMap::const_iterator it = _entries.find( name );
if( it != _entries.end() )
{
// remove
delete it->second;
removed = _entries.erase( name ) > 0;
}
return removed;
}
// Returns pointer to entry (lookup by name)
GaCatalogueEntry<T>* GACALL GetEntry(const char* name) const
{
LOCK_THIS_OBJECT( lock );
// find entry and return pointer to entry
GaCataolgueHashMap::const_iterator it = _entries.find( name );
return it == _entries.end() ? NULL : it->second;
}
// Returns pointer to entry's data (lookup by name)
T* GACALL GetEntryData(const char* name) const
{
LOCK_THIS_OBJECT( lock );
// find entry and return pointer to data
GaCataolgueHashMap::const_iterator it = _entries.find( name );
return it == _entries.end() ? NULL : &it->second->GetData();
}
// Returns pointer to entry's data (lookup by name)
T* GACALL operator [](const char* name) const
{
return GetEntryData( name );
}
// Returns first N names in catalogue
// Caller must allocate memory for array of pointers to strings.
// This method allocates memory for names but caller is responsible for it.
// It also returns a number of names for which is memory allocated.
bool GACALL GetKeys(char** names,
int& number) const
{
LOCK_THIS_OBJECT( lock );
// no buffer or too small?
if( !names || number < (int)_entries.size() )
{
// returns error and number of entries
number = _entries.size();
return false;
}
// fill buffer with names
int i = 0;
for( GaCataolgueHashMap::const_iterator it = _entries.begin(); it != _entries.end(); it++, i++ )
{
names[ i ] = new char[ it->second->GetNameLength() + 1 ];
strcpy( names[ i ], it->second->GetName() );
}
number = i;
return true;
}
// Returns number of entries in catalogue
int GACALL GetCount() const
{
LOCK_THIS_OBJECT( lock );
return _entries.size();
}
// Returns TRUE if entry with given name exists in catalogue
bool GACALL IsExist(const char* name) const
{
LOCK_THIS_OBJECT( lock );
return _entries.count( name ) > 0;
}
};// END CLASS DEFINITION GaCatalogue
#ifdef DLL_EXPORTING
// Global instance of the catalogue
template <typename T>
GaCatalogue<T>* GaCatalogue<T>::_instance = NULL;
#endif
} // Common
#endif //__GA_CATALOGUE_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -