Files correlati : diction.exe Ricompilazione Demo : [ ] Commento : Corretta lettura sequenze di escape all'interno dei testi dei file XML git-svn-id: svn://10.65.10.50/trunk@14324 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			829 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			829 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include "baseserv.h"
 | 
						|
#include <wx/hashmap.h>
 | 
						|
#include <wx/mstream.h>
 | 
						|
 | 
						|
#include <ctype.h>
 | 
						|
 | 
						|
//////////////////////////////////////////////////////////
 | 
						|
// Conversion utilities
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
int FindChar(const wxString& str, char c, int from)
 | 
						|
{
 | 
						|
  if (from <= 0)
 | 
						|
    return str.Find(c);
 | 
						|
  for (int i = from; str[i]; i++)
 | 
						|
    if (str[i] == c)
 | 
						|
      return i;
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 | 
						|
wxString txt2xml(const wxString& str)
 | 
						|
{
 | 
						|
  wxString tmp;
 | 
						|
  for (int i = 0; str[i]; i++)
 | 
						|
  {
 | 
						|
    if (str[i] < ' ' || str[i] > 'z' || strchr("&<>/", str[i]) != NULL)
 | 
						|
      tmp << wxString::Format("&#%X;", (int)(unsigned char)(str[i]));
 | 
						|
    else
 | 
						|
      tmp << str[i];
 | 
						|
  }
 | 
						|
  return tmp;
 | 
						|
}
 | 
						|
 | 
						|
wxString xml2txt(const wxString& str)
 | 
						|
{
 | 
						|
  int i = str.Find('&');
 | 
						|
  if (i >= 0)
 | 
						|
  {
 | 
						|
    wxString tmp = str.Left(i);
 | 
						|
    for (; str[i]; i++)
 | 
						|
    {
 | 
						|
      bool bProcessed = false;
 | 
						|
      if (str[i] == '&')
 | 
						|
      {
 | 
						|
        const int semicolon = FindChar(str, ';', i);
 | 
						|
        if (semicolon > i)
 | 
						|
        {
 | 
						|
          const wxString sub = str.Mid(i+1, semicolon-i-1);
 | 
						|
          int n;
 | 
						|
          if (sub[0] == '#')
 | 
						|
            bProcessed = sscanf(sub, "#%X", &n) == 1;
 | 
						|
          else
 | 
						|
            bProcessed = sscanf(sub, "%d", &n) == 1;
 | 
						|
          if (bProcessed)
 | 
						|
          {
 | 
						|
            tmp << char(n & 0xFF);
 | 
						|
            i = semicolon;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if (!bProcessed)
 | 
						|
        tmp << str[i];
 | 
						|
    }
 | 
						|
    return tmp;
 | 
						|
  }
 | 
						|
  return str;
 | 
						|
}
 | 
						|
 | 
						|
//////////////////////////////////////////////////////////
 | 
						|
// TDictionary
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct TEntry : public wxObject
 | 
						|
{
 | 
						|
  wxString m_eng, m_src;
 | 
						|
  int m_max;
 | 
						|
 | 
						|
  TEntry& operator=(const TEntry& e)
 | 
						|
  { m_eng = e.m_eng; m_src = e.m_src; m_max = e.m_max; return *this; }
 | 
						|
};
 | 
						|
 | 
						|
WX_DECLARE_STRING_HASH_MAP( TEntry, TStringHashTable );
 | 
						|
 | 
						|
class TDictionary : public TStringHashTable
 | 
						|
{
 | 
						|
  TBaseServerApp* m_app;
 | 
						|
	wxSortedArrayString m_sorted;
 | 
						|
  bool m_bDirty;
 | 
						|
 | 
						|
protected:
 | 
						|
  void ParseSpaces(const wxString& str, wxString& prefix, 
 | 
						|
			 						 wxString& body, wxString& postfix) const;
 | 
						|
  void AddEntry(const wxString& ita, const wxString& eng, const wxString& src, int max); 
 | 
						|
 | 
						|
	static bool FillCallback(TXmlItem& item, long jolly);
 | 
						|
	bool Load();
 | 
						|
  void Save();
 | 
						|
 | 
						|
public:
 | 
						|
	wxString Translate(const wxString& ita);
 | 
						|
	
 | 
						|
	wxString GetFileName() const;
 | 
						|
  bool LoadIfEmpty();
 | 
						|
	void SaveIfNeeded();
 | 
						|
	
 | 
						|
	wxString OriginalEntry(size_t i);
 | 
						|
	wxString TranslatedEntry(size_t i);
 | 
						|
  const TEntry& GetEntry(size_t i);
 | 
						|
 | 
						|
  void UpdateEntry(size_t i, const wxString& strValue);
 | 
						|
 | 
						|
  void SetApp(TBaseServerApp* app) { m_app = app; }
 | 
						|
 | 
						|
  TDictionary();
 | 
						|
  ~TDictionary();
 | 
						|
};
 | 
						|
 | 
						|
wxString TDictionary::GetFileName() const
 | 
						|
{
 | 
						|
	TBaseServerApp& app = (TBaseServerApp&)*wxTheApp;
 | 
						|
  return app.GetConfigString("Dictionary", "campodic.xml");
 | 
						|
}
 | 
						|
 | 
						|
void TDictionary::Save()
 | 
						|
{
 | 
						|
  const char* eol = "\r\n";
 | 
						|
	wxFileOutputStream outf(GetFileName());
 | 
						|
  outf << "<?xml version=\"1.0\"?>" << eol;
 | 
						|
	outf << "<dictionary>" << eol;
 | 
						|
	for (size_t i = 0; i < m_sorted.GetCount(); i++)
 | 
						|
	{
 | 
						|
		const wxString& ita = m_sorted[i];
 | 
						|
		outf << " <entry>" << eol;
 | 
						|
		outf << "  <ita>";
 | 
						|
		WriteXmlString(outf, ita);
 | 
						|
		outf << "</ita>" << eol;
 | 
						|
		outf << "  <eng>";
 | 
						|
    const TEntry& e = operator[](ita);
 | 
						|
		WriteXmlString(outf, e.m_eng);
 | 
						|
		outf << "</eng>" << eol;
 | 
						|
    if (!e.m_src.IsEmpty())
 | 
						|
    {
 | 
						|
  		outf << "  <src>";
 | 
						|
		  WriteXmlString(outf, e.m_src);
 | 
						|
		  outf << "</src>" << eol;
 | 
						|
    }
 | 
						|
    if (e.m_max > 0)
 | 
						|
    {
 | 
						|
      wxString str; str.Printf("%d", e.m_max);
 | 
						|
		  outf << "  <max>" << str << "</max>" << eol;
 | 
						|
    }
 | 
						|
		outf << " </entry>" << eol;
 | 
						|
	}
 | 
						|
	outf << "</dictionary>" << eol;
 | 
						|
  m_bDirty = false;
 | 
						|
}
 | 
						|
 | 
						|
void TDictionary::SaveIfNeeded()
 | 
						|
{
 | 
						|
	if (m_bDirty)
 | 
						|
		Save();
 | 
						|
}
 | 
						|
 | 
						|
void TDictionary::AddEntry(const wxString& ita, const wxString& eng, const wxString& src, int max)
 | 
						|
{
 | 
						|
  TEntry e;
 | 
						|
  e.m_eng = eng;
 | 
						|
  e.m_src = src;
 | 
						|
  e.m_max = max;
 | 
						|
 | 
						|
  operator[](ita) = e;
 | 
						|
  m_sorted.Add(ita);
 | 
						|
	m_bDirty = true;
 | 
						|
}
 | 
						|
 | 
						|
void TDictionary::UpdateEntry(size_t nEntry, const wxString& strValue)
 | 
						|
{
 | 
						|
	if (nEntry >= 0 && nEntry < m_sorted.GetCount())
 | 
						|
	{
 | 
						|
	  const wxString& ita = m_sorted[nEntry];
 | 
						|
    TEntry& e = operator[](ita);
 | 
						|
	  e.m_eng = strValue;
 | 
						|
		Save();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
wxString TDictionary::OriginalEntry(size_t i)
 | 
						|
{
 | 
						|
	return m_sorted[i];
 | 
						|
}
 | 
						|
 | 
						|
const TEntry& TDictionary::GetEntry(size_t i)
 | 
						|
{
 | 
						|
  const wxString& ita = m_sorted[i];
 | 
						|
  const TEntry& e = operator[](ita);
 | 
						|
  return e;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
wxString TDictionary::TranslatedEntry(size_t i)
 | 
						|
{
 | 
						|
  const TEntry& e = GetEntry(i);
 | 
						|
  return e.m_eng;
 | 
						|
}
 | 
						|
 | 
						|
wxSocketClient& operator<<(wxSocketClient& sock, const wxChar* str)
 | 
						|
{
 | 
						|
	if (str && *str)
 | 
						|
		sock.Write(str, wxStrlen(str));
 | 
						|
	return sock;
 | 
						|
}
 | 
						|
 | 
						|
bool TDictionary::Load()
 | 
						|
{
 | 
						|
  clear();
 | 
						|
  m_sorted.Clear();
 | 
						|
	wxFileInputStream scan(GetFileName());
 | 
						|
 | 
						|
  wxString ita, eng, src, line;
 | 
						|
  int max;
 | 
						|
  while (!scan.Eof())
 | 
						|
  {
 | 
						|
    scan >> line;
 | 
						|
    line.Trim(false);
 | 
						|
    if (line.StartsWith("<entry>"))
 | 
						|
    {
 | 
						|
      ita = eng = src = "";
 | 
						|
      max = 0;
 | 
						|
    } else
 | 
						|
    if (line.StartsWith("<ita>"))
 | 
						|
    {
 | 
						|
      const int eoi = line.Find("</ita>");
 | 
						|
      ita = xml2txt(line.Mid(5, eoi-5));
 | 
						|
    } else
 | 
						|
    if (line.StartsWith("<eng>") && !ita.IsEmpty())
 | 
						|
    {
 | 
						|
      const int eoe = line.Find("</eng>");
 | 
						|
      eng = xml2txt(line.Mid(5, eoe-5));
 | 
						|
    } else
 | 
						|
    if (line.StartsWith("<max>"))
 | 
						|
    {
 | 
						|
      const int eom = line.Find("</max>");
 | 
						|
      max = atoi(line.Mid(5, eom-5));
 | 
						|
    } else
 | 
						|
    if (line.StartsWith("<src>"))
 | 
						|
    {
 | 
						|
      const int eos = line.Find("</src>");
 | 
						|
      src = xml2txt(line.Mid(5, eos-5));
 | 
						|
    } else
 | 
						|
    if (line.StartsWith("</entry>"))
 | 
						|
    {
 | 
						|
      AddEntry(ita, eng, src, max);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  m_bDirty = false;
 | 
						|
	return size() > 0;
 | 
						|
}
 | 
						|
 | 
						|
bool TDictionary::LoadIfEmpty()
 | 
						|
{
 | 
						|
	bool full = size() > 0;
 | 
						|
	if (!full)
 | 
						|
		full = Load();
 | 
						|
	return full;
 | 
						|
}
 | 
						|
 | 
						|
inline bool IsGoodChar(wxChar c)
 | 
						|
{
 | 
						|
	return isalnum(c) || strchr("@%'", c);
 | 
						|
}
 | 
						|
 | 
						|
void TDictionary::ParseSpaces(const wxString& str, wxString& prefix, 
 | 
						|
															wxString& body, wxString& postfix) const
 | 
						|
{
 | 
						|
	int i, j;
 | 
						|
  for (i = 0; !IsGoodChar(str[i]); i++);
 | 
						|
  for (j = str.Length()-1; j >= i && !IsGoodChar(str[j]); j--);
 | 
						|
	if (i > 0)
 | 
						|
		prefix = str.Left(i);
 | 
						|
	if (j >= i)
 | 
						|
		postfix = str.Mid(j+1);
 | 
						|
	body = str.Mid(i, j-i+1);
 | 
						|
}
 | 
						|
 | 
						|
wxString TDictionary::Translate(const wxString& ita)
 | 
						|
{
 | 
						|
  LoadIfEmpty();
 | 
						|
 | 
						|
	wxString prefix, body, postfix;
 | 
						|
	ParseSpaces(ita, prefix, body, postfix);
 | 
						|
 | 
						|
  const TStringHashTable::iterator i = find(body);
 | 
						|
	if (i != end())
 | 
						|
	{
 | 
						|
    const TEntry& e = i->second;
 | 
						|
	  if (e.m_eng != "???")
 | 
						|
		{
 | 
						|
			body = prefix;
 | 
						|
			body += e.m_eng;
 | 
						|
			body += postfix;
 | 
						|
		  return body;
 | 
						|
		}
 | 
						|
	}
 | 
						|
  else
 | 
						|
  {
 | 
						|
	  AddEntry(ita, "???", wxEmptyString, 0);
 | 
						|
    if (m_app != NULL)
 | 
						|
      m_app->WriteLog("*** Unknown sentence");
 | 
						|
  }
 | 
						|
	
 | 
						|
	return ita;
 | 
						|
}
 | 
						|
 | 
						|
TDictionary::TDictionary() 
 | 
						|
           : TStringHashTable(10000), m_app(NULL), m_bDirty(false)
 | 
						|
{ 
 | 
						|
}
 | 
						|
 | 
						|
TDictionary::~TDictionary()
 | 
						|
{
 | 
						|
	SaveIfNeeded();
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TDictionaryServer
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TDictionaryServer : public TBaseServerApp
 | 
						|
{
 | 
						|
  TDictionary m_DevotoOli;
 | 
						|
 | 
						|
protected:  
 | 
						|
	virtual const wxChar* GetAppName() const;
 | 
						|
  virtual void ProcessCommand(wxString cmd, wxSocketBase& outs);
 | 
						|
 | 
						|
  size_t FindIndex(const wxString& strKey);
 | 
						|
 | 
						|
public:
 | 
						|
  bool DoTranslate(const TXmlItem& xmlMethod, TXmlItem& xmlAnswer);
 | 
						|
  bool SoapProcessMethod(const TXmlItem& xmlMethod, TXmlItem& xmlAnswer);
 | 
						|
  void ProcessSoapCommand(wxString cmd, wxSocketBase& outs);
 | 
						|
  void ProcessHttpGet(wxString cmd, wxSocketBase& outs);
 | 
						|
  void ProcessFormCommand(wxString cmd, wxSocketBase& outs);
 | 
						|
 | 
						|
	void ProcessFormUpdateEntry(wxString& strFileName, THashTable& hashArgs);
 | 
						|
  void ProcessFormTranslate(wxString& strFileName, THashTable& hashArgs);
 | 
						|
 | 
						|
  void CallCgi(wxString& strFilename);
 | 
						|
	bool IsMagicName(wxString& strFilename) const;
 | 
						|
  bool IsCgiName(wxString strFilename) const;
 | 
						|
 | 
						|
	void Add2Columns(TXmlItem& table, const wxChar* href0, const wxChar* td0, const wxChar* td1) const;
 | 
						|
  void AddEditableRow(TXmlItem& table, const wxChar* txt1, const wxChar* txt2, const wxChar* txt3, const wxChar* txt4) const;
 | 
						|
  void GenerateIndex(TXmlItem& body);
 | 
						|
	void GenerateFile(wxString& strFilename);
 | 
						|
 | 
						|
	virtual bool Initialization();
 | 
						|
  virtual bool Deinitialization();
 | 
						|
 | 
						|
  TDictionaryServer();
 | 
						|
};
 | 
						|
 | 
						|
bool TDictionaryServer::SoapProcessMethod(const TXmlItem& xmlMethod, TXmlItem& xmlAnswer)
 | 
						|
{
 | 
						|
	const wxString& strMethod = xmlMethod.GetTag();
 | 
						|
	if (strMethod == "m:Translate")
 | 
						|
		return DoTranslate(xmlMethod, xmlAnswer);
 | 
						|
 | 
						|
	return false;
 | 
						|
}
 | 
						|
 | 
						|
bool TDictionaryServer::DoTranslate(const TXmlItem& xmlMethod, TXmlItem& xmlAnswer)
 | 
						|
{
 | 
						|
  const TXmlItem* xmlSentence = xmlMethod.FindFirst("sentence");
 | 
						|
  if (xmlSentence != NULL)
 | 
						|
	{
 | 
						|
		const wxString ita = xmlSentence->GetEnclosedText();
 | 
						|
		wxString result = m_DevotoOli.Translate(ita);
 | 
						|
    xmlAnswer.AddSoapString("sentence", result);
 | 
						|
		return true;
 | 
						|
	}
 | 
						|
	return false;
 | 
						|
}
 | 
						|
 | 
						|
bool TDictionaryServer::IsMagicName(wxString& strFilename) const
 | 
						|
{
 | 
						|
  wxString strName;
 | 
						|
	wxSplitPath(strFilename, NULL, &strName, NULL);
 | 
						|
  strName.MakeLower();
 | 
						|
  const int q = strName.Find('?');
 | 
						|
	if (q > 0)
 | 
						|
	  strName.Truncate(q);
 | 
						|
 | 
						|
	if (strName == "index" || strName == "dictionary")
 | 
						|
	{
 | 
						|
		return true;
 | 
						|
	}
 | 
						|
	if (strName == "log")
 | 
						|
	{
 | 
						|
		strFilename = GetLogFileName();
 | 
						|
	}
 | 
						|
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
bool TDictionaryServer::IsCgiName(wxString strFilename) const
 | 
						|
{
 | 
						|
	const int q = strFilename.Find('?');
 | 
						|
	if (q > 0)
 | 
						|
		strFilename = strFilename.Left(q);
 | 
						|
 | 
						|
	wxString strExt;
 | 
						|
	wxSplitPath(strFilename, NULL, NULL, &strExt);
 | 
						|
  strExt.MakeLower();
 | 
						|
	return strExt == "cgi" || strExt == "exe";
 | 
						|
}
 | 
						|
 | 
						|
void TDictionaryServer::Add2Columns(TXmlItem& table, const wxChar* href0, const wxChar* txt0, const wxChar* txt1) const
 | 
						|
{
 | 
						|
	TXmlItem& tr = table.AddChild("tr");
 | 
						|
	TXmlItem& a = tr.AddChild("td").AddChild("a");
 | 
						|
	a.SetAttr("href", href0);
 | 
						|
	a << txt0;
 | 
						|
  tr.AddChild("td") << txt1;
 | 
						|
}
 | 
						|
 | 
						|
void TDictionaryServer::GenerateIndex(TXmlItem& body)
 | 
						|
{
 | 
						|
  TXmlItem& table = body.AddChild("table");
 | 
						|
	table.SetAttr("border", "1"); table.SetAttr("width", "100%");
 | 
						|
	TXmlItem& tr = table.AddChild("tr");
 | 
						|
 | 
						|
	wxChar cLast = '\0';
 | 
						|
	for (size_t i = 0; i < m_DevotoOli.size(); i++)
 | 
						|
	{
 | 
						|
		const wxChar cCurr = toupper(m_DevotoOli.OriginalEntry(i)[0u]);
 | 
						|
		if (cCurr > cLast)
 | 
						|
		{
 | 
						|
      TXmlItem& td = tr.AddChild("td").SetAttr("align", "center");
 | 
						|
			td.AddChild("a").SetAttr("href", wxString::Format("Dictionary?%c", cCurr));
 | 
						|
      td << wxString::Format("%c", cCurr);
 | 
						|
			cLast = cCurr;
 | 
						|
		}
 | 
						|
	}
 | 
						|
  body.AddChild("br");
 | 
						|
}
 | 
						|
 | 
						|
void TDictionaryServer::AddEditableRow(TXmlItem& table, const wxChar* txt1, const wxChar* txt2, const wxChar* txt3, const wxChar* txt4) const
 | 
						|
{
 | 
						|
	TXmlItem& tr = table.AddChild("tr");
 | 
						|
	TXmlItem& td0 = tr.AddChild("td");
 | 
						|
	const wxString cgi = wxString::Format("EditEntry.cgi?%c-%u", 
 | 
						|
		                                    toupper(*txt1), table.GetChildren()-3);
 | 
						|
	AddLinkButton(td0, "Edit", cgi).SetAttr("width", "100%");
 | 
						|
	tr.AddChild("td") << txt1; 
 | 
						|
	tr.AddChild("td") << txt2; 
 | 
						|
	tr.AddChild("td") << txt3; 
 | 
						|
	tr.AddChild("td") << txt4; 
 | 
						|
}
 | 
						|
 | 
						|
void TDictionaryServer::GenerateFile(wxString& strFilename)
 | 
						|
{
 | 
						|
  const int q = strFilename.Find('?');
 | 
						|
	wxString strArgs;
 | 
						|
	if (q > 0)
 | 
						|
	{
 | 
						|
		strArgs = strFilename.Mid(q+1);
 | 
						|
	  strFilename.Truncate(q);
 | 
						|
	}
 | 
						|
 | 
						|
  wxString strName;
 | 
						|
	wxSplitPath(strFilename, NULL, &strName, NULL);
 | 
						|
  strName.MakeLower();
 | 
						|
 | 
						|
	TXmlItem html; 
 | 
						|
	TXmlItem& body = CreatePageBody(html);
 | 
						|
 | 
						|
	if (strName == "index")
 | 
						|
	{
 | 
						|
		TXmlItem& table = body.AddChild("center").AddChild("table");
 | 
						|
		table.SetAttr("border", "1"); table.SetAttr("width", "70%");
 | 
						|
		Add2Columns(table, "Dictionary", "Dictionary", "Sorted listing of entries");
 | 
						|
		Add2Columns(table, "TranslateSentence.cgi", "Translate", "Translate a sentence");
 | 
						|
		Add2Columns(table, "Log", "Log", "Server activity log");
 | 
						|
		Add2Columns(table, "stop.cgi", "Stop", "Stop the server");
 | 
						|
		
 | 
						|
		strFilename = GetTempFilename();
 | 
						|
  }
 | 
						|
	if (strName == "dictionary")
 | 
						|
	{
 | 
						|
		const wxChar cFilter = strArgs.IsEmpty() ? 'A' : toupper(strArgs[ 0u]);
 | 
						|
		GenerateIndex(body);
 | 
						|
 | 
						|
		TXmlItem& table = body.AddChild("table");
 | 
						|
		table.SetAttr("border", "1"); table.SetAttr("width", "100%");
 | 
						|
		table.AddChild("caption").AddChild("h1") << wxString::Format("%c", cFilter);
 | 
						|
 | 
						|
		TXmlItem& table_th = table.AddChild("thead");
 | 
						|
    TXmlItem& th0 = table_th.AddChild("th"); th0.SetAttr("width", "6%");
 | 
						|
    TXmlItem& th1 = table_th.AddChild("th"); th1.SetAttr("width", "47%"); 
 | 
						|
		th1 << "Original text";
 | 
						|
    TXmlItem& th2 = table_th.AddChild("th").SetAttr("width", "47%"); 
 | 
						|
		th2 << "Translated text";
 | 
						|
    TXmlItem& th3 = table_th.AddChild("th");
 | 
						|
		th3 << "Sources";
 | 
						|
    TXmlItem& th4 = table_th.AddChild("th");
 | 
						|
		th4 << "Max. Size";
 | 
						|
 | 
						|
		for (size_t i = 0; i < m_DevotoOli.size(); i++)
 | 
						|
		{
 | 
						|
			const wxString& orig = m_DevotoOli.OriginalEntry(i);
 | 
						|
			if (toupper(orig[0]) == cFilter)
 | 
						|
      {
 | 
						|
        const TEntry& e = m_DevotoOli.GetEntry(i);
 | 
						|
        wxString str; 
 | 
						|
        if (e.m_max > 0)
 | 
						|
          str.Printf("%d", e.m_max);
 | 
						|
			  AddEditableRow(table, orig, e.m_eng, e.m_src, str);
 | 
						|
      }
 | 
						|
		}
 | 
						|
		
 | 
						|
		strFilename = GetTempFilename();
 | 
						|
	}
 | 
						|
 | 
						|
  html.Save(strFilename);
 | 
						|
}
 | 
						|
 | 
						|
// Convert code (B-23) to position (107)
 | 
						|
size_t TDictionaryServer::FindIndex(const wxString& strKey)
 | 
						|
{
 | 
						|
	const wxChar cFirst = toupper(strKey[0]);
 | 
						|
	const size_t nPos = atoi(strKey.Mid(2));
 | 
						|
	size_t nFound = 0;
 | 
						|
	size_t i;
 | 
						|
	
 | 
						|
	for (i = 0; i < m_DevotoOli.size(); i++)
 | 
						|
	{
 | 
						|
		const wxChar c = toupper(m_DevotoOli.OriginalEntry(i)[ 0u]);
 | 
						|
		if (c == cFirst)
 | 
						|
		{
 | 
						|
			if (nFound == nPos)
 | 
						|
				break;
 | 
						|
			nFound++;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return i;
 | 
						|
}
 | 
						|
 | 
						|
void TDictionaryServer::CallCgi(wxString& strFileName)
 | 
						|
{
 | 
						|
	wxString strName, strExt, strArgs;
 | 
						|
	const int q = strFileName.Find('?');
 | 
						|
	if (q > 0)
 | 
						|
	{
 | 
						|
		strArgs = strFileName.Mid(q+1);
 | 
						|
		strFileName = strFileName.Left(q);
 | 
						|
	}
 | 
						|
	wxSplitPath(strFileName, NULL, &strName, &strExt);
 | 
						|
	if (strExt == "cgi")
 | 
						|
	{
 | 
						|
		TXmlItem html; 
 | 
						|
		TXmlItem& body = CreatePageBody(html).AddChild("center");
 | 
						|
    if (strName == "EditEntry")
 | 
						|
		{
 | 
						|
			const size_t i = FindIndex(strArgs);
 | 
						|
      const TEntry& e = m_DevotoOli.GetEntry(i);
 | 
						|
 | 
						|
      TXmlItem& ee = body.AddChild("h2");
 | 
						|
			ee << "Edit Entry " << strArgs;
 | 
						|
 | 
						|
			TXmlItem& form = body.AddChild("form");
 | 
						|
			form.SetAttr("method", "post");
 | 
						|
			form.SetAttr("action", "UpdateEntry.cgi");
 | 
						|
 | 
						|
			TXmlItem& ot = form.AddChild("h3");
 | 
						|
      ot << "Original text";
 | 
						|
      if (!e.m_src.IsEmpty())
 | 
						|
        ot << " (" << e.m_src << ")";
 | 
						|
 | 
						|
			TXmlItem& ita = form.AddChild("textarea");
 | 
						|
			ita.SetAttr("cols", "80"); ita.SetAttr("rows", "4");
 | 
						|
			ita << m_DevotoOli.OriginalEntry(i);
 | 
						|
      
 | 
						|
			form.AddChild("br");
 | 
						|
 | 
						|
			TXmlItem& tt = form.AddChild("h3");
 | 
						|
      tt << "Translated text";
 | 
						|
      if (e.m_max > 0)
 | 
						|
        tt << wxString::Format(" (Max. %d chars)", e.m_max);
 | 
						|
				
 | 
						|
			TXmlItem& ent = form.AddChild("input");
 | 
						|
			ent.SetAttr("type", "hidden"); ent.SetAttr("name", "Entry");
 | 
						|
			ent.SetAttr("value", strArgs);
 | 
						|
			
 | 
						|
			TXmlItem& eng = form.AddChild("textarea");
 | 
						|
			eng.SetAttr("name", "Trans"); 
 | 
						|
			eng.SetAttr("cols", "80"); eng.SetAttr("rows", "4");
 | 
						|
			eng << e.m_eng;
 | 
						|
 | 
						|
			form.AddChild("br");
 | 
						|
      form.AddChild("br");
 | 
						|
 | 
						|
			TXmlItem& sub = form.AddChild("input");
 | 
						|
			sub.SetAttr("type", "submit"); 
 | 
						|
			sub.SetAttr("value", "Update Translation");
 | 
						|
 | 
						|
			AddLinkButton(body, "Return to main page", "/");
 | 
						|
		}
 | 
						|
    if (strName == "TranslateSentence")
 | 
						|
		{
 | 
						|
			body.AddChild("h3") << "Input the text to be translated:";
 | 
						|
 | 
						|
			TXmlItem& form = body.AddChild("form");
 | 
						|
			form.SetAttr("method", "post");
 | 
						|
			form.SetAttr("action", "Translate.cgi");
 | 
						|
 | 
						|
			TXmlItem& ita = form.AddChild("textarea");
 | 
						|
			ita.SetAttr("name", "Sentence"); 
 | 
						|
			ita.SetAttr("cols", "80"); ita.SetAttr("rows", "4");
 | 
						|
			ita << "Menu Principale";
 | 
						|
 | 
						|
			form.AddChild("br");
 | 
						|
      form.AddChild("br");
 | 
						|
 | 
						|
			TXmlItem& sub = form.AddChild("input");
 | 
						|
			sub.SetAttr("type", "submit"); 
 | 
						|
			sub.SetAttr("value", "Translate");
 | 
						|
    }
 | 
						|
		strFileName = GetTempFilename();
 | 
						|
		html.Save(strFileName);
 | 
						|
	} else
 | 
						|
	if (strExt == "exe")
 | 
						|
	{
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Implementazione delle due funzioni pure virtuali
 | 
						|
 | 
						|
const wxChar* TDictionaryServer::GetAppName() const
 | 
						|
{
 | 
						|
	return "Dictionary";
 | 
						|
}
 | 
						|
 | 
						|
void TDictionaryServer::ProcessSoapCommand(wxString cmd, wxSocketBase& sock)
 | 
						|
{
 | 
						|
	TXmlItem xmlEnvelope;
 | 
						|
	xmlEnvelope.SetTag("SOAP-ENV:Envelope");
 | 
						|
	TXmlItem& xmlBody = xmlEnvelope.AddChild("SOAP-ENV:Body");
 | 
						|
 | 
						|
	const int soapstart = cmd.Find("<SOAP-ENV:");
 | 
						|
	if (soapstart > 0)
 | 
						|
	{
 | 
						|
		const size_t soaplen = cmd.length() - soapstart;
 | 
						|
		const char* buff = (const char*)cmd;
 | 
						|
		buff += soapstart;
 | 
						|
		wxMemoryInputStream input(buff, soaplen);
 | 
						|
		TXmlItem query; 
 | 
						|
		if (query.Read(input))
 | 
						|
		{
 | 
						|
			const TXmlItem* pxmlBody = query.FindFirst("SOAP-ENV:Body");
 | 
						|
			if (pxmlBody != NULL) for (int m = 0; ; m++)
 | 
						|
			{
 | 
						|
				const TXmlItem* pxmlMethod = pxmlBody->GetChild(m);
 | 
						|
				if (pxmlMethod == NULL)
 | 
						|
					break;
 | 
						|
				if (pxmlMethod->GetTag().StartsWith("m:"))
 | 
						|
				{
 | 
						|
					wxString str = pxmlMethod->GetTag(); str += "Result";
 | 
						|
					TXmlItem& xmlAnswer = xmlBody.AddChild(str);
 | 
						|
					SoapProcessMethod(*pxmlMethod, xmlAnswer);
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	const wxString strResult = xmlEnvelope.AsString();
 | 
						|
  
 | 
						|
	sock << "HTTP/1.1 200 OK" << endl;
 | 
						|
	sock << "Connection: keep-alive" << endl;
 | 
						|
	sock << "Content-Length: " << strResult.Length() << endl;
 | 
						|
	sock << "Content-Type: text/xml; charset=utf-8" << endl;
 | 
						|
	sock << "Date: " << wxDateTime::Now().Format("%#c") << endl;
 | 
						|
	sock << "Server: " << GetAppName() << endl;
 | 
						|
  sock << "Host: " << wxGetFullHostName() << endl;
 | 
						|
	sock << endl;
 | 
						|
	sock << strResult;
 | 
						|
}
 | 
						|
 | 
						|
void TDictionaryServer::ProcessHttpGet(wxString cmd, wxSocketBase& outs)
 | 
						|
{
 | 
						|
  const int stop = cmd.Find(" HTTP");
 | 
						|
	wxString str = cmd.Mid(4, stop-4).Trim();
 | 
						|
 | 
						|
	if (str == "/")
 | 
						|
		str += "index.htm";
 | 
						|
	wxString strFilename = GetDocumentRoot() + str;
 | 
						|
 | 
						|
	if (IsMagicName(strFilename))
 | 
						|
		GenerateFile(strFilename); else
 | 
						|
 	if (IsCgiName(strFilename))
 | 
						|
	  CallCgi(strFilename);
 | 
						|
 | 
						|
	SendFile(strFilename, outs);
 | 
						|
}
 | 
						|
 | 
						|
void TDictionaryServer::ProcessFormUpdateEntry(wxString& strFileName, 
 | 
						|
																							 THashTable& hashArgs)
 | 
						|
{
 | 
						|
	const wxString key = hashArgs.Get("Entry");
 | 
						|
	size_t nEntry = FindIndex(key);
 | 
						|
	const wxString strValue = hashArgs.Get("Trans");
 | 
						|
	m_DevotoOli.UpdateEntry(nEntry, strValue);
 | 
						|
 | 
						|
	TXmlItem html; 
 | 
						|
	TXmlItem& body = CreatePageBody(html).AddChild("center");
 | 
						|
	body.AddChild("h2") << "Entry updated!";
 | 
						|
	body.AddChild("br");
 | 
						|
 | 
						|
	strFileName = "dictionary?";
 | 
						|
	strFileName << key[0];
 | 
						|
  AddLinkButton(body, "Return to Dictionary", strFileName);
 | 
						|
 | 
						|
	strFileName = GetTempFilename();
 | 
						|
  html.Save(strFileName);
 | 
						|
}
 | 
						|
 | 
						|
void TDictionaryServer::ProcessFormTranslate(wxString& strFileName, 
 | 
						|
																						 THashTable& hashArgs)
 | 
						|
{
 | 
						|
	const wxString strValue = hashArgs.Get("Sentence");
 | 
						|
 | 
						|
	TXmlItem html; 
 | 
						|
	TXmlItem& body = CreatePageBody(html).AddChild("center");
 | 
						|
	body.AddChild("h3") << "Input the text to be translated:";
 | 
						|
 | 
						|
	TXmlItem& form = body.AddChild("form");
 | 
						|
	form.SetAttr("method", "post");
 | 
						|
	form.SetAttr("action", "Translate.cgi");
 | 
						|
 | 
						|
	TXmlItem& ita = form.AddChild("textarea");
 | 
						|
	ita.SetAttr("name", "Sentence"); 
 | 
						|
	ita.SetAttr("cols", "80"); ita.SetAttr("rows", "3");
 | 
						|
	ita << strValue;
 | 
						|
 | 
						|
	form.AddChild("h3") << "Translated text:";
 | 
						|
 | 
						|
	const wxString strTrans = m_DevotoOli.Translate(strValue);
 | 
						|
	if (strTrans == strValue)
 | 
						|
	{
 | 
						|
	  form.AddChild("p") << "Couldn't find a good translation for your text!";
 | 
						|
	}
 | 
						|
  else
 | 
						|
	{
 | 
						|
  	TXmlItem& eng = form.AddChild("textarea");
 | 
						|
	  eng.SetAttr("cols", "80"); eng.SetAttr("rows", "3");
 | 
						|
	  eng << strTrans;
 | 
						|
	}
 | 
						|
 | 
						|
	form.AddChild("br");
 | 
						|
	form.AddChild("br");
 | 
						|
 | 
						|
	TXmlItem& sub = form.AddChild("input");
 | 
						|
	sub.SetAttr("type", "submit"); 
 | 
						|
	sub.SetAttr("value", "Translate");
 | 
						|
 | 
						|
	body.AddChild("br");
 | 
						|
	AddLinkButton(body, "Return to main page", "/");
 | 
						|
 | 
						|
  strFileName = GetTempFilename();
 | 
						|
	html.Save(strFileName);
 | 
						|
}
 | 
						|
 | 
						|
void TDictionaryServer::ProcessFormCommand(wxString cmd, wxSocketBase& outs)
 | 
						|
{
 | 
						|
  const int stop = cmd.Find(" HTTP");
 | 
						|
	wxString strFileName = cmd.Mid(5, stop-5).Trim();
 | 
						|
 | 
						|
	wxString strName, args;
 | 
						|
	wxSplitPath(strFileName, NULL, &strName, NULL);
 | 
						|
 | 
						|
	const int pos = cmd.Find("\r\n\r\n");
 | 
						|
	if (pos > 0)
 | 
						|
	  args = cmd.Mid(pos+4);
 | 
						|
 | 
						|
	THashTable hashArgs(13);
 | 
						|
  ParseArguments(args, hashArgs);
 | 
						|
 | 
						|
  strFileName = GetTempFilename();
 | 
						|
 | 
						|
	if (strName == "UpdateEntry")
 | 
						|
		ProcessFormUpdateEntry(strFileName, hashArgs); else
 | 
						|
	if (strName == "Translate")
 | 
						|
		ProcessFormTranslate(strFileName, hashArgs);
 | 
						|
 | 
						|
	SendFile(strFileName, outs);
 | 
						|
}
 | 
						|
 | 
						|
void TDictionaryServer::ProcessCommand(wxString cmd, wxSocketBase& outs)
 | 
						|
{
 | 
						|
  if (cmd.StartsWith("POST "))
 | 
						|
	{
 | 
						|
    if (cmd.Find("SOAPAction") > 0)
 | 
						|
			ProcessSoapCommand(cmd, outs);
 | 
						|
		else
 | 
						|
      ProcessFormCommand(cmd, outs);
 | 
						|
	} else
 | 
						|
  if (cmd.StartsWith("GET "))
 | 
						|
		ProcessHttpGet(cmd, outs);
 | 
						|
}
 | 
						|
 | 
						|
bool TDictionaryServer::Initialization()
 | 
						|
{
 | 
						|
  return m_DevotoOli.LoadIfEmpty();
 | 
						|
}
 | 
						|
 | 
						|
bool TDictionaryServer::Deinitialization()
 | 
						|
{
 | 
						|
  m_DevotoOli.SaveIfNeeded();
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
TDictionaryServer::TDictionaryServer()
 | 
						|
{ 
 | 
						|
  m_DevotoOli.SetApp(this);
 | 
						|
}
 | 
						|
 | 
						|
// Istanziare l'applicazione principale
 | 
						|
 | 
						|
IMPLEMENT_APP(TDictionaryServer)
 |