//============================================================================= // // Glagen : a planet sized landscape generator // Copyright (C) 2002 Julien Guertault, Hugues Hiegel, Meng-Tih Lam // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // //============================================================================= // // Glagen : GPL LAndscape GENerator // // libclass.cc for Glagen : made by Hugues HIEGEL // // www.glagen.org // //============================================================================= //--LIBRARY CLASS IMPLEMENTATION--// #include #include #include #include #include #include "../includes/errors.hh" #include "libclass.hh" using std::cout; using std::cerr; using std::endl; /****************************************** * Constructors * * && Destructors * ******************************************/ Library::Library() { } Library::Library(string Filename) { this->Filename = Filename; this->properties.clear(); } Library::~Library() { if (this->handler) this->UnloadLib(); this->Filename = ""; this->properties.clear(); } /****************************************** * Loaders * * -just loads libs files- * ******************************************/ int Library::LoadLib(string Filename) { this->Filename = Filename; return this->LoadLib(); } int Library::LoadLib() { this->properties.clear(); /* ** Tries to open the library itself */ this->handler = dlopen(Filename.c_str(), RTLD_LAZY); if (!(this->handler)) /* This is not a library */ { cerr << "#Err " << ERR_OPENLIB << ": " << dlerror() << "" << endl; return ERR_OPENLIB; } typedef string (*name_t)(); name_t Name = (name_t) dlsym(this->handler, "GLG_Name"); if (!Name) { cerr << "#Err " << ERR_LIBSYMBOL << ": Missing symbol 'string GLG_Name()' in " << this->Filename << "" << endl; return ERR_LIBSYMBOL; } cout << "Loading library: "; cout << Name(); // This shows the dependancies in loading time. list deps; std::list::iterator deps_i; deps = this->getDependancies(); if (! deps.empty()) { cout << " {"; for (deps_i = deps.begin(); deps_i != deps.end(); deps_i++) cout << *deps_i << ", "; cout << "}"; } cout << endl; typedef void* (*hello_t)(); hello_t Hello = (hello_t) dlsym(this->handler, "GLG_Hello"); if (Hello) Hello(); return 0; } int Library::Initialize() { cout << "Moteur\tlibrary::initialize " << endl ; // typedef int (*init_t)(void*, Library*); // init_t Init = (init_t) dlsym(this->handler, "GLG_Init"); // if (Init) // Init(palloc, this); /*********************************************** ** typedef struct dot_property_t { ** ** int pos; ** ** size_t size; ** ** }; ** ** ** ** std::list this->properties ** ***********************************************/ return 0; } int Library::MainLoop(Dot* dot) { cout << "Moteur\tlibrary::mainloop " << endl ; typedef int (*main_t)(Dot*, void*); main_t _Main = (main_t) dlsym(this->handler, "GLG_Main"); if (_Main) _Main(dot, NULL); return 0; } /****************************************** * Miscellaneous stuffs * * Useful functions * ******************************************/ list Library::getDependancies() const { /* ** Gets all library's dependancies */ typedef list (*deps_t)(); deps_t Deps = (deps_t) dlsym(this->handler, "GLG_Dependancies"); list deps; deps.clear(); if (!Deps) return deps; deps = Deps(); return deps; } string Library::getName() const { /* ** Gets the library's basename */ typedef string (*name_t)(); name_t Name = (name_t) dlsym(this->handler, "GLG_Name"); if (!Name) return this->Filename; return Name(); } string Library::getFilename() const { return this->Filename; } list Library::getDotProperties() const { return this->properties; } int Library::getRealPos(int pos) const { std::list::const_iterator prop_i; int i = 0; for (prop_i = this->properties.begin(); (i < pos) && (prop_i != this->properties.end()); prop_i++) i++; if (i != pos) return (-1); return (prop_i->pos); } int Library::AccesAllowed(string& ToLib) const { if (ToLib == this->getName()) return 1; int allowed = 0; std::list deps = this->getDependancies(); std::list::const_iterator dep_i; for (dep_i = deps.begin(); !allowed && (dep_i != deps.end()); dep_i++) allowed = (*dep_i == ToLib); return allowed; } /****************************************** * Unloader * * -closes the library handler if exists- * ******************************************/ void Library::UnloadLib() { using std::cout; using std::cerr; using std::endl; /* ** Asks the library to say 'Bye' */ cout << "Closing library: "; typedef string (*name_t)(); name_t Name = (name_t) dlsym(this->handler, "GLG_Name"); cout << Name() << endl; typedef string (*bye_t)(); bye_t Bye = (bye_t) dlsym(this->handler, "GLG_Bye"); if (Bye) Bye(); dlclose(this->handler); } /****************************************** * _palloc * * stores infos on dot properties needed * ******************************************/ void Library::_palloc(kind_lib_t type, size_t size) { // in (*this) handler, we will store all this shit. GLG_property_pos++; cout << "\tThis is this->_palloc" << endl; dot_property_t property; property.pos = GLG_property_pos; property.size = size; property.type = type; this->properties.push_back(property); return ; } /****************************************** * Utilities * * external functions needed for developers* ******************************************/ /* I am sure I know that ?? */ extern list Client_DotPropertyTab; extern const list list_libs; Library* getLibraryByName(const string Name, const list list_libs) { std::list::const_iterator lib_i; for (lib_i = list_libs.begin(); (lib_i->getName() != Name) && (lib_i != list_libs.end()); lib_i++) ; /* Yeah, we got the library. */ Library* toto = NULL; (*toto) = *lib_i; return (toto); } void GLG_write(int pos, size_t size, void* data, Library* REF) { int real_pos = REF->getRealPos(pos); if (real_pos > -1) { std::list::const_iterator prop_i; int i = 0; for (prop_i = Client_DotPropertyTab.begin(); (i < real_pos) && (prop_i != Client_DotPropertyTab.end()); prop_i++) ; if (i == real_pos) memcpy(prop_i->data, data, size); /* ou alors j'ai rien compris */ } } void GLG_read(string& LibName, int pos, size_t size, void* data, Library* REF) { cout << REF->getName() << " hvufidoshvuiovhfudsviofdhvudiso" << endl; if (/*REF->AccessAllowed(LibName)*/ 1) { Library* Lib = getLibraryByName(LibName, list_libs); int real_pos = Lib->getRealPos(pos); if (real_pos > -1) { std::list::const_iterator prop_i; int i = 0; for (prop_i = Client_DotPropertyTab.begin(); (i < real_pos) && (prop_i != Client_DotPropertyTab.end()); prop_i++) ; if (i == real_pos) memcpy(data, prop_i->data, size); /* ou alors j'ai rien compris */ } } return ; } void GLG_read(int pos, size_t size, void* data, Library* REF) { string toto = REF->getName(); GLG_read(toto, pos, size, data, REF); } void palloc(kind_lib_t type, size_t size, Library* REF) { cout << "\tThis is palloc itself" << endl; /************************************************* ** ** ** From a .so, we cannot call a class method. ** ** But we need to do that !! ** ** ** ** So, I made this little shortcut : ** ** a function that takes a class pointer, ** ** and that calls the real method. ** ** ** ** So easy. ** ** ** *************************************************/ REF->_palloc(type, size); return ; }