Class Device

Header file

/*
   D_device.hpp

   Header file for RUL device drivers.

   Copyright (C), 1992 by Rijksuniversiteit Leiden.

   Version: 0.012
   Date   : 28 Jun 1994
   Disk	  : ruldev\inc\ruldev
   Author : M.J. Moene

   Compiler	   : Borland C++ 2.0
   Operating system: MS-DOS 3.21
   Hardware system : PC XT, AT
*/

#ifndef __D_DEVICE_HPP				// already included?
#define __D_DEVICE_HPP

#ifndef __OBJECT_H				// general info
#include <tclass\object.h>
#endif

#ifndef __D_CLSTYP_HPP                           // class types
#include <ruldev\d_clstyp.hpp>
#endif

#ifndef __D_USUAL_HPP                           // general info
#include <ruldev\d_usual.hpp>
#endif


// definitions

#define DEF_NAME	"Name"			// default device name
#define NODEVICE   ( (Device&) NOOBJECT )	// returned from DeviceIterator


// declarations

typedef int    Status;				// Status type
						// error handler type
typedef void (*ErrorHandlerType)(const char *string, Boolean is_fatal = false);
typedef	       ErrorHandlerType EHT;


// class definition

class Device : public Object				// Device base class
{
   friend class DeviceIterator;				// Device list iterator class

public:							// public part
   virtual ~Device();					// destructor
   Device( const  char *n = DEF_NAME);                  // constructor

   Device                 (const Device &aDevice);	// copy-initializer
   virtual void operator= (const Device &aDevice);	// assignment

   virtual classType      isA       () const = 0;	// type representation
   virtual char          *nameOf    () const = 0;    	// device name
   virtual hashValueType  hashValue () const;
   virtual int            isEqual   (const Object& test) const;
   virtual void           printOn   (ostream&      os  ) const;

   virtual void    dialog           () ;                // dialog box (ezview)
   virtual void    groupDialog      () ;                // dialog box (ezview)

   virtual char   *getDeviceName    () const;           // device name

   virtual void    clearErrorStatus () ;                // clear error status
   virtual Status  getErrorStatus   () const;           // return error status
   virtual char   *getErrorText     () const;           // return error string

   virtual Status  scan     (istream &is = cin );       // scan object
   virtual Status  print    (ostream &os = cout);       // print object

   static  Status  scanAll  (istream &is = cin );       // scan all devices
   static  Status  printAll (ostream &os = cout);       // print all devices

   static  EHT     getErrorHandler (           );       // get error handler
   static  EHT     setErrorHandler (EHT handler);       // set error handler

   enum	  /* Status */					// common status codes
   {
      Ok = 0,
      BadCommand,
      BadValue,
      BadMask ,
      BadCondition,
      BadRecord,
      BadInput,
      BadOutput,
      MinValue,
      MaxValue,
      Timeout,
      Internal,
      Undefined,
   };

protected:						// protected part
   Status  errorTrap	  (Status status, const char *function);
   Status  fatalErrorTrap (Status status, const char *function);

   virtual Status _scan   (istream &is = cin ) = 0;	// scan 
   virtual Status _print  (ostream &os = cout) = 0;	// print

private:                                                // private part
   char	  *deviceName;					// device name
   char	  *functionName;				// function name

   Device *prev;					// link to previous Device
   Device *next;					// link to next Device
   static  Device *front;				// front of list of devices
   static  Device *rear;				// rear of list of devices

   void    appendSelf();				// append to list
   void    detachSelf();				// remove from list

   Status  statusCode;					// last status code
   static  EHT errorHandler;				// current errorHandler
   Status  trap (Status status, const char *function, Boolean is_fatal = false);
};


class DeviceIterator			// iterate through device list
{
public:
   DeviceIterator() : current(Device::front) { }	// constructor

	    operator int ();		// more devices?
	    operator Device& ();	// reference to current device
	    operator Device* ();	// pointer to current device
   Device&  operator ++ ();		// ref. to current device, post incr.
   Device&  operator -- ();		// ref. to current device, post decr.
   void     restart (); 		// restart the iterator

private:
   Device *current;			// current device
};


