campo-sirio/omnia/Omnia0.cpp
guy c95157e55e Patch level : 2.0
Files correlati     : Omnia0.exe
Ricompilazione Demo : [ ]
Commento            :

Prima versione del traduttore universale


git-svn-id: svn://10.65.10.50/trunk@11690 c028cbd2-c16b-5b4b-a496-9718f37d4682
2004-01-08 15:08:43 +00:00

240 lines
5.3 KiB
C++
Executable File

#include <windows.h>
#include <fstream.h>
#include "utility.h"
#include "xml.h"
class TLettore : public TObject
{
TXmlItem _trc;
int _lines, _chars;
TString _rseparator, _fseparator;
TString_array _curr;
protected:
bool load_trc(const char* trc);
char* get_line_buffer(int i, int size);
bool read_record(istream& input);
const TString& get_field(const TXmlItem& field) const;
const TXmlItem* find_field(const TXmlItem& record, const TString& name) const;
void evaluate(const TString& expr, const TXmlItem& recin, TString& val) const;
void smart_trim(TString& val, int mode) const;
public:
int convert(const TFilename& src, const TFilename& trc, const TFilename& dst);
int convert(const char* cmd);
};
bool TLettore::load_trc(const char* t)
{
const TFilename trc = t;
bool ok = trc.exist();
if (ok)
{
ifstream in(trc);
ok = _trc.Read(in);
}
_curr.destroy(); // reset line sizes
return ok;
}
char* TLettore::get_line_buffer(int i, int size)
{
TToken_string* str = (TToken_string*)_curr.objptr(i);
if (str == NULL)
{
str = new TToken_string(size);
_curr.add(str, i);
}
char* buff = str->get_buffer(size);
*buff = '\0';
return buff;
}
bool TLettore::read_record(istream& input)
{
bool ok = true;
if (_lines <= 1 && _chars > 0) // Record a lunghezza fissa
{
char* buff = get_line_buffer(0, _chars);
input.read(buff, _chars);
buff[_chars] = '\0';
}
else
{
int size = _chars;
if (size <= 0)
size = 1024;
for (int i = 0; i < _lines; i++)
{
char* buff = get_line_buffer(i, size);
input.getline(buff, size);
buff[size] = '\0';
}
}
return ok;
}
const TString& TLettore::get_field(const TXmlItem& field) const
{
int y = field.GetIntAttr("Y" ) - 1;
if (y < 0) y = 0;
int x = field.GetIntAttr("X" ) - 1;
if (x < 0) x = 0;
int l = field.GetIntAttr("Length");
const TString& str = _curr.row(y).mid(x, l);
return str;
}
void TLettore::smart_trim(TString& val, int mode) const
{
switch (mode)
{
case 1: val.rtrim(); break;
case 2: val.ltrim(); break;
case 3: val.trim(); break;
default: break;
}
}
const TXmlItem* TLettore::find_field(const TXmlItem& record, const TString& name) const
{
for (int i = 0; i < record.GetChildren(); i++)
{
const TXmlItem* field = record.GetChild(i);
if (field->GetAttr("Name") == name)
return field;
}
return NULL;
}
void TLettore::evaluate(const TString& expr, const TXmlItem& recin, TString& val) const
{
TToken_string expression(expr, '+');
val.cut(0);
TString str;
FOR_EACH_TOKEN(expression, tok)
{
str = tok; str.trim();
if (str[0] == '\'' || str[0] == '"')
{
str.rtrim(1); str.ltrim(1);
val << str;
}
else
{
bool trim = false;
if (str.starts_with("TRIM("))
{
str.ltrim(5); str.rtrim(1);
str.trim();
trim = true;
}
const TXmlItem* infield = find_field(recin, str);
if (infield != NULL)
{
str = get_field(*infield);
if (trim)
str.trim();
val << str;
}
}
}
}
int TLettore::convert(const TFilename& src, const TFilename& trc, const TFilename& dst)
{
if (!src.exist())
{
error_box("Non esiste il file di input\n%s", (const char*)src);
return 1;
}
if (!load_trc(trc))
{
error_box("Non esiste il tracciato record\n%s", (const char*)trc);
return 2;
}
if (dst.blank())
{
error_box("File di output non valido:\n%s", (const char*)dst);
return 3;
}
const TXmlItem* infile = _trc.FindFirst("Input");
const TXmlItem* outfile = _trc.FindFirst("Output");
if (infile == NULL || outfile == NULL)
{
error_box("Tracciato record non valido:\nNon esiste il tag <Input> o <Output>");
return 4;
}
const TXmlItem* recin = infile->FindFirst("Record");
const TXmlItem* recout = outfile->FindFirst("Record");
if (recin == NULL || recout == NULL)
{
error_box("Tracciato record non valido:\nNon esiste il tag <Record>");
return 4;
}
_lines = recin->GetIntAttr("Lines");
if (_lines <= 0)
_lines = 1;
_chars = recin->GetIntAttr("Chars");
_rseparator = esc(outfile->GetAttr("RecordSeparator"));
_fseparator = esc(recout->GetAttr("FieldSeparator"));
const int inmode = infile->GetIntAttr("Binary") != 0 ? (ios::in|ios::binary) : ios::in;
ifstream input(src, inmode);
const int outmode = outfile->GetIntAttr("Binary") != 0 ? (ios::out|ios::binary) : ios::out;
ofstream output(dst, outmode);
TString expr, val;
while (!input.eof())
{
read_record(input);
for (int i = 0; i < recout->GetChildren(); i++)
{
const TXmlItem* outfield = recout->GetChild(i);
outfield->GetEnclosedText(expr);
if (expr.empty())
expr = outfield->GetAttr("Name");
evaluate(expr, *recin, val);
smart_trim(val, outfield->GetIntAttr("Trim"));
if (i > 0)
output << _fseparator;
output << val;
}
output << _rseparator;
}
return 0;
}
int TLettore::convert(const char* cmd)
{
TToken_string str(cmd, ' ');
str.strip_d_spaces();
const TFilename src = str.get();
const TFilename trc = str.get();
const TFilename dst = str.get();
return convert(src, trc, dst);
}
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR lpCmdLine, int)
{
TLettore app;
const int err = app.convert(lpCmdLine);
return err;
}