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();
119 void CInstrFactory::loadLibsIntoMap(map<short, Iinstr*>& instr, string dir)
122 cout << "Loaded " << this->searchLibsInDir(dir) << " Libraryfiles" << endl;
124 this->searchLibsInDir(dir);
126 while(this->getNumFiles() >= 1) {
127 Iinstr* pinstr = this->getNextInstr();
128 instr.insert(make_pair(pinstr->getOpcode(),pinstr));
130 cout << "found: " << pinstr->getName() << " its opcode is : " << pinstr->getOpcode() << endl;
137 * Name: ~CInstrFactory
138 * Purpose: Destructor of the Object
140 CInstrFactory::~CInstrFactory()
142 void (*destroy_instruction)(Iinstr*);
144 while(!m_libStore.empty()) {
145 void* destroy = dlsym(m_libStore.begin()->first, "destroy_instruction");
146 memcpy(&destroy_instruction, &destroy, sizeof(destroy));
147 destroy_instruction(m_libStore.begin()->second);
148 dlclose(m_libStore.begin()->first);
149 m_libStore.erase(m_libStore.begin());