isamrpc.* Gestione chiamate a server remoto

netutils.*   Generici server e client di rpc via Sockets


git-svn-id: svn://10.65.10.50/trunk@4502 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 1997-06-03 13:54:55 +00:00
parent f9b9e70dbd
commit e9ecf5c85e
4 changed files with 784 additions and 0 deletions

269
include/isamrpc.cpp Executable file
View File

@ -0,0 +1,269 @@
#include <time.h>
#include <checks.h>
#include <isamrpc.h>
#define NO_MFC
#define CObject TObject
#define CString TString
#define CStringArray TString_array
#include <netsock.h>
static TSocketClient* _client = NULL;
static DWORD _connection = 0;
bool rpc_Start()
{
bool ok = TRUE;
if (_client == NULL)
{
_client = new TSocketClient;
if (!_client->IsOk())
{
delete _client;
_client = NULL;
ok = error_box("Errore di inizializzazione del client.");
}
}
return ok;
}
bool rpc_Stop()
{
if (_client)
{
delete _client;
_client = NULL;
_connection = 0;
}
return TRUE;
}
bool rpc_Call(const char* cmd)
{
CHECK(_connection, "Server not connected");
bool ok = _client->Execute(_connection, cmd);
return ok;
}
char* rpc_Request(const char* cmd, DWORD& size, real& total)
{
CHECK(_connection, "Server not connected");
const clock_t start = clock();
_client->Request(_connection, cmd);
total = (clock() - start) / double(CLOCKS_PER_SEC);
char* buff = (char*)_client->GetBuffer(size);
return buff;
}
static TString256 _rpc_call;
static TString _rpc_string;
inline bool BoolCall()
{
CHECK(_connection, "Server not connected");
BOOL yes;
bool ok = _client->RequestBool(_connection, _rpc_call, yes);
if (!ok)
{
#ifndef DBG
yesnofatal_box("RPC call failed: %s", (const char*)_rpc_call);
#endif
yes = FALSE;
}
return yes ? TRUE : FALSE;
}
inline long IntCall()
{
CHECK(_connection, "Server not connected");
long n;
bool ok = _client->RequestInteger(_connection, _rpc_call, n);
if (!ok)
{
#ifndef DBG
yesnofatal_box("RPC call failed: %s", (const char*)_rpc_call);
#endif
n = 0;
}
return n;
}
inline TString& StrCall()
{
CHECK(_connection, "Server not connected");
bool ok = _client->RequestString(_connection, _rpc_call, _rpc_string);
if (!ok)
{
#ifndef DBG
yesnofatal_box("RPC call failed: %s", (const char*)_rpc_call);
#endif
_rpc_string.cut(0);
}
return _rpc_string;
}
inline bool BoolCallInt(const char* fn, long n)
{
_rpc_call.format("%s(%ld)", fn, n);
return BoolCall();
}
inline long IntCallInt(const char* fn, long n)
{
_rpc_call.format("%s(%ld)", fn, n);
return IntCall();
}
inline long IntCallIntInt(const char* fn, long n, long k)
{
_rpc_call.format("%s(%ld,%ld)", fn, n, k);
return IntCall();
}
inline long IntCallIntIntInt(const char* fn, long n, long k, long f)
{
_rpc_call.format("%s(%ld,%ld,%ld)", fn, n, k, f);
return IntCall();
}
inline long IntCallIntIntStr(const char* fn, long n, long k, const char* str)
{
_rpc_call.format("%s(%ld,%ld,|%s|)", fn, n, k, str);
return IntCall();
}
inline long IntCallIntStr(const char* fn, long n, const char* str)
{
_rpc_call.format("%s(%ld,|%s|)", fn, n, str);
return IntCall();
}
inline int IntCallIntStrInt(const char* fn, long n, const char* s, long f)
{
_rpc_call.format("%s(%ld,|%s|,%ld)", fn, n, s, f);
return (int)IntCall();
}
inline long IntCallIntStrStr(const char* fn, long n, const char* str, const char* val)
{
_rpc_call.format("%s(%ld,|%s|,|%s|)", fn, n, str, val);
return IntCall();
}
inline long IntCallStr(const char* fn, const char* str)
{
_rpc_call.format("%s(%s)", fn, str);
return IntCall();
}
inline TString& StrCallIntInt(const char* fn, long n, long k)
{
_rpc_call.format("%s(%ld,%ld)", fn, n, k);
return StrCall();
}
inline TString& StrCallIntStr(const char* fn, long n, const char* str)
{
_rpc_call.format("%s(%ld,|%s|)", fn, n, str);
return StrCall();
}
bool rpc_DongleHasModule(word af)
{
return BoolCallInt("DongleHasModule", af);
}
bool rpc_DongleModules(word* int_tab0)
{
DWORD size;
real time;
char* buff = rpc_Request("DongleModules()", size, time);
if (buff)
memcpy(int_tab0, buff, (size_t)size);
return size > 0;
}
unsigned rpc_DongleNumber()
{
_rpc_call = "DongleNumber()";
return (unsigned)IntCall();
}
bool rpc_UserLogin(const char* server, const char* user,
const char* password, const char* application)
{
if (_client == NULL)
{
if (!rpc_Start())
return FALSE;
}
const bool local = server == NULL || *server == '\0';
TString name(40);
if (local)
name = "locale";
else
name = server;
const char* str = (const char*)name;
TString80 error;
if (_connection != 0)
_client->RemoveConnection(_connection);
_connection = _client->QueryConnection("1883", server);
if (_connection)
{
TString cmd(32);
cmd << "UserLogin(" << user << ")";
_rpc_call.format("UserLogin(%s,%s,%s)", user, password, application);
BOOL logged = FALSE;
bool connected = _client->RequestBool(_connection, _rpc_call, logged);
if (connected)
{
if (!logged)
{
connected = FALSE;
error.format("La connessione di %s e' stata rifiutata dal Server %s", (const char*)user, str);
}
}
else
{
error.format("Impossibile connettersi al Server %s", str);
}
if (!connected)
{
_client->RemoveConnection(_connection);
_connection = 0;
}
}
else
{
error.format("Impossibile connettersi al Server %s", str);
}
if (error.not_empty())
error_box(error);
return _connection != 0;
}
bool rpc_UserLogout()
{
if (_connection)
{
rpc_Call("UserLogout()");
_client->RemoveConnection(_connection);
_connection = 0;
}
return TRUE;
}

