#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 { // @cmember descrizione del contenuto TString _name; //@cmember tipo del campo del file di testo (umero, tringa, ata char _datatype; //@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 public: TTracciato_campo(int position = -1, int length = -1, int decimal = -1, const char align = ' ', 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 char datatype() const {return _datatype;} 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;} 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_datatype(const char type) {_datatype = type;} void set_type(const char* 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;} 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 { // @cmember Relazione associata al tracciato TRelation * _rel; // TString _type;//tipo del record TArray _tracciati_campo;//tracciati dei vari campi public: TTracciato_record(const TString& tipo) : _type(tipo) ,_rel(NULL){} 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;} // @cmember Restituisce la relazione associata al tracciato TRelation * relation() const {return _rel;} // @cmember Setta la relazione associata al tracciato void set_relation(TRelation * rel) ; void add(const TTracciato_campo& tc, int pos = -1);//aggiunge tracciato campo all'array void add(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 { TString16 _type; //tipo del record TString_array _array; //array che contiene i valori dei campi public: const TString& type() const {return _type;} void set_type(const TString& type) {_type = type;} const TString& row(int pos) const;//usare la get!!! TString& row(int pos); const TString& get(int pos) const {return row(pos);}//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);} TRecord_text() {} TRecord_text(const TString& type): _type(type) {} virtual ~TRecord_text(){} }; ///////////////////////////////// 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 int _skiplines;//Righe iniziali da ignorare char _decsep;//separatore decimale int _recordsize;//dimensione dei record TString _recordsep;//separatore di record a lunghezza variabile (blank() se lung.fissa) char _fieldsep; //separatore di campo (se a lunghezza variabile) bool _fixedlen; //indicatore di lunghezza fissa dei campi bool _kill_zeroes; // Flag per svuotare i campi pieni di zero bool _force_record_separator; // Flag per forzare la scrittura del separatore di record anche se siamo a lunghezza fissa 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: const int flength(const TTracciato_campo &tc, const TRectype & r ) const; 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; // @cmember caricamento automatico del record_text corrente dalla relazione l bool _autoload(TRecord_text& rec, TCursor& cur , TTracciato_record& tr ); // @cmember caricamento automatico della relazione definita nel tracciato dal record_text int _autosave(TRelation& rel, const TRecord_text& rec, TTracciato_record& tr ); // @cmember formatta la data void format_date(const TDate& data, const TString& form, TString& data_str); // @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, short lfile, TString& campo); //effettua modifiche particolari dal cursore al 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){} //effettua modifiche particolari al valore da assegnare ad un campo dell'isamfile //virtual void preformat_field(TRelation& rel,const TFieldref&field,const TRecord_text& rec,TString &str) {} virtual void preformat_field(const TFieldref&field,TString &str,TRelation& rel,const TString &tipo_tr) {} //effettua modifiche sui record della relazione prima di effettuarne la write; ritorna TRUE se deve effettuare la write virtual bool pre_writerel(TRelation& rel,const TRecord_text& rec) {return TRUE;} virtual bool can_write(TRecord_text&, TRelation&) {return TRUE;} public: 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='r');//apertura del file di testo (mode = r|w) int open(const char* name, char mode='r');//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 int skiplines() const {return _skiplines;} 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 // @cmember ritorna il tracciato record del tipo passato TTracciato_record* t_rec(const char* type) const ; // @cmember ritorna il tracciato record relativo alla relazione del file passato // NB: si assume che ogni tracciato sia relativo ad una relazione diversa TTracciato_record* t_rec(int mainfile, const char* tab=NULL) const ; 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 // @cmember caricamento automatico del record_text dalla relazione bool autoload(TRecord_text& rec, TCursor& cur, const TString* tipo = NULL); // @cmember caricamento automatico del record_text corrente dalla relazione l bool autoload(TCursor& cur, const TString* tipo = NULL) ; // @cmember caricamento automatico del record_text passato dalla relazione di file principale mainfile definita sul tracciato bool autoload(TRecord_text& rec, int mainfile); // @cmember caricamento automatico del record_text passato dalla relazione bool autoload(TRecord_text& rec, const char * tabname); // @cmember caricamento automatico del record_text corrente dalla relazione di file principale mainfile definita sul tracciato void autoload(int mainfile) {autoload(*_current, mainfile);} 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); }; //caricamento automatico della relazione definita nel tracciato dal record_text int autosave(const TRecord_text& rec, int mainfile=0); //caricamento automatico della relazione definita nel tracciato dal record_text int autosave(int mainfile); 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); //carica nel record_text il campo con il valore già formattato void add_field(TRecord_text& rec, const char* name, const char* val); //carica nel record_text il campo con il valore void add_field(TRecord_text& rec, const char* name, long 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); //Svuota i campi pieni di zeri void kill_zero_only(const bool b = TRUE) { _kill_zeroes = b; } //Forza la scrittura del separatore di record anche se è a lunghezza fissa void force_record_separator(const bool b = TRUE) { _force_record_separator = b; if (b && _recordsep.empty()) _recordsep = "\r\n";} TFile_text(const char* file_name, const char* config_name); virtual ~TFile_text(); }; #endif //__FILETEXT_H