C++: Some examples
By Abhishek
//****************************************************************************** // // File Name: UTConfig.c // // Description: // This file defines the member functions that comprise the UTConfig // class. // // Contents: // //****************************************************************************** #include <rw/hashdict.h> #include <rw/ctoken.h> #include <fstream.h> #include <stdlib.h> #include <UTConfig.h> #include <UTLog.h> #include <UTTrace.h> #include <UTSnowrDefs.h> // // Initialize static data members. // UTConfig *UTConfig::_instancePtr = NULL; RWHashDictionary *UTConfig::_cfgCltnPtr = NULL; //****************************************************************************** // // Name: UTConfig TYPE: constructor // // Description: // Creates an instance of Config and reads the specified configuration // options file. There can be only a single instance of Config in // a process. // // Returns: void // //****************************************************************************** UTConfig :: UTConfig( const RWCString& fileName) { UTTrace trace(UTTrace::UTIL, "UTConfig::UTConfig()"); if ( _instancePtr == NULL ) { _instancePtr = this; _cfgCltnPtr = new RWHashDictionary(); } else { return; } // Construct the full path to the configuration file by appending the // passed file name to the $CFGDIR environment variable. // _cfgFile = getenv("CFGDIR"); if(_cfgFile.isNull() == TRUE) { // Log a message that 'CFGDIR' was not found in the environment. UT_ERROR(E_UT_ENVVAR("CFGDIR")); return; } _cfgFile += "/" + fileName; // Read configuration options file. LoadConfigOptions(); } //****************************************************************************** // // Name: ~UTConfig TYPE: destructor // // Description: // Resets instance pointer. // Called via Destroy(). // //****************************************************************************** UTConfig :: ~UTConfig() { UTTrace trace(UTTrace::UTIL, "UTConfig::~UTConfig()"); _cfgCltnPtr->clearAndDestroy(); delete _cfgCltnPtr; _instancePtr = NULL; } //****************************************************************************** // // Name: Destroy TYPE: static,public // // Description: // Destructs memory for Config instance. // // Returns: void // //****************************************************************************** void UTConfig :: Destroy( void ) { UTTrace trace(UTTrace::UTIL, "UTConfig::Destroy()"); delete _instancePtr; } //****************************************************************************** // // Name: GetCfgOptAsString TYPE: static,public // // Description: // Retrieve a configuration option given the option name. If the option // is not found and it is not an optional option then throw an excetion. // // Returns: The option value as RWCString. // //****************************************************************************** RWCString UTConfig :: GetCfgOptAsString( RWCollectableString key, bool optional ) { UTTrace trace(UTTrace::UTIL, "UTConfig::GetCfgOptAsString(" + key + ")"); if ( _instancePtr == NULL ) { // This is a programming error. Log a message. UT_ERROR(E_UT_NOCFG()); return(""); } RWCollectable *valuePtr = _cfgCltnPtr->findValue( &key ); RWCString rtnString; if ( valuePtr == NULL ) { // Log the fact that an unknown option was requested if the option // is not optional if (optional == false) { UT_ERROR(E_UT_BADCFG(key)); } } else { rtnString = *((RWCollectableString *)valuePtr); } trace.Print("Value= [" + rtnString + "]"); return( rtnString ); } //****************************************************************************** // // Name: LoadConfigOptions TYPE: instance,public // // Description: // Loads the Configuration file. // // Returns: UTSUCCESS, UTFAILURE // //****************************************************************************** int UTConfig :: LoadConfigOptions() { UTTrace trace(UTTrace::UTIL, "UTConfig::LoadConfigOptions()"); // Open the configuration options file and check for errors. ifstream file( _cfgFile ); if(file.good() == 0) { // Unable to read file. Log a message. UT_ERROR(E_UT_NOCFGFILE(_cfgFile)); return( UTFAILURE ); } // File is open for reading. Read entire file into String buffer. // RWCString fileS; fileS.readFile( file ); _cfgCltnPtr->clearAndDestroy(); // Clear out previouse options. // Iterate through each line in the file buffer and load the options into // the cfgOpts collection. Skip empty lines. // RWCTokenizer fileIter( fileS ); RWCString line; while( (line = fileIter( "\n", TRUE )).isNull() != TRUE ) { // Skip over commentary lines. if( line(0) == '#' ) { continue; } // Tokenize the line and retrieve the key and value. // RWCTokenizer lineIter(line); RWCollectableString *keyPtr = new RWCollectableString(lineIter("=")); RWCollectableString *valuePtr = new RWCollectableString(lineIter("=#")); *keyPtr = keyPtr->strip( RWCString::both, ' ' ); *keyPtr = keyPtr->strip( RWCString::both, '\t' ); *valuePtr = valuePtr->strip( RWCString::both, ' ' ); *valuePtr = valuePtr->strip( RWCString::both, '\t' ); trace.Print("Loading key [" + *keyPtr + "] value [" + *valuePtr + "]"); if( _cfgCltnPtr->insertKeyAndValue( keyPtr, valuePtr ) == NULL ) { UT_ERROR(E_UT_CFGFILE(*keyPtr, *valuePtr)); return( UTFAILURE ); } } return( UTSUCCESS ); } //****************************************************************************** // // Name: ReloadConfigOptions TYPE: static,public // // Description: // Reloads the Configuration file. // // Returns: UTSUCCESS, UTFAILURE // //****************************************************************************** int UTConfig :: ReloadConfigOptions() { UTTrace trace(UTTrace::UTIL, "UTConfig::ReloadConfigOptions() "); _instancePtr->LoadConfigOptions(); return( UTSUCCESS ); } //****************************************************************************** // // Name: operator<< TYPE: friend. // // Description: // Places data elements of class onto ostream. // //****************************************************************************** ostream& operator<< (ostream& os, const UTConfig& cfg ) { if (os.opfx() != 0) { os << "UTConfig: - \n"; RWHashDictionaryIterator iter( *cfg._cfgCltnPtr ); while ( iter() != NULL ) { os << *( (RWCollectableString *)(iter.key()) ) << "=" << *( (RWCollectableString *)(iter.value()) ) << "\n"; } os.osfx(); } return os; }
#ifndef UT_CONFIG_H
#define UT_CONFIG_H
// File Name: UTConfig.h
//
// Description:
// Defines the Config class. This class is used
to access a configuration
// file.
//
//******************************************************************************
#pragma VERSIONID "@(#) UTConfig.h 1.1.2.3@(#) 12/17/99 15:08:10
/sablime/sdb/ut/ut/src/s.UTConfig.h"
#include <rw/hashdict.h>
#include <rw/collstr.h>
#include <stdlib.h>
class UTConfig
{
private:
//***************************************************************************
// Private Data Members
//***************************************************************************
// Static Data members.
static UTConfig *_instancePtr;
// Address of this
class's instance
static RWHashDictionary *_cfgCltnPtr; // Map
collection of
// configuration options
// accessed by key.
RWCString _cfgFile;
public:
//***************************************************************************
// Public Constructor and Destructor
//***************************************************************************
UTConfig(const RWCString& fileName);
~UTConfig();
public:
//***************************************************************************
// Public Member functions.
//***************************************************************************
// Static Methods.
static const UTConfig * GetInstance() { return _instancePtr; }
static void Destroy( void );
static int ReloadConfigOptions();
// Instance Methods.
int LoadConfigOptions();
// Getters for configuration options.
static RWCString GetCfgOptAsString(
RWCollectableString key,
bool optional = false );
static short
GetCfgOptAsShort( RWCollectableString key,
bool optional = false );
static int
GetCfgOptAsInt(
const RWCollectableString key,
bool optional = false );
static long
GetCfgOptAsLong( RWCollectableString key,
bool optional = false );
//***************************************************************************
// Friend functions
//***************************************************************************
friend ostream&
operator<< (ostream& os, const UTConfig& cfg);
};
//***************************************************************************
// Define inline member functions.
//***************************************************************************
inline short UTConfig ::
GetCfgOptAsShort( RWCollectableString key, bool optional )
{
return( (short) atoi( GetCfgOptAsString( key, optional ) ));
}
inline int UTConfig ::
GetCfgOptAsInt( const RWCollectableString key, bool optional )
{
return( atoi( GetCfgOptAsString( key, optional ) ));
}
inline long UTConfig ::
GetCfgOptAsLong( RWCollectableString key, bool optional )
{
return( atol( GetCfgOptAsString( key, optional ) ));
}
#endif /* UT_CONFIG_H */
//***********************************************************************
// UTCorba.c
// Description:
// This file defines the methods that comprise the UTCorba class.
//
//***********************************************************************
#pragma VERSIONID "@(#) UTCorba.c 1.1.2.4@(#) 01/20/00 10:57:26
/sablime/sdb/ut/ut/src/s.UTCorba.c"
#include <rw/cstring.h>
#include <rw/ctoken.h>
#include <CosNaming_c.hh>
#include <UTTrace.h>
#include <UTSnowrDefs.h>
#include <UTConfig.h>
#include <UTException.h>
#include <UTCorba.h>
UTCorba* UTCorba::hereIAm = NULL;
//***********************************************************************
// MethodName: Create TYPE: public, static
// Description:
// This method is used to create the singleton
instance of UTCorba.
// Set the clientOnlyFlag to true if the program
is only a CORBA
// client (not a server).
//
//
// Author Id Date Comment
// --------- -------- ------------------------------------------------
// ringeise 05/1999 Create.
//***********************************************************************
void UTCorba::
Create(bool clientOnlyFlag, int argc, char*const* argv)
{
UTTrace trace(UTTrace::UTIL,"UTCorba::Create");
if (hereIAm == NULL)
hereIAm = new UTCorba(clientOnlyFlag, argc,
argv);
}
//***********************************************************************
// MethodName: UTCorba TYPE: private, constructor
// Description:
// This constructor is called exclusively by the
static Create method
//
//
// Author Id Date Comment
// --------- -------- ------------------------------------------------
// ringeise 05/1999 Create.
// dfultz 12/1999 Added InitRetryAttributes call and RETRY
//***********************************************************************
UTCorba::
UTCorba(bool clientOnlyFlag, int argc, char*const* argv)
: clientOnly(clientOnlyFlag), nsRoot(NULL)
{
UTTrace trace(UTTrace::UTIL,"UTCorba::UTCorba");
InitRetryAttributes();
// Initialize ORB.
orb = CORBA::ORB_init(argc, argv);
// Initialize the BOA if this is a server
if (!clientOnly)
boa = orb->BOA_init(argc, argv);
}
//***********************************************************************
// MethodName: InitRetryAttributes TYPE: public, instance
// Description:
// This method will set the retryCnt and retrySS
from either
// environmental variables or from the config file. The config vars
// take precedence over the environmentals and if neither exists, they
// are defaulted to 1 try/1 second.
//
//
// Author Id Date Comment
// --------- -------- ------------------------------------------------
// dfultz 05/1999 Create.
//***********************************************************************
void UTCorba::
InitRetryAttributes()
{
UTTrace trace(UTTrace::UTIL,"UTCorba::InitRetryAttributes");
RWCString sRetry;
sRetry = getenv("UTCORBA_RETRY_CNT");
if (sRetry.isNull())
retryCnt = 1; //default
else
retryCnt = atoi(sRetry.data());
sRetry = getenv("UTCORBA_RETRY_SS");
if (sRetry.isNull())
retrySS = 1; //default
else
retrySS = atoi(sRetry.data());
sRetry = UTConfig::GetCfgOptAsString("UTCORBA_RETRY_CNT",
true);
if (!sRetry.isNull()) //override detected
retryCnt = atoi(sRetry.data());
sRetry = UTConfig::GetCfgOptAsString("UTCORBA_RETRY_SS",
true);
if (!sRetry.isNull()) //override detected
retrySS = atoi(sRetry.data());
strstream buf;
buf << "Attribute settings: retryCnt["
<< retryCnt
<< "] retrySS["
<< retrySS
<< "]"
<< ends;
trace.Print(buf.str());
delete [] buf.str();
}
//***********************************************************************
// MethodName: RegisterObjectImpl TYPE: public, instance
// Description:
// This method will register an object
implementation with the BOA
// and bind it to the name passed in.
//
//
// Author Id Date Comment
// --------- -------- ------------------------------------------------
// ringeise 05/1999 Create.
//***********************************************************************
void UTCorba::
RegisterObjectImpl(const char * moduleName,
const char * interfaceName, CORBA::Object_ptr obj)
{
UTTrace trace(UTTrace::UTIL,"UTCorba::RegisterObjectImpl");
// Clients can't call this method
if (clientOnly)
return;
// Get the name
CosNaming::Name name;
BuildName(moduleName, interfaceName, name);
try
{
SetNSRoot();
nsRoot->rebind(name, obj);
boa->obj_is_ready(obj);
}
catch( CORBA::Exception &corbaError)
{
// TODO: Handle this better
cerr << "CORBA error in
UTCorba::RegisterObjectImpl: " <<
corbaError <<
endl;
throw; // Rethrow to main
}
}
//***********************************************************************
// MethodName: EnterEventLoop TYPE: public, instance
// Description:
// This method encapsulates the
BOA::impl_is_ready method.
// This method does not return unless an error
occurs or the CORBA
// event loop is terminated.
//
//
// Author Id Date Comment
// --------- -------- ------------------------------------------------
// ringeise 05/1999 Create.
//***********************************************************************
void UTCorba::
EnterEventLoop()
{
UTTrace trace(UTTrace::UTIL,"UTCorba::EnterEventLoop");
// This method does not return until after server exits
boa->impl_is_ready();
}
//***********************************************************************
// MethodName: BuildName TYPE: private, instance
// Description:
// This method will take a component name and
interface name and
// return the COS name for an object.
//
// Author Id Date Comment
// --------- -------- ------------------------------------------------
// ringeise 08/1999 Create.
//***********************************************************************
void UTCorba::
BuildName(const char * componentName, const char * interfaceName,
CosNaming::Name& name)
{
UTTrace trace(UTTrace::UTIL,"UTCorba::BuildName");
// Look in the configuration file to get path name in naming service.
RWCString inputName(componentName);
inputName += ':';
inputName += interfaceName;
RWCString outputName = UTConfig::GetCfgOptAsString(inputName);
if (outputName.length() == 0)
{
RWCString errMsg(inputName);
errMsg += " not found in configuration
file";
throw UTException(errMsg, __FILE__, __LINE__);
}
// Determine the number of slashes(/) in outputName
// Assumption: outputName has a beginning / but no ending /
const char* theData = outputName.data();
int slashCount = 0;
for ( int ii = 0; theData[ii] != '\0'; ii++)
{
if (theData[ii] == '/')
slashCount++;
}
// Create the Name object
name.length(slashCount);
RWCTokenizer itr(outputName);
RWCString token;
int nameIdx = 0;
while(!(token = itr("/\n")).isNull())
{
name[nameIdx].id = CORBA::string_dup(token);
nameIdx++;
}
return;
}
//***********************************************************************
// MethodName: SetNSRoot TYPE: private, instance
// Description:
// This method will set the instance attribute
nsRoot (name service
// root), for use in binding and resolving
names. It is only called
// internally.
//
//
// Author Id Date Comment
// --------- -------- ------------------------------------------------
// ringeise 05/1999 Create.
//***********************************************************************
void UTCorba::
SetNSRoot()
{
if (nsRoot == NULL)
{
UTTrace
trace(UTTrace::UTIL,"UTCorba::SetNSRoot");
nsRoot = this->ResolveInitialReference
<CosNaming::NamingContext, CosNaming::NamingContext_ptr>
("NameService");
}
}
#ifndef UT_CORBA
#define UT_CORBA
// ****************************************************************************
// AT&T Proprietary - Use Pursuant to Company Instructions
// ****************************************************************************
//
// File: UTCorba.h
//
// Description:
// This class contains generic CORBA
methods, encapsulating the ORB
// It is a singleton
//
// ****************************************************************************
#pragma VERSIONID "@(#) UTCorba.h 1.1.2.5@(#) 12/10/99 08:16:05
/sablime/sdb/ut/ut/src/s.UTCorba.h"
#include <rw/cstring.h>
#include <CosNaming_c.hh>
#include <UTTrace.h>
#include <UTException.h>
#include <unistd.h>
class UTCorba
{
// ****************************************************************************
// Data memebers
// ****************************************************************************
private:
static UTCorba* hereIAm;
bool clientOnly; // True if this is a client
int retryCnt; // Nbr times to try a method
int retrySS; // Nbr seconds to sleep between method tries
CORBA::ORB_var orb;
CORBA::BOA_var boa;
CosNaming::NamingContext_var nsRoot;
// ****************************************************************************
// Public member functions
// ****************************************************************************
public:
static void Create(bool clientOnlyFlag, int argc, char*const* argv);
static UTCorba* GetInstance();
static void Shutdown();
void RegisterObjectImpl(const char * moduleName,
const char * interfaceName, CORBA::Object_ptr
obj);
template<class T, class T_ptr> T_ptr
ResolveInitialReference(const char * id);
template<class T, class T_ptr> T_ptr
GetIOR(const char * moduleName, const char *
interfaceName);
void EnterEventLoop();
void InitRetryAttributes();
int GetRetryCnt() const { return retryCnt; }
int GetRetrySS() const { return retrySS; }
CORBA::ORB_ptr GetOrb() const { return orb; };
// ****************************************************************************
// Private member functions
// ****************************************************************************
private:
UTCorba(bool clientOnlyFlag, int argc, char*const* argv); // Private
constructor
void SetNSRoot();
void BuildName(const char * moduleName,
const char * interfaceName,
CosNaming::Name& name);
};
//***********************************************************************
// MethodName: GetInstance TYPE: static, public
// Description:
// This method returns a pointer to the
singleton UTCorba object.
// Note that this method expects that
UTCorba::Create() has already
// been called. If not, it will return a NULL
pointer.
//
//
// Author Id Date Comment
// --------- -------- ------------------------------------------------
// ringeise 05/1999 Create.
//***********************************************************************
inline UTCorba* UTCorba::
GetInstance()
{
// WATCH OUT: This method assumes that the singleton has been
instantiated
return hereIAm;
}
// Templated methods must be defined here so programs that use them
// can instantiate them by using the header files.
//***********************************************************************
// MethodName: GetIOR TYPE: instance, public
// Description:
// This method resolves a name and returns an
object pointer of the
// type that the template has been specialized
with.
//
//
// Author Id Date Comment
// --------- -------- ------------------------------------------------
// ringeise 05/1999 Create.
//***********************************************************************
template<class T, class T_ptr>
T_ptr UTCorba::
GetIOR(const char * moduleName, const char * interfaceName)
{
UTTrace trace(UTTrace::UTIL,"UTCorba::GetIOR");
int iRetryCnt=0;
T_ptr ref;
while (true)
{
try
{
CosNaming::Name name;
BuildName(moduleName,
interfaceName, name);
SetNSRoot();
CORBA::Object_var obj =
nsRoot->resolve(name);
trace.Print("Got
object reference");
ref = T::_narrow(obj);
trace.Print("Narrowed object reference");
if (CORBA::is_nil(ref))
{
if (++iRetryCnt == retryCnt)
throw UTExIPCFailure("IOR always nil; retries exceeded",__FILE__,__LINE__);
else
{
RWCString s("IOR is nil;");
s += " sleeping and then retrying until max retries.";
trace.Print(s);
sleep(retrySS);
}
}
else
break;
}
catch (CORBA::Exception &cEx)
{
if (++iRetryCnt ==
retryCnt)
throw UTExIPCFailure(cEx._name(),__FILE__,__LINE__);
else
{
RWCString s("Caught[");
s += cEx._name();
s += "]; sleeping and then retrying until max retries.";
trace.Print(s);
sleep(retrySS);
}
}
}
return ref;
}
//***********************************************************************
// MethodName: ResolveInitialReference TYPE: instance, public
// Description:
// This method encapsulates the CORBA
ORB::resolve_initial_references
// method. It returns an object pointer of the
type that the template
// has been specialized with.
//
//
// Author Id Date Comment
// --------- -------- ------------------------------------------------
// ringeise 05/1999 Create.
//***********************************************************************
template<class T, class T_ptr>
T_ptr UTCorba::
ResolveInitialReference(const char * id)
{
UTTrace
trace(UTTrace::UTIL,"UTCorba::ResolveInitialReference");
CORBA::Object_var obj = orb->resolve_initial_references(id);
if (CORBA::is_nil(obj))
{
throw UTExIPCFailure("Failed to get name
service IOR",__FILE__,__LINE__);
}
trace.Print("Got initial reference");
T_ptr ref = T::_narrow(obj);
trace.Print("Narrowed initial reference");
// TODO: What about nil references. Right now we are expecting
// the calling function to do CORBA::is_nil() on the returned object.
return ref;
}
//***********************************************************************
// MethodName: Shutdown
TYPE: instance,
public
// Description:
// This method encapsulates the CORBA
ORB::shutdown()
// method. It instructs the ORB to exit its
event loop once it has
// has control.
//
//***********************************************************************
inline void UTCorba::
Shutdown()
{
UTTrace trace(UTTrace::UTIL,"UTCorba::Shutdown");
CORBA::ORB::shutdown();
}
//***********************************************************************
// MACROS: UTCORBA_RETRY_VOID
// : UTCORBA_RETRY_RETURN
// USES: UTCORBA_RETRY_INIT
// : UTCORBA_RETRY_CATCH
// Description:
// These macros should be used in CORBA proxies as shown below to
// standardize retrying CORBA methods based on CORBA::SystemExceptions.
// The number of retries and delay between retries is set by one of the
// following, shown in order of precedence.
//
// 1) UTCORBA_RETRY_CNT= <-number representing # of retries
// UTCORBA_RETRY_SS= <-number representing wait between retries
// set in the config file for the process
// 2) UTCORBA_RETRY_CNT=
// UTCORBA_RETRY_SS=
// exported as enviromentals to the process
// 3) Default (try 1 time)
//
// EXAMPLE:
//
// try
// {
// marshall ins here, if applicable
//
// UTCORBA_RETRY_VOID(myFunction(any parms here. . .))
// (if myFunction returns void)
// OR
// UTCORBA_RETRY_RETURN(myReturnType,myFunction(any parms here. . .))
// (if myFunction returns non-void)
//
// marshall outs, inouts and returns here, if applicable
//
// return (void or return object here)
// }
// :
// other application catch blocks here
// :
//
// NOTE: If all attempts to retry the method fail, a UTExIPCFailure
// exception will be thrown.
//
//***********************************************************************
#define UTCORBA_RETRY_INIT \
{ \
int retryCnt=0; \
while (true) \
{ \
try \
{
#define UTCORBA_RETRY_CATCH \
break; \
} \
catch (CORBA::SystemException &cEx) \
{ \
if (++retryCnt ==
UTCorba::GetInstance()->GetRetryCnt()) \
throw UTExIPCFailure(cEx._name(), __FILE__, __LINE__); \
else \
{ \
RWCString s("Caught["); \
s += cEx._name(); \
s += "]; sleeping and then retrying until max retries."; \
\
trace.Print(s); \
\
sleep(UTCorba::GetInstance()->GetRetrySS()); \
} \
} \
} \
}
#define UTCORBA_INVOKE_VOID(theFUNCTION) \
UTCORBA_RETRY_INIT \
theFUNCTION; \
UTCORBA_RETRY_CATCH
#define UTCORBA_INVOKE_RETURN(theRETURN, theFUNCTION) \
UTCORBA_RETRY_INIT \
theRETURN =
theFUNCTION; \
UTCORBA_RETRY_CATCH
// ****************************************************************************
// AT&T Proprietary - Use Pursuant to Company Instructions
// ****************************************************************************
#endif /* UT_CORBA */