515 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			515 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include "filetext.h"
 | ||
| //////////////////////////////////////// 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);
 | ||
| }
 | ||
| 
 | ||
| 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 TString& type)
 | ||
| {
 | ||
|   return (TTracciato_record&)_tracciati_record[type];
 | ||
| } 
 | ||
| 
 | ||
| void TFile_text::set_gen_parm(TConfig& config, TString& section)
 | ||
| {
 | ||
|   _decsep = config.get_char("DECSEP",section);
 | ||
|   _recordsize = config.get_int("RECORDSIZE",section);
 | ||
|   _fieldsep = config.get_char("FIELDSEP",section);// solo se a lung. variabile
 | ||
|   _recordsep = config.get("RECORDSEP",section);// solo se a lung. variabile
 | ||
|   _typefield =  config.get_int("TYPEFIELD",section);
 | ||
|   _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, TString& 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 <n>
 | ||
|     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 TString& file_name, const TString& 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());
 | ||
|     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<70> separatori decimali.");
 | ||
|         }              
 | ||
|     }
 | ||
|     rec.add(campo, i);       
 | ||
|     campo.cut(0);
 | ||
|   }                                                          
 | ||
| } 
 | ||
| 
 | ||
| //Legge da file il record text
 | ||
| int TFile_text::read(TRecord_text& rec)
 | ||
| {
 | ||
|   TString buffer(_recordsize), lavoro;
 | ||
|   CHECK(_read_file, "Impossibile leggere su un file chiuso.");
 | ||
|   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 ();
 | ||
|     while(c != _recordsep[0]&&ok_r())
 | ||
|     {  
 | ||
|          buffer << c;
 | ||
|          c = _read_file-> get ();
 | ||
|          if (!ok_r()) return 1;//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);
 | ||
|     TString tipo = 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();                 
 | ||
|   TString valore;
 | ||
|   for (int i = 0; i < items; i++)
 | ||
|   {
 | ||
|     TTracciato_campo& tc = tr.get(i);
 | ||
|     const TFieldref& field = tc.field();
 | ||
|     valore = rec.row(i);                     
 | ||
|     if (!field.name().empty())
 | ||
|         field.write(valore, rel);//faccio una write sulla relazione del fieldref
 | ||
|     }
 | ||
|   int err = rel.write();
 | ||
|   if (err != NOERR)   
 | ||
|      if (err == _isdupkey || err ==_isreinsert)
 | ||
|          err = rel.rewrite();     
 | ||
|   return err;       
 | ||
| } 
 | ||
| 
 | ||
| //Scarica dal record_text il campo alla posizione <ncampo>
 | ||
| const TString& TFile_text::get_field(TRecord_text& rec, int ncampo) 
 | ||
| {                                         
 | ||
|   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);
 | ||
| }
 | ||
| 
 | ||
| //Carica nel record_text il campo alla posizione <ncampo> con il valore <val> gi<67> formattato  
 | ||
| void TFile_text::add_field(TRecord_text& rec, const int ncampo, const char* val)
 | ||
| {
 | ||
|    const TString& type = rec.type(); 
 | ||
|    TTracciato_record& tr = t_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(TFilename name, char mode)
 | ||
| {                               
 | ||
|   set_name(name);             
 | ||
|   if (mode == 'r')//apertura in lettura
 | ||
|   {          
 | ||
|     _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
 | ||
|     _write_file = new ofstream(name,ios::binary|ios::app);  
 | ||
|   return 0;  
 | ||
| }                 
 | ||
| 
 | ||
| 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;
 | ||
| }
 | ||
| 
 |