#undef DEF_NAME                                 // undefine this one


// prototypes

PUBLIC istream& operator>> (istream &is, Device &dev);	// input
PUBLIC ostream& operator<< (ostream &os, Device &dev);	// output


#endif						// #ifndef __D_DEVICE_HPP


/*** End of file ***/


Programmer's reference

------------------------------------------------------------------------------
Device - root class for devices
------------------------------------------------------------------------------

Class		Device

Derived from	Object	(tclass library)

Remarks		Class Device is the root of the device class hierarchy.
		The main purpose of this class is to provide derived classes 
		with errorhandling capabilities. Further class Device maintains 
		a list of all devices, which can be traversed with an iterator
		of type DeviceIterator.

		Class Device provides functions to:
		- get name of a device, 
		- get or clear error status,
		- get an error text,
		- print a device representation to a stream,
		- initialize a device from a stream,
		- print device representations of all devices to a stream,
		- initialize all devices from a stream,
		- install a user defined error handler.

		and provides the Object class functions to:
		- get a type name,
		- get a type identification number,
		- get a hash value based on the object,
		- test Devices for equality,


------------------------------------------------------------------------------
constructor								Device
------------------------------------------------------------------------------

Function	construct an instance of class Device.

Syntax		#include <ruldev\d_device.hpp>
		Device::Device(const char *name);

Prototype in	d_device.hpp

Remarks		This is the constructor for class Device. It saves the name
		of this instance and puts the device on the device list.

Arguments	name: name of instance		 (default: "Name")

Return value	none


------------------------------------------------------------------------------
destructor								Device
------------------------------------------------------------------------------

Function	destruct an instance of class Device

Syntax		#include <ruldev\d_device.hpp>
		virtual Device::~Device()

Prototype in	d_device.hpp

Remarks		This is the destructor for class Device. It deletes the
		name of this instance and the name of the function executed
		for this instance where the last error occurred. Further it
		removes the device from the device list.

Arguments	none

Return value	none


-------------------------------------------------------------------------------
constructor								 Device
-------------------------------------------------------------------------------

Function	copy-initializer constructor.

Syntax		#include <ruldev\d_device.hpp>
		Device::Device(const Device &dev);

Prototype in	d_device.hpp

Remarks		The copy-initializer constructor is present, but does not 
		construct anything really. we don't want copies of a device 
		to exist. It writes the message
		   "typename: copy-initialization not supported; aborting."
		to the stream cerr and aborts execution of the program.

Arguments	dev: reference to a device.

Return value	none


-------------------------------------------------------------------------------
operator=								 Device
-------------------------------------------------------------------------------

Function	Device assignment operator.

Syntax		#include <ruldev\d_device.hpp>
		void Device::operator= (const Device &dev);

Prototype in	d_device.hpp

Remarks		The assignment operator is present, but does not assign 
		anything really. we don't want copies of a device to exist.
		It writes the message
		   "typename: assignment not supported; aborting."
		to the stream cerr and aborts execution of the program.

Arguments	dev: reference to a device.

Return value	none


------------------------------------------------------------------------------
isA									Device
------------------------------------------------------------------------------

Function	return type information.

Syntax		#include <ruldev\d_device.hpp>
		virtual classType Device::isA() const = 0;

Prototype in	d_device.hpp

Remarks		isA should return an unique number. This can be used for
		type checking. isA is defined purely virtual in this class,
		so no instances of this base class can be defined.

Arguments	none

Return value	an unique number, representing a type.


------------------------------------------------------------------------------
nameOf								Device
------------------------------------------------------------------------------

Function	return the type name of this device instance.

Syntax		#include <ruldev\d_device.hpp>
		virtual char *Device::nameOf() const;

Prototype in	d_device.hpp

Remarks		nameOf returns a string representation of the name of
		this type.

Arguments	none

Return value	"Device".


-------------------------------------------------------------------------------
hashValue								 Device
-------------------------------------------------------------------------------

Function	return a unique key based on the object.

Syntax		#include <ruldev\d_device.hpp>
		hashValueType Device::hashValue () const;

