22 #ifndef __BaseFactory_hh__
23 #define __BaseFactory_hh__
25 #include <bias_config.h>
27 #include <Base/Common/FileHandling.hh>
28 #include <Base/Common/Singleton.hh>
29 #include <Base/Debug/Debug.hh>
30 #include <Base/Debug/LogFacility.hh>
38 # include <sys/types.h>
49 template<
class BaseClassType,
class TagType>
class BaseFactory;
51 template<
class BaseClassType,
class TagType>
142 template<
class BaseClassType,
class TagType = std::
string>
148 typedef BaseClassType* (*AllocatorFunctionPointer)();
171 void SetPrefix(
const std::string &prefix);
175 BaseClassType *
Generate(
const TagType& tag);
177 void GetNearTag(
const TagType& tag, TagType& t1, TagType& t2)
const;
188 std::vector<std::string>& files)
const;
198 friend std::ostream &
199 operator<<<>(std::ostream& os,
207 #ifdef BIAS_BUILD_SHARED_LIBS
219 std::map<TagType, MapEntry>
Map_;
238 {
return (
Map_.find(tag) !=
Map_.end()); }
248 const std::string& directory)
const;
252 int OpenDll_(
const std::string& tag);
261 template <
class BaseClassType,
class TagType>
264 : Map_(), Directories_(), Prefix_()
268 template <
class BaseClassType,
class TagType>
271 : Map_(), Directories_(), Prefix_()
275 template <
class BaseClassType,
class TagType>
282 template <
class BaseClassType,
class TagType>
285 { BIASABORT;
return *
this; }
288 template <
class BaseClassType,
class TagType>
292 #ifdef BIAS_BUILD_SHARED_LIBS
299 std::string::size_type pos = 0;
300 std::string::size_type offset = 0;
301 std::string directory;
302 while ( (pos = directories.find(seperator, offset)) != std::string::npos){
303 directory = directories.substr(offset, pos-offset);
304 Directories_.push_back(directory);
307 directory = directories.substr(offset, directories.length()-offset);
308 Directories_.push_back(directory);
313 template <
class BaseClassType,
class TagType>
317 #ifdef BIAS_BUILD_SHARED_LIBS
323 template <
class BaseClassType,
class TagType>
327 BaseClassType *(*CreateFunc)() = NULL;
328 typename std::map<TagType, MapEntry>::const_iterator it;
330 #ifdef BIAS_BUILD_SHARED_LIBS
331 if (it == Map_.end()) {
332 if (OpenDll_(tag) < 0) {
336 CreateFunc = Map_[tag].AllocatorFunction_;
338 if (it != Map_.end()){
339 CreateFunc = it->second.AllocatorFunction_;
341 BLF(
"failed to load static library for tag \""<<tag<<
"\"");
345 BIASASSERT(CreateFunc != NULL);
351 template <
class BaseClassType,
class TagType>
353 GetNearTag(
const TagType& tag, TagType& tagupper, TagType& taglower)
const
356 std::vector<TagType> tags;
360 std::sort(tags.begin(),tags.end());
362 while (tags[i] != tag && i<tags.size()) i++;
363 if (i>0 && i<tags.size()) tagupper = tags[i-1];
364 if (i<tags.size()) taglower = tags[i+1];
396 template <
class BaseClassType,
class TagType>
401 #ifdef BIAS_BUILD_SHARED_LIBS
402 std::vector<std::string> tmp;
403 typename std::vector<std::string>::const_iterator it;
404 for (it = Directories_.begin(); it!=Directories_.end(); it++){
405 GetKnownTags_(tmp, *it);
406 tags.insert(tags.begin(), tmp.begin(), tmp.end());
409 typename std::map<TagType, MapEntry>::const_iterator it;
410 for (it=Map_.begin(); it!=Map_.end(); it++){
411 tags.push_back(it->first);
414 std::sort(tags.begin(),tags.end());
415 return (
int)tags.size();
419 template <
class BaseClassType,
class TagType>
423 #ifndef BIAS_BUILD_SHARED_LIBS
424 BaseClassType *cl = (*allocFunc)();
426 BEXCEPTION(
"allocator function is not working!");
431 if (IsInMap_(cl->GetTag())) {
432 BEXCEPTION(
"tag \""<<cl->GetTag()<<
"\" already exists in factory instance!");
435 Map_.insert(make_pair(cl->GetTag(), me));
442 template <
class BaseClassType,
class TagType>
446 #ifdef BIAS_BUILD_SHARED_LIBS
447 typename std::map<TagType, MapEntry >::iterator it;
448 for (it = Map_.begin(); it!= Map_.end(); it++){
450 if (FreeLibrary(it->second.DllHandle)!=0) {
451 BLF(
"error unloading library \""<<it->first<<
"\"!");
454 if (dlclose(it->second.DllHandle)!=0) {
455 BLF(
"error unloading library \""<<it->first<<
"\"!");
456 BLF(
"-> "<<dlerror());
459 BLD(
"unloaded library \""<<it->first<<
"\"");
466 template <
class BaseClassType,
class TagType>
470 #ifdef BIAS_BUILD_SHARED_LIBS
471 typename std::vector<std::string>::const_iterator it;
472 std::string filename;
474 NewModule.DllHandle = NULL;
477 # ifdef COMPILE_NDEBUG
479 # else //COMPILE_NDEBUG
481 # endif //COMPILE_NDEBUG
484 # ifdef COMPILE_NDEBUG
486 # else //COMPILE_NDEBUG
488 # endif //COMPILE_NDEBUG
490 # ifdef COMPILE_NDEBUG
492 # else //COMPILE_NDEBUG
494 # endif //COMPILE_NDEBUG
497 for (it = Directories_.begin(); it!=Directories_.end(); it++) {
498 filename = *it +
"/" + Prefix_ + tag + postfix;
500 NewModule.DllHandle = LoadLibrary(filename.c_str());
502 NewModule.DllHandle = dlopen(filename.c_str(),RTLD_NOW);
504 if (NewModule.DllHandle != NULL) {
508 BLF(
"failed to load library \""<<filename<<
"\"!");
510 BLF(
"-> "<<dlerror());
514 if (!NewModule.DllHandle){
515 BLD(
"failed to load library \""<<Prefix_+tag+postfix<<
"\" from :");
516 for (
unsigned i=0; i<Directories_.size(); i++)
517 BLD(
" "<< Directories_[i]);
521 std::string CreateSym;
524 CreateSym =
"create";
526 (AllocatorFunctionPointer)GetProcAddress(NewModule.DllHandle, CreateSym.c_str());
528 CreateSym =
"create";
530 void *damnedvoidpointer = dlsym(NewModule.DllHandle,CreateSym.c_str());
531 memcpy(&(NewModule.
AllocatorFunction_), &damnedvoidpointer,
sizeof(damnedvoidpointer));
538 BLF(
"can not find symbol \""<<CreateSym<<
"\" in file \""<<filename<<
"\"");
541 BLD(
"loaded library \""<<filename<<
"\"");
542 TagToFileMap_[tag] = filename;
546 Map_[tag] = NewModule;
551 template <
class BaseClassType,
class TagType>
553 GetKnownTags_(std::vector<TagType> &tags,
const std::string& directory)
const
555 #ifdef BIAS_BUILD_SHARED_LIBS
557 std::string filename;
561 # ifdef COMPILE_NDEBUG
563 # else //COMPILE_NDEBUG
565 # endif //COMPILE_NDEBUG
567 std::string tmp = directory +
"/"+Prefix_+
"*"+postfix;
569 TCHAR searchPath[MAX_PATH];
571 lstrcpy(searchPath, tmp.c_str());
576 HANDLE sh = FindFirstFile(searchPath, &ffd);
577 if(INVALID_HANDLE_VALUE == sh)
return;
580 const int prefix_len = (int)Prefix_.length();
581 const int postfix_len = (int)postfix.length();
590 filename = ffd.cFileName;
591 int l = (int)filename.length();
592 if (filename.substr(0,prefix_len) == Prefix_
593 && filename.substr(l-postfix_len) == postfix) {
594 filename = filename.substr(prefix_len,l-postfix_len-prefix_len);
595 tags.push_back(filename);
597 }
while (FindNextFile(sh, &ffd));
602 # ifdef COMPILE_NDEBUG
604 # else //COMPILE_NDEBUG
606 # endif //COMPILE_NDEBUG
610 dp = opendir (directory.c_str());
612 perror (directory.c_str());
615 while ( (ep = readdir (dp)) != NULL) {
616 filename = ep->d_name;
617 int l = filename.length();
618 const int prefix_lenth = Prefix_.length();
619 const int postfix_len = postfix.length();
620 if (filename.substr(0,prefix_lenth) == Prefix_
621 && filename.substr(l-postfix_len) ==postfix) {
622 filename = filename.substr(prefix_lenth,l-prefix_lenth-postfix_len);
623 tags.push_back(filename);
626 (void) closedir (dp);
628 std::sort(tags.begin(),tags.end());
635 template <
class BaseClassType,
class TagType>
637 GetLoadedFiles(std::vector<TagType>& tags, std::vector<std::string>& files)
const
641 typename std::map<TagType,std::string>::const_iterator it;
642 it = TagToFileMap_.begin();
643 while(it !=TagToFileMap_.end()) {
644 tags.push_back(it->first);
645 files.push_back(it->second);
648 return (
int)files.size();
659 template <
class BaseClassType,
class TagType>
664 typename std::map<TagType,
667 for (it=bf.
Map_.begin(); it!=bf.
Map_.end(); it++){
668 os <<
"tag :"<<(it->first)<<std::endl;
674 #endif // __BaseFactory_hh__
void SetPrefix(const std::string &prefix)
This function only makes sense when shared libraries are used: Set the prefix used i...
void Clear()
empties the map, and unloads all shared libraries
static char GetSeperator()
void GetNearTag(const TagType &tag, TagType &t1, TagType &t2) const
void AddType(AllocatorFunctionPointer allocFunc)
This function is only meaningfull, when static libraries are used.
BaseClassType *(* AllocatorFunctionPointer)()
typedef for function pointer to class allocator function
struct for storing class details in member map Map_
BaseFactory()
private constructor, the factory is designed as a singleton
AllocatorFunctionPointer AllocatorFunction_
pointer to the static allocator function of this class
std::map< TagType, MapEntry > Map_
tag - class allocator correspondences are stored in this map
std::ostream & operator<<(std::ostream &os, const Array2D< T > &arg)
int OpenDll_(const std::string &tag)
This function is onyl meaningfull when shared libraries are used: open file and store handle in DllMa...
void GetKnownTags_(std::vector< TagType > &tags, const std::string &directory) const
This function is onyl meaningfull when shared libraries are used: Search for all libraries with names...
int GetKnownTags(std::vector< TagType > &tags) const
Searches for all available modules and gives all their tag.
BaseClassType * Generate(const TagType &tag)
function for generic class generation from
void Add2Directories(const std::string &directories)
This function only makes sense when shared libraries are used: Initialize the factory with ':' (linux...
bool IsInMap_(const TagType &tag) const
checks if tag is already in map
BaseFactory & operator=(const BaseFactory &b)
std::map< TagType, std::string > TagToFileMap_
Simple singleton implementation for multithreaded applications.
std::vector< std::string > Directories_
These members are onyl meaningfull when shared libraries are used.
simple factory class designed for usage as a singleton
int GetLoadedFiles(std::vector< TagType > &tags, std::vector< std::string > &files) const
Get all tags and associated filenames of all modules which have been loaded already.