#include #include #include #include #include #ifndef FOXPRO #include #include #else #include #endif #include #define BLOCKLEN 512 #define INVFLD 255 HIDDEN char _files_tmp_string[128]; TFile::TFile (int lenrec, int base) { _file = new SecDef; // if (_file == NULL) fatal_box ("Can't allocate record file "); _file->IOR = NOERR; _len = lenrec; _base = base; _file->LockMode = _manulock; _file->lpos = -1; _file->name[0] = '\0'; } TFile::~TFile () { delete _file; } // @doc EXTERNAL // @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) { COpen (_file, (char *) name, _len, _base, lockmode); } bool TFile::verify (const char *name) { CVerify (_file, (char *) name); return _file->IOR == NOERR; } // @doc EXTERNAL // @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

record { CCreate (_file, (char *) name, _len, _base, (nrecord * _len) / BLOCKLEN + 1); } void TFile::chsize (const char *name, TRecnotype nrecord) { CChsize (_file, (char *) name, _len, _base, (nrecord * _len) / BLOCKLEN + 1); } void TFile::close () { CClose (_file); } void TFile::unlink (const char *name) { CDelete (_file, (char *) name); } // @doc EXTERNAL // @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) { _file->LenRec = _len; _file->BaseFil = _base; CRead (_file, record, recnum, lock); } // @doc EXTERNAL // @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) { _file->LenRec = _len; _file->BaseFil = _base; CWrite (_file, record, recnum, lock); } int TFile::status () const { return _file->IOR; } TDir::TDir () : _num(-1), _com(FALSE) { _dir = new FileDes; if (_dir == NULL) fatal_box ("Can't allocate dir"); zero (); } TDir::~TDir () { delete _dir; } const char *TDir::name () const { return _dir->SysName; } const char *TDir::filename () const { strcpy(_files_tmp_string, _dir->SysName); strcat(_files_tmp_string, ".dbf"); return _files_tmp_string; } void TDir::set_name (const char * name) { CHECK(name != NULL, "NULL Filename"); CHECK(strlen(name) < 42, "Name too long"); char * p = strchr(name, '.'); CHECK(p == NULL, "Can't use extension"); if (p) p = '\0'; strncpy(_dir->SysName, _files_tmp_string, 42); _dir->SysName[41] = '\0'; } const char *TDir::des () const { return _dir->Des; } const char* TDir::tab_des(const char* tab) { const char* t = tab; if (t[0] == '$' || t[0] == '%') t++; TString256 tmp; tmp << DESCDIR << "/d" << t << ".des"; #ifndef FOXPRO TConfig cnf(tmp, DESCTAB); t = cnf.get("Description", NULL, -1, tab); #endif return strcpy(__tmp_string, t); } const char *TDir::expr () const { return _dir->FCalc; } TRecnotype & TDir::eod () const { return _dir->EOD; } TRecnotype & TDir::eox () const { return _dir->EOX; } TRecnotype & TDir::flags () const { return _dir->Flags; } word & TDir::len () { return (word &) _dir->LenR; } int TDir::status (TDirtype dirop) const { return fdir[dirop].IOR; } void TDir::set_len (const UINT16 len) { _dir->LenR = len; } void TDir::set_eox (const RecNoType eox) { _dir->EOX = eox; } void TDir::set (const char *name, const RecNoType eod, const RecNoType flag, const char *des, const char *calc) { strncpy (_dir->SysName, name, sizeof (_dir->SysName)); _dir->EOD = eod; _dir->Flags = flag; strncpy (_dir->Des, des, sizeof (_dir->Des)); strncpy (_dir->FCalc, calc, sizeof (_dir->FCalc)); } // @doc EXTERNAL // @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) { int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR); if (op == _nordirop) COpenFile (nfile, _dir, int (lock), _whichdir); else CGetFile (nfile, _dir, int (lock), _whichdir); _num = nfile; _com = _dir->SysName[0] != '$'; } // @doc EXTERNAL // @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) { CHECKD(nfile > 0, "Bad file number ", nfile); const int whichdir = (dirtype == _nordir ? NORDIR : COMDIR); if (op == _nordirop) CCloseFile (nfile, _dir, whichdir); else CPutFile (nfile, _dir, whichdir); } void TDir::zero () { zerofdes (_dir); } // @doc EXTERNAL // @mfunc Ritorna il numero di file presenti nella directory

