Source: classlib/include/exchanger.h


Annotated List
Files
Globals
Hierarchy
Index
/***************************************************************************
           exchanger.h - infrastruttura per lo scambio di dati
                             -------------------
    begin                : sab set 27 17:40:01 CET 2002
    copyright            : (C) 2001 by Nicola De Nisco
    email                : nicola@winada.it
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef __EXCHANGER_H
#define __EXCHANGER_H

#include "variant.h"

/**

	class Exchanger

	Scambiatore generico di valori a Variant.
	L'obbiettivo principale di questa classe e' quello di offrire una rapida
	implementazione di una interfaccia per scambiare dati fra una applicazione
	client e una server.

	Attraverso le macro elencate dopo la classe e' possibile inserire
	velocemente una infrastruttura di codice che legge e scrive delle variabili
	interne all'applicazione da e verso Variant.
	Questi Variant possono essere scambiati molto agevolmente fra il
	client e il server per trasportare i valori.

	Vedi serverex.cpp e clientex.cpp per un esempio di implementazione.

*/

class Exchanger
{
 public:
	Exchanger();
	virtual ~Exchanger();

  enum Funzioni_DED {
	LeggiCampoIndice,
	ScriviCampoIndice,
	LeggiCampoNome,
	ScriviCampoNome,
	LeggiNomeCampo,
	LeggiIndiceCampo,
	ContaNumeroCampi,
	TipoPreferitoIndice,
	TipoPreferitoNome,
	DimensioneIndice,
	DimensioneNome
  };

	/** Legge il valore associato al nome simbolico specificato.
	*/
	virtual VARIANT GetCampo(LPCTSTR nomeCampo);

	/** Imposta il valore associato al nome simbolico specificato.
	*/
	virtual void SetCampo(LPCTSTR nomeCampo, const VARIANT& newValue);

	/** Legge il valore in base all'indice specificato.
	*/
	virtual VARIANT GetCampo( int indice );

	/** Imposta il valore in base all'indice specificato.
	*/
	virtual void SetCampo( int indice, const VARIANT& newValue);

	/** Ritorna il nome simbolico associato all'indice specificato.
	*/
	virtual LPCSTR GetNomeCampo(short IndiceCampo);

	/** Ritorna l'indice associato al nome simbolico specificato.
	*/
	virtual short GetIndiceCampo(LPCTSTR NomeCampo);

	/** Ritorna il numero dei campi disponibili in questa istanza.
	*/
	virtual short GetCampiCount();

	/** Ritorna il tipo di campo nativo per l'indice specificato.
	*/
	virtual short GetTipoCampo(short IndiceCampo);

	/** Ritorna il tipo di campo nativo per il nome simbolico specificato.
	*/
	virtual short GetTipoCampo(LPCTSTR NomeCampo);

	/** Ritorna la dimensione del campo per l'indice specificato.
	*/
	virtual short GetDimensioneCampo(short IndiceCampo);

	/** Ritorna la dimensione del campo per il nome simbolico specificato.
	*/
	virtual short GetDimensioneCampo(LPCTSTR NomeCampo);

 protected:
	virtual int DoExcangeDataRunner( int indice, const char* nome,
				    VARIANT* valore, Funzioni_DED Funzione );
	int AidSwitch( int indice, const char* nome, Funzioni_DED Funzione,
		 VARENUM tipoPreferito, short Dimensione );
	virtual void DoExcangeData( int indice, const char* nome, VARIANT* valore, Funzioni_DED Funzione ) {};
	virtual void ThrowError(SCODE code, int idErr, int errInfo=0) {}

 private:
	// usati nella ricerca dei nomi campi o indici campi dai nomi
	const char* NomeCampoRitorno;
	short IndiceCampoRitorno;
	// usate da aidswitch per sapere chi è il campo che si sta cercando
	const char* NomeCampoAndata;
	short IndiceCampoAndata;
	short ConteggioCampi;
	short DimensioneCampi;
	VARENUM TipoPreferitoRitorno;
	short NumeroCampi;
};

//-----------------------------------------------------------------------

#define sDED_GENERIC( __indice, __nome, __campo, __tipo, __dim, __ScriviFun, __LeggiFun ) \
	switch( AidSwitch( __indice, __nome, Funzione, __tipo, __dim ) ) {	\
		case 1: /* lettura del campo */									\
				__LeggiFun( (__campo), valore );						\
				return;													\
		case 2: /* scrittura del campo */								\
				(__campo) = __ScriviFun( valore );						\
				return;													\
		case 3: /* funzione già eseguita */								\
				return;													\
		}