23
include/isamrpc.h Executable file
View File

@ -0,0 +1,23 @@
#ifndef __ISAMRPC_H
#define __ISAMRPC_H
#ifndef __REAL_H
#include <real.h>
#endif
bool rpc_Call(const char* cmd);
char* rpc_Request(const char* cmd, unsigned long& size, real& time);
bool rpc_DongleHasModule(word af);
bool rpc_DongleModules(word* int_tab0);
word rpc_DongleNumber();
bool rpc_UserLogin(const char* server, const char* user,
const char* password, const char* application);
bool rpc_UserLogout();
bool rpc_Start();
bool rpc_Stop();
#endif

377
include/netutils.cpp Executable file
View File

@ -0,0 +1,377 @@
#define NO_MFC
#define CObject TObject
#define CString TString
#define CStringArray TString_array
#include "NetUtils.h"
OsType GetOsType()
{
OsType ver;
DWORD dwVersion = GetVersion();
if (dwVersion < 0x80000000)
ver = WINDOWS_NT;
else
{
if (LOBYTE(LOWORD(dwVersion)) < 4)
ver = WINDOWS_31;
else
ver = WINDOWS_95;
}
return ver;
}
TLanManager::TLanManager()
{ }
TLanManager::~TLanManager()
{
RemoveAllConnections();
}
TConnection* TLanManager::OnCreateConnection(DWORD id)
{
return new TConnection(this, id);
}
BOOL TLanManager::HasConnections() const
{
#ifdef NO_MFC
return m_mapConn.items() > 0;
#else
return m_mapConn.GetCount() > 0;
#endif
}
BOOL TLanManager::Request(DWORD id, const char* cmd)
{
TConnection* conn = GetConnection(id) ;
return conn ? conn->Request(cmd) : FALSE;
}
BOOL TLanManager::Execute(DWORD id, const char* cmd)
{
TConnection* conn = GetConnection(id) ;
return conn ? conn->Execute(cmd) : FALSE;
}
// Physically disconnect
BOOL TLanManager::OnRemoveConnection(DWORD id)
{
return id != NULL;
}
DWORD TLanManager::AddConnection(TConnection* pConn)
{
DWORD id = 0;
if (pConn)
{
id = pConn->Id();
#ifdef NO_MFC
TString16 key; key.format("%lu", id);
m_mapConn.add(key, pConn, TRUE);
#else
TConnection* c;
BOOL ok = m_mapConn.Lookup(id, c);
if (ok)
delete c;
m_mapConn.SetAt(id, pConn);
#endif
}
return id;
}
BOOL TLanManager::RemoveConnection(DWORD id)
{
TConnection* pConn = GetConnection(id);
BOOL ok = FALSE;
if (pConn != NULL && OnRemoveConnection(id))
{
#ifdef NO_MFC
TString16 key; key.format("%lu", id);
m_mapConn.remove(key);
#else
delete pConn;
VERIFY(m_mapConn.RemoveKey(id));
#endif
ok = TRUE;
}
return ok;
}
void TLanManager::RemoveAllConnections()
{
TConnection* pConn;
#ifdef NO_MFC
m_mapConn.restart();
for (pConn = (TConnection*)m_mapConn.get(); pConn; pConn = (TConnection*)m_mapConn.get())
OnRemoveConnection(pConn->Id());
m_mapConn.destroy();
#else
for (POSITION pos = m_mapConn.GetStartPosition(); pos != NULL;)
{
DWORD key;
m_mapConn.GetNextAssoc(pos, key, pConn);
{
OnRemoveConnection(pConn->Id());
delete pConn;
}
}
m_mapConn.RemoveAll();
#endif
}
TConnection* TLanManager::GetConnection(DWORD id) const
{
TConnection* pConn = NULL;
#ifdef NO_MFC
TString16 key; key.format("%lu", id);
pConn = (TConnection*)m_mapConn.objptr(key);
#else
m_mapConn.Lookup(id, pConn);
#endif
return pConn;
}
int TLanManager::ForEachConnection(ConnectionFunction f, void* pJolly)
{
int result = 0;
TConnection* pConn;
#ifdef NO_MFC
m_mapConn.restart();
for (pConn = (TConnection*)m_mapConn.get();
pConn != NULL;
pConn = (TConnection*)m_mapConn.get())
result += f(*pConn, pJolly);
#else
DWORD key;
for (POSITION pos = m_mapConn.GetStartPosition(); pos != NULL; )
{
m_mapConn.GetNextAssoc(pos, key, pConn);
result += f(*pConn, pJolly);
}
#endif
return result;
}
///////////////////////////////////////////////////////////
// TLanServer
///////////////////////////////////////////////////////////
BYTE* TLanServer::GetBufferSetString(const char* str)
{
if (str == NULL)
str = "";
const size_t dwSize = strlen(str)+1;
BYTE* buff = GetBuffer(dwSize);
memcpy(buff, str, dwSize);
return buff;
}
BYTE* TLanServer::GetBufferSetBool(BOOL n)
{
const size_t dwSize = sizeof(DWORD);
BYTE* buff = GetBuffer(dwSize);
*(DWORD*)buff = n ? -1 : 0;
return buff;
}
BYTE* TLanServer::GetBufferSetInteger(long n)
{
const size_t dwSize = sizeof(DWORD);
BYTE* buff = GetBuffer(dwSize);
*(DWORD*)buff = n;
return buff;
}
///////////////////////////////////////////////////////////
// TLanClient
///////////////////////////////////////////////////////////
DWORD TLanClient::QueryConnection(const char* service,
const char* server)
{
TConnection* pConn = OnQueryConnection(service, server);
return AddConnection(pConn) ;
}
BOOL TLanClient::Execute(DWORD id, const char* cmd)
{
return FALSE;
}
BOOL TLanClient::Request(DWORD id, const char* cmd)
{
return FALSE;
}
BOOL TLanClient::RequestString(DWORD id, const char* cmd, CString& res)
{
BOOL valid = Request(id, cmd);
if (valid)
{
DWORD dwSize;
BYTE* pData = GetBuffer(dwSize);
#ifdef NO_MFC
char* ptr = res.get_buffer((int)dwSize);
memcpy(ptr, pData, (size_t)dwSize);
#else
char* ptr = res.GetBuffer((int)dwSize);
memcpy(ptr, pData, dwSize);
res.ReleaseBuffer();
#endif
ReleaseBuffer();
}
return valid;
}
BOOL TLanClient::RequestInteger(DWORD id, const char* cmd, long& num)
{
BOOL valid = Request(id, cmd);
if (valid)
{
DWORD dwSize;
BYTE* pData = GetBuffer(dwSize);
num = *(long*)pData;
ReleaseBuffer();
}
return valid;
}
BOOL TLanClient::RequestBool(DWORD id, const char* cmd, BOOL& ok)
{
BOOL valid = Request(id, cmd);
if (valid)
{
DWORD dwSize;
BYTE* pData = GetBuffer(dwSize);
ok = *(DWORD*)pData != 0;
ReleaseBuffer();
}
return valid;
}
///////////////////////////////////////////////////////////
// TConnection
///////////////////////////////////////////////////////////
TConnection::TConnection(TLanManager* pManager, DWORD id)
: m_pManager(pManager), m_dwId(id)
{
}
TConnection::~TConnection()
{
}
TLanServer& TConnection::Server() const
{
#ifdef NO_MFC
CHECK(Manager().IsServer(), "Can't cast client to server");
#else
ASSERT(Manager().IsServer());
#endif
return (TLanServer&)Manager();
}
int TConnection::ParseCommand(const char* cmd, CStringArray& argv)
{
#ifdef NO_MFC
argv.destroy();
#else
argv.RemoveAll();
#endif
BOOL is_quoted = FALSE;
char end_quote = '\0';
CString token;
const char* token_start = NULL;
for (char* c = (char*)cmd; *c; c++)
{
if (end_quote)
{
if (*c == end_quote)
{
*c = '\0';
token = token_start;
*c = end_quote;
end_quote = '\0';
is_quoted = TRUE;
}
continue;
}
if (*c == '(' || *c == ')' || *c == ',')
{
if (token_start)
{
if (is_quoted)
{
}
else
{
const char old = *c;
*c = '\0';
token = token_start;
*c = old;
#ifdef NO_MFC
token.rtrim();
#else
token.TrimRight();
#endif
}
}
#ifdef NO_MFC
argv.add(token);
#else
argv.Add(token);
#endif
token_start = NULL;
token = "";
is_quoted = FALSE;
continue;
}
if (*c == '"' || *c == '\'' || *c == '|' || BYTE(*c) >= 254)
{
end_quote = *c;
token_start = c+1;
}
if (token_start == NULL && *c > ' ')
{
token_start = c;
}
}
#ifdef NO_MFC
return argv.items();
#else
return argv.GetSize();
#endif
}
BOOL TConnection::Execute(const char* cmd)
{
CStringArray argv;
return ParseCommand(cmd, argv) > 0;
}
BOOL TConnection::Request(const char* cmd)
{
CStringArray argv;
return ParseCommand(cmd, argv) > 0;
}

