729 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			729 lines
		
	
	
		
			18 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)
 | |
| {
 | |
|   wxString tmp;
 | |
|   for (int i = 0; str[i]; i++)
 | |
|   {
 | |
|     if (str[i] == '&' && str[i+1] == '#')
 | |
|     {
 | |
|       i += 2;
 | |
|       const int semicolon = FindChar(str, ';', i);
 | |
|       if (semicolon > i)
 | |
|       {
 | |
|         int n;
 | |
|         sscanf(str.Mid(i, semicolon-i), "%X", &n);
 | |
|         tmp << char(n & 0xFF);
 | |
|         i = semicolon;
 | |
|       }
 | |
|       else
 | |
|         tmp << str[i] << str[i+1];
 | |
|     }
 | |
|     else
 | |
|       tmp << str[i];
 | |
|   }
 | |
|   return tmp;
 | |
| }
 | |
| 
 | |
| 
 | |
| //////////////////////////////////////////////////////////
 | |
| // TDictionary
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| WX_DECLARE_STRING_HASH_MAP( wxString, TStringHashTable );
 | |
| 
 | |
| class TDictionary : public TStringHashTable
 | |
| {
 | |
| 	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); 
 | |
| 
 | |
| 	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);
 | |
| 
 | |
|   void UpdateEntry(size_t i, const wxString& strValue);
 | |
| 
 | |
|   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 wxString& eng = operator[](ita);
 | |
| 		WriteXmlString(outf, eng);
 | |
| 		outf << "</eng>" << 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)
 | |
| {
 | |
|   operator[](ita) = eng;
 | |
|   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];
 | |
| 	  operator[](ita) = strValue;
 | |
| 		Save();
 | |
| 	}
 | |
| }
 | |
| 
 | |
| wxString TDictionary::OriginalEntry(size_t i)
 | |
| {
 | |
| 	return m_sorted[i];
 | |
| }
 | |
| 
 | |
| wxString TDictionary::TranslatedEntry(size_t i)
 | |
| {
 | |
|   const wxString& ita = m_sorted[i];
 | |
|   return operator[](ita);
 | |
| }
 | |
| 
 | |
| 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, line;
 | |
|   while (!scan.Eof())
 | |
|   {
 | |
|     scan >> line;
 | |
|     line.Trim(false);
 | |
|     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>");
 | |
|       const wxString eng = xml2txt(line.Mid(5, eoe-5));
 | |
|       AddEntry(ita, eng);
 | |
|     }
 | |
|   }
 | |
|   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 wxString& eng = i->second;
 | |
| 	  if (eng != "???")
 | |
| 		{
 | |
| 			body = prefix;
 | |
| 			body += eng;
 | |
| 			body += postfix;
 | |
| 		  return body;
 | |
| 		}
 | |
| 	}
 | |
|   else
 | |
| 	  AddEntry(ita, "???");
 | |
| 	
 | |
| 	return ita;
 | |
| }
 | |
| 
 | |
| TDictionary::TDictionary() : TStringHashTable(10000), 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;
 | |
|   void GenerateIndex(TXmlItem& body);
 | |
| 	void GenerateFile(wxString& strFilename);
 | |
| 
 | |
| 	virtual bool Initialization();
 | |
|   virtual bool Deinitialization();
 | |
| };
 | |
| 
 | |
| 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
 | |
| {
 | |
| 	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; 
 | |
| }
 | |
| 
 | |
| 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";
 | |
| 
 | |
| 		for (size_t i = 0; i < m_DevotoOli.size(); i++)
 | |
| 		{
 | |
| 			const wxString& orig = m_DevotoOli.OriginalEntry(i);
 | |
| 			if (toupper(orig[0]) == cFilter)
 | |
| 			  AddEditableRow(table, orig, m_DevotoOli.TranslatedEntry(i));
 | |
| 		}
 | |
| 		
 | |
| 		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);
 | |
| 
 | |
| 			body.AddChild("h2") << "Edit Entry " << strArgs;
 | |
| 
 | |
| 			TXmlItem& form = body.AddChild("form");
 | |
| 			form.SetAttr("method", "post");
 | |
| 			form.SetAttr("action", "UpdateEntry.cgi");
 | |
| 
 | |
| 			form.AddChild("h3") << "Original text:";
 | |
| 			TXmlItem& ita = form.AddChild("textarea");
 | |
| 			ita.SetAttr("cols", "80"); ita.SetAttr("rows", "4");
 | |
| 			ita << m_DevotoOli.OriginalEntry(i);
 | |
|       
 | |
| 			form.AddChild("br");
 | |
| 			form.AddChild("h3") << "Translated text:";
 | |
| 				
 | |
| 			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 << m_DevotoOli.TranslatedEntry(i);
 | |
| 
 | |
| 			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;
 | |
| }
 | |
| 
 | |
| // Istanziare l'applicazione principale
 | |
| 
 | |
| IMPLEMENT_APP(TDictionaryServer)
 |