343 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			343 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
// definizione dei record_text per trasferimento da/a file di testo
 | 
						|
 | 
						|
#include <config.h>
 | 
						|
#include <fstream.h>
 | 
						|
#include <object.h>
 | 
						|
#include <strings.h>
 | 
						|
 | 
						|
//	nomi delle variabili in .ini per HEADER
 | 
						|
#define HEADER		"HEADER"
 | 
						|
#define NOMEFILE	"NOMEFILE"
 | 
						|
#define LUNGHEZZA	"LUNGHEZZA"
 | 
						|
#define RECORDSEP "RECORDSEP"
 | 
						|
#define FIELDSEP	"FIELDSEP"
 | 
						|
 | 
						|
 | 
						|
class TFile_text;
 | 
						|
class TRecord_text : public TToken_string
 | 
						|
{
 | 
						|
	
 | 
						|
	// lunghezza del record (se a lunghezza fissa)
 | 
						|
	int 			_length;
 | 
						|
	
 | 
						|
	// separatore di record (se necessario)
 | 
						|
	TString16	_recordsep;
 | 
						|
 | 
						|
	// il separatore di campi esiste già (_separator)
 | 
						|
	
 | 
						|
public:
 | 
						|
 | 
						|
	// restituisce la lunghezza del record
 | 
						|
	int length() { return _length; }
 | 
						|
	// restituisce il separatore di record (se esiste)
 | 
						|
	const char* recordsep() { return _recordsep; }
 | 
						|
 | 
						|
	// ritorna il campo alla posizione <pos> 
 | 
						|
	// aggiungere la possibilità di estrarlo <da> <a>
 | 
						|
	const char* get(int pos) const;	
 | 
						|
	                              
 | 
						|
	// ritorna il campo che va dal carattere <da> al carattere <a>
 | 
						|
	const char* get(int da, int a) const; 
 | 
						|
	
 | 
						|
	// scrive il campo <c> nel record alla posizione <pos>
 | 
						|
	
 | 
						|
	void put(const char* c, int pos = -1);	
 | 
						|
	
 | 
						|
	// scrive il campo <c> nel record partendo dal carattere <da> fino al carattere <a>
 | 
						|
	// se il campo <c> è più lungo viene troncato
 | 
						|
	
 | 
						|
	void put(const char* c, int da, int a);
 | 
						|
	             
 | 
						|
	// costruttore	             
 | 
						|
	TRecord_text(const char* recordsep = "\n", char fieldsep = '|')
 | 
						|
	: _length(-1), _recordsep(recordsep)
 | 
						|
	{
 | 
						|
		TToken_string::TToken_string("",fieldsep);
 | 
						|
	}
 | 
						|
	
 | 
						|
	// costruttore
 | 
						|
	TRecord_text(int length, const char* recordsep = "\n")
 | 
						|
	: _length(length)
 | 
						|
	{
 | 
						|
		TToken_string::TToken_string(length);
 | 
						|
		spaces();
 | 
						|
	}
 | 
						|
	       
 | 
						|
	// distruttore	       
 | 
						|
	~TRecord_text() {};
 | 
						|
	
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
const char* TRecord_text::get(int pos) const
 | 
						|
{
 | 
						|
	return ((TToken_string*)this)->get(pos);		
 | 
						|
}
 | 
						|
 | 
						|
const char* TRecord_text::get(int da, int a) const
 | 
						|
{
 | 
						|
	CHECK(_length > 0, "Get non consentita su record non a lunghezza fissa");
 | 
						|
	
 | 
						|
	return sub(da, a);
 | 
						|
}
 | 
						|
 | 
						|
void TRecord_text::put(const char* c, int pos)
 | 
						|
{
 | 
						|
	add(c, pos);
 | 
						|
}
 | 
						|
 | 
						|
void TRecord_text::put(const char* c, int da, int a)
 | 
						|
{ 
 | 
						|
	CHECK(_length > 0, "Put non consentita su record non a lunghezza fissa");
 | 
						|
	
 | 
						|
	TString s = c;
 | 
						|
	int len = da-a+1;
 | 
						|
	if ( s.len() > len)	s = s.cut(len);
 | 
						|
	// sistemare se è più corta (la fill non va bene)
 | 
						|
	TToken_string::overwrite(s, da);
 | 
						|
}
 | 
						|
 | 
						|
// definizione dei field_text per trasferimento da/a file di testo
 | 
						|
 | 
						|
class TField_text : public TObject
 | 
						|
{               
 | 
						|
	// nome del campo
 | 
						|
	TString16 _name;
 | 
						|
	// posizione assoluta nel record (se con separatore)
 | 
						|
	int			_pos;
 | 
						|
	// posizione iniziale nel record (se a lunghezza fissa)
 | 
						|
	int			_from;
 | 
						|
	// posizione finale /se a lunghezza fissa)
 | 
						|
	int			_to;
 | 
						|
		
 | 
						|
protected:
 | 
						|
	
 | 
						|
public:
 | 
						|
	// costruttore
 | 
						|
	TField_text() : _name(0), _pos(-1), _from(-1), _to(-1) {}
 | 
						|
	// costruttore
 | 
						|
	TField_text(const char* name, int pos = -1, int from = -1, int to = -1)
 | 
						|
	:	_name(name), _pos(pos), _from(from), _to(to) {}
 | 
						|
 | 
						|
	// ritorna il nome del campo	
 | 
						|
	const char* name() const { return _name; }
 | 
						|
	// setta il nome del campo
 | 
						|
	void set_name(const char* name) { _name = name; }
 | 
						|
 | 
						|
	// ritorna la posizione iniziale del campo	
 | 
						|
	int from() const { return _from; } 
 | 
						|
	// setta la posizione iniziale del campo
 | 
						|
	void set_from(int from) { _from = from; }
 | 
						|
	
 | 
						|
	// ritorna la posizione finale del campo
 | 
						|
	int to() const { return _to; }
 | 
						|
	// setta la posizione finale del campo
 | 
						|
	void set_to(int to) { _to = to; }
 | 
						|
	                                      
 | 
						|
	// ritorna la posizione del campo	                                      
 | 
						|
	int pos() const { return _pos; }
 | 
						|
	// setta la posizione del campo
 | 
						|
	void set_pos(int pos) { _pos = pos; }
 | 
						|
 | 
						|
	// cerca nel record il campo e ne ritorna il contenuto	
 | 
						|
	const char* read(const TRecord_text& rec) const;
 | 
						|
	
 | 
						|
	// cerca nel record il campo e vi scrive <val>
 | 
						|
	void write(const char* val, TRecord_text& rec);
 | 
						|
 | 
						|
	virtual ~TField_text() {};		
 | 
						|
	
 | 
						|
};
 | 
						|
 | 
						|
const char* TField_text::read(const TRecord_text& rec) const
 | 
						|
{
 | 
						|
	int pos = TField_text::pos();
 | 
						|
	if (pos = -1)
 | 
						|
	{
 | 
						|
		int from = TField_text::from();
 | 
						|
		int to = TField_text::to();
 | 
						|
		if (from != -1 && to != -1)
 | 
						|
			return rec.get(from, to);
 | 
						|
		else
 | 
						|
			return "";
 | 
						|
	}
 | 
						|
	else
 | 
						|
		return rec.get(pos);						
 | 
						|
}
 | 
						|
 | 
						|
void TField_text::write(const char* val, TRecord_text& rec)
 | 
						|
{
 | 
						|
	int pos = TField_text::pos();
 | 
						|
	if (pos != -1)
 | 
						|
	{
 | 
						|
		int from = TField_text::from();
 | 
						|
		int to = TField_text::to();
 | 
						|
		if (from != -1 && to != -1)
 | 
						|
			rec.put(val, from, to);
 | 
						|
	}
 | 
						|
	else
 | 
						|
		rec.put(val, pos);
 | 
						|
}
 | 
						|
 | 
						|
// definizione dei file_text per trasferimento da/a file di testo
 | 
						|
 | 
						|
class TFile_text: public fstream
 | 
						|
{
 | 
						|
	TFilename			_name;
 | 
						|
	TRecord_text	_current;
 | 
						|
	TString 			_buffer;
 | 
						|
	TArray				_arr_exprs;
 | 
						|
	TArray				_arr_fields;
 | 
						|
	
 | 
						|
public:
 | 
						|
 | 
						|
	// apre il file, se create = TRUE e il file non esiste lo crea
 | 
						|
	int open(TFilename name, bool create = FALSE);
 | 
						|
	// chiude il file 
 | 
						|
	int close();
 | 
						|
	// crea il file
 | 
						|
	int create(TFilename name) { return open(name, TRUE); };
 | 
						|
	// cancella il file
 | 
						|
	int remove();
 | 
						|
 | 
						|
	// ritorna il record corrente
 | 
						|
	TRecord_text& curr() { return _current; }
 | 
						|
 | 
						|
	// setta _current	a rec
 | 
						|
	void set_curr(TRecord_text& rec);
 | 
						|
 | 
						|
	// restituisce il nome del file
 | 
						|
	const char* name() { return _name; }	
 | 
						|
 | 
						|
	// setta il nome del file	
 | 
						|
	void set_name(TFilename name) { _name = name;}
 | 
						|
	
 | 
						|
	// si posiziona sul primo record del file
 | 
						|
	int first();
 | 
						|
	// si posiziona sul prossimo record del file
 | 
						|
	int next();
 | 
						|
 | 
						|
	// aggiunge il record rec in fondo
 | 
						|
	int write(TRecord_text& rec);
 | 
						|
	// aggiunge il record corrente in fondo
 | 
						|
	int write();
 | 
						|
 | 
						|
	// costruttore
 | 
						|
	TFile_text(const char* file_name, const char* config_name)
 | 
						|
	: _name(file_name), _buffer(1024*16)
 | 
						|
	{         
 | 
						|
  	setbuf((char*)(const char*)_buffer, _buffer.size());
 | 
						|
		TConfig config(config_name);
 | 
						|
		const TString_array fields;
 | 
						|
		const char* recordsep = config.get(RECORDSEP,HEADER);
 | 
						|
		const char* fieldsep = config.get(FIELDSEP,HEADER);
 | 
						|
		int lunghezza = config.get_int(LUNGHEZZA,HEADER);
 | 
						|
		if (lunghezza = 0)
 | 
						|
			_current(recordsep, fieldsep);			
 | 
						|
		else
 | 
						|
			_current(lunghezza,recordsep);
 | 
						|
		const int i = config.list_paragraphs(fields);
 | 
						|
		//int posheader = fields.find(HEADER);
 | 
						|
		fields.remove(fields.find(HEADER),TRUE);
 | 
						|
		//for ( int k = 0; k < fields.items(); k++ )
 | 
						|
	};
 | 
						|
	
 | 
						|
	// distruttore
 | 
						|
	~TFile_text() 
 | 
						|
	{
 | 
						|
		
 | 
						|
	};
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
void TFile_text::set_curr(TRecord_text& rec)
 | 
						|
{
 | 
						|
	//CHECK(rec,"NULL record");
 | 
						|
	_current = rec;
 | 
						|
}
 | 
						|
 | 
						|
int TFile_text::write(TRecord_text& rec)
 | 
						|
{
 | 
						|
	//CHECK(rec = NULL, "NULL record");
 | 
						|
	const char* record = (char*)&rec;
 | 
						|
	if (rec.length() > 0)
 | 
						|
		fstream::write(record, rec.length());
 | 
						|
	else
 | 
						|
		fstream::write(record, rec.len());
 | 
						|
	const TString16 separator = rec.recordsep();
 | 
						|
	if ( separator.ok())
 | 
						|
	{
 | 
						|
		int lensep = separator.len();
 | 
						|
		fstream::write(separator, lensep);
 | 
						|
	}
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int TFile_text::write()
 | 
						|
{
 | 
						|
	//CHECK(_current, "NULL current record");
 | 
						|
	const char* record = (char*)(&_current);
 | 
						|
	if (_current.length() > 0)
 | 
						|
		fstream::write(record, _current.length());
 | 
						|
	else
 | 
						|
		fstream::write(record, _current.len());
 | 
						|
	const TString16 separator = _current.recordsep();
 | 
						|
	if ( separator.ok())
 | 
						|
	{
 | 
						|
		int lensep = separator.len();
 | 
						|
		fstream::write(separator, lensep);
 | 
						|
	}
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int TFile_text::open(TFilename name, bool create)
 | 
						|
{
 | 
						|
	set_name(name);
 | 
						|
	if (create)
 | 
						|
		open(name,ios::app|ios::binary|ios::out);
 | 
						|
	else		
 | 
						|
		open(name,ios::app|ios::binary|ios::in|ios::nocreate);
 | 
						|
	if (bad())
 | 
						|
		fatal_box("Impossibile aprire %s",name);
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int TFile_text::next()
 | 
						|
{
 | 
						|
	//CHECK(_current, "NULL current record");
 | 
						|
	if (_current.length() > 0)
 | 
						|
		fstream::read((char*)(&_current), _current.length());
 | 
						|
	else
 | 
						|
	{
 | 
						|
		TString16 separator = curr().recordsep();
 | 
						|
		if (separator.ok())		
 | 
						|
		{
 | 
						|
			TString record;
 | 
						|
			int countsep = 0;
 | 
						|
			do	
 | 
						|
			{
 | 
						|
				char c = get();
 | 
						|
				record << c;
 | 
						|
				if (c = separator[countsep])
 | 
						|
					countsep++;
 | 
						|
				else
 | 
						|
					countsep = 0;				
 | 
						|
			}	while (countsep < separator.len() && good() && !eof());
 | 
						|
			if (countsep = separator.len())
 | 
						|
				record.cut(record.len()-separator.len());
 | 
						|
			(TToken_string&)_current = record;							
 | 
						|
		}							
 | 
						|
	}		
 | 
						|
	return 0;		
 | 
						|
}
 | 
						|
 | 
						|
int TFile_text::close()
 | 
						|
{
 | 
						|
	_name = "";
 | 
						|
	_current = NULL;
 | 
						|
	_buffer = "";
 | 
						|
	fstream::close();
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 |