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.
306 lines
6.6 KiB
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];
|
|
}
|