From 52fd0bd54470a789d28359bf1334aa432c80039a Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 30 Jul 1997 12:36:24 +0000 Subject: [PATCH] anafis.h Tolto campo inesistente TIPOA anagiu.h Tolto campo inesistente TIPOA form.cpp Modificato costruttore delle subsection per non dare warning msksheet.cpp Tolta riga vuota utility.cpp Tolto errore fatale nella funzione copyfile filetext.* Aggiunta gestione file di testo della Paola git-svn-id: svn://10.65.10.50/trunk@4974 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- include/anafis.h | 2 +- include/anagiu.h | 2 +- include/anagr.h | 2 +- include/filetext.cpp | 593 +++++++++++++++++++++++++++++++++++++++++++ include/filetext.h | 191 ++++++++++++++ include/form.cpp | 21 +- include/form.h | 6 +- include/msksheet.cpp | 1 - include/utility.cpp | 17 +- 9 files changed, 807 insertions(+), 28 deletions(-) create mode 100755 include/filetext.cpp create mode 100755 include/filetext.h diff --git a/include/anafis.h b/include/anafis.h index 4a9e9ead1..226e10b95 100755 --- a/include/anafis.h +++ b/include/anafis.h @@ -7,7 +7,7 @@ #define ANF_STATONASC "STATO" #define ANF_COMNASC "COMNASC" #define ANF_COMRES "COMRES" -#define ANF_TIPOA "TIPOA" +//#define ANF_TIPOA "TIPOA" #endif diff --git a/include/anagiu.h b/include/anagiu.h index b9fb04a28..b99b1ec97 100755 --- a/include/anagiu.h +++ b/include/anagiu.h @@ -1,10 +1,10 @@ #ifndef __ANAGIU_H #define __ANAGIU_H -#define ANG_TIPOA "TIPOA" #define ANG_CODANAGR "CODANAGR" #define ANG_NATGIU "NATGIU" #define ANG_COMRES "COMRES" +//#define ANG_TIPOA "TIPOA" #endif diff --git a/include/anagr.h b/include/anagr.h index 1313555f9..e69bdcfeb 100755 --- a/include/anagr.h +++ b/include/anagr.h @@ -6,12 +6,12 @@ #define ANA_PAIV "PAIV" #define ANA_COFI "COFI" #define ANA_RAGSOC "RAGSOC" -#define ANA_COMRF "COMRF" #define ANA_STATORES "STATORES" #define ANA_COMRES "COMRES" #define ANA_INDRES "INDRES" #define ANA_CIVRES "CIVRES" #define ANA_CAPRES "CAPRES" +#define ANA_COMRF "COMRF" #define ANA_INDRF "INDRF" #define ANA_CIVRF "CIVRF" #define ANA_CAPRF "CAPRF" diff --git a/include/filetext.cpp b/include/filetext.cpp new file mode 100755 index 000000000..62015e61b --- /dev/null +++ b/include/filetext.cpp @@ -0,0 +1,593 @@ +#include + +#include + +//////////////////////////////////////// TTracciato_Campo //////////////////////////////////////// +TTracciato_campo::TTracciato_campo(int position, int length, int decimal, const char align, const char filler) + :_position(position), _length(length), _decimal(decimal), _align(align), _filler(filler) {} + +TObject* TTracciato_campo::dup() const +{ + TTracciato_campo* t = new TTracciato_campo(*this); + return t; +} + +const TTracciato_campo& TTracciato_campo::operator =(const TTracciato_campo& tc) +{ + copy(tc); + return *this; +} + +void TTracciato_campo::copy(const TTracciato_campo& tc) +{ + set_name(tc._name); + set_type(tc._type); + set_field(tc._field); + set_position(tc._position); + set_length(tc._length); + set_decimal(tc._decimal); + set_align(tc._align); + set_filler(tc._filler); + set_picture(tc._picture); + set_message(tc._message); +} +//////////////////////////////////////// TTracciato_record //////////////////////////////////////// +TObject* TTracciato_record::dup() const +{ + TTracciato_record* t = new TTracciato_record(*this); + return t; +} + +TTracciato_record::TTracciato_record(const TTracciato_record& tr) +{ + set_type(tr.type()); + _tracciati_campo = tr._tracciati_campo; +} + +void TTracciato_record::add(const TTracciato_campo& tc, int pos) +{ + _tracciati_campo.add(tc,pos); +} + +int TTracciato_record::get_pos(const char* name) const +{ + for (int i = _tracciati_campo.last(); i >= 0; i = _tracciati_campo.pred(i)) + { + const TTracciato_campo& tc = get(i); + if (tc.name() == name) + break; + } + return i; +} + +TTracciato_campo& TTracciato_record::get(int n) +{ + if (TTracciato_record::ptr(n) == NULL)//se non esiste lo creo + { + TTracciato_campo* t = new TTracciato_campo(); + TTracciato_record::add(*t, n); + } + return (TTracciato_campo&)_tracciati_campo[n]; +} +//////////////////////////////////////// TRecord_text //////////////////////////////////////// +const TString& TRecord_text::row(int pos) const +{ + return _array.row(pos); +} + +void TRecord_text::add(const TString& c, int pos) +{ + _array.add(c, pos); +} +//////////////////////////////////////// TFile_text //////////////////////////////////////// +TTracciato_record& TFile_text::t_rec(const char* type) +{ + return (TTracciato_record&)_tracciati_record[type]; +} + +void TFile_text::set_gen_parm(TConfig& config, const TString& section) +{ + _decsep = config.get_char("DECSEP",section); + _recordsize = config.get_int("RECORDSIZE",section); // solo se a lung. fissa + _fieldsep = config.get_char("FIELDSEP",section); // solo se a lung. variabile + _recordsep = config.get("RECORDSEP",section); // solo se a lung. variabile + 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(); + _typepos = -1; + _typelen = -1; +} + +void TFile_text::set_type_parm(TConfig& config, TString& section) +{ + TString lavoro = section; + lavoro.ltrim(4);//elimino la parola 'TYPE' e gli spazi vuoti + lavoro.trim();//per avere solo il nome del tipo predefinito + TTracciato_campo tipo; + tipo.set_type(lavoro); + tipo.set_length(config.get_int("LENGTH", section)); + tipo.set_decimal(config.get_int("DECIMAL", section)); + tipo.set_align(config.get_char("ALIGN", section)); + TString s = config.get("FILLER", section); + tipo.set_filler(s[1]); + tipo.set_picture(config.get("PICTURE", section)); + _tipi.add(lavoro, tipo);// aggiungo il tracciato campo all'assoc_array dei tipi predefiniti +} + +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 + //setto tutti i dati relatvi ai tipi predefini nei tracciati campo per i diversi campi del record + config.set_paragraph(section); + TString lavoro; + TString_array variables; + const int numvar = config.list_variables(variables, TRUE);//scarico tutte le variabili della sezione + TBit_array indici(numvar); + indici.reset(); + for (int j = 0; j < numvar; j++)//scandisco tutte le variabili della sezione + { + const TString key = variables.row(j).get(0);//estraggo nome + const TString& obj = variables.row(j).get(1);//estraggo valore + lavoro = key.left(3); + int pos = key.find('('); + int n = atoi(key.mid(pos+1, -1));//estraggo l'indice + if (!indici[n]) + { + 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); + } + TTracciato_campo& tc = tr.get(n);//prendo il tracciato campo con indice + if (lavoro == "NAM") + { + tc.set_name(obj); + continue; + } + if (lavoro == "FIE") + { + TFieldref field; + field = obj; + tc.set_field(field); + continue; + } + if (lavoro == "POS") + { + int pos = atoi(obj); + tc.set_position(pos); + if (_fixedlen && _typepos < 0 && n == _typefield) + _typepos = pos; + continue; + } + if (lavoro == "LEN") + { + int len = atoi(obj); + if (tc.length() <= 0 && len >= 0 && tc.length() != len) + tc.set_length(len); + if (_fixedlen && _typelen < 0 && n == _typefield) + _typelen = len; + continue; + } + if (lavoro == "DEC") + { + int dec = atoi(obj); + if (tc.decimal() <= 0 && dec >= 0 && tc.decimal() != dec) + tc.set_decimal(dec); + continue; + } + if (lavoro == "ALI") + { + bool condition = tc.align() != obj[0]; + if (condition) + tc.set_align(obj[0]); + continue; + } + if (lavoro == "FIL") + { + if (!obj.blank()) + { + bool condition = tc.filler() != obj[1]; + if (condition) + tc.set_filler(obj[0]); + } + continue; + } + if (lavoro == "PIC") + { + if (tc.picture().blank() && (!obj.blank())) + tc.set_picture(obj); + continue; + } + if (lavoro == "MES") + { + tc.set_message(obj); + continue; + } + } + //aggiungo il tracciato record all'assoc_array dei tracciati record + _tracciati_record.add(comodo, tr); +} + +TFile_text::TFile_text(const char* file_name, const char* config_name) + : _name(file_name) +{ + _read_file = NULL; + _write_file = NULL; + TConfig config(config_name); + TString_array paragraphs; + config.list_paragraphs(paragraphs);//scarico la lista dei paragrafi + int items = paragraphs.items();//quanti paragrafi ho scaricato + TString section, sec; + for (int i = 0; i < items; i++)//scandisco tutti i paragrafi + { + section = paragraphs.row(i) ;//prendo il nome del paragrafo + sec = section.left(3);//prendo le prime tre lettere del nome + if (sec == "MAI") //inizializzo i parametri generali del file + { + set_gen_parm(config,section); + continue; + } + if (sec == "TYP") + { + set_type_parm(config, section); + continue; + } + if ((sec == "REC")||(sec == "HEA")||(sec == "FOO")) + { + set_rec_parm(config, section); + continue; + } + } +} + +//Scrive su file il record_text (valido anche per header e footer) +int TFile_text::write(TRecord_text& rec) +{ + TString buffer; + TString campo; + const TString& type = rec.type(); + TTracciato_record& tr = t_rec(type); + TArray& a_tc = tr.tracciati_campo(); + int items = rec.items(); + if (_fixedlen) + { + 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); + } + CHECK(_write_file, "Impossibile scrivere su un file chiuso."); + *_write_file << buffer; + if (!ok_w()) return 1; + buffer.cut(0); + } + else + { + TToken_string ts(buffer, _fieldsep); + for (int i = 0; i < items; i++) + { + campo = rec.row(i); + ts.add(campo, i); + campo.cut(0); + } + CHECK(_write_file, "Impossibile scrivere su un file chiuso."); + *_write_file << ts; + *_write_file << _recordsep; + if (!ok_w()) return 1; + ts.cut(0); + } + return 0; +} + +//Carica tutti i dati nel tracciato record (valido anche per header e footer) nel record_text +void TFile_text::autoload(TRecord_text& rec, TCursor& cur , const TString* tipo) +{ + TString campo; + TRelation& rel = *cur.relation(); + const TString& type = rec.type(); + if (tipo == NULL) tipo = &type; + TTracciato_record& tr = t_rec(*tipo); + TArray& a_tc = tr.tracciati_campo(); + int items = a_tc.items(); + for (int i = 0; i < items; i++) + { + TTracciato_campo& tc = tr.get(i); + const TFieldref& field = tc.field(); + if (!field.name().empty()) + campo = field.read(rel); + TString message = tc.message(); + if (!message.empty()) + { + 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); + 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++) + { + lavoro = ts.get(); + 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) +{ + const TString& type = rec.type();//prendo il tracciato record del tipo del record_text + TTracciato_record& tr = t_rec(type); + TArray& a_tc = tr.tracciati_campo(); + int items = a_tc.items(); + for (int i = 0; i < items; i++) + { + const TTracciato_campo& tc = tr.get(i); + const TFieldref& field = tc.field(); + if (field.name().not_empty()) + { + const TString& valore = rec.row(i); + field.write(valore, rel);//faccio una write sulla relazione del fieldref + } + } + int err = rel.write(); + if (err == _isdupkey || err ==_isreinsert) + err = rel.rewrite(); + return err; +} + +//Scarica dal record_text il campo alla posizione +const TString& TFile_text::get_field(const TRecord_text& rec, int ncampo) +{ +/* Guy was here + const TString& type = rec.type();//prendo il tracciato record del tipo del record_text + TTracciato_record tr(type); + TTracciato_campo& tc = tr.get(ncampo); +*/ + return rec.row(ncampo); +} + +//Scarica dal record_text il campo +const TString& TFile_text::get_field(const TRecord_text& rec, const char* name) +{ + TTracciato_record& tr = t_rec(rec.type()); + int ncampo = tr.get_pos(name); + CHECKS(ncampo >= 0, "Campo inesistente ", name); + return rec.row(ncampo); +} + +//Carica nel record_text il campo alla posizione con il valore già formattato +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); + rec.add(valore, ncampo); +} + +//Formatta la data in base al tracciato +void TFile_text::format_date(const TDate& data, const TString& form, TString& data_str) +{ + int i = 1, cnt = 0; + char x = form[0]; + do + { + char k = x; + if (k != 'a' && k != 'm'&& k != 'g') + data_str << k; + else + cnt++; + x = form[i]; + i++; + if (k != x) + switch (k) + { + case 'g': CHECKD(cnt >= 1 && cnt <= 4, "Formato per giorno non valido ", cnt); + if (cnt == 1) data_str << data.day(); + if (cnt == 2) data_str << format("%02d", data.day()); + if (cnt == 3) {TString s = itow(data.wday());s.cut(3);data_str << s;} + if (cnt == 4) data_str << itow(data.wday()); + cnt = 0; + break; + case 'm': CHECKD(cnt >= 1 && cnt <= 4, "Formato per mese non valido ", cnt); + if (cnt == 1) data_str << data.month(); + if (cnt == 2) data_str << format("%02d", data.month()); + if (cnt == 3) {TString s = itom(data.month());s.cut(3);data_str << s;} + if (cnt == 4) data_str << itom(data.month()); + cnt = 0; + break; + case 'a': CHECKD(cnt >= 2 && cnt <= 4, "Formato per anno non valido ", cnt); + if (cnt == 2) {TString s;s << data.year();s.ltrim(2);data_str << s;} + if (cnt == 3) {TString s;s << data.year();s.ltrim(1);data_str << s;} + if (cnt == 4) data_str << data.year(); + cnt = 0; + break; + } + } + while (i <= form.len()); +} + +//Formatta la stringa in base al tracciato +TString& TFile_text::format_field(TTracciato_campo& tc, TString& campo) +{ + int pos = tc.position(); + int length = tc.length(); + if (!tc.picture().blank()) + campo.picture(tc.picture(), campo); + if (length > campo.len()) + { + if (tc.align() == 'R') + campo.right_just(length, tc.filler()); + else + campo.left_just(length, tc.filler()); + } + else + campo.cut(length); + return campo; +} + +int TFile_text::open(char mode) +{ + if (mode == 'r')//apertura in lettura + { + if (_read_file) + delete _read_file; + + _read_file = new ifstream(_name, ios::binary); + if (!ok_r()) + error_box("Impossibile aprire il file %s in lettura", (const char *)_name); + } + if (mode == 'w')//apertura in scrittura + { + if (_write_file) + delete _write_file; + _write_file = new ofstream(_name, ios::binary|ios::app); + } + + return 0; +} + +int TFile_text::open(const char* name, char mode) +{ + set_name(name); + return open(mode); +} + + +int TFile_text::close() +{ + _name = ""; + _current = NULL; + _tipi.destroy(); + _tracciati_record.destroy(); + if (_read_file) _read_file->close(); + if (_write_file) _write_file->close(); + return 0; +} + diff --git a/include/filetext.h b/include/filetext.h new file mode 100755 index 000000000..cd392dd3b --- /dev/null +++ b/include/filetext.h @@ -0,0 +1,191 @@ +#ifndef __FILETEXT_H +#define __FILETEXT_H + +#ifndef __CONFIG_H +#include +#endif + +#ifndef __RELATION_H +#include +#endif + +#ifndef _INC_FSTREAM +#include +#endif + +///////////////////////////TTracciato_Campo//////////////////////////////// +// Classe per la definizione delle specifiche riguardanti un campo di un // +// record di un file di testo // +/////////////////////////////////////////////////////////////////////////// +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 + +protected: + void copy(const TTracciato_campo& tc);//copia membro a membro + +public: + TTracciato_campo(int position = -1, int length = -1, int decimal = -1, const char align = 'R', const char filler = ' '); + TTracciato_campo(const TTracciato_campo& tc){copy(tc);} + virtual ~TTracciato_campo() {} + virtual TObject* dup() const; + const TTracciato_campo& operator =(const TTracciato_campo& tc); + const TString& name() const {return _name;} + const TString& type() const {return _type;} + const TFieldref& field() const {return _field;} + const int position() const {return _position;} + const int length() const {return _length;} + const int decimal() const {return _decimal;} + const char align() const {return _align;} + const char filler() const {return _filler;} + const TString& picture() const {return _picture;} + const TString& message() const {return _message;} + 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_position(const int position) {_position = position;} + void set_length(const int length) {_length = length;} + void set_decimal(const int decimal) {_decimal = decimal;} + void set_align(const char align) {_align = toupper(align);} + void set_filler(const char filler ) {_filler = filler;} + void set_picture(const TString& picture ) {_picture = picture;} + void set_message(const TString& message ) {_message = message;} +}; +/////////////////////////// TTracciato_record ///////////////////////// +// Classe per la definizione delle specifiche riguardanti un record // +// come insieme di più campi // +/////////////////////////////////////////////////////////////////////// +class TTracciato_record : public TObject +{ + TString _type;//tipo del record + TArray _tracciati_campo;//tracciati dei vari campi +public: + TTracciato_record(const TString& tipo) : _type(tipo) {} + TTracciato_record(const TTracciato_record& tr); + virtual ~TTracciato_record() {} + virtual TObject* dup() const; + TArray& tracciati_campo() { return _tracciati_campo;}//ritorna un riferimento all'array dei tracciati campo + const TString& type() const {return _type;} + void set_type(const TString& type) {_type = type;} + void add(const TTracciato_campo& tc, int pos = -1);//aggiunge tracciato campo all'array + TTracciato_campo& get(int n);//ritorna il tracciato campo n dell'array (se non c'e' lo crea) + //ritorna il tracciato campo n dell'array + const TTracciato_campo& get(int n) const {return (TTracciato_campo&)_tracciati_campo[n];} + int get_pos(const char* name) const; + //ritorna il puntatore al tracciato campo n dell'array (NULL se non esiste) + TTracciato_campo* ptr(int n) {return (TTracciato_campo*)_tracciati_campo.objptr(n);} +}; +///////////////////////////// TRecord_text ///////////////////////////////// +// Classe per la definizione di un record di un File_text, consiste di un // +// array che contiene tutti i valori dei campi risultanti dal tracciato // +// record // +//////////////////////////////////////////////////////////////////////////// +class TRecord_text : public TObject +{ + TString _type;//tipo del record + TString_array _array;//array che contiene i valori dei campi +public: + TRecord_text() {} + TRecord_text(const TString& type): _type(type) {} + virtual ~TRecord_text(){} + const TString& type() const {return _type;} + void set_type(const TString& type) {_type = type;} + const TString& row(int pos) const;//ritorna il campo dell'array della posizione + void add(const TString& c, int pos = -1);//scrive il campo nell'array alla posizione + const int items() const {return _array.items();}//ritorna il numero di elementi dell'array + virtual bool destroy(int index = -1, bool pack = FALSE) {return _array.destroy(index, pack);} +}; +///////////////////////////////// TFile_text ////////////////////////////////////// +// Classe per la definizione di un file di testo capace di leggersi e scriversi,// +// in base ai tracciati record e campo risultanti; utilizzabile per trasferimenti// +// (ricezioni ed invii) di file o di relazioni // +/////////////////////////////////////////////////////////////////////////////////// +class TFile_text : public TObject +{ + ifstream* _read_file;//stream per lettura da file di testo + ofstream* _write_file;//stream per scrittura su file di testo + TFilename _name;//nome del file di testo + TRecord_text* _current;//puntatore al record_text corrente + TAssoc_array _tipi;//tracciati campo per i vari tipi predefiniti + TAssoc_array _tracciati_record;//tracciati record per i vari tipi di record + char _decsep;//separatore decimale + int _recordsize;//dimensione dei record + char _fieldsep;//separatore di campo (se a lunghezza variabile) + TString _recordsep;//separatore di record (se a lunghezza variabile) + bool _fixedlen;//booleano TRUE lunghezza fissa FALSE lunghezza variabile + int _typepos;//posizione ove trovare la chiave nel record a lunghezza fissa + int _typelen;//lunghezza della chiave del record a lunghezza fissa + int _typefield;//posizione ove trovare la chiave nel record a lunghezza variabile + +protected: + //effettua operazioni personalizzate dall'applicazione sul record_text + // è il cursore della relazione + // è il record da modificare + // 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){} + +public: + TFile_text(const char* file_name, const char* config_name); + virtual ~TFile_text(){} + ifstream* read_file() {return _read_file;} + ofstream* write_file() {return _write_file;} + void set_gen_parm(TConfig& config, const TString& section);//scarica i parametri generali dal file di configurazione + //scarica i parametri relativi ai vari tipi predefiniti dal file di configurazione + void set_type_parm(TConfig& config, TString& section); + //scarica i parametri relativi ai vari tipi di record dal file di configurazione + void set_rec_parm(TConfig& config, const char* section); + int open(char mode);//apertura del file di testo (mode = r|w) + int open(const char* name, char mode);//apertura del file di testo (mode = r|w) + int close();//chiusura del file di testo + inline const int ok_r() {return _read_file->good();}//ritorna lo stato del file di lettura + inline const int ok_w() {return _write_file->good();}//ritorna lo stato del file di scrittura + const TFilename& name() const {return _name;}//ritorna il nome del file + void set_name(const char* name) {_name = name;} //setta il nome del file + const char decsep() const {return _decsep;} + const int recordsize() const {return _recordsize;} + const char fieldsep() const {return _fieldsep;} + const TString& recordsep() const {return _recordsep;} + const bool fixedlen() const {return _fixedlen;} + const int typepos() const {return _typepos;} + const int typelen() const {return _typelen;} + const int typefield() const {return _typefield;} + const TRecord_text& curr() const {return *_current;}//ritorna il record corrente + void set_curr(TRecord_text& rec) {_current = &rec;}//setta il record corrente a rec + void set_curr(TRecord_text* rec) {_current = rec;}//setta il record corrente a rec + TTracciato_record& t_rec(const char* type);//ritorna il tracciato record del tipo passato + const int items_tr() const {return _tracciati_record.items();}//ritorna il numero di tracciati record nel file + TAssoc_array& tracciati() {return _tracciati_record;}//ritorna un riferimento all'assoc_array dei tracciati record + //caricamento automatico del record_text dalla relazione + void autoload(TRecord_text& rec, TCursor& cur, const TString* tipo = NULL); + //caricamento automatico del record_text corrente dalla relazione l + void autoload(TCursor& cur, const TString* tipo = NULL) {autoload(*_current, cur, tipo); }; + int write(TRecord_text & rec);//scrive su file di testo il record + int write(){return write(*_current);}//scrive su file di testo il record_text corrente + //caricamento automatico della relazione dal record_text + int autosave(TRelation& rel, const TRecord_text& rec); + //caricamento automatico della relazione dal record_text corrente + int autosave(TRelation& rel) {return autosave(rel, *_current); }; + int read(TRecord_text & rec);//legge da file di testo il record_text + int read(){return read(*_current);}//legge da file di testo il record_text corrente + //carica nel record_text il campo alla posizione con il valore già formattato + void add_field(TRecord_text& rec, const int ncampo, const char* val); + //scarica dal record_text il campo alla posizione + const TString& get_field(const TRecord_text& rec, int ncampo); + //scarica dal record_text il campo di nome + 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 +}; + +#endif //__FILETEXT_H \ No newline at end of file diff --git a/include/form.cpp b/include/form.cpp index 2529d1f7d..52abc2f63 100755 --- a/include/form.cpp +++ b/include/form.cpp @@ -1003,10 +1003,12 @@ short TForm_item::x() /////////////////////////////////////////////////////////// -TForm_subsection::TForm_subsection(TPrint_section* s, const char* nm) : -TForm_item(s), _ssec(&(s->form()), s->section_type(), s->page_type(), this), -_file_id(-1), _name(nm), _condexpr(NULL) -{} +TForm_subsection::TForm_subsection(TPrint_section* s, const char* nm) + : TForm_item(s), _ssec(&(s->form()), s->section_type(), s->page_type()), + _file_id(-1), _name(nm), _condexpr(NULL) +{ + _ssec.set_subsection_above(this); +} TForm_subsection::~TForm_subsection() { @@ -2242,7 +2244,7 @@ TExpression & TPrint_section::eval_expr(TExpression & expr,int defaultfile_id) } -TPrint_section::TPrint_section(TForm* f, char st, pagetype pt, TForm_subsection * father) +TPrint_section::TPrint_section(TForm* f, char st, pagetype pt, TForm_subsection* father) : _height(0), _form(f), _sec_type(st), _page_type(pt), _dirty(FALSE), _upsection(father), _repeat_count(0), _ofspc(0), _ofsvr(0), _nfld(0), _temp(0), _columnwise(FALSE) @@ -3851,14 +3853,9 @@ word TForm::set_body( return body.height(); } -TForm_subsection * TPrint_section::subsection_above() const -{ if (_upsection) - return _upsection; - return NULL; -} - TPrint_section * TPrint_section::section_above() const -{ if (_upsection) +{ + if (_upsection) return &_upsection->section(); return NULL; } diff --git a/include/form.h b/include/form.h index d4aba2cef..dd60ea642 100755 --- a/include/form.h +++ b/include/form.h @@ -554,9 +554,11 @@ public: // @cmember Restituisce il numero di sottosezioni int subsections() const ; // @cmember Restituisce il puntatore alla sezione "Padre" - TPrint_section * section_above() const ; + TPrint_section* section_above() const ; // @cmember Restituisce il puntatore alla sezione "Padre" - TForm_subsection * subsection_above() const ; + TForm_subsection* subsection_above() const { return _upsection; } // Maybe NULL + // @cmember Setta il puntatore alla sezione "Padre" + void set_subsection_above(TForm_subsection* ssa) { _upsection = ssa; } // Maybe NULL // @cmember ricompone le espressioni di FILE GROUP delle sottosezioni contenute void set_subs_cond(int file,const char *newcond,const char * oldcond); diff --git a/include/msksheet.cpp b/include/msksheet.cpp index 237db3311..d977f80f2 100755 --- a/include/msksheet.cpp +++ b/include/msksheet.cpp @@ -2183,7 +2183,6 @@ bool TSheet_field::parse_item(TScanner& scanner) NFCHECK("Manca la definizione del campo di autonumerazione nel campo %d", (int)dlg()); } - } } return TRUE; diff --git a/include/utility.cpp b/include/utility.cpp index cc9812713..7e24ed771 100755 --- a/include/utility.cpp +++ b/include/utility.cpp @@ -54,26 +54,23 @@ bool fcopy( // @comm Nel caso vengano ravvisati degli errori durante l'operazione vengono // creati dei box di comunicazione che indicano la causa del problema { - const char* wflag; #if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_WIN32 const char* const rflag = "rb"; - if (append) - wflag = "ab"; - else - wflag = "wb"; + const char* wflag = append ? "ab" : "wb"; #else const char* const rflag = "r"; - if (append) - wflag = "a"; - else - wflag = "w"; + const char* wflag = append ? "a" : "w"; #endif FILE* i = fopen(orig, rflag); if (!i) return error_box("Impossibile leggere il file %s", orig); FILE* o = fopen(dest, wflag); - CHECKS(o, "Impossibile scrivere il file ", dest); + if (!o) + { + fclose(i); + return error_box("Impossibile scrivere il file ", dest); + } const word size = 16*1024; TString buffer(size);