Prototype in	d_device.hpp

Remarks		hashValue returns a unique key based on the object's state.

Arguments	none

Return value	0..65535.


-------------------------------------------------------------------------------
isEqual									 Device
-------------------------------------------------------------------------------

Function	Determine if two Devices are equal.

Syntax		#include <ruldev\d_device.hpp>
		int Device::isEqual(const Object& test) const;

Prototype in	d_device.hpp

Remarks		isEqual only returns 1 if the specified test object is exactly
		the same one instance as this object.

Arguments	test: reference to an Object.

Return value	1, 0 (same, not same).


-------------------------------------------------------------------------------
printOn									 Device
-------------------------------------------------------------------------------

Function	print the state of the Device.

Syntax		#include <ruldev\d_device.hpp>
		void Device::printOn(ostream& os) const;

Prototype in	d_device.hpp

Remarks		printOn prints the state of the Device to the specified output
		stream os.  printOn uses the function print to do the work.

Arguments	os: reference to the output stream.

Return value	none


-------------------------------------------------------------------------------
dialog									Device
-------------------------------------------------------------------------------

Function	perform dialog.

Syntax		#include <ruldev\d_device.hpp>
		virtual void Device::dialog();

Prototype in	d_device.hpp

Remarks		redefine dialog for real devices to perform a dialog to
		control the instrument. These functions should be placed
		in the rulins library.

Arguments	none

Return value	none


------------------------------------------------------------------------------
getDeviceName								Device	      Device
------------------------------------------------------------------------------

Function	return the name of this device instance.

Syntax		#include <ruldev\d_device.hpp>
		virtual char *Device::getDeviceName() const;

Prototype in	d_device.hpp

Remarks		getDeviceName returns a string representation of the name of this
		device instance.

Arguments	none

Return value	name of instance.


------------------------------------------------------------------------------
clearErrorStatus							Device
------------------------------------------------------------------------------

Function	set the error status to Ok.

Syntax		#include <ruldev\d_device.hpp>
		virtual void Device::clearErrorStatus()

Prototype in	d_device.hpp

Remarks		clearErrorStatus resets the error status to Ok and clears
		the name of the function last executed to "(undefined)".

Arguments	none

Return value	none


------------------------------------------------------------------------------
getErrorStatus								Device
------------------------------------------------------------------------------

Function	get the current error status.

Syntax		#include <ruldev\d_device.hpp>
		virtual Status Device::getErrorStatus() const;

Prototype in	d_device.hpp

Remarks		getErrorStatus returns the current error status.

Arguments	none