#define sDED_FUNC( __indice, __nome, __tipo, __dim, __ScriviFun, __LeggiFun ) \
	switch( AidSwitch( __indice, __nome, Funzione, __tipo, __dim ) ) {	\
		case 1: /* lettura del campo */									\
				__LeggiFun( valore );									\
				return;													\
		case 2: /* scrittura del campo */								\
				__ScriviFun( valore );									\
				return;													\
		case 3: /* funzione già eseguita */								\
				return;													\
		}

#define sDED_FUNC_GENERIC( __indice, __nome, __tipo, __dim, __ScriviFun, __LeggiFun, __PUT, __GET ) \
	switch( AidSwitch( __indice, __nome, Funzione, __tipo, __dim ) ) {	\
		case 1: /* lettura del campo */									\
				__LeggiFun( __GET(), valore );							\
				return;													\
		case 2: /* scrittura del campo */								\
				__PUT( __ScriviFun( valore ) );							\
				return;													\
		case 3: /* funzione già eseguita */								\
				return;													\
		}
		
// stringhe con destinazione array a lunghezza fissa
#define sDED_VTSTR1( __indice, __nome, __campo ) \
	switch( AidSwitch( __indice, __nome, Funzione, VT_BSTR, sizeof( __campo )-1 ) ) {	\
		case 1: /* lettura del campo */									\
				SafeStringToVariant( (const char*)(__campo), valore, sizeof( __campo )); \
				return;													\
		case 2: /* scrittura del campo */								\
				{														\
				strncpy((char*)(__campo), ::trim(VariantToString( valore )), sizeof( __campo ));\
				}														\
				return;													\
		case 3: /* funzione già eseguita */								\
				return;													\
		}

// stringhe con destinazione pointer char generici
#define sDED_VTSTR2( __indice, __nome, __campo, __dim ) \
	switch( AidSwitch( __indice, __nome, Funzione, VT_BSTR, __dim ) ) {	\
		case 1: /* lettura del campo */									\
				StringToVariant( (const char*)(__campo), valore );		\
				return;													\
		case 2: /* scrittura del campo */								\
				{														\
				strncpy((char*)(__campo), ::trim(VariantToString( valore )), __dim);\
				}														\
				return;													\
		case 3: /* funzione già eseguita */								\
				return;													\
		}

// stringhe con destinazione oggetti CString o simili
#define sDED_VTSTR3( __indice, __nome, __campo, __dim ) \
	switch( AidSwitch( __indice, __nome, Funzione, VT_BSTR, __dim ) ) {	\
		case 1: /* lettura del campo */									\
				StringToVariant( (const char*)(__campo), valore );		\
				return;													\
		case 2: /* scrittura del campo */								\
				(__campo) = ::trim(VariantToString( valore ));			\
				return;													\
		case 3: /* funzione già eseguita */								\
				return;													\
		}

#define sDED_VTI2( __indice, __nome, __campo )		\
	sDED_GENERIC( __indice, __nome, __campo, VT_I2, 2, VariantToInt16, Int16ToVariant )
#define sDED_VTI4( __indice, __nome, __campo )		\
	sDED_GENERIC( __indice, __nome, __campo, VT_I4, 4, VariantToInt32, Int32ToVariant )
#define sDED_VTR4( __indice, __nome, __campo )		\
	sDED_GENERIC( __indice, __nome, __campo, VT_R4, 4, VariantToFloat, FloatToVariant )
#define sDED_VTR8( __indice, __nome, __campo )		\
	sDED_GENERIC( __indice, __nome, __campo, VT_R8, 8, VariantToDouble, DoubleToVariant )
#define sDED_VTDATE( __indice, __nome, __campo )		\
	sDED_GENERIC( __indice, __nome, __campo, VT_DATE, 4, VariantToDate, DateToVariant )
#define sDED_VTBOOL( __indice, __nome, __campo )		\
	sDED_GENERIC( __indice, __nome, __campo, VT_BOOL, 1, VariantToBOOL, BOOLToVariant )


#define sDED_FUNC_I2( __indice, __nome, __funcWrite, __funcRead )		\
	sDED_FUNC_GENERIC( __indice, __nome, VT_I2, 2, VariantToInt16, Int16ToVariant, __funcWrite, __funcRead )
