/*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE Versions 3.13.7 * and higher are distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ // // Example EPICS CA directory server // // // caServer // | // directoryServer // // // // ANSI C // #include #include // // EPICS // #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" #define caNetAddrSock #include "casdef.h" #include "epicsAssert.h" #include "resourceLib.h" #ifndef NELEMENTS # define NELEMENTS(A) (sizeof(A)/sizeof(A[0])) #endif class directoryServer; // // pvInfo // class pvInfo { public: pvInfo (const char *pNameIn, sockaddr_in addrIn) : addr(addrIn), pNext(pvInfo::pFirst) { pvInfo::pFirst = this; this->pName = new char [strlen(pNameIn)+1u]; strcpy(this->pName, pNameIn); } const struct sockaddr_in getAddr() const { return this->addr; } const char *getName () const { return this->pName; } const pvInfo *getNext () const { return this->pNext; } static const pvInfo *getFirst () { return pvInfo::pFirst; } private: struct sockaddr_in addr; char * pName; const pvInfo * pNext; static const pvInfo * pFirst; }; // // pvEntry // // o entry in the string hash table for the pvInfo // o Since there may be aliases then we may end up // with several of this class all referencing // the same pv info class (justification // for this breaking out into a seperate class // from pvInfo) // class pvEntry // X aCC 655 : public stringId, public tsSLNode { public: pvEntry (const pvInfo &infoIn, directoryServer &casIn, const char *pAliasName) : stringId(pAliasName), info(infoIn), cas(casIn) { assert(this->stringId::resourceName()!=NULL); } inline ~pvEntry(); const pvInfo &getInfo() const { return this->info; } inline void destroy (); private: const pvInfo &info; directoryServer &cas; }; // // directoryServer // class directoryServer : public caServer { public: directoryServer ( const char * const pvPrefix, unsigned aliasCount ); ~directoryServer(); void show ( unsigned level ) const; void installAliasName ( const pvInfo &info, const char *pAliasName ); void removeAliasName ( pvEntry &entry ); private: resTable < pvEntry, stringId > stringResTbl; pvExistReturn pvExistTest ( const casCtx&, const char *pPVName ); pvExistReturn pvExistTest ( const casCtx&, const caNetAddr &, const char *pPVName ); }; // // directoryServer::removeAliasName() // inline void directoryServer::removeAliasName ( pvEntry & entry ) { pvEntry * pE = this->stringResTbl.remove ( entry ); assert ( pE == & entry ); } // // pvEntry::~pvEntry() // inline pvEntry::~pvEntry() { this->cas.removeAliasName(*this); } // // pvEntry::destroy() // inline void pvEntry::destroy () { // // always created with new // delete this; }