// // @rdesc Ritorna il numero di file presenti int TDir::items ( TDirtype dirtype) const // @parm Directory della quale contare i file { FileDes f; int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR); CGetFile (1, &f, _nolock, _whichdir); return (int) f.EOD; } TTrec::TTrec () { _des = NULL; _tab = ""; _rec = new RecDes; zero (); _num = -1; } TTrec::~TTrec () { delete _rec; } int TTrec::compare(const TSortable & a) const { const TTrec & r = (const TTrec &) a; const int res = memcmp ((const void *) _rec, (const void *) r._rec, sizeof (*_rec)); return res; } void TTrec::rehash() { setrdes (_rec); } TTrec & TTrec::operator = (const TTrec & b) { _num = b._num; memcpy (_rec, b._rec, sizeof (*_rec)); return *this; } // @doc EXTERNAL // @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) { int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR); CGetRec (nfile, _rec, _whichdir); _num = nfile; } // @doc EXTERNAL // @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) { int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR); if (nfile <= 0) fatal_box ("Bad file number %d", nfile); CPutRec (nfile, _rec, _whichdir); } void TTrec::zero () { zerordes (_rec); } int TTrec::status (TDirtype dirop) const { return rdir[dirop].IOR; } int TTrec ::field (const char *name) const { return findfld (_rec, (char *) name); } const char *TTrec ::fielddef (int fld) const { sprintf (_files_tmp_string, "%s|%d|%d|%d", _rec->Fd[fld].Name, (int) _rec->Fd[fld].TypeF, (int) _rec->Fd[fld].Len, (int) _rec->Fd[fld].Dec); return _files_tmp_string; } const char *TTrec ::keydef (int key) const { TFixed_string s (_files_tmp_string, 128); s = ""; for (int j = 0; j < _rec->Ky[key].NkFields; j++) { const bool upper = _rec->Ky[key].FieldSeq[j] > MaxFields; const int nfld = _rec->Ky[key].FieldSeq[j] - (upper ? MaxFields : 0); if (j) s << "+"; if (upper) s << "UPPER("; 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); if (upper) s << ")"; } s << (_rec->Ky[key].DupKeys ? "|X" : "| "); return (const char *) s; } #ifndef FOXPRO bool TDir::is_active () const { const int module = abs((int)flags()); return main_app().has_module(module, CHK_DONGLE); } void TTrec::update_fielddef (int nfld, const char *desc) { TToken_string s (desc); strcpy (_rec->Fd[nfld].Name, s.get ()); _rec->Fd[nfld].TypeF = s.get_int (); _rec->Fd[nfld].Len = s.get_int (); _rec->Fd[nfld].Dec = s.get_int (); } void TTrec::update_keydef (int key, const char *desc) { TExpression expr ("", _strexpr); TToken_string s (desc); TString ke (s.get ()); if (expr.set ((const char *) ke, _strexpr)) { _rec->Ky[key].DupKeys = (*s.get () != ' '); TCodearray & c = expr.code (); c.begin (); int n = 0; while (!c.end ()) { TCode & inst = c.step (); TCodesym sym = inst.getsym (); if (sym == _variable) { const char *s = inst.string (); for (int i = 0; i < _rec->NFields; i++) if (strcmp (_rec->Fd[i].Name, s) == 0) break; _rec->Ky[key].FieldSeq[n] = i; _rec->Ky[key].FromCh[n] = INVFLD; _rec->Ky[key].FromCh[n] = INVFLD; inst = c.step (); sym = inst.getsym (); if (sym == _upper) _rec->Ky[key].FieldSeq[n] += MaxFields; else if (sym == _number) { _rec->Ky[key].FromCh[n] = (int)inst.number().integer() - 1; inst = c.step (); _rec->Ky[key].ToCh[n] = _rec->Ky[key].FromCh[n] + (int)inst.number ().integer () - 1; inst = c.step (); } else c.backtrace (); n++; } } _rec->Ky[key].NkFields = n; } } void TTrec::print_on (ostream & out) const { const int n = num(); out << n; if (_des && n>=3 && n<=5) // Solo se e' una tabella... out << "|" << _tab; out << '\n'; const int nfields = fields (); TToken_string s (80); out << nfields << '\n'; for (int i = 0; i < nfields; i++) { s = fielddef (i); out << s ; if (_des) out << "|" << _des->get(_rec->Fd[i].Name); out << '\n'; } const int nkeys = keys (); out << nkeys << '\n'; for (i = 0; i < nkeys; i++) { s = keydef (i); out << s << '\n'; } } void TTrec::read_from (istream & in) { int ln; const int n = num(); in.getline (_files_tmp_string, sizeof (_files_tmp_string), '\n'); if (_des && n>=3 && n<=5) { TString t(_files_tmp_string); if (t.find('|')>-1) { TString tabname(t.right(3)); strcpy(_files_tmp_string,t.left(t.len()-4)); // Toglie il nome della tabella if (_tab != tabname && !yesno_box("Descrizione relativa alla tabella %s.\n Continuo ?",(const char*) tabname)) return; } } ln = atoi (_files_tmp_string); if (ln != n && !yesno_box ("Descrizione relativa al file n.ro %d.\n Continuo ?", ln)) return; int nfields; in.getline (_files_tmp_string, sizeof (_files_tmp_string), '\n'); nfields = atoi (_files_tmp_string); set_fields (nfields); TToken_string t; for (int i = 0; i < nfields; i++) { in.getline (_files_tmp_string, sizeof (_files_tmp_string), '\n'); t = _files_tmp_string; const int itms = t.items(); if (_des && itms == 5) // La descrizione viene caricata solo se esiste _des->set(_rec->Fd[i].Name, t.get(itms-1)); update_fielddef (i, _files_tmp_string); } int nkeys; in.getline (_files_tmp_string, sizeof (_files_tmp_string), '\n'); nkeys = atoi (_files_tmp_string); set_keys (nkeys); for (i = 0; i < nkeys; i++) { in.getline (_files_tmp_string, sizeof (_files_tmp_string), '\n'); update_keydef (i, _files_tmp_string); } rehash (); _des = NULL; _tab = ""; } #endif // FOXPRO