115
include/netutils.h Executable file
View File

@ -0,0 +1,115 @@
#ifndef __NETUTILS_H__
#define __NETUTILS_H__
#ifdef NO_MFC
#define STRICT
#include <windows.h>
#include "assoc.h"
#endif
class TConnection;
typedef int (*ConnectionFunction)(TConnection& conn, void* pJolly);
class TLanManager : public CObject
{
#ifdef NO_MFC
TAssoc_array m_mapConn;
#else
CMap<DWORD, DWORD, TConnection*, TConnection*> m_mapConn;
#endif
protected:
DWORD AddConnection(TConnection* pConn);
virtual TConnection* OnCreateConnection(DWORD id);
virtual BOOL OnRemoveConnection(DWORD id);
public:
virtual BOOL IsServer() const { return FALSE; }
virtual BOOL IsClient() const { return FALSE; }
virtual BOOL IsOk() const { return FALSE; }
virtual BOOL Execute(DWORD id, const char* cmd);
virtual BOOL Request(DWORD id, const char* cmd);
int ForEachConnection(ConnectionFunction f, void* pJolly);
BOOL HasConnections() const;
TConnection* GetConnection(DWORD id) const;
BOOL RemoveConnection(DWORD id);
void RemoveAllConnections();
TLanManager();
virtual ~TLanManager();
};
class TLanServer : public TLanManager
{
CString m_strName;
public:
const CString& Name() const { return m_strName; }
virtual BOOL IsServer() const { return TRUE; }
virtual BYTE* GetBuffer(DWORD dwSize) = 0;
BYTE* GetBufferSetString(const char* str);
BYTE* GetBufferSetBool(BOOL ok);
BYTE* GetBufferSetInteger(long n);
TLanServer(const char* name) : m_strName(name) { }
virtual ~TLanServer() { }
};
class TLanClient : public TLanManager
{
protected:
virtual TConnection* OnQueryConnection(const char* service,
const char* server) = 0;
public:
virtual BOOL IsClient() const { return TRUE; }
DWORD QueryConnection(const char* service,
const char* server = NULL);
virtual BOOL Execute(DWORD id, const char* cmd);
virtual BOOL Request(DWORD id, const char* cmd);
virtual BYTE* GetBuffer(DWORD& dwSize) = 0;
virtual void ReleaseBuffer() = 0;
BOOL RequestString(DWORD id, const char* cmd, CString& res);
BOOL RequestInteger(DWORD id, const char* cmd, long& num);
BOOL RequestBool(DWORD id, const char* cmd, BOOL& ok);
};
class TConnection : public CObject
{
TLanManager* m_pManager;
DWORD m_dwId;
protected:
int ParseCommand(const char* cmd, CStringArray& argv);
public:
DWORD Id() const { return m_dwId; }
TLanManager& Manager() const { return *m_pManager; }
TLanServer& Server() const;
virtual BOOL Execute(const char* cmd);
virtual BOOL Request(const char* cmd);
BOOL ReturnBool(int b) const { return Server().GetBufferSetBool(b) != NULL; }
BOOL ReturnInteger(long n) const { return Server().GetBufferSetInteger(n) != NULL; }
BOOL ReturnString(const CString& s) const { return Server().GetBufferSetString(s) != NULL; }
TConnection(TLanManager* lm, DWORD id);
virtual ~TConnection();
};
enum OsType { WINDOWS_31, WINDOWS_95, WINDOWS_NT };
OsType GetOsType();
#endif