#include #include #include #include #include #include #ifndef __EXTCDECL_H #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; } void TFile::open(const char* name, TFilelock lockmode) { COpen(_file, (char*) name, _len, _base, lockmode); } bool TFile::verify(const char* name) { CVerify(_file, (char*) name); return _file->IOR == NOERR; } void TFile::create(const char* name, TRecnotype nrecord) { 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); } void TFile::read(char* record, TRecnotype recnum, TReclock lock) { _file->LenRec = _len; _file->BaseFil = _base; CRead(_file, record, recnum, lock); } void TFile::write(char* record, TRecnotype recnum, TReclock lock) { _file->LenRec = _len; _file->BaseFil = _base; CWrite(_file, record, recnum, lock); } int TFile::status() const { return _file->IOR; } TDir::TDir() { _dir = new FileDes; if (_dir == NULL) fatal_box("Can't allocate dir"); zero(); _num = - 1; } TDir::~TDir() { delete _dir; } const char* TDir::name() const { return _dir->SysName; } const char* TDir::des() const { return _dir->Des; } 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)); } void TDir::get(int nfile, TReclock lock, TDirtype dirtype, TDirop op) { int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR); if (op == _nordirop) COpenFile(nfile, _dir, int(lock), _whichdir); else CGetFile(nfile, _dir, int(lock), _whichdir); _num = nfile; } void TDir::put(int nfile, TDirtype dirtype, TDirop op) { int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR); if (nfile <= 0) fatal_box("Bad file number %d", nfile); if (op == _nordirop) CCloseFile(nfile, _dir, _whichdir); else CPutFile(nfile, _dir, _whichdir); } void TDir::zero() { zerofdes(_dir); } int TDir::items(TDirtype dirtype) const { FileDes f; int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR); CGetFile(1, &f, _nolock, _whichdir); return (int)f.EOD; } TTrec::TTrec() { _rec = new RecDes; if (_rec == NULL) fatal_box("Can't allocate record description"); 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; } void TTrec::get(int nfile, TDirtype dirtype) { int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR); CGetRec(nfile, _rec, _whichdir); _num = nfile; } void TTrec::put(int nfile, TDirtype dirtype) { 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; } 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] = inst.number().integer() - 1; inst = c.step(); _rec->Ky[key].ToCh[n] = _rec->Ky[key].FromCh[n] + inst.number().integer() - 1; inst = c.step(); } else c.backtrace(); n++; } } _rec->Ky[key].NkFields = n; } } void TTrec::print_on(ostream& out) const { out << num() << '\n'; const int nfields = fields(); TToken_string s(80); out << nfields << '\n'; for (int i = 0; i < nfields; i++) { s = fielddef(i); out << s << '\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; in.getline(_files_tmp_string, sizeof(_files_tmp_string), '\n'); ln = atoi(_files_tmp_string); if (ln != num() && !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); for (int i = 0; i < nfields; i++) { in.getline(_files_tmp_string, sizeof(_files_tmp_string), '\n'); 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(); }