Return value	the following values must be preceded by `Device::' when
		used outside an object of type Device:

		Ok, BadValue, BadMask, BadCondition, BadRecord,
		BadInput, BadOutput, MinValue, MaxValue, Timeout,
		Internal, Undefined.


------------------------------------------------------------------------------
getErrorText								Device
------------------------------------------------------------------------------

Function	get a verbose description of the current error status.

Syntax		#include <ruldev\d_device.hpp>
		virtual const char *Device::getErrorText() const;

Prototype in	d_device.hpp

Remarks		getErrorText returns a string representation of the current
		error status. An example of the format of the message
		returned is:
		   "device dev, type typ: bad value in function 'fn'."

Arguments	none

Return value	string with explaining text.


------------------------------------------------------------------------------
getErrorHandler								Device
------------------------------------------------------------------------------

Function	return a pointer to the current device error handler.

Syntax		#include <ruldev\d_device.hpp>
		static EHT Device::getErrorHandler();

Prototype in	d_device.hpp

Remarks		getDeviceErrorHandler returns a pointer to the handler that
		is currently installed to handle the device errors.
		The return type EHT is defined as follows:
		    void (*EHT)(const char *msg, Boolean is_fatal);

Arguments	none

Return value	pointer of type EHT.


------------------------------------------------------------------------------
setErrorHandler								Device
------------------------------------------------------------------------------

Function	install a new device error handler, return a pointer to
		the previous handler.

Syntax		#include <ruldev\d_device.hpp>
		static EHT Device::setErrorHandler(EHT handler);

Prototype in	d_device.hpp

Remarks		setDeviceErrorHandler installs a new device error handler.
		It returns a pointer to the previously installed handler.
		You can suspend error handling by specifying NULL (0) for
		handler. The type EHT is defined as follows:
		    void (*EHT)(const char *msg, Boolean is_fatal);

Arguments	handler: pointer to the new error handler function

Return value	pointer to the previous error handler.

Example		EHT oldHandler =			// save old hanlder,
		Device::setErrorHandler( NULL );	//   suspend handling
		// other actions go here
		Device::setErrorHandler( oldHandler );	// restore handler


-------------------------------------------------------------------------------
scan									 Device
-------------------------------------------------------------------------------

Function	initialize the device from a stream.

Syntax		#include <ruldev\d_device.hpp>
		virtual Status Device::scan(istream &is = cin);

Prototype in	d_device.hpp

Remarks		scan reads the device representation as created by print
		and initializes the device with these settings. scan returns
		Ok when it properly read the object, otherwise it returns
		BadRecord if the record read was not for this device, or
		BadInput if a stream input error occurred.
		See also Device::print.

Arguments	is: reference to the input stream	(default: cin)

Return value	Ok, BadRecord, BadInput.


-------------------------------------------------------------------------------
print									 Device
-------------------------------------------------------------------------------

Function	write an initialization record for this object to a stream.

Syntax		#include <ruldev\d_device.hpp>
		virtual Status Device::print(ostream &os = cout);

Prototype in	d_device.hpp

Remarks		print writes a device represention to a stream from which
		scan can initialize the device. You can use this to save a
		device's configuration to a fstream (file) or to a strstream
		(incore). print returns Ok when it properly wrote the object,
		otherwise it returns BadOutput if a stream write error occurred.

Arguments	os: reference to the output stream	(default: cout)

Return value	Ok, BadOutput.

Example		aDeviceType aDevice;		// declare a device

		strstream ioss;			// declare string stream
		aDevice.print( ioss );		// save device configuration
		ioss << ends;			// append end of string ('\0')
		// actions that change configuration ...
		aDevice.scan( ioss );		// restore device configuration

		alternatively, you can use the overloaded operators '<<' and '>>':

		strstream ioss;			// declare string stream
		ioss << aDevice << ends;	// save device configuration
		// actions that change configuration ...
		ioss >> aDevice;		// restore device configuration

		or to a file:
						// declare file stream
		fstream iof("filename", ios::in | ios::out);
		iof << aDevice;			// save device configuration
		// actions that change configuration ...
		iof.seekg(0);			// reset to start of file
		iof >> aDevice;			// restore device configuration


-------------------------------------------------------------------------------
scanAll									Device	
-------------------------------------------------------------------------------

Function	initialize all devices from a stream.

Syntax		#include <ruldev\d_device.hpp>
		static Status Device::scanAll(istream &is = cin);

Prototype in	d_device.hpp

Remarks		scanAll reads the device representation as created by printAll
		and initializes the devices with these settings. scanAll returns
		Ok when it properly read all objects, otherwise it returns
		BadRecord if the last record read was not for this device, or
		BadInput if a stream input error occurred.
		See also Device::print.

Arguments	is: reference to the input stream	(default: cin)

Return value	Ok, BadRecord, BadInput.

Example		ifstream ifs("applic.dev");	// open file stream
		Device::scanAll(ifs);		// read repres. from file
		// ifs.close();			// file closes when out of scope


-------------------------------------------------------------------------------
printAll								Device	
-------------------------------------------------------------------------------

Function	write initialization records for all devices to a stream.

Syntax		#include <ruldev\d_device.hpp>
		static Status Device::printAll(ostream &os = cout);

Prototype in	d_device.hpp

Remarks		printAll writes representions for all devices to a stream from 
		which scanAll can initialize the devices. You can use this to 
		save the device configurations to a fstream (file) or to a strstream
		(incore). printAll returns Ok when it properly wrote all devices,
		otherwise it returns BadOutput if a stream write error occurred.

Arguments	os: reference to the output stream	(default: cout)

Return value	Ok, BadOutput.

Example		ofstream ofs("applic.dev");	// open output file stream
		Device::printAll(ofs);		// write repres. to file
		// ofs.close();			// file closes when out of scope


------------------------------------------------------------------------------
(errorTrap)								Device
------------------------------------------------------------------------------

Function	execute error handler, if installed, and return status.

Syntax		#include <ruldev\d_device.hpp>
		Status Device::errorTrap(Status status, const char *function);

Prototype in	d_device.hpp

Remarks		errorTrap executes the error handler, if one is installed.
		If the error handler does not exit the program, errorTrap
		returns the error status.

Arguments	status	: any value of type Status
		function: name of function where trap occurred

Return value	status value.


------------------------------------------------------------------------------
(fatalErrorTrap)							Device
------------------------------------------------------------------------------

Function	execute error handler, if installed, and exit with EXIT_FAILURE.

Syntax		#include <ruldev\d_device.hpp>
		Status Device::fatalErrorTrap(Status status, const char *function);

Prototype in	d_device.hpp

Remarks		fatalErrorTrap executes the error handler, if one is installed.
		The errorhandler should exit the program. If the error handler
		does not exit the program, fatalErrorTrap returns the error status.

Arguments	status	: any value of type Status
		function: name of function where trap occurred

Return value	status value.


-------------------------------------------------------------------------------
(_scan)									Device
-------------------------------------------------------------------------------

Function	initialize the device from a stream.

Syntax		#include <ruldev\d_device.hpp>
		virtual Status Device::_scan(istream &is = cin) = 0;

Prototype in	d_device.hpp

Remarks		_scan reads the device representation as created by _print
		and initializes the device with these settings. _scan returns
		Ok when it properly read the object, otherwise it returns
		BadRecord if the record read was not for this device, or
		BadInput if a stream input error occurred.
		See also Device::scan.

Note		each class derived from class Device must define it's own
		_scan function to add it's specific information:

		Status aClass::_scan(istream &is /* = cin */ )
		{
		   Status status;

		   if ( (status = Device::_scan( is )) != Ok )
		      return status;

		   is >> someClassInfo; is.ignore(MAXLINE, '\n');
		   is >> ....	      ; is.ignore(MAXLINE, '\n');

		   return is.good() ? Ok : BadInput;
		}

Arguments	is: reference to the input stream	(default: cin)

Return value	Ok, BadRecord, BadInput.


-------------------------------------------------------------------------------
(_print)								Device
-------------------------------------------------------------------------------

Function	write an initialization record for this object to a stream.

Syntax		#include <ruldev\d_device.hpp>
		virtual Status Device::_print(ostream &os = cout) = 0;

Prototype in	d_device.hpp

Remarks		_print writes a device represention to a stream from which
		_scan can initialize the device. _print returns Ok when it
		properly wrote the object, otherwise it returns BadOutput
		if a stream write error occurred. See also Device::print.

Note		each class derived from class Device must define it's own
		_print function to add it's specific information:

		Status aClass::_print(ostream& os /* = cout */ )
		{
		   Status status;

		   if ( (status = Device::_print(os)) != Ok )
		       return status;

		   os << "   " << "aClass_info" << "\t// aClass info\n"
		      << "   " <<  ....		<< "\t// ....\n" ;

		   return os.good() ? Ok : BadOutput;
		}

Arguments	os: reference to the output stream	(default: cout)

Return value	Ok, BadOutput.


------------------------------------------------------------------------------
operator>>								Device
------------------------------------------------------------------------------

Function	extract a device object from a stream.

Syntax		#include <ruldev\d_device.hpp>
		PUBLIC istream& operator>> (istream &is, Device &dev);

Prototype in	d_device.hpp

Remarks		operator>> extracts a device object from the given input
		stream is, using the virtual function scan.

Arguments	is : reference to the input stream
		dev: reference to the device

Return value	reference to input stream.


------------------------------------------------------------------------------
operator<<								Device
------------------------------------------------------------------------------

Function	insert a device object into a stream.

Syntax		#include <ruldev\d_device.hpp>
		PUBLIC ostream& operator<< (ostream &os, Device &dev);

Prototype in	d_device.hpp

Remarks		operator<< inserts the device object into the given output
		stream os, using the virtual function print.

Arguments	os : reference to the output stream
		dev: reference to the device

Return value	reference to output stream.


------------------------------------------------------------------------------
DeviceIterator - class to iterate through the list of devices
------------------------------------------------------------------------------

Class		DeviceIterator

Derived from	none

Remarks		Class DeviceIterator provides a way to scan through the list
		of all devices that are currently in scope in the program.

		Class DeviceIterator provides functions to:
		- reset the iterator to the begin of the list,
		- check if at end of the list,
		- return a reference to the device in focus,
		- return a pointer to the device in focus,
		- return a reference and select the next device,
		- return a reference and select the previous device.


-------------------------------------------------------------------------------
restart								DeviceIterator	
-------------------------------------------------------------------------------

Function	reset the iterator to the start of the device list.

Syntax		#include <ruldev\d_device.hpp>
		void DeviceIterator::restart();

Prototype in	d_device.hpp

Remarks		restart resets the iterator to the front of the device list.

Arguments	none

Return value	none


-------------------------------------------------------------------------------
operator int							DeviceIterator	
-------------------------------------------------------------------------------

Function	check if iterator is not yet at the end of the device list.

Syntax		#include <ruldev\d_device.hpp>
		DeviceIterator::operator int ();

Prototype in	d_device.hpp

Remarks		operator int returns 1 if the iterator is not yet at the
		end of the device list, 0 if it is at the end.

Arguments	none

Return value	1, 0 (more devices, no more devices).

Example		typedef Device& DeviceRef;		// type

		void printDeviceNames(ostream& os)	// print all devicenames
		{
		   DeviceIterator nameIterator;		// declare iterator

		   while ( int(nameIterator) )		// more devices?
		   {
		      os << DeviceRef(nameIterator++).getDeviceName() << endl;
		   }
		}


-------------------------------------------------------------------------------
operator Device&						DeviceIterator
-------------------------------------------------------------------------------

Function	return a reference to the device in focus.

Syntax		#include <ruldev\d_device.hpp>
		DeviceIterator::operator Device& ();

Prototype in	d_device.hpp

Remarks		operator Device& returns a reference to the device currently 
		in focus of the iterator. If no more devices are left, operator
		Device& returns NODEVICE.  See also operator int.

Arguments	none

Return value	Device reference, NODEVICE.


-------------------------------------------------------------------------------
operator Device*						DeviceIterator	
-------------------------------------------------------------------------------

Function	return a pointer to the device in focus.

Syntax		#include <ruldev\d_device.hpp>
		DeviceIterator::operator Device* ();

Prototype in	d_device.hpp

Remarks		operator Device* returns a pointer to the device currently 
		in focus of the iterator. If no more devices are left, operator
		Device* returns the address of NODEVICE.  See also operator int.

Arguments	none

Return value	Device pointer, address of NODEVICE.


-------------------------------------------------------------------------------
operator++							DeviceIterator	
-------------------------------------------------------------------------------

Function	return reference and select next device.

Syntax		#include <ruldev\d_device.hpp>
		Device& DeviceIterator::operator++ ();

Prototype in	d_device.hpp

Remarks		operator++ returns a reference to the device currently in focus 
		of the iterator and selects the next device in the list. If there
		are no more devices in the list, operator++ returns a reference
		to NODEVICE. See also operator int.

Arguments	none

Return value	Device reference, NODEVICE.


-------------------------------------------------------------------------------
operator--							DeviceIterator	
-------------------------------------------------------------------------------

Function	return reference and select previous device.

Syntax		#include <ruldev\d_device.hpp>
		Device& DeviceIterator::operator-- ();

Prototype in	d_device.hpp

Remarks		operator-- returns a reference to the device currently in focus
		of the iterator and selects the previous device in the list. 
		If there are no more devices in the list, operator-- returns a 
		reference to NODEVICE. See also operator int.

Arguments	none

Return value	Device reference, NODEVICE.

Martin J. Moene   (e-mail)  /  Revised: .