You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
arts/mcop/ifacerepo_impl.cc

306 lines
6.6 KiB

/*
Copyright (C) 2000 Stefan Westerfeld
stefan@space.twc.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "ifacerepo_impl.h"
#include "debug.h"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace Arts;
InterfaceRepo_impl::InterfaceRepo_impl()
{
nextModuleID = 1;
tiMap["void"] = tiVoid;
tiMap["byte"] = tiByte;
tiMap["string"] = tiString;
tiMap["boolean"] = tiBoolean;
tiMap["float"] = tiFloat;
tiMap["long"] = tiLong;
tiMap["object"] = tiInterface;
}
InterfaceRepo_impl::~InterfaceRepo_impl()
{
while(!unloadModuleList.empty())
{
removeModule(unloadModuleList.front());
unloadModuleList.pop_front();
}
}
long InterfaceRepo_impl::insertModule(const ModuleDef& newModule)
{
long moduleID = nextModuleID++;
/* insert interfaces */
vector<InterfaceDef>::const_iterator ii;
for(ii=newModule.interfaces.begin();
ii != newModule.interfaces.end();ii++)
{
Buffer b;
ii->writeType(b);
InterfaceEntry *ie = new InterfaceEntry(b,moduleID);
interfaces.push_back(ie);
tiMap[ie->name] = tiInterface;
}
/* insert types */
vector<TypeDef>::const_iterator ti;
for(ti=newModule.types.begin();
ti != newModule.types.end();ti++)
{
Buffer b;
ti->writeType(b);
TypeEntry *entry = new TypeEntry(b,moduleID);
types.push_back(entry);
tiMap[entry->name] = tiType;
}
/* insert enums */
vector<EnumDef>::const_iterator ei;
for(ei=newModule.enums.begin();
ei != newModule.enums.end();ei++)
{
Buffer b;
ei->writeType(b);
EnumEntry *entry = new EnumEntry(b,moduleID);
enums.push_back(entry);
tiMap[entry->name] = tiEnum;
}
return moduleID;
}
void InterfaceRepo_impl::removeModule(long moduleID)
{
/* erase interfaces */
list<InterfaceEntry *>::iterator ii;
ii = interfaces.begin();
while(ii != interfaces.end())
{
if((*ii)->moduleID == moduleID)
{
delete (*ii);
interfaces.erase(ii);
ii = interfaces.begin();
}
else ii++;
}
/* erase types */
list<TypeEntry *>::iterator ti;
ti = types.begin();
while(ti != types.end())
{
if((*ti)->moduleID == moduleID)
{
delete (*ti);
types.erase(ti);
ti = types.begin();
}
else ti++;
}
/* erase enums */
list<EnumEntry *>::iterator ei;
ei = enums.begin();
while(ei != enums.end())
{
if((*ei)->moduleID == moduleID)
{
delete (*ei);
enums.erase(ei);
ei = enums.begin();
}
else ei++;
}
}
InterfaceDef InterfaceRepo_impl::queryInterfaceLocal(const string& name)
{
list<InterfaceEntry *>::iterator ii;
for(ii = interfaces.begin();ii != interfaces.end();ii++)
{
if((*ii)->name == name)
return **ii;
}
return InterfaceDef();
}
InterfaceDef InterfaceRepo_impl::queryInterface(const string& name)
{
InterfaceDef def = queryInterfaceLocal(name);
if(def.name.empty())
{
TraderQuery q;
q.supports("Type",name);
vector<TraderOffer> *offers = q.query();
vector<TraderOffer>::iterator i;
for(i = offers->begin(); i != offers->end();i++)
{
TraderOffer& offer = *i;
if(def.name.empty())
{
vector<string> *types = offer.getProperty("TypeFile");
if(types->size() == 1)
{
const vector<string> *path = MCOPUtils::traderPath();
vector<string>::const_iterator pi = path->begin();
while(pi != path->end() && def.name.empty())
{
string filename = *pi++ + "/" + types->front();
FILE *extfile = fopen(filename.c_str(),"r");
if(extfile)
{
arts_debug("InterfaceRepo: loading %s",
filename.c_str());
Buffer b;
int c;
while((c = fgetc(extfile)) >= 0) b.writeByte(c);
fclose(extfile);
long id = insertModule(ModuleDef(b));
def = queryInterfaceLocal(name);
unloadModuleList.push_back(id);
}
}
}
delete types;
}
}
delete offers;
}
if(def.name.empty())
{
arts_warning("InterfaceRepo: no information about the interface %s "
"is known", name.c_str());
}
return def;
}
TypeDef InterfaceRepo_impl::queryType(const string& name)
{
list<TypeEntry *>::iterator ti;
for(ti = types.begin();ti != types.end();ti++)
{
if((*ti)->name == name)
return **ti;
}
arts_warning("InterfaceRepo: no information about the type %s is known.",
name.c_str());
return TypeDef();
}
EnumDef InterfaceRepo_impl::queryEnum(const string& name)
{
list<EnumEntry *>::iterator ei;
for(ei = enums.begin();ei != enums.end();ei++)
{
if((*ei)->name == name)
return **ei;
}
arts_warning("InterfaceRepo: no information about the enum %s is known.",
name.c_str());
return EnumDef();
}
vector<string> *InterfaceRepo_impl::queryChildren(const std::string& name)
{
vector<string> *result = new vector<string>;
list<InterfaceEntry *>::iterator ii;
for(ii = interfaces.begin();ii != interfaces.end();ii++)
{
bool found = false;
vector<string>::iterator j;
for(j = (*ii)->inheritedInterfaces.begin();
j != (*ii)->inheritedInterfaces.end() && !found; j++)
{
if(*j == name)
{
result->push_back((*ii)->name);
found = true;
}
}
if((*ii)->inheritedInterfaces.empty() && ((name == "Arts::Object") || (name == "object")) && ((*ii)->name != "Arts::Object"))
result->push_back((*ii)->name);
}
return result;
}
vector<string> *InterfaceRepo_impl::queryInterfaces()
{
vector<string> *result = new vector<string>;
list<InterfaceEntry *>::iterator ii;
for(ii = interfaces.begin();ii != interfaces.end();ii++)
result->push_back((*ii)->name);
return result;
}
vector<string> *InterfaceRepo_impl::queryTypes()
{
vector<string> *result = new vector<string>;
list<TypeEntry *>::iterator ti;
for(ti = types.begin();ti != types.end();ti++)
result->push_back((*ti)->name);
return result;
}
vector<string> *InterfaceRepo_impl::queryEnums()
{
vector<string> *result = new vector<string>;
list<EnumEntry *>::iterator ei;
for(ei = enums.begin();ei != enums.end();ei++)
result->push_back((*ei)->name);
return result;
}
TypeIdentification InterfaceRepo_impl::identifyType(const string& name)
{
return tiMap[name];
}