campo-sirio/omnia/Omnia0.cpp
guy 05314c3ac4 Patch level : 2.0 nopatch
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
Prime correzioni Omnia0


git-svn-id: svn://10.65.10.50/trunk@11731 c028cbd2-c16b-5b4b-a496-9718f37d4682
2004-01-29 15:09:07 +00:00

433 lines
10 KiB
C++
Executable File

#include <windows.h>
#include <fstream.h>
#include "expr.h"
#include "utility.h"
#include "xml.h"
///////////////////////////////////////////////////////////
// TTextRecord
///////////////////////////////////////////////////////////
class TTextRecord : public TString_array
{
const TXmlItem* m_trc;
const TXmlItem* m_inrec;
int m_nLines, m_nColumns;
TString m_str;
protected:
char* GetLineBuffer(int i, int size);
const TString& GetFieldValue(const TXmlItem& field) const;
const TXmlItem* FindField(const TString& name) const;
public:
void SetTrc(const TXmlItem& trc);
bool Read(istream& input);
const TString& GetValue(const TString& name) const;
const TString& Evaluate(TExpression& exp) const;
TTextRecord() : m_trc(NULL), m_nLines(0), m_nColumns(0) { }
TTextRecord(const TXmlItem& trc) : m_trc(&trc) { }
};
void TTextRecord::SetTrc(const TXmlItem& trc)
{
m_trc = &trc;
m_nLines = trc.GetIntAttr("Lines");
if (m_nLines <= 0)
m_nLines = 1;
m_nColumns = trc.GetIntAttr("Columns");
m_inrec = trc.FindFirst("Record");
CHECK(m_inrec, "Null input record");
}
char* TTextRecord::GetLineBuffer(int i, int size)
{
CHECKD(i >= 0 && i < m_nLines, "Line out of range ", i);
CHECKD(size > 0, "Bad record size ", size);
TToken_string* str = (TToken_string*)objptr(i);
if (str == NULL)
{
str = new TToken_string(size);
add(str, i);
}
char* buff = str->get_buffer(size);
*buff = '\0';
return buff;
}
bool TTextRecord::Read(istream& input)
{
bool ok = true;
if (m_nLines <= 1 && m_nColumns > 0) // Record a lunghezza fissa
{
char* buff = GetLineBuffer(0, m_nColumns);
input.read(buff, m_nColumns);
buff[m_nColumns] = '\0';
}
else
{
int size = m_nColumns;
if (size <= 0)
size = 1024*16;
for (int i = 0; i < m_nLines; i++)
{
char* buff = GetLineBuffer(i, size);
input.getline(buff, size);
buff[size] = '\0';
}
}
return ok;
}
const TString& TTextRecord::GetFieldValue(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;
const int l = field.GetIntAttr("Length");
TString& str = (TString&)m_str;
str = row(y).mid(x, l);
const TString& strTrim = field.GetAttr("Trim");
int nTrim = 2;
if (strTrim.not_empty())
nTrim = atoi(strTrim);
switch (nTrim)
{
case 0: break;
case 1: str.ltrim(); break;
case 2: str.rtrim(); break;
default: str.trim(); break;
}
return str;
}
const TXmlItem* TTextRecord::FindField(const TString& name) const
{
for (int i = 0; i < m_inrec->GetChildren(); i++)
{
const TXmlItem* field = m_inrec->GetChild(i);
if (field->GetAttr("Name") == name)
return field;
}
return NULL;
}
const TString& TTextRecord::GetValue(const TString& name) const
{
const TXmlItem* f = FindField(name);
if (f != NULL)
return GetFieldValue(*f);
return EMPTY_STRING;
}
const TString& TTextRecord::Evaluate(TExpression& exp) const
{
for (int i = exp.numvar()-1; i >= 0; i--)
{
const TString& name = exp.varname(i);
const TString& value = GetValue(name);
exp.setvar(i, value);
}
return exp.as_string();
}
///////////////////////////////////////////////////////////
// TScrittore
///////////////////////////////////////////////////////////
class TScrittore : public TObject
{
private:
ofstream* _out;
public:
ofstream& OutStream() { return *_out; }
TScrittore(const char* name) { _out = new ofstream(name); }
virtual~ TScrittore() { delete _out; }
};
///////////////////////////////////////////////////////////
// TCasaEditrice
///////////////////////////////////////////////////////////
class TCasaEditrice : public TAssoc_array
{
const TXmlItem& m_trc;
TString m_strPrefix, m_strExt;
TExpression* m_exprSuffix;
TString m_strRecHead, m_strRecFoot, m_strFldHead, m_strFldFoot;
protected:
ofstream& OutStream(const char* suffix);
void WriteHeader(ostream& output) const;
void WriteFooter(ostream& output) const;
public:
const TString& RecHead() const { return m_strRecHead; }
const TString& RecFoot() const { return m_strRecFoot; }
const TString& FldHead() const { return m_strFldHead; }
const TString& FldFoot() const { return m_strFldFoot; }
ofstream& ChooseOutput(const TTextRecord& rec);
TCasaEditrice(const TXmlItem& trc, const char* name);
virtual ~TCasaEditrice();
};
void TCasaEditrice::WriteHeader(ostream& output) const
{
TXmlItem* pOutput = m_trc.FindFirst("Output");
CHECK(pOutput, "NULL output file");
TXmlItem* pHeader = pOutput->FindFirst("Header");
if (pHeader != NULL)
{
TString strHeader; pHeader->GetEnclosedText(strHeader);
if (strHeader[0] == '"')
{
strHeader.rtrim(1);
strHeader.ltrim(1);
}
strHeader = esc(strHeader);
output << strHeader;
if (pHeader->GetAttr("Auto") == "1")
{
TXmlItem* pRecOut = pOutput->FindFirst("Record");
CHECK(pRecOut, "NULL output record");
output << m_strRecHead;
for (int i = 0; i < pRecOut->GetChildren(); i++)
{
const TXmlItem* outfield = pRecOut->GetChild(i);
output << m_strFldHead;
output << outfield->GetAttr("Name");
output << m_strFldFoot;
}
output << m_strRecFoot;
}
}
}
void TCasaEditrice::WriteFooter(ostream& output) const
{
TXmlItem* pOutput = m_trc.FindFirst("Output");
CHECK(pOutput, "NULL output file");
TXmlItem* pFooter = pOutput->FindFirst("Footer");
if (pFooter != NULL)
{
TString strFooter; pFooter->GetEnclosedText(strFooter);
if (strFooter[0] == '"')
{
strFooter.rtrim(1);
strFooter.ltrim(1);
}
strFooter = esc(strFooter);
output << strFooter;
}
}
ofstream& TCasaEditrice::OutStream(const char* suffix)
{
TScrittore* s = (TScrittore*)objptr(suffix);
if (s == NULL)
{
TFilename n;
n << m_strPrefix << suffix;
if (m_strExt.not_empty())
n << '.' << m_strExt;
s = new TScrittore(n);
add(suffix, s);
WriteHeader(s->OutStream());
}
return s->OutStream();
}
ofstream& TCasaEditrice::ChooseOutput(const TTextRecord& rec)
{
TString16 strSuffix;
if (m_exprSuffix != NULL)
strSuffix = rec.Evaluate(*m_exprSuffix);
return OutStream(strSuffix);
}
TCasaEditrice::TCasaEditrice(const TXmlItem& trc, const char* name) : m_trc(trc), m_exprSuffix(NULL)
{
const TFilename path(name);
m_strExt = path.ext();
m_strPrefix = path.name();
const int dot = m_strPrefix.find('.');
if (dot >= 0)
m_strPrefix.cut(dot);
const TXmlItem* pOutFile = m_trc.FindFirst("Output");
CHECK(pOutFile, "NULL Output tag");
const TString strSuffix = pOutFile->GetAttr("Suffix");
if (strSuffix.not_empty())
m_exprSuffix = new TExpression(strSuffix, _strexpr);
TXmlItem* pRecOut = pOutFile->FindFirst("Record");
CHECK(pRecOut, "NULL output record");
m_strRecHead = esc(pRecOut->GetAttr("RecHead"));
m_strRecFoot = esc(pRecOut->GetAttr("RecFoot"));
m_strFldHead = esc(pRecOut->GetAttr("FldHead"));
m_strFldFoot = esc(pRecOut->GetAttr("FldFoot"));
}
TCasaEditrice::~TCasaEditrice()
{
TAssoc_array& myself = *this;
FOR_EACH_ASSOC_OBJECT(myself, h, k, o)
{
TScrittore* s = (TScrittore*)o;
WriteFooter(s->OutStream());
}
}
///////////////////////////////////////////////////////////
// TLettore
///////////////////////////////////////////////////////////
class TLettore : public TObject
{
TXmlItem _trc;
TTextRecord _curr;
TArray _expressions;
protected:
bool load_trc(const char* trc);
const TString& get_field(const TXmlItem& field) const;
const TXmlItem* find_field(const TXmlItem& record, const TString& name) const;
const TString& evaluate(int index) 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;
}
const TString& TLettore::evaluate(int index) const
{
TExpression& exp = (TExpression&)_expressions[index];
return _curr.Evaluate(exp);
}
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;
}
_curr.SetTrc(*infile);
const int inmode = infile->GetIntAttr("Binary") != 0 ? (ios::in|ios::binary) : ios::in;
ifstream input(src, inmode);
TCasaEditrice mondadori(_trc, dst);
TString expr;
for (int i = 0; i < recout->GetChildren(); i++)
{
const TXmlItem* outfield = recout->GetChild(i);
outfield->GetEnclosedText(expr);
_expressions.add(new TExpression(expr, _strexpr));
}
while (!input.eof())
{
_curr.Read(input);
ofstream& output = mondadori.ChooseOutput(_curr);
output << mondadori.RecHead();
for (int i = 0; i < recout->GetChildren(); i++)
{
const TXmlItem* outfield = recout->GetChild(i);
outfield->GetEnclosedText(expr);
const TString& val = evaluate(i);
output << mondadori.FldHead() << val << mondadori.FldFoot();
}
output << mondadori.RecFoot();
}
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;
}