2003-07-23 07:47:28 +00:00
|
|
|
#include <applicat.h>
|
|
|
|
#include <expr.h>
|
1994-08-16 16:35:22 +00:00
|
|
|
#include <files.h>
|
2008-10-08 10:23:29 +00:00
|
|
|
#include <lffiles.h>
|
1995-05-09 09:12:26 +00:00
|
|
|
#include <utility.h>
|
|
|
|
#include <config.h>
|
1994-08-22 09:47:35 +00:00
|
|
|
|
1995-02-09 14:47:31 +00:00
|
|
|
#include <extcdecl.h>
|
1994-08-16 16:35:22 +00:00
|
|
|
|
|
|
|
#define BLOCKLEN 512
|
1994-08-17 08:07:44 +00:00
|
|
|
#define INVFLD 255
|
1994-08-16 16:35:22 +00:00
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
TFile::TFile (int lenrec, int base)
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
_file = new SecDef;
|
|
|
|
_file->IOR = NOERR;
|
|
|
|
_len = lenrec;
|
|
|
|
_base = base;
|
|
|
|
_file->LockMode = _manulock;
|
|
|
|
_file->lpos = -1;
|
|
|
|
_file->name[0] = '\0';
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
TFile::~TFile ()
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
delete _file;
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
|
|
|
|
1995-06-27 10:18:49 +00:00
|
|
|
// @mfunc Apre il file specificato
|
|
|
|
void TFile::open (
|
|
|
|
const char *name, // @parm Nome del file da aprire
|
|
|
|
TFilelock lockmode) // @parm Tipo di lock da attivare durante l'apertura del file
|
|
|
|
// (default _manulock)
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
COpen (_file, (char *) name, _len, _base, lockmode);
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
bool TFile::verify (const char *name)
|
1994-08-16 16:35:22 +00:00
|
|
|
|
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
CVerify (_file, (char *) name);
|
|
|
|
return _file->IOR == NOERR;
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
|
|
|
|
1995-06-27 10:18:49 +00:00
|
|
|
// @mfunc Crea il file specificato
|
|
|
|
void TFile::create (
|
|
|
|
const char *name, // @parm Nome del file da creare
|
|
|
|
TRecnotype nrecord) // @parm Numero di recird che deve avere il file al momento
|
|
|
|
// della creazione (default 0)
|
|
|
|
|
|
|
|
// @comm Il file creato avra' dimensioni sufficienti a contenere <p nrecord> record
|
1994-08-16 16:35:22 +00:00
|
|
|
|
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
CCreate (_file, (char *) name, _len, _base, (nrecord * _len) / BLOCKLEN + 1);
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
void TFile::chsize (const char *name, TRecnotype nrecord)
|
1994-08-16 16:35:22 +00:00
|
|
|
|
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
CChsize (_file, (char *) name, _len, _base, (nrecord * _len) / BLOCKLEN + 1);
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
void TFile::close ()
|
1994-08-16 16:35:22 +00:00
|
|
|
|
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
CClose (_file);
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
void TFile::unlink (const char *name)
|
1994-08-16 16:35:22 +00:00
|
|
|
|
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
CDelete (_file, (char *) name);
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
|
|
|
|
1995-06-27 10:18:49 +00:00
|
|
|
// @mfunc Legge un record dal file
|
|
|
|
void TFile::read (
|
|
|
|
char *record, // @parm Record letto
|
|
|
|
TRecnotype recnum, // @parm Numero del record da leggere
|
|
|
|
TReclock lock) // @parm Tipo di blocco da attivare durante la letture (default _nolock)
|
1994-08-16 16:35:22 +00:00
|
|
|
|
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
_file->LenRec = _len;
|
|
|
|
_file->BaseFil = _base;
|
|
|
|
CRead (_file, record, recnum, lock);
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
|
|
|
|
1995-06-27 10:18:49 +00:00
|
|
|
// @mfunc Scrive un record sul file
|
|
|
|
void TFile::write (
|
|
|
|
char *record, // @parm Record da scrivere
|
|
|
|
TRecnotype recnum, // @parm Numero del record da scrivere
|
|
|
|
TReclock lock) // @parm Tipo di blocco da attivare durante la letture (default _nolock)
|
1994-08-16 16:35:22 +00:00
|
|
|
|
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
_file->LenRec = _len;
|
|
|
|
_file->BaseFil = _base;
|
|
|
|
CWrite (_file, record, recnum, lock);
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
int TFile::status () const
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
|
|
|
return _file->IOR;
|
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
TDir::TDir () : _num(-1), _com(false)
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
zero ();
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
TDir::TDir(int logicnum) : _num(logicnum), _com(false)
|
|
|
|
{
|
|
|
|
zero();
|
|
|
|
get(logicnum, _nolock, _nordir, _sysdirop);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TDir::TDir(const TDir& d)
|
1996-08-09 13:44:22 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
_dir = d._dir;
|
1996-08-09 13:44:22 +00:00
|
|
|
_num = d._num;
|
|
|
|
_com = d._com;
|
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
TDir::~TDir ()
|
2008-12-10 16:52:43 +00:00
|
|
|
{ }
|
1994-08-16 16:35:22 +00:00
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
const char *TDir::name () const
|
1995-07-17 16:58:13 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
return _dir.SysName;
|
1994-08-22 09:47:35 +00:00
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
|
2008-10-08 10:23:29 +00:00
|
|
|
const char* TDir::filename() const
|
1995-07-17 16:58:13 +00:00
|
|
|
{
|
2008-10-08 10:23:29 +00:00
|
|
|
TString& tmp = get_tmp_string();
|
2008-12-10 16:52:43 +00:00
|
|
|
tmp = CAddPref(_dir.SysName);
|
2008-10-08 10:23:29 +00:00
|
|
|
for (int i=tmp.len()-1; i>=0; i--)
|
1997-06-12 15:49:41 +00:00
|
|
|
{
|
2008-10-08 10:23:29 +00:00
|
|
|
const char c = tmp[i];
|
|
|
|
if (is_slash(c))
|
1997-06-12 15:49:41 +00:00
|
|
|
{
|
2008-10-08 10:23:29 +00:00
|
|
|
tmp << ".dbf";
|
1997-06-12 15:49:41 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (c == '.')
|
|
|
|
break;
|
|
|
|
}
|
2008-10-08 10:23:29 +00:00
|
|
|
return tmp;
|
1995-07-17 16:58:13 +00:00
|
|
|
}
|
|
|
|
|
2008-10-08 10:23:29 +00:00
|
|
|
void TDir::set_name(const char* name)
|
1995-07-17 16:58:13 +00:00
|
|
|
{
|
|
|
|
CHECK(name != NULL, "NULL Filename");
|
|
|
|
CHECK(strlen(name) < 42, "Name too long");
|
1997-06-12 15:49:41 +00:00
|
|
|
|
|
|
|
for (int i=strlen(name); i>0; i--)
|
|
|
|
{
|
|
|
|
char c = name[i-1];
|
|
|
|
if (c == '\\' || c == '/')
|
|
|
|
break;
|
|
|
|
else
|
|
|
|
if (c == '.')
|
|
|
|
c = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
strncpy(_dir.SysName, name, 42);
|
|
|
|
_dir.SysName[41] = '\0';
|
1995-07-17 16:58:13 +00:00
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
const char *TDir::des () const
|
1995-07-03 07:49:30 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
return _dir.Des;
|
1994-08-22 09:47:35 +00:00
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
|
1995-05-29 10:25:10 +00:00
|
|
|
const char* TDir::tab_des(const char* tab)
|
1995-05-09 09:12:26 +00:00
|
|
|
{
|
1995-05-29 10:25:10 +00:00
|
|
|
const char* t = tab; if (t[0] == '$' || t[0] == '%') t++;
|
|
|
|
|
2003-03-27 12:14:51 +00:00
|
|
|
TString& tmp = get_tmp_string();
|
1995-05-29 10:25:10 +00:00
|
|
|
tmp << DESCDIR << "/d" << t << ".des";
|
1995-07-03 07:49:30 +00:00
|
|
|
|
1995-05-29 10:25:10 +00:00
|
|
|
TConfig cnf(tmp, DESCTAB);
|
2003-03-27 12:14:51 +00:00
|
|
|
tmp = cnf.get("Description", NULL, -1, tab);
|
1995-05-09 09:12:26 +00:00
|
|
|
|
2003-03-27 12:14:51 +00:00
|
|
|
return tmp;
|
1995-05-09 09:12:26 +00:00
|
|
|
}
|
|
|
|
|
1994-08-16 16:35:22 +00:00
|
|
|
|
1995-05-09 09:12:26 +00:00
|
|
|
const char *TDir::expr () const
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
return _dir.FCalc;
|
1994-08-22 09:47:35 +00:00
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
TRecnotype TDir::eod () const
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
return _dir.EOD;
|
1994-08-22 09:47:35 +00:00
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
TRecnotype TDir::eox () const
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
return _dir.EOX;
|
1994-08-22 09:47:35 +00:00
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
long TDir::flags () const
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
return _dir.Flags;
|
1994-08-22 09:47:35 +00:00
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
word TDir::len () const
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
return _dir.LenR;
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
int TDir::status (TDirtype dirop) const
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
|
|
|
return fdir[dirop].IOR;
|
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
void TDir::set_len (const UINT16 len)
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
_dir.LenR = len;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TDir::set_flags(const RecNoType f)
|
|
|
|
{
|
|
|
|
_dir.Flags = f;
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
void TDir::set_eox(const RecNoType eox)
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
_dir.EOX = eox;
|
|
|
|
if (eox < eod())
|
|
|
|
set_eod(eox);
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
void TDir::reset_eox()
|
|
|
|
{ set_eox(0); }
|
|
|
|
|
|
|
|
void TDir::set_eod(const RecNoType eod)
|
2003-07-03 08:43:59 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
_dir.EOD = eod;
|
|
|
|
if (eod > eox())
|
|
|
|
set_eox(eod);
|
2003-07-03 08:43:59 +00:00
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
void TDir::set (const char *name, const RecNoType eod, const RecNoType flag, const char *des, const char *calc)
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
strncpy (_dir.SysName, name, sizeof (_dir.SysName));
|
|
|
|
set_eod(eod);
|
|
|
|
set_flags(flag);
|
|
|
|
strncpy(_dir.Des, des, sizeof (_dir.Des));
|
|
|
|
strncpy(_dir.FCalc, calc, sizeof (_dir.FCalc));
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
|
|
|
|
1995-06-27 10:18:49 +00:00
|
|
|
// @mfunc Aggiorna l'oggetto TDir con i parametri del file
|
|
|
|
void TDir::get (
|
|
|
|
int nfile, // @parm Numero del file con cui aggiornare l'oggetto
|
|
|
|
TReclock lock, // @parm Tipo di blocco (default _nolock)
|
|
|
|
TDirtype dirtype, // @parm Direttorio nella quale e' contenuto il file (default _nordir)
|
|
|
|
TDirop op) // @parm Tipo di operazioni effettuabili sul file (default _nordirop)
|
1994-08-16 16:35:22 +00:00
|
|
|
|
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
const int whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
|
1994-08-16 16:35:22 +00:00
|
|
|
|
1994-08-17 07:58:50 +00:00
|
|
|
if (op == _nordirop)
|
2008-12-10 16:52:43 +00:00
|
|
|
COpenFile (nfile, &_dir, int(lock), whichdir);
|
1994-08-17 07:58:50 +00:00
|
|
|
else
|
2008-12-10 16:52:43 +00:00
|
|
|
CGetFile (nfile, &_dir, int(lock), whichdir);
|
1994-08-17 07:58:50 +00:00
|
|
|
_num = nfile;
|
2008-12-10 16:52:43 +00:00
|
|
|
_com = _dir.SysName[0] != '$';
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
|
|
|
|
1995-06-27 10:18:49 +00:00
|
|
|
// @mfunc Aggiorna il file indicato con i parametri passati
|
|
|
|
void TDir::put (
|
|
|
|
int nfile, // @parm Numero del file da aggiornare
|
|
|
|
TDirtype dirtype, // @parm Direttorio nella quale e' contenuto il file (default _nordir)
|
|
|
|
TDirop op) // @parm Tipo di operazioni effettuabili sul file (default _nordirop)
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
1995-05-30 16:01:38 +00:00
|
|
|
CHECKD(nfile > 0, "Bad file number ", nfile);
|
|
|
|
|
|
|
|
const int whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
|
1994-08-16 16:35:22 +00:00
|
|
|
|
1994-08-17 07:58:50 +00:00
|
|
|
if (op == _nordirop)
|
2008-12-10 16:52:43 +00:00
|
|
|
CCloseFile (nfile, &_dir, whichdir);
|
1994-08-17 07:58:50 +00:00
|
|
|
else
|
2008-12-10 16:52:43 +00:00
|
|
|
CPutFile (nfile, &_dir, whichdir);
|
1994-08-17 07:58:50 +00:00
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
void TDir::zero ()
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
zerofdes(&_dir);
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1996-09-05 08:13:10 +00:00
|
|
|
void TDir::print_on (ostream & out) const
|
|
|
|
{
|
|
|
|
out << _num << '\n';
|
|
|
|
out << (int)_com << '\n';
|
2008-12-10 16:52:43 +00:00
|
|
|
out << _dir.SysName << '|';
|
|
|
|
out << _dir.EOD << '|';
|
|
|
|
out << _dir.EOX << '|';
|
|
|
|
out << _dir.LenR << '|';
|
|
|
|
out << _dir.Flags << '|';
|
|
|
|
out << _dir.Des << '|';
|
|
|
|
out << _dir.FCalc << '|';
|
|
|
|
out << _dir.GenPrompt << '|' << '\n';
|
1996-09-05 08:13:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void TDir::read_from (istream & in)
|
|
|
|
{
|
2008-10-08 10:23:29 +00:00
|
|
|
TToken_string line(256, '|');
|
|
|
|
char* buf = line.get_buffer();
|
|
|
|
const int bufsize = line.size();
|
|
|
|
|
|
|
|
in.getline (buf, bufsize, '\n');
|
|
|
|
_num = atoi(buf);
|
|
|
|
in.getline (buf, bufsize, '\n');
|
|
|
|
_com = atoi(buf) != 0;
|
|
|
|
in.getline (buf, bufsize, '\n');
|
|
|
|
|
1996-09-05 08:13:10 +00:00
|
|
|
line.restart();
|
2008-12-10 16:52:43 +00:00
|
|
|
strncpy(_dir.SysName, line.get(), sizeof(_dir.SysName));
|
|
|
|
_dir.EOD = line.get_long();
|
|
|
|
_dir.EOX = line.get_long();
|
|
|
|
_dir.LenR = line.get_int();
|
|
|
|
_dir.Flags = line.get_long();
|
|
|
|
strncpy(_dir.Des, line.get(), sizeof(_dir.Des));
|
|
|
|
strncpy(_dir.FCalc, line.get(), sizeof(_dir.FCalc));
|
|
|
|
strncpy(_dir.GenPrompt, line.get(), sizeof(_dir.GenPrompt));
|
1996-09-05 08:13:10 +00:00
|
|
|
}
|
1996-02-05 19:00:53 +00:00
|
|
|
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
|
|
// @mfunc Ritorna il numero di file presenti nella directory <p dirtype>
|
|
|
|
//
|
|
|
|
// @rdesc Ritorna il numero di file presenti
|
|
|
|
int TDir::items (
|
|
|
|
TDirtype dirtype) const // @parm Directory della quale contare i file
|
1994-08-16 16:35:22 +00:00
|
|
|
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
const int whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
|
1994-08-22 09:47:35 +00:00
|
|
|
FileDes f;
|
2008-12-10 16:52:43 +00:00
|
|
|
CGetFile (LF_DIR, &f, _nolock, whichdir);
|
1994-08-22 09:47:35 +00:00
|
|
|
return (int) f.EOD;
|
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
TTrec::TTrec (int logicnum) : _des(NULL), _num(-1)
|
|
|
|
{
|
|
|
|
zero();
|
|
|
|
get(logicnum);
|
|
|
|
}
|
1996-09-26 15:26:47 +00:00
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
|
|
|
|
TTrec::TTrec () : _des(NULL), _num(-1)
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
zero ();
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
TTrec::TTrec(const TTrec & r) : _des(NULL)
|
1996-08-09 13:44:22 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
_rec = r._rec;
|
1996-08-09 13:44:22 +00:00
|
|
|
_num = r._num;
|
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
TTrec::~TTrec ()
|
2008-12-10 16:52:43 +00:00
|
|
|
{ }
|
1994-08-16 16:35:22 +00:00
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
int TTrec::compare(const TSortable & a) const
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
|
|
|
const TTrec & r = (const TTrec &) a;
|
1997-05-14 11:01:50 +00:00
|
|
|
int res = 0;
|
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
if (_rec.NFields != r._rec.NFields || _rec.NKeys != r._rec.NKeys) // Confronta prima il numero dei campi o il numero delle chiavi
|
1997-05-14 11:01:50 +00:00
|
|
|
res = 1;
|
|
|
|
else
|
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
const int nkeys = _rec.NKeys;
|
1997-05-14 11:01:50 +00:00
|
|
|
for (int i=0; i<nkeys && res==0; i++) // scorre la lista delle chiavi (sono meno del numero di campi)
|
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
const KeyDes& k1 = _rec.Ky[i];
|
|
|
|
const KeyDes& k2 = r._rec.Ky[i];
|
1997-05-14 11:01:50 +00:00
|
|
|
if (k1.DupKeys != k2.DupKeys || k1.NkFields != k2.NkFields)
|
|
|
|
res = 1;
|
|
|
|
else
|
|
|
|
for (int j=0; j<k1.NkFields && res==0; j++)
|
|
|
|
if (k1.FieldSeq[j] != k2.FieldSeq[j] || k1.FromCh[j] != k2.FromCh[j]
|
|
|
|
|| (k1.FromCh[j] != INVFLD && k1.ToCh[j] != k2.ToCh[j]))
|
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (res == 0) // se sono ancora uguali confronta tutti i campi
|
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
const int nflds = _rec.NFields;
|
1997-05-14 11:01:50 +00:00
|
|
|
for (int n=0; n<nflds && res==0; n++)
|
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
const RecFieldDes& r1 = _rec.Fd[n];
|
|
|
|
const RecFieldDes& r2 = r._rec.Fd[n];
|
1997-05-14 11:01:50 +00:00
|
|
|
if (r1.TypeF != r2.TypeF || r1.Len != r2.Len || r1.Dec != r2.Dec)
|
|
|
|
res = 1;
|
|
|
|
else
|
|
|
|
if (strcmp(r1.Name,r2.Name) != 0)
|
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1996-05-08 11:09:13 +00:00
|
|
|
return res;
|
1994-08-22 09:47:35 +00:00
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
|
1996-05-08 11:09:13 +00:00
|
|
|
void TTrec::rehash()
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
1996-09-26 15:26:47 +00:00
|
|
|
int pos, tmppos, nf, i;
|
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
for (i = 0; i < MaxFields; i++) _rec.SortFd[i] = INVFLD;
|
|
|
|
if (_rec.NFields)
|
1996-09-26 15:26:47 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
if (_rec.NFields> MaxFields)
|
1999-04-06 15:34:39 +00:00
|
|
|
fatal_box("Troppi campi in questo tracciato") ;
|
2008-12-10 16:52:43 +00:00
|
|
|
for (i = 0; i < _rec.NFields; i++)
|
1996-09-26 15:26:47 +00:00
|
|
|
{
|
|
|
|
nf = i;
|
2008-12-10 16:52:43 +00:00
|
|
|
pos = hashfun(_rec.Fd[nf].Name);
|
1996-09-26 15:26:47 +00:00
|
|
|
while (TRUE)
|
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
if (_rec.SortFd[pos] == INVFLD)
|
1996-09-26 15:26:47 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
_rec.SortFd[pos] = (byte) nf;
|
1996-09-26 15:26:47 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
if (strcmp(_rec.Fd[_rec.SortFd[pos]].Name, _rec.Fd[nf].Name) <= 0)
|
1996-09-26 15:26:47 +00:00
|
|
|
{
|
|
|
|
pos++;
|
|
|
|
if (pos >= MaxFields)
|
|
|
|
pos = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
tmppos = _rec.SortFd[pos];
|
|
|
|
_rec.SortFd[pos] = (byte) nf;
|
1996-09-26 15:26:47 +00:00
|
|
|
nf = tmppos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-12-10 16:52:43 +00:00
|
|
|
_rec.Fd[0].RecOff = 1;
|
|
|
|
for (i = 1; i < _rec.NFields; i++)
|
|
|
|
_rec.Fd[i].RecOff = _rec.Fd[i - 1].RecOff + _rec.Fd[i - 1].Len;
|
1996-09-26 15:26:47 +00:00
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
TTrec & TTrec::operator = (const TTrec & b)
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
_num = b._num;
|
2008-12-10 16:52:43 +00:00
|
|
|
_rec = b._rec;
|
1994-08-17 07:58:50 +00:00
|
|
|
return *this;
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
|
|
|
|
1995-06-27 10:18:49 +00:00
|
|
|
// @mfunc Assegna all'oggetto TTrec il tracciato record del file indicato
|
|
|
|
void TTrec::get (
|
|
|
|
int nfile, // @parm Numero del file da cui estrarre il tracciato record
|
|
|
|
TDirtype dirtype) // @parm Direttorio nella quale e' contenuto il file (default _nordir)
|
1994-08-16 16:35:22 +00:00
|
|
|
|
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
const int whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
|
|
|
|
CGetRec (nfile, &_rec, whichdir);
|
1994-08-17 07:58:50 +00:00
|
|
|
_num = nfile;
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
|
|
|
|
1995-06-27 10:18:49 +00:00
|
|
|
// @mfunc Setta il file indicato con il tracciato record dell'oggetto
|
|
|
|
void TTrec::put (
|
|
|
|
int nfile, // @parm Numero del file di cui settare il tracciato record
|
|
|
|
TDirtype dirtype) // @parm Direttorio nella quale e' contenuto il file (default _nordir)
|
1994-08-16 16:35:22 +00:00
|
|
|
|
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
|
1994-08-16 16:35:22 +00:00
|
|
|
|
1994-08-17 07:58:50 +00:00
|
|
|
if (nfile <= 0)
|
|
|
|
fatal_box ("Bad file number %d", nfile);
|
2008-12-10 16:52:43 +00:00
|
|
|
CPutRec (nfile, &_rec, _whichdir);
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
void TTrec::zero ()
|
1994-08-16 16:35:22 +00:00
|
|
|
|
|
|
|
{
|
2004-03-12 15:08:44 +00:00
|
|
|
int i;
|
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
_rec.NFields = 0;
|
2004-03-12 15:08:44 +00:00
|
|
|
for (i = 0; i < MaxFields; i++)
|
1996-08-09 13:44:22 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
strcpy(_rec.Fd[i].Name, "");
|
|
|
|
_rec.Fd[i].TypeF = _nullfld;
|
|
|
|
_rec.Fd[i].Len = 0;
|
|
|
|
_rec.Fd[i].Dec = 0;
|
|
|
|
_rec.Fd[i].RecOff = 0;
|
|
|
|
_rec.SortFd[i] = INVFLD;
|
1996-08-09 13:44:22 +00:00
|
|
|
}
|
2008-12-10 16:52:43 +00:00
|
|
|
_rec.NKeys = 0;
|
1996-08-09 13:44:22 +00:00
|
|
|
for (i = 1; i < MaxKeys; i++)
|
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
_rec.Ky[i].DupKeys = FALSE;
|
|
|
|
_rec.Ky[i].NkFields = 0;
|
1996-08-09 13:44:22 +00:00
|
|
|
for (int j = 0; j < MKFields; j++)
|
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
_rec.Ky[i].FieldSeq[j] = INVFLD;
|
|
|
|
_rec.Ky[i].FromCh[j] = INVFLD;
|
|
|
|
_rec.Ky[i].ToCh[j] = INVFLD;
|
1996-08-09 13:44:22 +00:00
|
|
|
}
|
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
int TTrec::status (TDirtype dirop) const
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
|
|
|
return rdir[dirop].IOR;
|
|
|
|
}
|
|
|
|
|
2008-04-04 16:04:15 +00:00
|
|
|
int TTrec::field(const char *name) const
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
return findfld(&_rec, name);
|
1994-08-22 09:47:35 +00:00
|
|
|
}
|
|
|
|
|
2008-10-08 10:23:29 +00:00
|
|
|
const char* TTrec::fielddef(int fld) const
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
const RecFieldDes& fd = _rec.Fd[fld];
|
2008-10-08 10:23:29 +00:00
|
|
|
TString& tmp = get_tmp_string(50);
|
|
|
|
tmp.format("%s|%d|%d|%d", fd.Name, (int)fd.TypeF, (int)fd.Len, (int)fd.Dec);
|
|
|
|
return tmp;
|
1994-08-22 09:47:35 +00:00
|
|
|
}
|
|
|
|
|
1995-02-02 18:08:50 +00:00
|
|
|
const char *TTrec ::keydef (int key) const
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
2008-10-08 10:23:29 +00:00
|
|
|
TString& s = get_tmp_string(128);
|
1994-08-22 09:47:35 +00:00
|
|
|
|
|
|
|
s = "";
|
2008-12-10 16:52:43 +00:00
|
|
|
for (int j = 0; j < _rec.Ky[key].NkFields; j++)
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
const bool upper = _rec.Ky[key].FieldSeq[j] > MaxFields;
|
|
|
|
const int nfld = _rec.Ky[key].FieldSeq[j] - (upper ? MaxFields : 0);
|
1994-08-22 09:47:35 +00:00
|
|
|
|
|
|
|
if (j)
|
|
|
|
s << "+";
|
|
|
|
if (upper)
|
|
|
|
s << "UPPER(";
|
2008-12-10 16:52:43 +00:00
|
|
|
s << _rec.Fd[nfld].Name;
|
|
|
|
if (_rec.Ky[key].FromCh[j] < INVFLD)
|
|
|
|
s << format ("[%d,%d]", _rec.Ky[key].FromCh[j] + 1,
|
|
|
|
_rec.Ky[key].ToCh[j] + 1);
|
1994-08-22 09:47:35 +00:00
|
|
|
if (upper)
|
|
|
|
s << ")";
|
|
|
|
}
|
2008-12-10 16:52:43 +00:00
|
|
|
s << (_rec.Ky[key].DupKeys ? "|X" : "| ");
|
2008-10-08 10:23:29 +00:00
|
|
|
return s;
|
1994-08-22 09:47:35 +00:00
|
|
|
}
|
|
|
|
|
2005-09-23 15:57:29 +00:00
|
|
|
int TTrec::len() const
|
|
|
|
{
|
|
|
|
const int n = fields();
|
2008-12-10 16:52:43 +00:00
|
|
|
return (n > 0 && n <= MaxFields) ? _rec.Fd[n - 1].RecOff + _rec.Fd[n - 1].Len : 0;
|
2005-09-23 15:57:29 +00:00
|
|
|
}
|
1994-08-22 09:47:35 +00:00
|
|
|
|
|
|
|
#ifndef FOXPRO
|
1994-08-16 16:35:22 +00:00
|
|
|
|
1995-02-09 14:47:31 +00:00
|
|
|
bool TDir::is_active () const
|
|
|
|
{
|
1995-05-30 16:01:38 +00:00
|
|
|
const int module = abs((int)flags());
|
1995-02-09 14:47:31 +00:00
|
|
|
return main_app().has_module(module, CHK_DONGLE);
|
|
|
|
}
|
|
|
|
|
2008-04-04 16:04:15 +00:00
|
|
|
void TTrec::update_fielddef (int nfld, TToken_string& s)
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
RecFieldDes& rfd = _rec.Fd[nfld];
|
2008-04-04 16:04:15 +00:00
|
|
|
strcpy (rfd.Name, s.get(0));
|
|
|
|
rfd.TypeF = s.get_int ();
|
|
|
|
rfd.Len = s.get_int ();
|
|
|
|
rfd.Dec = s.get_int ();
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
2008-04-04 16:04:15 +00:00
|
|
|
void TTrec::update_keydef (int key, TToken_string& s)
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
1994-08-17 07:58:50 +00:00
|
|
|
TExpression expr ("", _strexpr);
|
2008-04-04 16:04:15 +00:00
|
|
|
TString ke (s.get(0));
|
1994-08-17 07:58:50 +00:00
|
|
|
|
2008-04-04 16:04:15 +00:00
|
|
|
if (expr.set(ke, _strexpr))
|
1996-11-04 11:02:43 +00:00
|
|
|
{
|
2008-04-04 16:04:15 +00:00
|
|
|
const char* dup = s.get();
|
2008-12-10 16:52:43 +00:00
|
|
|
_rec.Ky[key].DupKeys = (dup && *dup != ' ');
|
1994-08-22 09:47:35 +00:00
|
|
|
TCodearray & c = expr.code ();
|
|
|
|
c.begin ();
|
|
|
|
int n = 0;
|
|
|
|
while (!c.end ())
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
1994-08-22 09:47:35 +00:00
|
|
|
TCode & inst = c.step ();
|
|
|
|
TCodesym sym = inst.getsym ();
|
|
|
|
|
|
|
|
if (sym == _variable)
|
|
|
|
{
|
|
|
|
const char *s = inst.string ();
|
2004-03-12 15:08:44 +00:00
|
|
|
int i;
|
1994-08-22 09:47:35 +00:00
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
for (i = 0; i < _rec.NFields; i++)
|
|
|
|
if (strcmp (_rec.Fd[i].Name, s) == 0)
|
1994-08-22 09:47:35 +00:00
|
|
|
break;
|
|
|
|
|
2008-12-10 16:52:43 +00:00
|
|
|
_rec.Ky[key].FieldSeq[n] = i;
|
|
|
|
_rec.Ky[key].FromCh[n] = INVFLD;
|
|
|
|
_rec.Ky[key].ToCh[n] = INVFLD;
|
1994-08-22 09:47:35 +00:00
|
|
|
inst = c.step ();
|
|
|
|
sym = inst.getsym ();
|
|
|
|
if (sym == _upper)
|
2008-12-10 16:52:43 +00:00
|
|
|
_rec.Ky[key].FieldSeq[n] += MaxFields;
|
1994-08-22 09:47:35 +00:00
|
|
|
else if (sym == _number)
|
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
_rec.Ky[key].FromCh[n] = (int)inst.number().integer() - 1;
|
1994-08-22 09:47:35 +00:00
|
|
|
inst = c.step ();
|
2008-12-10 16:52:43 +00:00
|
|
|
_rec.Ky[key].ToCh[n] = _rec.Ky[key].FromCh[n] + (int)inst.number ().integer () - 1;
|
1994-08-22 09:47:35 +00:00
|
|
|
inst = c.step ();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
c.backtrace ();
|
|
|
|
n++;
|
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
2008-12-10 16:52:43 +00:00
|
|
|
_rec.Ky[key].NkFields = n;
|
1994-08-22 09:47:35 +00:00
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
|
|
|
|
2008-04-04 16:04:15 +00:00
|
|
|
void TTrec::print_on(ostream & out) const
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
1996-05-24 13:11:23 +00:00
|
|
|
const int n = num();
|
|
|
|
out << n;
|
1997-05-14 11:01:50 +00:00
|
|
|
if (_des && n>=LF_TABGEN && n<=LF_TAB && _tab.not_empty()) // Solo se e' una tabella...
|
1996-05-24 13:11:23 +00:00
|
|
|
out << "|" << _tab;
|
|
|
|
out << '\n';
|
1994-08-22 09:47:35 +00:00
|
|
|
const int nfields = fields ();
|
|
|
|
TToken_string s (80);
|
2004-03-12 15:08:44 +00:00
|
|
|
int i;
|
1994-08-22 09:47:35 +00:00
|
|
|
|
|
|
|
out << nfields << '\n';
|
2004-03-12 15:08:44 +00:00
|
|
|
for (i = 0; i < nfields; i++)
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
|
|
|
s = fielddef (i);
|
1996-05-24 13:11:23 +00:00
|
|
|
out << s ;
|
|
|
|
if (_des)
|
2008-12-10 16:52:43 +00:00
|
|
|
out << "|" << _des->get(_rec.Fd[i].Name);
|
1996-05-24 13:11:23 +00:00
|
|
|
out << '\n';
|
1994-08-22 09:47:35 +00:00
|
|
|
}
|
|
|
|
const int nkeys = keys ();
|
|
|
|
|
|
|
|
out << nkeys << '\n';
|
|
|
|
for (i = 0; i < nkeys; i++)
|
|
|
|
{
|
|
|
|
s = keydef (i);
|
|
|
|
out << s << '\n';
|
|
|
|
}
|
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
|
2008-04-04 16:04:15 +00:00
|
|
|
void TTrec::read_from(istream & in)
|
1994-08-16 16:35:22 +00:00
|
|
|
{
|
1996-05-24 13:11:23 +00:00
|
|
|
const int n = num();
|
1994-08-16 16:35:22 +00:00
|
|
|
|
2008-04-04 16:04:15 +00:00
|
|
|
TToken_string t(256);
|
|
|
|
in.getline (t.get_buffer(), t.size(), '\n');
|
|
|
|
if (_des && n >= LF_TABGEN && n <= LF_TAB)
|
1996-05-24 13:11:23 +00:00
|
|
|
{
|
2003-07-23 07:47:28 +00:00
|
|
|
if (t.find('|') >= 0)
|
1996-05-24 13:11:23 +00:00
|
|
|
{
|
2003-07-23 07:47:28 +00:00
|
|
|
const TString4 tabname(t.right(3));
|
2008-04-04 16:04:15 +00:00
|
|
|
t.rtrim(4); // Toglie il nome della tabella
|
|
|
|
if (_tab != tabname && !yesno_box("Descrizione relativa alla tabella %s.\n Continuare?",(const char*) tabname))
|
1996-05-24 13:11:23 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2008-04-04 16:04:15 +00:00
|
|
|
const int ln = t.get_int(0);
|
|
|
|
if (n > 0 && ln != n && !yesno_box ("Descrizione relativa al file n.ro %d.\n Continuare?", ln))
|
1994-08-16 16:35:22 +00:00
|
|
|
return;
|
|
|
|
|
2008-04-04 16:04:15 +00:00
|
|
|
in.getline (t.get_buffer(), t.size(), '\n');
|
|
|
|
const int nfields = t.get_int(0);
|
1994-08-17 07:58:50 +00:00
|
|
|
set_fields (nfields);
|
2004-03-12 15:08:44 +00:00
|
|
|
|
2008-04-04 16:04:15 +00:00
|
|
|
for (int i = 0; i < nfields; i++)
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
2008-04-04 16:04:15 +00:00
|
|
|
in.getline (t.get_buffer(), t.size(), '\n');
|
|
|
|
update_fielddef (i, t);
|
1996-05-24 13:11:23 +00:00
|
|
|
const int itms = t.items();
|
2008-04-04 16:04:15 +00:00
|
|
|
if (_des && itms >= 5) // La descrizione viene caricata solo se esiste
|
2008-12-10 16:52:43 +00:00
|
|
|
_des->set(_rec.Fd[i].Name, t.get(4));
|
1994-08-22 09:47:35 +00:00
|
|
|
}
|
1994-08-16 16:35:22 +00:00
|
|
|
|
2008-04-04 16:04:15 +00:00
|
|
|
in.getline (t.get_buffer(), t.size(), '\n');
|
|
|
|
const int nkeys = t.get_int(0);
|
1994-08-17 07:58:50 +00:00
|
|
|
set_keys (nkeys);
|
2008-04-04 16:04:15 +00:00
|
|
|
for (int i = 0; i < nkeys; i++)
|
1994-08-22 09:47:35 +00:00
|
|
|
{
|
2008-04-04 16:04:15 +00:00
|
|
|
in.getline (t.get_buffer(), t.size(), '\n');
|
|
|
|
update_keydef (i, t);
|
1994-08-22 09:47:35 +00:00
|
|
|
}
|
1994-08-17 07:58:50 +00:00
|
|
|
rehash ();
|
1996-05-24 13:11:23 +00:00
|
|
|
_des = NULL;
|
|
|
|
_tab = "";
|
1994-08-16 16:35:22 +00:00
|
|
|
}
|
1994-08-22 09:47:35 +00:00
|
|
|
|
|
|
|
#endif // FOXPRO
|