campo-sirio/server/diction.cpp

223 lines
4.8 KiB
C++
Raw Normal View History

#include <wx/wx.h>
#include <wx/wfstream.h>
#include <wx/socket.h>
#include <wx/config.h>
#include <wx/msw/iniconf.h>
#include <ctype.h>
#include "Soap.h"
#include "Diction.h"
//////////////////////////////////////////////////////////
// TDictionaryEntry
///////////////////////////////////////////////////////////
class TDictionaryEntry : public wxObject
{
public:
wxString m_str;
TDictionaryEntry(const wxChar* str) : m_str(str) { }
};
//////////////////////////////////////////////////////////
// Sorted array of TDictionaryEntry
///////////////////////////////////////////////////////////
static int CompareNodes(wxNode** n1, wxNode** n2)
{
return strcmp((*n1)->GetKeyString(), (*n2)->GetKeyString());
}
WX_DEFINE_ARRAY(wxNode*, TArrayOfNodes);
//////////////////////////////////////////////////////////
// TDictionary
///////////////////////////////////////////////////////////
class TDictionary : public wxHashTable
{
bool m_bDirty;
protected:
wxString Accentuate(const wxString& str) const;
const TDictionaryEntry* AddEntry(const wxString& ita, const wxChar* eng);
wxString GetFileName() const;
static bool FillCallback(TXmlItem& item, long jolly);
bool Load();
public:
wxString Translate(const wxString& ita, const wxString& lan);
TDictionary();
~TDictionary();
};
static TDictionary DevotoOli;
wxString TDictionary::GetFileName() const
{
wxIniConfig ini("", "", "./server.ini");
ini.SetPath("/Dictionary");
wxString fname = ini.Read("FileName", "campo.dic");
return fname;
}
wxString TDictionary::Accentuate(const wxString& str) const
{
const int pos = str.Find('\'');
if (pos <= 0)
return str;
wxString bello = str.Left(pos);
for (size_t a = pos; str[a]; a++)
{
if (str[a] == '\'')
{
if ((isspace(str[a+1]) || str[a+1] == '\0') &&
strchr("aeiou", str[a-1]))
{
switch(str[a-1])
{
case 'a':
bello[a-1] = '<EFBFBD>'; break;
case 'e':
if (a >= 2 && (isspace(str[a-2]) || str[a-2] == '\''))
bello[a-1] = '<EFBFBD>';
else
bello[a-1] = '<EFBFBD>';
break;
case 'i':
bello[a-1] = '<EFBFBD>'; break;
case 'o':
bello[a-1] = '<EFBFBD>'; break;
case 'u':
bello[a-1] = '<EFBFBD>'; break;
default:
break;
}
}
else
bello << str[a];
}
else
bello << str[a];
}
return bello;
}
const TDictionaryEntry* TDictionary::AddEntry(const wxString& ita, const wxChar* eng)
{
const wxString key = Accentuate(ita);
TDictionaryEntry* entry = new TDictionaryEntry(eng);
Put(key, entry);
m_bDirty = true;
return entry;
}
wxSocketClient& operator<<(wxSocketClient& sock, const wxChar* str)
{
if (str && *str)
sock.Write(str, wxStrlen(str));
return sock;
}
bool TDictionary::FillCallback(TXmlItem& item, long jolly)
{
if (item.GetTag() == "entry")
{
const TXmlItem* ita = item.GetChild(0);
const TXmlItem* eng = item.GetChild(1);
if (ita != NULL && eng != NULL)
{
ita = ita->GetChild(0);
eng = eng->GetChild(0);
if (ita != NULL && eng != NULL)
{
TDictionary* d = (TDictionary*)jolly;
d->AddEntry(ita->GetText(), eng->GetText());
}
}
}
return false;
}
bool TDictionary::Load()
{
wxFileInputStream inf(GetFileName());
if (inf.Ok())
{
TXmlItem item;
item.Read(inf);
item.ForEach(FillCallback, (long)this);
}
m_bDirty = false; // No last minute additions :-)
return GetCount() > 0;
}
wxString TDictionary::Translate(const wxString& ita, const wxString& lan)
{
if (GetCount() == 0)
Load();
const wxString key = Accentuate(ita);
TDictionaryEntry* eng = (TDictionaryEntry*)Get(key);
if (eng != NULL)
{
if (eng->m_str != "???")
return eng->m_str;
}
else
AddEntry(ita, "???");
return key;
}
TDictionary::TDictionary() : wxHashTable(wxKEY_STRING, 883), m_bDirty(false)
{ }
TDictionary::~TDictionary()
{
DeleteContents(true);
if (m_bDirty)
{
// Fill an array of nodes and sort them out
TArrayOfNodes arr;
BeginFind();
for (wxNode* pNode = Next(); pNode != NULL; pNode = Next())
arr.Add(pNode);
arr.Sort(CompareNodes);
wxFileOutputStream outf(GetFileName());
outf << "<xml><dictionary>\n";
for (size_t i = 0; i < arr.GetCount(); i++)
{
const wxNode* pNode = arr[i];
outf << " <entry>\n";
outf << " <ita>" << pNode->GetKeyString() << "</ita>\n";
outf << " <eng>" << ((TDictionaryEntry*)pNode->GetData())->m_str << "</eng>\n";
outf << " </entry>\n";
}
outf << "</dictionary></xml>\n";
}
}
bool DoTranslate(const TXmlItem& xmlMethod, TXmlItem& xmlAnswer)
{
const TXmlItem* xmlSentence = xmlMethod.FindFirst("sentence");
// const TXmlItem* xmlLanguage = xmlMethod.FindFirst("language");
if (xmlSentence != NULL /* && xmlLanguage != NULL */)
{
const wxString ita = xmlSentence->GetEnclosedText();
const wxString lan; // = xmlLanguage->GetEnclosedText();
wxString result = DevotoOli.Translate(ita, lan);
xmlAnswer.AddSoapString("sentence", result);
return true;
}
return false;
}