#define sDED_FUNC_I4( __indice, __nome, __funcWrite, __funcRead )		\
	sDED_FUNC_GENERIC( __indice, __nome, VT_I4, 4, VariantToInt32, Int32ToVariant, __funcWrite, __funcRead )
#define sDED_FUNC_R4( __indice, __nome, __funcWrite, __funcRead )		\
	sDED_FUNC_GENERIC( __indice, __nome, VT_R4, 4, VariantToFloat, FloatToVariant, __funcWrite, __funcRead )
#define sDED_FUNC_R8( __indice, __nome, __funcWrite, __funcRead )		\
	sDED_FUNC_GENERIC( __indice, __nome, VT_R8, 8, VariantToDouble, DoubleToVariant, __funcWrite, __funcRead )
#define sDED_FUNC_DATE( __indice, __nome, __funcWrite, __funcRead )		\
	sDED_FUNC_GENERIC( __indice, __nome, VT_DATE, 4, VariantToDate, DateToVariant, __funcWrite, __funcRead )
#define sDED_FUNC_BOOL( __indice, __nome, __funcWrite, __funcRead )		\
	sDED_FUNC_GENERIC( __indice, __nome, VT_BOOL, 1, VariantToBOOL, BOOLToVariant, __funcWrite, __funcRead )
		
//-----------------------------------------------------------------------

#define DED_GENERIC( __indice, __nome, __campo, __tipo, __dim, __ScriviFun, __LeggiFun ) \
	case __indice:														\
	switch( AidSwitch( __indice, __nome, Funzione, __tipo, __dim ) ) {	\
		case 1: /* lettura del campo */									\
				__LeggiFun( (__campo), valore );						\
				return;													\
		case 2: /* scrittura del campo */								\
				(__campo) = __ScriviFun( valore );						\
				return;													\
		case 3: /* funzione già eseguita */								\
				return;													\
		}																\
	if( indice )	return;

#define DED_FUNC( __indice, __nome, __tipo, __dim, __ScriviFun, __LeggiFun ) \
	case __indice:														\
	switch( AidSwitch( __indice, __nome, Funzione, __tipo, __dim ) ) {	\
		case 1: /* lettura del campo */									\
				__LeggiFun( valore );									\
				return;													\
		case 2: /* scrittura del campo */								\
				__ScriviFun( valore );									\
				return;													\
		case 3: /* funzione già eseguita */								\
				return;													\
		}																\
	if( indice )	return;

#define DED_FUNC_GENERIC( __indice, __nome, __tipo, __dim, __ScriviFun, __LeggiFun, __PUT, __GET ) \
	case __indice:														\
	switch( AidSwitch( __indice, __nome, Funzione, __tipo, __dim ) ) {	\
		case 1: /* lettura del campo */									\
				__LeggiFun( __GET(), valore );							\
				return;													\
		case 2: /* scrittura del campo */								\
				__PUT( __ScriviFun( valore ) );							\
				return;													\
		case 3: /* funzione già eseguita */								\
				return;													\
		}																\
	if( indice )	return;

// stringhe con destinazione array a lunghezza fissa
#define DED_VTSTR1( __indice, __nome, __campo ) \
	case __indice:														\
	switch( AidSwitch( __indice, __nome, Funzione, VT_BSTR, sizeof( __campo )-1 ) ) {	\
		case 1: /* lettura del campo */									\
				SafeStringToVariant( (const char*)(__campo), valore, sizeof( __campo )); \
				return;													\
		case 2: /* scrittura del campo */								\
				{														\
				strncpy((char*)(__campo), ::trim(VariantToString( valore )), sizeof( __campo ));\
				}														\
				return;													\
		case 3: /* funzione già eseguita */								\
				return;													\
		}																\
	if( indice )	return;

// stringhe con destinazione pointer char generici
#define DED_VTSTR2( __indice, __nome, __campo, __dim ) \
	case __indice:														\
	switch( AidSwitch( __indice, __nome, Funzione, VT_BSTR, __dim ) ) {	\
		case 1: /* lettura del campo */									\
				StringToVariant( (const char*)(__campo), valore );		\
				return;													\
		case 2: /* scrittura del campo */								\
				{														\
				strncpy((char*)(__campo), ::trim(VariantToString( valore )), __dim);\
				}														\
				return;													\
		case 3: /* funzione già eseguita */								\
				return;													\
		}																\
	if( indice )	return;

