360 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			360 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#define NO_MFC
 | 
						|
#define CObject TObject
 | 
						|
#define CString TString
 | 
						|
#define CStringArray TString_array
 | 
						|
 | 
						|
#include "NetUtils.h"
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 |