WvStreams
monikers.cc
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002  *
00003  * XPLC - Cross-Platform Lightweight Components
00004  * Copyright (C) 2002, Net Integration Technologies, Inc.
00005  * Copyright (C) 2002-2003, Pierre Phaneuf
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00020  * USA
00021  */
00022 
00023 #include <xplc/core.h>
00024 #include <xplc/utils.h>
00025 #include "monikers.h"
00026 
00027 #define MONIKER_SEPARATOR_CHAR ':'
00028 
00029 UUID_MAP_BEGIN(MonikerService)
00030   UUID_MAP_ENTRY(IObject)
00031   UUID_MAP_ENTRY(IMoniker)
00032   UUID_MAP_ENTRY(IMonikerService)
00033   UUID_MAP_END
00034 
00035 MonikerService::~MonikerService() {
00036   MonikerNode* node;
00037   MonikerNode* ptr;
00038 
00039   node = monikers;
00040 
00041   while(node) {
00042     ptr = node;
00043     node = node->next;
00044     delete ptr;
00045   }
00046 
00047   monikers = 0;
00048 }
00049 
00050 IObject* MonikerService::resolve(const char* aName) {
00051   MonikerNode* node;
00052   IServiceManager* servmgr;
00053   IObject* obj = 0;
00054   IMoniker* moniker;
00055   char* name = strdup(aName);
00056   char* rest = strchr(name, MONIKER_SEPARATOR_CHAR);
00057 
00058   node = monikers;
00059 
00060   if(rest) {
00061     *rest = 0;
00062     ++rest;
00063   }
00064 
00065   while(node) {
00066     if(strcmp(name, node->name) == 0) {
00067       servmgr = XPLC_getServiceManager();
00068       if(!servmgr)
00069         break;
00070 
00071       obj = servmgr->getObject(node->uuid);
00072       servmgr->release();
00073 
00074       if(rest) {
00075         moniker = mutate<IMoniker>(obj);
00076         if(moniker) {
00077           obj = moniker->resolve(rest);
00078           moniker->release();
00079         } else
00080           obj = 0;
00081       }
00082 
00083       break;
00084     }
00085 
00086     node = node->next;
00087   }
00088 
00089   free(name);
00090 
00091   return obj;
00092 }
00093 
00094 void MonikerService::registerObject(const char* aName, const UUID& aUuid) {
00095   MonikerNode* node;
00096 
00097   /*
00098    * FIXME: we should do something about registering a name that
00099    * contains the separator character.
00100    */
00101 
00102   node = monikers;
00103 
00104   while(node) {
00105     if(strcmp(aName, node->name) == 0)
00106       break;
00107 
00108     node = node->next;
00109   }
00110 
00111   /*
00112    * FIXME: maybe add a "replace" bool parameter? Or would this
00113    * encourage moniker hijacking too much?
00114    */
00115   if(node)
00116     return;
00117 
00118   node = new MonikerNode(aName, aUuid, monikers);
00119   monikers = node;
00120 }
00121