283 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			283 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include "netutils.h"
 | 
						|
 | 
						|
TLanManager::TLanManager()
 | 
						|
{ }
 | 
						|
 | 
						|
TLanManager::~TLanManager()
 | 
						|
{
 | 
						|
  RemoveAllConnections();
 | 
						|
}
 | 
						|
 | 
						|
TConnection* TLanManager::OnCreateConnection(CONNID id)
 | 
						|
{
 | 
						|
  return new TConnection(this, id);
 | 
						|
}           
 | 
						|
 | 
						|
bool TLanManager::HasConnections() const 
 | 
						|
{ 
 | 
						|
  return m_mapConn.items() > 0; 
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TLanManager::Request(CONNID id, const char* cmd)
 | 
						|
{
 | 
						|
   TConnection* conn = GetConnection(id) ;
 | 
						|
   return conn ? conn->Request(cmd) : FALSE;
 | 
						|
}
 | 
						|
 | 
						|
bool TLanManager::Execute(CONNID id, const char* cmd)
 | 
						|
{
 | 
						|
   TConnection* conn = GetConnection(id) ;
 | 
						|
   return conn ? conn->Execute(cmd) : FALSE;
 | 
						|
}
 | 
						|
 | 
						|
// Physically disconnect
 | 
						|
bool TLanManager::OnRemoveConnection(CONNID id)
 | 
						|
{
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
CONNID TLanManager::AddConnection(TConnection* pConn)
 | 
						|
{
 | 
						|
  CONNID id = 0;
 | 
						|
  if (pConn)
 | 
						|
  {
 | 
						|
    id = pConn->Id();
 | 
						|
    TString16 key; key.format("%lu", id);
 | 
						|
    m_mapConn.add(key, pConn, TRUE);
 | 
						|
  }
 | 
						|
  return id;
 | 
						|
}
 | 
						|
 | 
						|
bool TLanManager::RemoveConnection(CONNID id)
 | 
						|
{
 | 
						|
  TConnection* pConn = GetConnection(id);
 | 
						|
  bool ok = FALSE;
 | 
						|
  if (pConn != NULL && OnRemoveConnection(id))
 | 
						|
  {
 | 
						|
    TString16 key; key.format("%lu", id);
 | 
						|
    m_mapConn.remove(key);
 | 
						|
    ok = TRUE;
 | 
						|
  }  
 | 
						|
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
void TLanManager::RemoveAllConnections()
 | 
						|
{   
 | 
						|
  m_mapConn.restart();
 | 
						|
  for (TConnection* pConn = (TConnection*)m_mapConn.get(); 
 | 
						|
	     pConn != NULL; pConn = (TConnection*)m_mapConn.get())
 | 
						|
    OnRemoveConnection(pConn->Id());
 | 
						|
  m_mapConn.destroy();
 | 
						|
}
 | 
						|
 | 
						|
TConnection* TLanManager::GetConnection(CONNID id) const
 | 
						|
{
 | 
						|
  TString16 key; key.format("%lu", id);
 | 
						|
  TConnection* pConn = (TConnection*)m_mapConn.objptr(key);
 | 
						|
  return pConn;
 | 
						|
}
 | 
						|
 | 
						|
int TLanManager::ForEachConnection(ConnectionFunction f, void* pJolly)
 | 
						|
{
 | 
						|
  int result = 0;
 | 
						|
  TConnection* pConn;
 | 
						|
 | 
						|
  m_mapConn.restart();
 | 
						|
  for (pConn = (TConnection*)m_mapConn.get(); 
 | 
						|
    pConn != NULL; 
 | 
						|
    pConn = (TConnection*)m_mapConn.get()) 
 | 
						|
    result += f(*pConn, pJolly);
 | 
						|
 | 
						|
  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(size_t);
 | 
						|
  byte* buff = GetBuffer(dwSize);
 | 
						|
  *(size_t*)buff = n ? -1 : 0;
 | 
						|
  return buff;
 | 
						|
}
 | 
						|
 | 
						|
byte* TLanServer::GetBufferSetInteger(long n)
 | 
						|
{
 | 
						|
  const size_t dwSize = sizeof(size_t);
 | 
						|
  byte* buff = GetBuffer(dwSize);
 | 
						|
  *(size_t*)buff = n;
 | 
						|
  return buff;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TLanClient
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
CONNID TLanClient::QueryConnection(const char* service, const char* server)
 | 
						|
{
 | 
						|
  TConnection* pConn = OnQueryConnection(service, server);
 | 
						|
  return AddConnection(pConn) ;
 | 
						|
}
 | 
						|
 | 
						|
bool TLanClient::Execute(CONNID id, const char* cmd)
 | 
						|
{
 | 
						|
	TConnection* pConn = GetConnection(id);
 | 
						|
	return pConn ? pConn->Execute(cmd) : FALSE;
 | 
						|
}
 | 
						|
 | 
						|
bool TLanClient::Request(CONNID id, const char* cmd)
 | 
						|
{
 | 
						|
	TConnection* pConn = GetConnection(id);
 | 
						|
	return pConn ? pConn->Request(cmd) : FALSE;
 | 
						|
}
 | 
						|
 | 
						|
bool TLanClient::RequestString(CONNID id, const char* cmd, TString& res)
 | 
						|
{
 | 
						|
  bool valid = Request(id, cmd);
 | 
						|
  if (valid)
 | 
						|
  {
 | 
						|
    size_t dwSize;
 | 
						|
    byte* pData = GetBuffer(dwSize);
 | 
						|
    char* ptr = res.get_buffer((int)dwSize);
 | 
						|
    memcpy(ptr, pData, (size_t)dwSize);
 | 
						|
    ReleaseBuffer();
 | 
						|
  }
 | 
						|
  return valid;
 | 
						|
}
 | 
						|
 | 
						|
bool TLanClient::RequestInteger(CONNID id, const char* cmd, long& num)
 | 
						|
{
 | 
						|
  bool valid = Request(id, cmd);
 | 
						|
  if (valid)
 | 
						|
  {
 | 
						|
    size_t dwSize;
 | 
						|
    byte* pData = GetBuffer(dwSize);
 | 
						|
    num = *(long*)pData;
 | 
						|
    ReleaseBuffer();
 | 
						|
  }
 | 
						|
  return valid;
 | 
						|
}
 | 
						|
 | 
						|
bool TLanClient::RequestBool(CONNID id, const char* cmd, bool& ok)
 | 
						|
{
 | 
						|
  bool valid = Request(id, cmd);
 | 
						|
  if (valid)
 | 
						|
  {
 | 
						|
    size_t dwSize;
 | 
						|
    byte* pData = GetBuffer(dwSize);
 | 
						|
    ok = *pData != 0;
 | 
						|
    ReleaseBuffer();
 | 
						|
  }
 | 
						|
  return valid;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TConnection
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TConnection::TConnection(TLanManager* pManager, CONNID id)
 | 
						|
           : m_pManager(pManager), m_dwId(id)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
TConnection::~TConnection()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
TLanServer& TConnection::Server() const
 | 
						|
{
 | 
						|
  CHECK(Manager().IsServer(), "Can't cast client to server");
 | 
						|
  return (TLanServer&)Manager();
 | 
						|
}
 | 
						|
 | 
						|
int TConnection::ParseCommand(const char* cmd, TString_array& argv)
 | 
						|
{             
 | 
						|
  argv.destroy();
 | 
						|
 | 
						|
  bool is_quoted = FALSE;
 | 
						|
  char end_quote = '\0';
 | 
						|
  TString 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;
 | 
						|
          token.rtrim();
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      argv.add(token);
 | 
						|
    
 | 
						|
      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;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return argv.items();
 | 
						|
}
 | 
						|
 | 
						|
bool TConnection::Execute(const char* cmd)
 | 
						|
{
 | 
						|
  TString_array argv;
 | 
						|
  return ParseCommand(cmd, argv) > 0;
 | 
						|
}
 | 
						|
 | 
						|
bool TConnection::Request(const char* cmd)
 | 
						|
{
 | 
						|
  TString_array argv;
 | 
						|
  return ParseCommand(cmd, argv) > 0;
 | 
						|
}
 | 
						|
 |