3 * Author: Martin Perner, 0725782, 535
4 * E-Mail: e0725782@student.tuwien.ac.at
5 * Purpose: Factory for creating Instruction from shared libraries
9 #include "CInstrFactory.hpp"
15 * Purpose: loads a command from the given library file
17 * Parameter: std::string lib location of the library file
19 * Preconditions: lib references to a valid library
21 Iinstr* CInstrFactory::loadFromLib(string lib)
23 Iinstr* (*create_instruction)();
25 // load a Instruction from library
26 void* instruction = dlopen(lib.c_str(), RTLD_LAZY);
28 cerr << "Cannot load library: " << dlerror() << endl;
33 void* create = dlsym(instruction, "create_instruction");
34 void* destroy = dlsym(instruction, "destroy_instruction");
36 if (!create || !destroy) {
37 cerr << "Cannot load symbols: " << dlerror() << endl;
42 memcpy(&create_instruction, &create, sizeof(create));
44 Iinstr* instructionPointer = create_instruction();
46 m_libStore.insert(make_pair(instruction, instructionPointer));
48 return instructionPointer;
52 * Name: getNextInstruction
53 * Purpose: returns a pointer to a command
55 * Returns: Pointer to the loaded command
58 * Preconditions: a command is left to load
60 Iinstr* CInstrFactory::getNextInstr()
62 if(m_files.size() >= 1) {
64 instruction = loadFromLib(m_files[0]);
65 m_files.erase(m_files.begin());
69 throw string("No more instruction left!");
75 * Name: searchLibsInDir
76 * Purpose: finds librarys in the given directory
78 * Returns: number of found librarays
80 * Parameters: std::string dir Directory where the libraries are located
82 * Postconditions: all files with a trailing '.so' are ready to be used
84 size_t CInstrFactory::searchLibsInDir(string dir)
88 if((dp = opendir(dir.c_str())) == NULL) {
90 errmsg << "Error(" << errno << ") opening " << dir << endl;
94 while ((dirp = readdir(dp)) != NULL) {
95 string file = dirp->d_name;
96 if(file.size() >= 3) {
97 file = file.substr(file.size()-3);
98 std::transform(file.begin(), file.end(), file.begin(), ::tolower);
100 m_files.push_back(dir+"/"+string(dirp->d_name));
105 return m_files.size();
110 * Purpose: returns the number of librarys left
112 * Returns: size_t number of files left
114 size_t CInstrFactory::getNumFiles()
116 return m_files.size();
120 * Name: ~CInstrFactory
121 * Purpose: Destructor of the Object
123 CInstrFactory::~CInstrFactory()
125 void (*destroy_instruction)(Iinstr*);
127 while(!m_libStore.empty()) {
128 void* destroy = dlsym(m_libStore.begin()->first, "destroy_instruction");
129 memcpy(&destroy_instruction, &destroy, sizeof(destroy));
130 destroy_instruction(m_libStore.begin()->second);
131 dlclose(m_libStore.begin()->first);
132 m_libStore.erase(m_libStore.begin());