// stringhe con destinazione oggetti CString o simili
#define DED_VTSTR3( __indice, __nome, __campo, __dim ) \
	case __indice:														\
	switch( AidSwitch( __indice, __nome, Funzione, VT_BSTR, __dim ) ) {	\
		case 1: /* lettura del campo */									\
				StringToVariant( (const char*)(__campo), valore );		\
				return;													\
		case 2: /* scrittura del campo */								\
				(__campo) = ::trim(VariantToString( valore ));			\
				return;													\
		case 3: /* funzione già eseguita */								\
				return;													\
		}																\
	if( indice )	return;

#define DED_VTI2( __indice, __nome, __campo )		\
	DED_GENERIC( __indice, __nome, __campo, VT_I2, 2, VariantToInt16, Int16ToVariant )
#define DED_VTI4( __indice, __nome, __campo )		\
	DED_GENERIC( __indice, __nome, __campo, VT_I4, 4, VariantToInt32, Int32ToVariant )
#define DED_VTR4( __indice, __nome, __campo )		\
	DED_GENERIC( __indice, __nome, __campo, VT_R4, 4, VariantToFloat, FloatToVariant )
#define DED_VTR8( __indice, __nome, __campo )		\
	DED_GENERIC( __indice, __nome, __campo, VT_R8, 8, VariantToDouble, DoubleToVariant )
#define DED_VTDATE( __indice, __nome, __campo )		\
	DED_GENERIC( __indice, __nome, __campo, VT_DATE, 4, VariantToDate, DateToVariant )
#define DED_VTBOOL( __indice, __nome, __campo )		\
	DED_GENERIC( __indice, __nome, __campo, VT_BOOL, 1, VariantToBOOL, BOOLToVariant )

#define DED_FUNC_I2( __indice, __nome, __funcWrite, __funcRead )		\
	DED_FUNC_GENERIC( __indice, __nome, VT_I2, 2, VariantToInt16, Int16ToVariant, __funcWrite, __funcRead )
#define DED_FUNC_I4( __indice, __nome, __funcWrite, __funcRead )		\
	DED_FUNC_GENERIC( __indice, __nome, VT_I4, 4, VariantToInt32, Int32ToVariant, __funcWrite, __funcRead )
#define DED_FUNC_R4( __indice, __nome, __funcWrite, __funcRead )		\
	DED_FUNC_GENERIC( __indice, __nome, VT_R4, 4, VariantToFloat, FloatToVariant, __funcWrite, __funcRead )
#define DED_FUNC_R8( __indice, __nome, __funcWrite, __funcRead )		\
	DED_FUNC_GENERIC( __indice, __nome, VT_R8, 8, VariantToDouble, DoubleToVariant, __funcWrite, __funcRead )
#define DED_FUNC_DATE( __indice, __nome, __funcWrite, __funcRead )		\
	DED_FUNC_GENERIC( __indice, __nome, VT_DATE, 4, VariantToDate, DateToVariant, __funcWrite, __funcRead )
#define DED_FUNC_BOOL( __indice, __nome, __funcWrite, __funcRead )		\
	DED_FUNC_GENERIC( __indice, __nome, VT_BOOL, 1, VariantToBOOL, BOOLToVariant, __funcWrite, __funcRead )
	
//-----------------------------------------------------------------------

#define DECLARE_EXCANGE()	\
	protected:				\
	void DoExcangeData( int indice, const char* nome, VARIANT* valore, Funzioni_DED Funzione );

#define SIMPLE_EXCANGE( xx )	\
	void \
	xx::DoExcangeData( int indice, const char* nome, VARIANT* valore, Funzioni_DED Funzione )

#define IMPLEMENT_EXCANGE( xx )	\
	void \
	xx::DoExcangeData( int indice, const char* nome, VARIANT* valore, Funzioni_DED Funzione ) { \
	switch( indice ) {	\
	case 0:

#define END_EXCANGE	\
	} /* end switch */ \
	} /* end function */ 


#define BOOSTCASE	case __indice:
#define BOOSTEND	if( indice ){return;}

#define CTL_E_ILLEGALFUNCTIONCALL	1
#define IDS_FIELDUNKNOW				100
#define IDS_NOFLDORDER				101
#define IDS_NOFLDZERO				102

#endif // __EXCHANGER_H


Generated by: nicola on gulliver.wadahome.it on Sun May 25 13:54:34 2003, using kdoc 2.0a53.