Separati in due fasi la formattazione dei campi e dei records

git-svn-id: svn://10.65.10.50/trunk@5315 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
sauro 1997-10-02 07:50:13 +00:00
parent dc383cc028
commit e5614d3ef3
3 changed files with 242 additions and 163 deletions

View File

@ -23,6 +23,7 @@ void TTracciato_campo::copy(const TTracciato_campo& tc)
set_name(tc._name);
set_type(tc._type);
set_field(tc._field);
set_ftype(tc._ftype);
set_position(tc._position);
set_length(tc._length);
set_decimal(tc._decimal);
@ -31,6 +32,38 @@ void TTracciato_campo::copy(const TTracciato_campo& tc)
set_picture(tc._picture);
set_message(tc._message);
}
const int TFile_text::fdecimal(const TTracciato_campo &tc ) const
{
if (tc.ftype().empty())
return tc.decimal();
else
return ((TTracciato_campo &)_tipi[tc.ftype()]).decimal();
}
const char TFile_text::falign(const TTracciato_campo &tc ) const
{
if (tc.ftype().empty())
return tc.align();
else
return ((TTracciato_campo &)_tipi[tc.ftype()]).align();
}
const char TFile_text::ffiller(const TTracciato_campo &tc ) const
{
if (tc.ftype().empty())
return tc.filler();
else
return ((TTracciato_campo &)_tipi[tc.ftype()]).filler();
}
const TString& TFile_text::fpicture(const TTracciato_campo &tc ) const
{
if (tc.ftype().empty())
return tc.picture();
else
return ((TTracciato_campo &)_tipi[tc.ftype()]).picture();
}
//////////////////////////////////////// TTracciato_record ////////////////////////////////////////
TObject* TTracciato_record::dup() const
{
@ -104,7 +137,7 @@ void TFile_text::set_gen_parm(TConfig& config, const TString& section)
if (_recordsize <= 0 && (_recordsep.empty())) // separatore di record standard
_recordsep = "\r\n";
_typefield = config.get_int("TYPEFIELD",section); // Numero del campo tipo (puo' essere -1)
_fixedlen = _fieldsep <= ' ' && _recordsep.blank();
_fixedlen = _fieldsep <= ' '; // && _recordsep.blank();
_typepos = -1;
_typelen = -1;
}
@ -130,10 +163,10 @@ void TFile_text::set_type_parm(TConfig& config, TString& section)
void TFile_text::set_rec_parm(TConfig& config, const char* section)
{
TString comodo = section;
comodo.ltrim(6);//elimino la parola 'RECORD' o 'HEADER' o 'FOOTER' e gli spazi vuoti
comodo.trim();//per avere solo il nome del tipo del record
TTracciato_record tr(comodo);//istanzio un tracciato_record del tipo corrente
TString sectkey = section;
sectkey.ltrim(6);//elimino la parola 'RECORD' o 'HEADER' o 'FOOTER' e gli spazi vuoti
sectkey.trim();//per avere solo il nome del tipo del record
TTracciato_record tr(sectkey);//istanzio un tracciato_record del tipo corrente
//setto tutti i dati relatvi ai tipi predefini nei tracciati campo per i diversi campi del record
config.set_paragraph(section);
TString lavoro;
@ -153,13 +186,13 @@ void TFile_text::set_rec_parm(TConfig& config, const char* section)
if (config.exist("TYPE", n))
{
TString tipo = config.get("TYPE", section, n);
if (!tipo.empty())
{
TTracciato_campo& tc = (TTracciato_campo&)_tipi[tipo];
tr.add(tc, n);
}
}
indici.set(n);
if (!tipo.empty())
{
TTracciato_campo& tc = (TTracciato_campo&)_tipi[tipo];
tr.add(tc, n);
}
}
indici.set(n);
}
TTracciato_campo& tc = tr.get(n);//prendo il tracciato campo con indice <n>
if (lavoro == "NAM")
@ -174,6 +207,12 @@ void TFile_text::set_rec_parm(TConfig& config, const char* section)
tc.set_field(field);
continue;
}
if (lavoro == "FTY") // field type
{
CHECKS(_tipi.objptr(obj)!=NULL,"Riferimento a campo inesistente:%s",obj);
tc.set_ftype(obj);
continue;
}
if (lavoro == "POS")
{
int pos = atoi(obj);
@ -228,7 +267,7 @@ void TFile_text::set_rec_parm(TConfig& config, const char* section)
}
}
//aggiungo il tracciato record all'assoc_array dei tracciati record
_tracciati_record.add(comodo, tr);
_tracciati_record.add(sectkey, tr);
}
TFile_text::TFile_text(const char* file_name, const char* config_name)
@ -250,7 +289,12 @@ TFile_text::TFile_text(const char* file_name, const char* config_name)
set_gen_parm(config,section);
continue;
}
if (sec == "TYP")
if (sec == "TYP")
{
set_type_parm(config, section);
continue;
}
if (sec == "FTY") // field type
{
set_type_parm(config, section);
continue;
@ -271,6 +315,76 @@ TFile_text::~TFile_text()
delete _write_file;
}
//Legge da file il record text
int TFile_text::read(TRecord_text& rec)
{
CHECK(_read_file, "Impossibile leggere da un file chiuso.");
TToken_string buffer(_recordsize), lavoro;
if (_recordsize>0)
{
buffer.cut(0);
_read_file->read(buffer.get_buffer(),buffer.size());
if (!ok_r()) return 1; //non ritorna errore se fine file ed il record e' completo!
}
else
{
//legge carattere per carattere fino a quando non si trova il separatore di record
char c = _read_file->get();
if (c == EOF)
return EOF;
while (c != _recordsep[0])
{
buffer << c;
c = _read_file->get();
if (!ok_r())
return EOF; //non ritorna errore se fine file ed il record e' completo!
}
// prendo il resto del separatore
int l = _recordsep.len()-1;
for (int j = 0; j < l;c = _read_file-> get (), j++);
}
if (_fieldsep > ' ')
{
buffer.separator(_fieldsep);
const char* tipo = _typefield >= 0 ? buffer.get(_typefield) : "";
TTracciato_record& tr = t_rec(tipo);
rec.set_type(tipo);//istanzio il tipo del record text
TArray& a_tc = tr.tracciati_campo();
int items = a_tc.items();
buffer.restart();
for (int i = 0; i < items; i++)
{
// TTracciato_campo& tc = tr.get(i);
lavoro = buffer.get();
rec.add(lavoro, i);
}
}
else
{
TString tipo = buffer.mid(_typepos, _typelen);
tipo.trim();
rec.set_type(tipo);//istanzio il tipo del record text
TTracciato_record& tr = t_rec(tipo);
//ora che ho il tracciato record devo scandire i tracciati campo e caricare il record text
TArray& a_tc = tr.tracciati_campo();
int items = a_tc.items();
for (int i = 0; i < items; i++)
{
TTracciato_campo& tc = tr.get(i);
int pos = tc.position();
int len = tc.length();
lavoro = buffer.mid(pos, len);
rec.add(lavoro, i);
}
}
return 0;
}
//Scrive su file il record_text (valido anche per header e footer)
int TFile_text::write(TRecord_text& rec)
{
@ -284,11 +398,12 @@ int TFile_text::write(TRecord_text& rec)
{
for (int i = 0; i < items; i++)
{
campo = rec.row(i);
TTracciato_campo& tc = tr.get(i);
//buffer.insert(campo, tc.position());
buffer << campo;
campo.cut(0);
TTracciato_campo& tc = tr.get(i);
campo = rec.row(i);
campo = format_textfield(tc, campo);
//buffer.insert(campo, tc.position());
buffer << campo;
campo.cut(0);
}
CHECK(_write_file, "Impossibile scrivere su un file chiuso.");
*_write_file << buffer;
@ -300,7 +415,9 @@ int TFile_text::write(TRecord_text& rec)
TToken_string ts(buffer, _fieldsep);
for (int i = 0; i < items; i++)
{
TTracciato_campo& tc = tr.get(i);
campo = rec.row(i);
campo = format_textfield(tc, campo);
ts.add(campo, i);
campo.cut(0);
}
@ -335,132 +452,13 @@ void TFile_text::autoload(TRecord_text& rec, TCursor& cur , const TString* tipo)
TToken_string msg (message, ',');
if (!msg.blank())
validate(cur, rec, msg, campo);
}
const TRectype& rel_rec = rel.curr(field.file());
TFieldtypes tipo_campo = rel_rec.type(field.name());
/* Guy was here
if (tipo_campo != _datefld && tipo_campo != _realfld && tipo_campo != _intfld && tipo_campo != _longfld && message != "_IMPORTO,!TOT")
campo = format_field(tc, campo);//formatta il campo secondo le specifiche del tracciato
else
{
if (tipo_campo == _datefld)
{
TDate data(campo);
TString s;
format_date(data, tc.picture(), s);//formatta la data secondo le specifiche del tracciato
campo = s ;
}
if (tipo_campo == _realfld || tipo_campo == _intfld || tipo_campo == _longfld)
{
real numero(campo);
campo = numero.string(tc.picture());//formatta il numero secondo le specifiche del tracciato
int length = tc.length();
if (tc.align() == 'R')
campo.right_just(length, tc.filler());
else
campo.left_just(length, tc.filler());
int j = campo.replace('.', _decsep);
CHECK(j >= 0 && j <= 1 , "Impossibile scrivere più separatori decimali.");
}
}
*/
switch(tipo_campo)
{
case _datefld:
{
TDate data(campo);
format_date(data, tc.picture(), campo);//formatta la data secondo le specifiche del tracciato
}
break;
case _realfld:
case _intfld:
case _longfld:
{
real numero(campo);
campo = numero.string(tc.picture());//formatta il numero secondo le specifiche del tracciato
int length = tc.length();
if (tc.align() == 'R')
campo.right_just(length, tc.filler());
else
campo.left_just(length, tc.filler());
int j = campo.replace('.', _decsep);
CHECK(j >= 0 && j <= 1 , "Impossibile scrivere più separatori decimali.");
}
break;
default:
campo = format_field(tc, campo);//formatta il campo secondo le specifiche del tracciato
break;
}
}
rec.add(campo, i);
campo.cut(0);
}
}
//Legge da file il record text
int TFile_text::read(TRecord_text& rec)
{
CHECK(_read_file, "Impossibile leggere da un file chiuso.");
TString buffer(_recordsize), lavoro;
if (_fixedlen)
{
buffer.cut(0);
_read_file->read(buffer.get_buffer(),buffer.size());
if (!ok_r()) return 1; //non ritorna errore se fine file ed il record e' completo!
const TString tipo = buffer.mid(_typepos, _typelen);
rec.set_type(tipo);//istanzio il tipo del record text
TTracciato_record& tr = t_rec(tipo);
//ora che ho il tracciato record devo scandire i tracciati campo e caricare il record text
TArray& a_tc = tr.tracciati_campo();
int items = a_tc.items();
for (int i = 0; i < items; i++)
{
TTracciato_campo& tc = tr.get(i);
int pos = tc.position();
int len = tc.length();
lavoro = buffer.mid(pos, len);
lavoro = format_field(tc, lavoro);
rec.add(lavoro, i);
}
}
else
{
//legge carattere per carattere fino a quando non si trova il separatore di record
char c = _read_file->get();
if (c == EOF)
return EOF;
while (c != _recordsep[0])
{
buffer << c;
c = _read_file->get();
if (!ok_r())
return EOF; //non ritorna errore se fine file ed il record e' completo!
}
// prendo il resto del separatore
int l = _recordsep.len()-1;
for (int j = 0; j < l;c = _read_file-> get (), j++);
TToken_string ts(buffer, _fieldsep);
const char* tipo = _typefield >= 0 ? ts.get(_typefield) : "";
TTracciato_record& tr = t_rec(tipo);
rec.set_type(tipo);//istanzio il tipo del record text
TArray& a_tc = tr.tracciati_campo();
int items = a_tc.items();
ts.restart();
for (int i = 0; i < items; i++)
{
TTracciato_campo& tc = tr.get(i);
lavoro = ts.get();
lavoro = format_field(tc, lavoro);
rec.add(lavoro, i);
}
}
return 0;
}
//Carico la relazione con i dati del record text
int TFile_text::autosave(TRelation& rel, const TRecord_text& rec)
@ -476,8 +474,39 @@ int TFile_text::autosave(TRelation& rel, const TRecord_text& rec)
const TFieldref& field = tc.field();
if (field.name().not_empty())
{
valore = rec.row(i);
field.write(valore, rel);//faccio una write sulla relazione del fieldref
valore = rec.row(i);
// formatta il campo del file di testo secondo le specifiche del campo su file isam
const TRectype& rel_rec = rel.curr(field.file());
TFieldtypes tipo_campo = rel_rec.type(field.name());
switch(tipo_campo)
{
case _datefld:
{
TDate data(valore);
format_date(data, fpicture(tc), valore);//formatta la data secondo le specifiche del tracciato
}
break;
case _realfld:
case _intfld:
case _longfld:
{
real numero(valore);
valore = numero.string(fpicture(tc));//formatta il numero secondo le specifiche del tracciato
int length = rel_rec.length(field.name());
if (falign(tc) == 'R')
valore.right_just(length, ffiller(tc));
else
valore.left_just(length, ffiller(tc));
int j = valore.replace('.', _decsep); //!?!?! consento decsep diversi per isam e text ?
CHECK(j >= 0 && j <= 1 , "Impossibile scrivere più separatori decimali.");
}
break;
default:
valore = format_field(tc, valore);//formatta il campo secondo le specifiche del record
break;
}
field.write(valore, rel);//faccio una write sulla relazione del fieldref
}
}
int err = rel.write();
@ -512,7 +541,7 @@ void TFile_text::add_field(TRecord_text& rec, const int ncampo, const char* val)
TTracciato_record& tr = t_rec(rec.type());
TTracciato_campo& tc = tr.get(ncampo);
TString valore = val;
valore = format_field(tc, valore);
//valore =format_textfield(tc, valore);
rec.add(valore, ncampo);
}
@ -559,14 +588,14 @@ void TFile_text::format_date(const TDate& data, const TString& form, TString& da
}
//Formatta la stringa in base al tracciato
TString& TFile_text::format_field(TTracciato_campo& tc, TString& campo)
TString& TFile_text::format_textfield(const TTracciato_campo& tc, TString& campo)
{
int pos = tc.position();
//int pos = tc.position();
int length = tc.length();
if (!tc.picture().blank())
{ TString tmp;
tmp.picture(tc.picture(), campo);
campo=tmp;
{ TString tmp;
tmp.picture(tc.picture(), campo);
campo=tmp;
}
if (length > campo.len())
{
@ -576,8 +605,38 @@ TString& TFile_text::format_field(TTracciato_campo& tc, TString& campo)
campo.left_just(length, tc.filler());
}
else
if (length > 0)
campo.cut(length);
if (length > 0)
if (tc.align() == 'R')
campo=campo.right(length);
else
campo.cut(length);
return campo;
}
//Formatta la stringa in base al field del file isam
TString& TFile_text::format_field(const TTracciato_campo& tc, TString& campo)
{
const TRectype record(tc.field().file());
int length = record.length(tc.name());
if (!fpicture(tc).blank())
{ TString tmp;
tmp.picture(fpicture(tc), campo);
campo=tmp;
}
if (length > campo.len())
{
if (falign(tc) == 'R')
campo.right_just(length, ffiller(tc));
else
campo.left_just(length, ffiller(tc));
}
else
if (length > 0)
if (falign(tc) == 'R')
campo=campo.right(length);
else
campo.cut(length);
return campo;
}

View File

@ -19,16 +19,28 @@
///////////////////////////////////////////////////////////////////////////
class TTracciato_campo : public TObject
{
TString _name;//descrizione del contenuto
TString _type;//tipo predefinito
TFieldref _field;//nome su file/relazione
int _position;//posizione su file di testo
int _length;//lunghezza
int _decimal;//numero di decimali
char _align;//allineamento
char _filler;//carattere di riempimento
TString _picture;//formato
TToken_string _message;//messaggio per gestire personalizzazione del campo
// @cmember descrizione del contenuto
TString _name;
//@cmember tipo predefinito del campo del file di testo
TString _type;
//@cmember nome su file/relazione
TFieldref _field;
//@cmember tipo predefinito del FIeld del file isam
TString _ftype;
//@cmember posizione su file di testo
int _position;
//@cmember lunghezza
int _length;
//@cmember numero di decimali
int _decimal;
//@cmember allineamento
char _align;
//@cmember carattere di riempimento
char _filler;
//@cmember formato
TString _picture;
//@cmember messaggio per gestire personalizzazione del campo
TToken_string _message;
protected:
void copy(const TTracciato_campo& tc);//copia membro a membro
@ -42,6 +54,7 @@ public:
const TString& name() const {return _name;}
const TString& type() const {return _type;}
const TFieldref& field() const {return _field;}
const TString& ftype() const {return _ftype;}
const int position() const {return _position;}
const int length() const {return _length;}
const int decimal() const {return _decimal;}
@ -52,6 +65,7 @@ public:
void set_name(const TString& name) {_name = name;}
void set_type(const TString& type) {_type = type;}
void set_field(const TFieldref& field) {_field = field;}
void set_ftype(const TString& type) {_ftype = type;}
void set_position(const int position) {_position = position;}
void set_length(const int length) {_length = length;}
void set_decimal(const int decimal) {_decimal = decimal;}
@ -135,6 +149,10 @@ protected:
// <val> contiene il messaggio da modificare e/o caircare nel record
// <str> conterrà il risultato dell'operazione
virtual void validate(TCursor& cur, TRecord_text &rec, TToken_string &val, TString& str){}
const int fdecimal(const TTracciato_campo &tc ) const;
const char falign(const TTracciato_campo &tc ) const;
const char ffiller(const TTracciato_campo &tc ) const ;
const TString& fpicture(const TTracciato_campo &tc ) const;
public:
TFile_text(const char* file_name, const char* config_name);
@ -187,7 +205,10 @@ public:
const TString& get_field(const TRecord_text& rec, const char* name);
void format_date(const TDate& data, const TString& form, TString& data_str);//formatta la data
TString& format_field(TTracciato_campo& tc, TString& campo);//formatta il campo secondo il suo tracciato
// @cmember formatta il campo secondo il suo tracciato
TString& format_textfield(const TTracciato_campo& tc, TString& campo);
// @cmember formatta il campo secondo il suo tracciato
TString& format_field(const TTracciato_campo& tc, TString& campo);
};
#endif //__FILETEXT_H

View File

@ -412,10 +412,9 @@ const TString& TString::mid(
from = 0;
}
#endif
if (from > l) from = l;
if (count < 0) count = l-from;
if (count < 0 || from+count>l)
count = l-from;
spark.strncpy(&_str[from], count);
return spark;
}