diff --git a/include/filetext.cpp b/include/filetext.cpp index b64ce6163..c6e94d5b3 100755 --- a/include/filetext.cpp +++ b/include/filetext.cpp @@ -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 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; } diff --git a/include/filetext.h b/include/filetext.h index 73b5af4a0..589f350ee 100755 --- a/include/filetext.h +++ b/include/filetext.h @@ -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: // contiene il messaggio da modificare e/o caircare nel record // 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 \ No newline at end of file diff --git a/include/strings.cpp b/include/strings.cpp index 569d6662e..2e8a7b5a4 100755 --- a/include/strings.cpp +++ b/include/strings.cpp @@ -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; }