2170 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			2170 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| 
 | |
| #define __ISAM_CPP
 | |
| 
 | |
| #ifndef FOXPRO
 | |
| #include <applicat.h>
 | |
| #include <expr.h>
 | |
| #include <execp.h>
 | |
| #include <progind.h>
 | |
| #endif
 | |
| 
 | |
| #include <config.h>
 | |
| #include <extcdecl.h>
 | |
| #include <mailbox.h>
 | |
| #include <prefix.h>
 | |
| #include <relation.h>
 | |
| #include <scanner.h>
 | |
| #include <utility.h>
 | |
| 
 | |
| #if XVT_OS==XVT_OS_SCOUNIX
 | |
| #include <sys/types.h>
 | |
| #include <sys/stat.h>
 | |
| #include <unistd.h>
 | |
| #else
 | |
| #include <direct.h>
 | |
| #include <process.h>
 | |
| #endif
 | |
| 
 | |
| #define NOT_LINKED(i,f) CHECKS(i != NULL, "Record senza tracciato: impossibile eseguire ", f)
 | |
| #define NOT_OPEN(f) CHECKS(_isamfile != NULL, "File chiuso: ", f)
 | |
| 
 | |
| HIDDEN void UNKNOWN_FIELD(int num, const char* name) 
 | |
| { yesnofatal_box("Il campo '%s' non appartiene al file %d", name, num); }
 | |
| 
 | |
| #define NOALLOC (char **) -1
 | |
| 
 | |
| HIDDEN bool __autoload = TRUE;
 | |
| 
 | |
| void set_autoload_new_files(bool on)
 | |
| {
 | |
|   __autoload = on;
 | |
| }
 | |
| 
 | |
| class TExtrectype : public TRectype
 | |
| {
 | |
| public:
 | |
|   // FPUB 
 | |
| 
 | |
|   TExtrectype(const TTrec& r);  // Costruisce il record a partire da r
 | |
|   virtual ~TExtrectype();
 | |
| };
 | |
| 
 | |
| TExtrectype::TExtrectype(const TTrec& r) : TRectype(6)
 | |
|   
 | |
| {
 | |
|   delete _rec;
 | |
|   _length = r.len();
 | |
|   _rec = new char [ _length ];
 | |
|   _i = new isdef;
 | |
|   _i->r = r.rec();
 | |
|   zero();
 | |
| }
 | |
| 
 | |
| TExtrectype::~TExtrectype()
 | |
|   
 | |
| {
 | |
|   delete _rec;
 | |
|   delete _i;
 | |
| }
 | |
| 
 | |
| TBaseisamfile::TBaseisamfile(int logicnum, bool linkrecinst)
 | |
| 
 | |
| {
 | |
|   TTrec   r;
 | |
| 
 | |
|   _isamfile = NULL;
 | |
|   _logicnum = logicnum;
 | |
|   _lasterr = NOERR;
 | |
|   _delopenrec = FALSE;
 | |
|   if ((openrec[_logicnum - 1] == NULL) || (!linkrecinst))
 | |
|   {
 | |
|     _current = new TRectype(this);
 | |
|     if (openrec[_logicnum - 1] == NULL)
 | |
|     {
 | |
|       openrec[_logicnum - 1] = _current;
 | |
|       _delopenrec = TRUE;
 | |
|     }
 | |
|     _delrec = TRUE;
 | |
|   }
 | |
|   else 
 | |
|   {
 | |
|     _current = openrec[_logicnum - 1];
 | |
|     _delrec = FALSE;
 | |
|   }
 | |
| 
 | |
|   r.get(logicnum);
 | |
|   /*  
 | |
|      _historicfile = ((r.field(RFLD_SYS_DATE) != FIELDERR) &&
 | |
|      (r.field(RFLD_SYS_FIRST) != FIELDERR) &&
 | |
|      (r.field(RFLD_SYS_LAST) != FIELDERR));
 | |
|      */                   
 | |
|   _historicfile = FALSE; 
 | |
| }
 | |
| 
 | |
| 
 | |
| TBaseisamfile::~TBaseisamfile()
 | |
|   
 | |
| {
 | |
|   if (_delrec)
 | |
|   {
 | |
|     if (_delopenrec)
 | |
|       openrec[_logicnum - 1] = NULL;
 | |
|     delete _current;
 | |
|   }
 | |
|   if (_isamfile != NULL)
 | |
|     delete _isamfile;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::gethr(TRectype& rec, TDate& atdate)
 | |
|   
 | |
| {
 | |
|   TRecfield               fd0(rec, RFLD_SYS_DATE);
 | |
|   TDate                   d0((const TDate&) fd0);
 | |
|   
 | |
|   if (d0 < atdate)
 | |
|   {
 | |
|     atdate = eotime;
 | |
|     return NOERR;
 | |
|   }
 | |
|   TRectype                wr(rec);              
 | |
|   
 | |
|   TRecfield               flf(wr, RFLD_SYS_FIRST),
 | |
|   fll(wr, RFLD_SYS_LAST),
 | |
|   fd1(wr, RFLD_SYS_DATE);
 | |
|   
 | |
|   TDate                           d1;
 | |
|   TRecnotype      wr0 = -1L, wr1 = -1L;
 | |
|   
 | |
|   if ((wr0 == flf.ptr()) == -1L) return _iskeynotfound;
 | |
|   _hf.read(wr.string(), wr0);
 | |
|   if ((d1 = (const TDate&) fd1) > atdate)
 | |
|   {
 | |
|     rec = wr;
 | |
|     atdate = d0 - 1L;
 | |
|     return _iskeynotfound;
 | |
|   }
 | |
|   while ((d1 < atdate) && (wr0 > 0))
 | |
|   {
 | |
|     rec = wr;
 | |
|     wr1 = wr0;
 | |
|     if ((wr0 = fll.ptr()) > 0)
 | |
|     {
 | |
|       _hf.read(wr.string(), wr0);
 | |
|       d1 = (const TDate&) fd1;
 | |
|     }
 | |
|   }
 | |
|   if (wr0 <= 0)
 | |
|     atdate = d0 - 1L;
 | |
|   else
 | |
|     atdate = d1 - 1L;
 | |
|   return NOERR;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::addhr(const TRectype& rec, TDate& atdate)
 | |
|   
 | |
| {
 | |
|   return NOERR;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::rewhr(const TRectype& rec, TDate& atdate)
 | |
| 
 | |
| {
 | |
|   return NOERR;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::delhr(const TRectype& rec, TDate& atdate)
 | |
| 
 | |
| {
 | |
|   return NOERR;
 | |
| }
 | |
| 
 | |
| long TBaseisamfile::items() const
 | |
| {
 | |
|   return filehnd()->i.Base[filehnd()->i.PN].PEOD;
 | |
| }
 | |
| 
 | |
| const char* TBaseisamfile::name() const
 | |
| {
 | |
|   sprintf(__tmp_string, "%d", num());
 | |
|   return __tmp_string;
 | |
| }
 | |
| 
 | |
| const char* TBaseisamfile::filename() const
 | |
| {
 | |
|   if (_isamfile == NULL)
 | |
|   {
 | |
|     TDir d;
 | |
|     d.get(num());
 | |
|     return strcpy(__tmp_string, d.name());
 | |
|   }
 | |
|   return _isamfile->d->SysName;
 | |
| }
 | |
| 
 | |
| const char* TBaseisamfile::description() const
 | |
| {
 | |
|   if (_isamfile == NULL)
 | |
|   {
 | |
|     TDir d;
 | |
|     d.get(num());
 | |
|     return strcpy(__tmp_string, d.des());
 | |
|   }
 | |
|   return _isamfile->d->Des;
 | |
| }
 | |
| 
 | |
| 
 | |
| void TBaseisamfile::setkey(int nkey)
 | |
| 
 | |
| {
 | |
|   CHECKD(nkey > 0 && nkey - 1 <= _isamfile->r->NKeys, "Chiave non valida n.ro ", nkey);
 | |
|   NOT_OPEN(name());
 | |
| 
 | |
|   _isamfile->i.PN = nkey - 1;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::getkey() const
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   return _isamfile->i.PN + 1;
 | |
| }
 | |
| 
 | |
| int TBaseisamfile::first(word lockop)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   curr().setdirty();
 | |
|   cisread(_isamfile, curr().string(), _isfirst + lockop, &_lasterr);
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::last(word lockop)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   curr().setdirty();
 | |
|   cisread(_isamfile, curr().string(), _islast + lockop, &_lasterr);
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::next(word lockop)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   curr().setdirty();
 | |
|   cisread(_isamfile, curr().string(), _isnext + lockop, &_lasterr);
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::next(TDate& atdate)
 | |
|   
 | |
| {
 | |
|   TRectype                wr(curr());
 | |
|   TRecfield               fll(curr(), RFLD_SYS_LAST),
 | |
|   fd(wr, RFLD_SYS_DATE);
 | |
|   TRecnotype      wrn;
 | |
|   
 | |
|   NOT_OPEN(name());
 | |
|   if (!_historicfile)
 | |
|     error_box("%s not historic file", filename());
 | |
|   if (_lasthf == -1L) return _iseof;
 | |
|   curr().setdirty();
 | |
|   _hf.read(curr().string(), _lasthf);
 | |
|   wrn = fll.ptr();
 | |
|   if (wrn < 0L)
 | |
|   {
 | |
|     readat(-wrn);
 | |
|     atdate = eotime;
 | |
|     _lasthf = -1L;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     _hf.read(curr().string(), wrn);
 | |
|     _lasthf = wrn;
 | |
|     wrn = fll.ptr();
 | |
|     if (wrn < 0) readat(wr, -wrn);
 | |
|     else _hf.read(wr.string(), wrn);
 | |
|     atdate = (const TDate&)fd - 1L;
 | |
|   }
 | |
|   return  NOERR;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::prev(word lockop)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   curr().setdirty();
 | |
|   cisread(_isamfile, curr().string(), _isprev + lockop, &_lasterr);
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::prev(TDate& atdate)
 | |
|   
 | |
| {
 | |
|   TRecfield               flf(curr(), RFLD_SYS_LAST),
 | |
|   fd(curr(), RFLD_SYS_DATE);
 | |
|   TRecnotype      wrn;
 | |
|   
 | |
|   NOT_OPEN(name());
 | |
|   if (!_historicfile)
 | |
|     error_box("%s not historic file", filename());
 | |
|   if (_lasthf == -1L) return _isbof;
 | |
|   curr().setdirty();
 | |
|   _hf.read(curr().string(), _lasthf);
 | |
|   wrn = flf.ptr();
 | |
|   atdate = (const TDate&) fd - 1L;
 | |
|   if (wrn < 0L) _lasthf = -1L;
 | |
|   else
 | |
|   {
 | |
|     _hf.read(curr().string(), wrn);
 | |
|     _lasthf = wrn;
 | |
|   }
 | |
|   return NOERR;
 | |
| }
 | |
| 
 | |
| int TBaseisamfile::reread(word lockop, TDate& atdate)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   
 | |
|   curr().setdirty();
 | |
|   if ((!_historicfile) || (atdate == botime))
 | |
|     return cisread(_isamfile, curr().string(), _iscurr + lockop, &_lasterr);
 | |
|   else
 | |
|   {
 | |
|     if (cisread(_isamfile, curr().string(), _iscurr + lockop, &_lasterr) == NOERR)
 | |
|       _lasterr =  gethr(curr(), atdate);
 | |
|   }
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::reread(TRectype& rec, word lockop, TDate& atdate)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   rec.setdirty();
 | |
|   if ((!_historicfile) || (atdate == botime))
 | |
|     cisread(_isamfile, rec.string(), _iscurr + lockop, &_lasterr);
 | |
|   else
 | |
|   {
 | |
|     if (cisread(_isamfile, rec.string(), _iscurr + lockop, &_lasterr) == NOERR)
 | |
|       _lasterr = gethr(rec, atdate);
 | |
|   }
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::skip(TRecnotype nrec, word lockop)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   if (!nrec) return NOERR;
 | |
|   curr().setdirty();
 | |
|   if (nrec >0)
 | |
|     cisread(_isamfile, curr().string(), _isnextn + lockop + (UINT16) nrec, &_lasterr);
 | |
|   else
 | |
|     cisread(_isamfile, curr().string(), _isprevn + lockop - (UINT16) nrec, &_lasterr);
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::read(word op, word lockop, TDate& atdate)
 | |
|   
 | |
| {
 | |
|   CHECKD(op >= _iscurr && op <= _isgteq, "Invalid read operation : ", op);
 | |
|   NOT_OPEN(name());
 | |
|   curr().setdirty();
 | |
|   if ((!_historicfile) || (atdate == botime))
 | |
|     cisread(_isamfile, curr().string(), op + lockop, &_lasterr);
 | |
|   else
 | |
|   {
 | |
|     if (cisread(_isamfile, curr().string(), op + lockop, &_lasterr) == NOERR)
 | |
|       _lasterr = gethr(curr(), atdate);
 | |
|   }
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::read(TRectype& rec, word op, word lockop, TDate& atdate)
 | |
|   
 | |
| {
 | |
|   CHECKD(op >= _iscurr && op <= _isgteq, "Invalid read operation : ", op);
 | |
|   NOT_OPEN(name());
 | |
|   rec.setdirty();
 | |
|   if ((!_historicfile) || (atdate == botime))
 | |
|     cisread(_isamfile, rec.string(), op + lockop, &_lasterr);
 | |
|   else
 | |
|   {
 | |
|     if (cisread(_isamfile, rec.string(), op + lockop, &_lasterr) == NOERR)
 | |
|       _lasterr = gethr(rec, atdate);
 | |
|   }
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::readat(TRecnotype nrec, word lockop)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   curr().setdirty();
 | |
|   cisreadrec(_isamfile, nrec, curr().string(), lockop, &_lasterr);
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::readat(TRectype& rec, TRecnotype nrec, word lockop)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   rec.setdirty();
 | |
|   cisreadrec(_isamfile, nrec, rec.string(), lockop, &_lasterr);
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::write(TDate& atdate)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   if ((!_historicfile) || (atdate == botime))
 | |
|     ciswrite(_isamfile, curr().string(), &_lasterr);
 | |
|   else
 | |
|     _lasterr = addhr(curr(), atdate);
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::write(const TRectype& rec, TDate& atdate)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(_isamfile->d->SysName);
 | |
|   if ((!_historicfile) || (atdate == botime))
 | |
|     ciswrite(_isamfile, rec.string(), &_lasterr);
 | |
|   else
 | |
|     _lasterr = addhr(rec, atdate);
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::rewrite(TDate& atdate)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   if ((!_historicfile) || (atdate == botime))
 | |
|     cisrewrite(_isamfile, curr().string(), &_lasterr);
 | |
|   else
 | |
|     _lasterr = rewhr(curr(), atdate);
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::rewrite(const TRectype& rec, TDate& atdate)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   if ((!_historicfile) || (atdate == botime))
 | |
|     cisrewrite(_isamfile, rec.string(), &_lasterr);
 | |
|   else
 | |
|     _lasterr = rewhr(rec, atdate);
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::rewriteat(TRecnotype nrec)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   return cisrewrec(_isamfile, nrec, curr().string(), &_lasterr);
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::rewriteat(const TRectype& rec, TRecnotype nrec)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   return cisrewrec(_isamfile, nrec, curr().string(), &_lasterr);
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::remove(TDate& atdate)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   if ((!_historicfile) || (atdate == botime))
 | |
|     cisdelete(_isamfile, curr().string(), &_lasterr);
 | |
|   else
 | |
|     _lasterr = delhr(curr(), atdate);
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::remove(const TRectype& rec, TDate& atdate)
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   if ((!_historicfile) || (atdate == botime))
 | |
|     cisdelete(_isamfile, rec.string(), &_lasterr);
 | |
|   else
 | |
|     _lasterr = delhr(rec, atdate);
 | |
|   _recno = _isamfile->RecNo;
 | |
|   return _lasterr;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::lock()
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   return cislock(_isamfile, &_lasterr);
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::unlock()
 | |
|   
 | |
| {
 | |
|   NOT_OPEN(name());
 | |
|   return cisunlock(_isamfile, &_lasterr);
 | |
| }
 | |
| 
 | |
| 
 | |
| void TBaseisamfile::indexon()
 | |
|   
 | |
| {
 | |
|   IndexOn();
 | |
| }
 | |
| 
 | |
| 
 | |
| bool TBaseisamfile::empty()
 | |
|   
 | |
| { 
 | |
|   return _isamfile->i.Base[_isamfile->i.PN].PEOD == 0;
 | |
| }
 | |
| 
 | |
| void TBaseisamfile::indexoff()
 | |
|   
 | |
| {
 | |
|   IndexOff();
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::_open(unsigned int mode)
 | |
|   
 | |
| {
 | |
|   int err;
 | |
|   
 | |
|   if (filehnd() != NULL)
 | |
|     fatal_box("Il file %d e' gia' aperto", _logicnum);
 | |
|   
 | |
|   if ((cisopen(&_isamfile, _logicnum, NOALLOC, mode, &err) == NOERR) &&
 | |
|       (_historicfile))
 | |
|   {
 | |
|     TFilename  s(filename());
 | |
|     
 | |
|     s.ext("hst");
 | |
|     _hf.len() = filehnd()->d->LenR;
 | |
|     _hf.base() = 1;
 | |
|     _hf.open(s);
 | |
|     if (_hf.status() == 2)
 | |
|     {
 | |
|       _hf.create(s);
 | |
|       _hf.open(s);
 | |
|     }
 | |
|     if (_hf.error()) return err = _hf.status();
 | |
|     _lasthf = -1L;
 | |
|     _hfhd = _hf;
 | |
|     _hfhd.len() = sizeof(TRecnotype);
 | |
|     _hfhd.base() = 0;
 | |
|   }
 | |
| 
 | |
|   if (err == NOERR)
 | |
|   {
 | |
|     isdef * fh = filehnd();
 | |
|     const TRecnotype nitems = fh->i.Base[0].PEOX;
 | |
|     if (fh->d->EOX != nitems)
 | |
|       recover();
 | |
|   }
 | |
|   _recno = -1L;
 | |
|   _current->_i = filehnd();
 | |
|   setstatus(err);
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TBaseisamfile::_close()
 | |
|   
 | |
| {
 | |
|   int err = NOERR;
 | |
|   
 | |
|   if (filehnd() != NULL)
 | |
|   {
 | |
|     cisclose(ptrfilehnd(), NULL, &err);
 | |
|     clearfilehnd();
 | |
|   }
 | |
|   _current->_i = NULL;
 | |
|   setstatus(err);
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| 
 | |
| TLocalisamfile::TLocalisamfile(int logicnum, bool linkrecinst)
 | |
| : TBaseisamfile(logicnum, linkrecinst)
 | |
| {
 | |
|   open();
 | |
|   if (_was_open)  
 | |
|     _oldkey = getkey();
 | |
|   setkey(1); 
 | |
| }
 | |
| 
 | |
| 
 | |
| TLocalisamfile::~TLocalisamfile()
 | |
| {         
 | |
|   if (_was_open)
 | |
|     setkey(_oldkey);
 | |
|   close();
 | |
| }
 | |
| 
 | |
| 
 | |
| int TLocalisamfile::close()
 | |
| {
 | |
|   int err = NOERR;
 | |
| 
 | |
|   if (!_was_open)
 | |
|   {
 | |
|     clearfilehnd();
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     if (_isamfile)
 | |
|     {
 | |
|       cisclose(&_isamfile, NULL, &err);
 | |
|       _isamfile = NULL;
 | |
|     }
 | |
|   }
 | |
|   setstatus(err);
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| int TLocalisamfile::open(unsigned int mode)
 | |
|   
 | |
| {
 | |
|   int err = NOERR;
 | |
|   const int logicnum = num();
 | |
| 
 | |
|   if (openf[logicnum - 1] != NULL)
 | |
|   {
 | |
|     _was_open = FALSE;
 | |
|     _isamfile = openf[logicnum - 1];
 | |
|     _current->_i = filehnd();
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     err = _open();
 | |
|     _was_open = TRUE;
 | |
|   }
 | |
|   setstatus(err);
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| int TLocalisamfile::operator +=(const TRecnotype npos)
 | |
|   
 | |
| { 
 | |
|   skip(npos);
 | |
|   return status();
 | |
| }
 | |
| 
 | |
| 
 | |
| int TLocalisamfile::operator -=(const TRecnotype npos)
 | |
|   
 | |
| {
 | |
|   skip(-npos);
 | |
|   return status();
 | |
| }
 | |
| 
 | |
| 
 | |
| int TLocalisamfile::operator ++()
 | |
|   
 | |
| {
 | |
|   next();
 | |
|   return status();
 | |
| }
 | |
| 
 | |
| 
 | |
| int TLocalisamfile::operator --()
 | |
|   
 | |
| {
 | |
|   prev();
 | |
|   return status();
 | |
| }
 | |
| 
 | |
| 
 | |
| TIsamfile::TIsamfile(int logicnum, bool linkrecinst) : TBaseisamfile(logicnum, linkrecinst) {}
 | |
| 
 | |
| 
 | |
| TIsamfile::~TIsamfile()
 | |
|   
 | |
| {
 | |
|   close();
 | |
| }
 | |
| 
 | |
| 
 | |
| int TIsamfile::flags(bool updateeod)
 | |
|   
 | |
| {
 | |
|   int err;
 | |
|   
 | |
|   NOT_OPEN(name());
 | |
|   setstatus(err);
 | |
|   return cisupdflags(filehnd(), &err, updateeod);
 | |
| }
 | |
| 
 | |
| 
 | |
| TIsamtempfile::TIsamtempfile(int logicnum, bool linkrecinst) : TBaseisamfile(logicnum, linkrecinst) {}
 | |
| 
 | |
| 
 | |
| TIsamtempfile::~TIsamtempfile()
 | |
|   
 | |
| {
 | |
|   close();
 | |
| }
 | |
| 
 | |
| 
 | |
| int TIsamtempfile::open(char* radix, bool create, TRecnotype eod, TRecnotype eox)
 | |
|   
 | |
| {
 | |
|   int err;
 | |
|   
 | |
|   if (filehnd() != NULL)
 | |
|     fatal_box("File %s already open", filename());
 | |
|   if ((cisopentemp(ptrfilehnd(), _logicnum, radix, NOALLOC, create, eod, eox, &err) == NOERR) &&
 | |
|       (_historicfile))
 | |
|   {
 | |
|     TFilename               s(filename());
 | |
|     
 | |
|     s.ext("hst");
 | |
|     _hf.len() = filehnd()->d->LenR;
 | |
|     _hf.base() = 1;
 | |
|     _hf.open(s);
 | |
|     if (_hf.status() == 2)
 | |
|     {
 | |
|       _hf.create(s);
 | |
|       _hf.open(s);
 | |
|     }
 | |
|     if (_hf.error()) return err = _hf.status();
 | |
|     _lasthf = -1L;
 | |
|     _hfhd = _hf;
 | |
|     _hfhd.len() = sizeof(TRecnotype);
 | |
|     _hfhd.base() = 0;
 | |
|   }
 | |
|   _current->_i = filehnd();
 | |
|   _recno = -1L;
 | |
|   setstatus(err);
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TIsamtempfile::close(bool flagdel)
 | |
|   
 | |
| {
 | |
|   int err;
 | |
|   
 | |
|   if (filehnd() != NULL)
 | |
|   {
 | |
|     cisclosetemp(ptrfilehnd(), NULL, flagdel, &err);
 | |
|     clearfilehnd();
 | |
|   }
 | |
|   _current->_i = NULL;
 | |
|   setstatus(err);
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TSystemisamfile::build(TRecnotype eox)
 | |
|   
 | |
| {
 | |
|   int err;
 | |
|   
 | |
|   if(filehnd() != NULL)
 | |
|     fatal_box("Can't recreate open file %s", filename());
 | |
|   TDir d;
 | |
| 
 | |
|   d.get(num());
 | |
|   TFilename f(d.name());
 | |
| 
 | |
|   f = f.path();
 | |
|   if (!fexist(f)) 
 | |
| #if XVT_OS==XVT_OS_SCOUNIX
 | |
|     mkdir(f, 0777);
 | |
| #else
 | |
|   mkdir(f);
 | |
| #endif
 | |
|   cisbuild(filehnd(), num(), eox, &err);
 | |
|   setstatus(err);
 | |
|   clearfilehnd();
 | |
|   
 | |
| #ifndef FOXPRO  
 | |
|   if (err == NOERR && __autoload)
 | |
|   {
 | |
|     TFilename lf;
 | |
| 
 | |
|     lf.format("%sstd/lf%04d.txt", __ptprf, num());
 | |
|     if (fexist(lf))
 | |
|       load(lf, '|', '\0', '\n', TRUE, TRUE);
 | |
|   }
 | |
| #endif
 | |
|   
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TSystemisamfile::extend(TRecnotype eox)
 | |
|   
 | |
| {
 | |
|   int     err;
 | |
|   
 | |
|   if (filehnd() != NULL)
 | |
|     fatal_box("Can't extend open file %s", filename());
 | |
|   cisextend(filehnd(), num(), eox, &err);
 | |
|   setstatus(err);
 | |
|   clearfilehnd();
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| 
 | |
| long TSystemisamfile::size(TRecnotype eox)
 | |
|   
 | |
| {
 | |
|   int err;
 | |
|   const long size = cisextension(num(), eox, &err);
 | |
|   if (err != NOERR) setstatus(err);
 | |
|   return size;
 | |
| }
 | |
| 
 | |
| #ifndef FOXPRO
 | |
| bool TSystemisamfile::exec_convapp(long flev, const bool before)
 | |
|   
 | |
| {
 | |
|   const char * const v = before ? "BCNV" : "ACNV";
 | |
| 
 | |
|   if (flev == 0) flev = 199401;
 | |
|   else flev++;
 | |
|   for (long l = flev; l <= stdlevel; l++)
 | |
|   {
 | |
|     TString16 paragraph(format("%06ld", l));
 | |
|     TConfig conv(CONFIG_FCONV, paragraph);
 | |
| 
 | |
|     if (!conv.new_paragraph() && conv.exist(v, num()))
 | |
|     {
 | |
|       int err = 0;
 | |
|       TString80 s(conv.get(v, NULL, num())); s << " " << main_app().get_firm();
 | |
|       TExternal_app app(s);
 | |
| 
 | |
|       if (app.can_run())
 | |
|       {
 | |
|         app.run();
 | |
|         err = app.error();
 | |
|         TMailbox mail;
 | |
|         TMessage* msg = mail.next(TRUE);
 | |
|         if (err == 0 && msg != NULL)
 | |
|           err = atoi(msg->body());
 | |
|       }
 | |
|       else err = 16;
 | |
|       if (err)
 | |
|         return error_box("Non posso eseguire il programma di %sconversione\ndel livello %ld/%ld\nErrore n.ro %d", before ? "pre" : "post", l / 100, l % 100, err); 
 | |
|     }
 | |
|   }
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| bool TSystemisamfile::getlcf(long flev)
 | |
|   
 | |
| {
 | |
|   _flds.destroy();
 | |
|   _exps.destroy();
 | |
|   if (flev == 0) flev = 199401;
 | |
|   else flev++;
 | |
|   for (long l = flev; l <= stdlevel; l++)
 | |
|   {
 | |
|     TString16 paragraph(format("%06ld", l));
 | |
|     TConfig conv(CONFIG_FCONV, paragraph);
 | |
|     
 | |
|     if (!conv.new_paragraph() && conv.exist("F", num()))
 | |
|     {
 | |
|       TToken_string exprline(conv.get("F", NULL, num()));
 | |
|       
 | |
|       if (exprline.empty()) return FALSE;
 | |
| 
 | |
|       TToken_string w("", '=');
 | |
|       const char * wexprs = exprline.get();
 | |
| 
 | |
|       while (wexprs != NULL)
 | |
|       {
 | |
|         w = wexprs;
 | |
|         TFixed_string fld(w.get());
 | |
|         _flds.add(new TFieldref(fld, 0));
 | |
|         _exps.add(new TExpression(w.get(), _strexpr));
 | |
|         wexprs = exprline.get();
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return _flds.items() > 0;
 | |
| }
 | |
| 
 | |
| void TSystemisamfile::makelc(TRectype& rec)
 | |
|   
 | |
| {
 | |
|   for (int i = 0 ; i < _flds.items(); i++)
 | |
|   {
 | |
|     TFieldref& f = (TFieldref&) _flds[i];
 | |
|     TExpression& e = (TExpression & )_exps[i]; 
 | |
| 
 | |
|     for (int k = 0; k < e.numvar(); k++)
 | |
|       e.setvar(k, get(e.varname(k)));
 | |
|     f.write(e, rec);
 | |
|   }
 | |
| }
 | |
| 
 | |
| int TSystemisamfile::update(TTrec& newrec, bool vis)
 | |
|   
 | |
| {
 | |
|   if (filehnd() != NULL)
 | |
|     fatal_box("Can't update description for open file %s", filename());
 | |
| 
 | |
|   TDir           dir;
 | |
| 
 | |
|   dir.get(num(), _lock, _nordir, _sysdirop);
 | |
|   const char p = *dir.name();
 | |
|   const bool is_com = prefhndl->is_com();
 | |
|   const bool toconvert = is_com ? dir.is_com() : dir.is_firm();
 | |
| 
 | |
|   int err = NOERR;
 | |
|   TTrec  oldrec;
 | |
| 
 | |
|   oldrec.get(num());
 | |
|   const long lev = prefhndl->filelevel();
 | |
|   const bool lcf = getlcf(lev);
 | |
|   exec_convapp(lev, TRUE);
 | |
| 
 | |
|   if (!lcf && newrec == oldrec)
 | |
|   {
 | |
|     exec_convapp(lev, FALSE);
 | |
|     return NOERR;
 | |
|   }
 | |
| 
 | |
|   const TRecnotype nitems = dir.eod();
 | |
|   const unsigned int lenr = newrec.len();
 | |
| 
 | |
|   if (!toconvert && dir.eox() > 0L)
 | |
|   {
 | |
|     dir.eod() = 0L; 
 | |
|     dir.eox() = 0L;
 | |
|   }
 | |
| 
 | |
|   if (toconvert && dir.eox() > 0L)
 | |
|   {
 | |
|     TRecnotype ni = 0L;
 | |
|     TFilename tmpfname;
 | |
| 
 | |
|     tmpfname.temp(NULL);
 | |
|     FILE* f = fopen(tmpfname, "w");
 | |
|     err = ferror(f);
 | |
| 
 | |
|     if (f == NULL) 
 | |
|     {
 | |
|       clearerr(f);
 | |
|       setstatus(err);
 | |
|       return err;
 | |
|     }
 | |
|     open(_excllock);
 | |
|     TFilename fname(filename());
 | |
|     TString s(80);
 | |
|     s.format("Aggiornamento archivio %s", (const char*) fname);
 | |
|     TProgind p(nitems ? nitems : 1, s, TRUE, TRUE, 70);
 | |
|     int nflds = curr().items();
 | |
|     TArray  fld(nflds);
 | |
|     TExtrectype nrec(newrec);
 | |
|     TRecnotype i;
 | |
| 
 | |
|     for (int j = 0; j < nflds; j++)
 | |
|       fld.add(TString(curr().fieldname(j)), j);
 | |
| 
 | |
|     for (i = 1; i <= nitems && !p.iscancelled(); i++)
 | |
|     {
 | |
|       if ((i % 50) == 0) p.setstatus(i + 1);
 | |
|       readat(i);
 | |
|       if (curr().valid())
 | |
|       {
 | |
|         nrec.zero();
 | |
|         ni++;
 | |
|         for (j = 0; j < nflds; j++)
 | |
|           if (nrec.exist((const TString&) fld[j]))
 | |
|             nrec.put((const TString&) fld[j], get((const TString&) fld[j]));
 | |
|         if (lcf)
 | |
|           makelc((TRectype &)nrec);
 | |
|         fwrite(nrec.string(), lenr, 1, f);
 | |
|       }
 | |
|     }
 | |
|     p.setstatus(nitems);
 | |
|     close();
 | |
|     fclose(f);
 | |
|     fcopy(tmpfname, fname);
 | |
|     ::remove(tmpfname);
 | |
|     dir.eod() = ni;
 | |
|   }
 | |
|   // aggiornare il log file
 | |
|   dir.set_len(lenr);
 | |
|   dir.put(num(), _nordir, _sysdirop);
 | |
|   newrec.put(num());
 | |
|   if (toconvert && dir.eox() > 0L) packindex();
 | |
|   exec_convapp(lev, FALSE);
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TSystemisamfile::packfile(bool vis)
 | |
|   
 | |
| {
 | |
|   int err;
 | |
|   
 | |
|   if (filehnd() != NULL)
 | |
|     fatal_box("Can't pack open file %s", filename());
 | |
|   setstatus(creorgfile(num(), vis, &err));
 | |
|   return err;
 | |
|   
 | |
| }
 | |
| 
 | |
| 
 | |
| int TSystemisamfile::packindex(bool vis)
 | |
|   
 | |
| {
 | |
|   int err;
 | |
|   
 | |
|   if (filehnd() != NULL)
 | |
|     fatal_box("Can't pack open file %s", filename());
 | |
|   setstatus(creorgindex(num(), vis, &err));
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TSystemisamfile::load(const char* from, char fs, char fd, char rs, bool vis, bool extended)
 | |
|   
 | |
| {
 | |
|   FILE* fl = fopen(from, "r+");
 | |
|   int err = ferror(fl);
 | |
|   TRecnotype r = 0, e = 0, nitems = 0, nread = 0;
 | |
|   TString16 firm, year, attprev("00000");
 | |
| 
 | |
|   if (extended)
 | |
|   {
 | |
|     TDate d(TODAY);
 | |
|     TLocalisamfile ditte(LF_NDITTE);
 | |
| 
 | |
|     firm.format("%05ld", main_app().get_firm());
 | |
|     year.format("%04d", d.year());
 | |
|     ditte.zero();
 | |
|     ditte.put("CODDITTA", firm);
 | |
|     if (ditte.read() == NOERR)
 | |
|       attprev = ditte.get("CODATTPREV");
 | |
|   }
 | |
|   if (fl == NULL) 
 | |
|   {
 | |
|     clearerr(fl);
 | |
|     setstatus(err);
 | |
|     return err;
 | |
|   }
 | |
|   char w[80];
 | |
|   while ((fgets(w, 80, fl) != NULL))
 | |
|   {
 | |
|     if (strncmp(w, "[Data]", 6) == 0)
 | |
|     {
 | |
|       nitems = ftell(fl);
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   fseek(fl, 0L, SEEK_END);
 | |
|   nitems = ftell(fl) - nitems;
 | |
|   fclose(fl);
 | |
|   TScanner f(from);
 | |
| 
 | |
|   open();
 | |
|   
 | |
|   TToken_string s(1024, fs);
 | |
|   bool fixedlen = (fs == '\0');
 | |
|   int nflds = curr().items();
 | |
|   TArray  fld(nflds);
 | |
|   int    len[MaxFields];
 | |
|   TString sfd(3);
 | |
|   TString s1(64);
 | |
|   bool lcf = FALSE;
 | |
| 
 | |
|   if (f.paragraph("Header"))
 | |
|   { 
 | |
|     f.equal();
 | |
|     const long level = atol(f.line());
 | |
|     if (level > stdlevel)
 | |
|       error_box("L' archivio %s e' stato generato con gli archivi di livello %ld%/%ld.\n Il livello attuale e' %ld/%ld.\n Convertire gli archivi e ripetere l' operazione.", from, level / 100, level % 100, stdlevel / 100, stdlevel % 100);
 | |
|     lcf = getlcf(level);
 | |
|     nflds = 0;
 | |
|     TToken_string s2(f.line());
 | |
|     int p = s2.find('=');
 | |
|     if (p > 0)
 | |
|     {
 | |
|       s1 = s2.left(p);
 | |
|       s2.ltrim(p+1);
 | |
|     }
 | |
|     else s1.cut(0);
 | |
|     while (s1 == "Fields")
 | |
|     {
 | |
|       for (const char * fd = s2.get(); fd != NULL;  fd = s2.get())
 | |
|       {
 | |
|         TToken_string wfd(fd, ',');
 | |
|         fld.add(new TString(wfd.get()));
 | |
|         len[nflds] = wfd.get_int();
 | |
|         nflds++;
 | |
|       }
 | |
|       s2 = f.line();
 | |
|       p = s2.find('=');
 | |
|       if (p > 0)
 | |
|       {
 | |
|         s1 = s2.left(p);
 | |
|         s2.ltrim(p+1);
 | |
|       }
 | |
|       else s1.cut(0);
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     for (int j = 0; j < nflds; j++)
 | |
|     {
 | |
|       fld.add(TString(curr().fieldname(j)), j);
 | |
|       const TString & wfld = (const TString & ) fld[j];
 | |
|       len[j] = (curr().type(wfld) == _datefld) ? 10 : curr().length(wfld);
 | |
|     }
 | |
|   }
 | |
|   if (!f.paragraph("Data"))
 | |
|   {
 | |
|     error_box("Formato dei dati non valido");
 | |
|     close();
 | |
|     err = 1;
 | |
|     setstatus(err);
 | |
|     return err;
 | |
|   }
 | |
|   
 | |
|   if (fd) sfd << fd;
 | |
|   int last = NOERR;    
 | |
|   
 | |
|   s1.format("Imp. archivio %s\n%6ld records %6ld errori - %3d", filename(), r, e, last);
 | |
|   TProgind p(nitems, s1, TRUE, TRUE, 70);
 | |
|   s = f.line();
 | |
|   while (s.not_empty() && !p.iscancelled())
 | |
|   {
 | |
|     if (extended)
 | |
|     {
 | |
|       int p, i;
 | |
| 
 | |
|       while ((p = s.find("%yr%")) >= 0)
 | |
|         for (i = 0; i < 4; i++) s[p + i] = year[i];
 | |
|       while ((p = s.find("%frm%")) >= 0)
 | |
|         for (i = 0; i < 5; i++) s[p + i] = firm[i];
 | |
|       while ((p = s.find("%att%")) >= 0)
 | |
|         for (i = 0; i < 5; i++) s[p + i] = attprev[i];
 | |
|     }
 | |
|     if ((r + e) % 50 == 0)
 | |
|     {
 | |
|       s1.format("Imp. archivio %s\n%6ld records %6ld errori - %3d", filename(), r, e, last);
 | |
|       p.set_text(s1);
 | |
|     }
 | |
|     p.setstatus(nread + 1);
 | |
|     nread += s.len() + 1;
 | |
|     zero();
 | |
|     if (fixedlen)
 | |
|     {
 | |
|       int pos = 0;
 | |
|       for (int j = 0; j < nflds; j++)
 | |
|       {
 | |
|         s1 = s.mid(pos,len[j]);
 | |
|         s1.rtrim();
 | |
|         put((const TString&) fld[j], s1);
 | |
|         pos += len[j];
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       s.restart();
 | |
|       for (int j = 0; j < nflds; j++)
 | |
|       {
 | |
|         char* s2 = (char*) s.get();
 | |
|         if (fd) 
 | |
|         {
 | |
|           s2++;
 | |
|           s2[strlen(s2) - 1] = '\0';
 | |
|         }
 | |
|         put((const TString&) fld[j], s2);
 | |
|       }
 | |
|     }            
 | |
|     if (write() == NOERR) r++;
 | |
|     else 
 | |
|     {
 | |
|       e++;
 | |
|       last = status();
 | |
|     }
 | |
|     s = f.line();
 | |
|   }
 | |
|   s1.format("Imp. archivio %s\n%6ld records %6ld errori - %3d", filename(), r, e, last);
 | |
|   p.set_text(s1);
 | |
|   close();
 | |
|   setstatus(err);
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| int TSystemisamfile::dump(const char* to, int nkey, char fs, char fd, char rs, bool vis, bool withdeleted)
 | |
| 
 | |
| {
 | |
|   FILE* f = fopen(to, "w");
 | |
|   int err = ferror(f);
 | |
| 
 | |
|   if (withdeleted) nkey = 0;
 | |
|   if (f == NULL) 
 | |
|   {
 | |
|     clearerr(f);
 | |
|     setstatus(err);
 | |
|     return err;
 | |
|   }
 | |
|   open();
 | |
|   TString s(512);
 | |
|   bool fixedlen = (fs == '\0');
 | |
|   int nflds = curr().items();
 | |
|   TArray  fld(nflds);
 | |
|   TBit_array rjust(nflds);
 | |
|   int        len[MaxFields];
 | |
| 
 | |
|   for (int j = 0; j < nflds; j++)
 | |
|   {
 | |
|     fld.add(TString(curr().fieldname(j)), j);
 | |
|     const TString & wfld = (const TString&) fld[j];
 | |
|     const TFieldtypes t = curr().type(wfld);
 | |
|     rjust.set(j, t == _intfld || t == _longfld || t == _realfld ||
 | |
|               t == _wordfld || t == _intzerofld || t == _longzerofld);
 | |
|     len[j] = (t == _datefld) ? 10 : curr().length(wfld);
 | |
|   }
 | |
|   TRecnotype i = 0;
 | |
|   const TRecnotype nitems = nkey ? items() : filehnd()->d->EOD;
 | |
|   s.format("Esportazione archivio %s", filename());
 | |
|   TProgind p(nitems, s, TRUE, TRUE, 70);
 | |
|   TString s1;
 | |
| 
 | |
|   fprintf(f, "[Header]\nVersion=%ld", prefhndl->filelevel());
 | |
|   for (int k = 0; k < nflds; k++)
 | |
|   {
 | |
|     if ((k % 10) == 0) fprintf(f, "\nFields=");
 | |
|     else fprintf(f, "|");
 | |
|     fprintf(f, "%s,%d", (const char *) (const TString&) fld[k], len[k]);
 | |
|   }
 | |
|   fprintf(f, "\n\n[Data]\n");
 | |
|   if (nkey)
 | |
|   {
 | |
|     setkey(nkey);
 | |
|     for ( first(); status() == NOERR && !p.iscancelled(); next(), i++)
 | |
|     {
 | |
|       p.setstatus(i + 1);
 | |
|       s = "";
 | |
|       for (j = 0; j < nflds; j++)
 | |
|       {
 | |
|         if (fixedlen)
 | |
|         {
 | |
|           s1 = get((const TString&)fld[j]);
 | |
|           if (rjust[j]) s1.right_just(len[j]);
 | |
|           else s1.left_just(len[j]);
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           s1 = "";
 | |
|           if (j && fs) s1 << fs;
 | |
|           if (fd) s1 << fd;
 | |
|           s1 << get((const TString&)fld[j]);
 | |
|           if (fd) s1 << fd;
 | |
|         }
 | |
|         s << s1;
 | |
|       }
 | |
|       fprintf(f, "%s%c", (const char*) s, rs);
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     for (i = 0; i < nitems && !p.iscancelled(); i++)
 | |
|     {
 | |
|       zero();
 | |
|       p.setstatus(i + 1);
 | |
|       readat(i + 1);
 | |
|       s="";
 | |
|       if (withdeleted || curr().valid())
 | |
|       {
 | |
|         for (j = 0; j < nflds; j++)
 | |
|         {
 | |
|           if (fixedlen)
 | |
|           {
 | |
|             s1 = get((const TString&)fld[j]);
 | |
|             if (rjust[j]) s1.right_just(len[j]);
 | |
|             else s1.left_just(len[j]);
 | |
|           }
 | |
|           else
 | |
|           {
 | |
|             s1 = "";
 | |
|             if (j && fs) s1 << fs;
 | |
|             if (fd) s1 << fd;
 | |
|             s1 << get((const TString&)fld[j]);
 | |
|             if (fd) s1 << fd;
 | |
|           }
 | |
|           s << s1;
 | |
|         }
 | |
|         fprintf(f, "%s%c", (const char*) s, rs);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   p.setstatus(nitems);
 | |
|   close();
 | |
|   fclose(f);
 | |
|   setstatus(err);
 | |
|   return err;
 | |
| }       
 | |
| 
 | |
| #endif // FOXPRO
 | |
| 
 | |
| 
 | |
| void TBaseisamfile::recover()
 | |
| {
 | |
|   isdef * fh = filehnd();
 | |
|   const TRecnotype nitems = fh->i.Base[0].PEOX;
 | |
| 
 | |
|   CHECKD(getkey() == 1, "La chiave corrente non e' 1 ma ", getkey()); 
 | |
|   TFilename fn = filename();
 | |
| 
 | |
|   fn = fn.name();
 | |
| #ifndef FOXPRO
 | |
|   if (yesno_box("La dimensione dell'archivio %s e' errata. Cerco di recuperarlo?", (const char *)fn))
 | |
|   {
 | |
|     TDir d;
 | |
|     TString mess(80);
 | |
| 
 | |
|     mess.format("Ricostruzione archivio %s : I Fase", (const char*) fn);
 | |
|     TProgind p(nitems ? nitems : 1, mess, TRUE, TRUE, 70);
 | |
|     
 | |
|     const TDirtype dir = (fh->ft == 0) ? _nordir : _comdir; 
 | |
|     d.get(num(), _lock, dir, _sysdirop);
 | |
|     d.eod() = fh->d->EOD = nitems;
 | |
|     d.eox() = fh->d->EOX = nitems;
 | |
|     d.put(num(), dir, _sysdirop);
 | |
|     for (TRecnotype r = 1; r <= nitems; r++)
 | |
|     {
 | |
|       p.addstatus(1);
 | |
|       CRead(&fh->f, curr().string(), r, _nolock);
 | |
|       curr().discard();
 | |
|       CWrite(&fh->f, curr().string(), r, _nolock);
 | |
|     }
 | |
|     p.close_modal();
 | |
|     
 | |
|     mess.format("Ricostruzione archivio %s : II Fase", (const char*) fn);
 | |
|     TProgind pi(items() ? items() : 1, mess, TRUE, TRUE, 70);
 | |
|     for (first(); good(); next())
 | |
|     {
 | |
|       pi.addstatus(1);
 | |
|       curr().recall();
 | |
|       rewrite();
 | |
|     }
 | |
|     message_box("L'archivio %s deve essere compattato", (const char *) fn);
 | |
|   }
 | |
|   else
 | |
| #endif  
 | |
|     fatal_box("L'archivio %s e' incosistente e deve essere corretto prima di utilizzarlo", (const char *)fn);
 | |
| }
 | |
| 
 | |
| 
 | |
| ////////////////////////////////////////////////////////////
 | |
| //      TRectype
 | |
| ////////////////////////////////////////////////////////////
 | |
| 
 | |
| TRectype::TRectype(int logicnum) 
 | |
| : _cod(NULL)
 | |
|   
 | |
| {
 | |
|   TDir wdir;
 | |
|   
 | |
|   _logicnum = logicnum;
 | |
|   wdir.get(_logicnum, _nolock, _nordir, _sysdirop);
 | |
|   if (wdir.name()[0] == '%')
 | |
|     wdir.get(_logicnum, _nolock, _comdir, _sysdirop);
 | |
|   _length = wdir.len();
 | |
|   _rec = new char [ _length ];
 | |
|   _i = openf[_logicnum - 1];
 | |
|   *_tab = '\0';
 | |
|   setempty(TRUE);     
 | |
| }
 | |
| 
 | |
| TRectype::TRectype(const TBaseisamfile* i)
 | |
| : _cod(NULL)
 | |
| 
 | |
| {
 | |
|   _logicnum = i->num();
 | |
|   if (i->filehnd() != NULL)
 | |
|     _length = i->filehnd()->d->LenR;
 | |
|   else
 | |
|   {
 | |
|     TDir wdir;
 | |
| 
 | |
|     wdir.get(_logicnum, _nolock, _nordir, _sysdirop);
 | |
|     if (wdir.name()[0] == '%')
 | |
|       wdir.get(_logicnum, _nolock, _comdir, _sysdirop);
 | |
|     _length = wdir.len();
 | |
|   }
 | |
|   *_tab = '\0';
 | |
|   _rec = new char [ _length ];
 | |
|   _i = i->filehnd();
 | |
|   setempty(TRUE); 
 | |
| }
 | |
| 
 | |
| 
 | |
| TRectype::TRectype(const TRectype& r)
 | |
| : _cod(NULL)
 | |
|   
 | |
| {
 | |
|   _logicnum = r._logicnum;
 | |
|   _length = r.len();
 | |
|   _rec = new char [ _length ];
 | |
|   _rec[0] = r._rec[0];
 | |
|   memcpy(_rec + 1, r._rec + 1, _length - 1);
 | |
|   _i = r._i;
 | |
|   strcpy(_tab, r._tab);
 | |
|   if (r._cod != NULL)
 | |
|     _cod = new TRecfield(*this, "COD");
 | |
|   setempty(r.empty());
 | |
| }
 | |
| 
 | |
| TRectype::~TRectype()
 | |
|   
 | |
| {
 | |
|   if (_cod != NULL) delete _cod;
 | |
|   delete _rec;
 | |
| }
 | |
| 
 | |
| void TRectype::settab(const char *tab)
 | |
| 
 | |
| { 
 | |
|   if (_cod != NULL)
 | |
|   {
 | |
|     delete _cod;
 | |
|     _cod = NULL;
 | |
|   }
 | |
|   strcpy(_tab, tab);
 | |
|   if (*_tab != '\0')
 | |
|     _cod = new TRecfield(*this, "COD"); 
 | |
|   zero();  
 | |
| }
 | |
| 
 | |
| TObject* TRectype::dup() const
 | |
| 
 | |
| {
 | |
|   TRectype* o = new TRectype(*this);
 | |
|   
 | |
|   return o;
 | |
| }
 | |
| 
 | |
| 
 | |
| HIDDEN bool fld_empty(const char* s, int len, bool number)
 | |
| 
 | |
| {
 | |
|   /*if (number)
 | |
|     {
 | |
|     for (; len; s++, len--)
 | |
|     if (strchr(" 0.", *s) == NULL) return FALSE;
 | |
|     }
 | |
|     else */
 | |
|   if (*s)
 | |
|   {
 | |
|     for (; len; s++, len--)
 | |
|       if (*s != ' ') return FALSE;
 | |
|   }
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| 
 | |
| HIDDEN int fld_cmp(const char* a, const char* b, int len, bool number)
 | |
| {
 | |
|   for (int i = 0; i < len && *a == *b; b++, a++, i++);
 | |
|   if (i == len) return 0;
 | |
|   int res = *a - *b;      
 | |
|   if (number)
 | |
|   {
 | |
|     b -= i;
 | |
|     i  = 0;
 | |
|   }
 | |
|   return fld_empty(b, len - i, number) ? 0 : res;
 | |
| }
 | |
| 
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TRectype (record di un file)
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| int TRectype::items() const
 | |
| 
 | |
| {
 | |
|   return _i->r->NFields;
 | |
| }
 | |
| 
 | |
| 
 | |
| const char* TRectype::start(int nf) const
 | |
| 
 | |
| {
 | |
|   return string() + _i->r->Fd[nf].RecOff;
 | |
| }
 | |
| 
 | |
| 
 | |
| int TRectype::compare(const TSortable& s) const
 | |
| 
 | |
| {
 | |
|   const TRectype& br = (const TRectype&) s;
 | |
|   int res = 0;
 | |
| 
 | |
|   if (br.empty()) return UNDEFINED;
 | |
|   for (int i = 0; i < items() ; i++)
 | |
|   {
 | |
|     const char* b = br.start(i);
 | |
|     const char* a = start(i);
 | |
|     const byte typ = _i->r->Fd[i].TypeF;
 | |
|     /* if (typ == _boolfld) res = *a - *b;
 | |
|        else
 | |
|        { */
 | |
|     const int  sz  = _i->r->Fd[i].Len;
 | |
|     const bool number = (typ == _intfld) || (typ == _realfld) ||
 | |
|       (typ == _longfld) || (typ == _wordfld) ||
 | |
|         (typ == _intzerofld) || (typ == _longzerofld)
 | |
| 
 | |
|           || (typ == _datefld) ;
 | |
| 
 | |
|     if (fld_empty(b, sz, number)) continue;
 | |
|     res = ::fld_cmp(a, b, sz, number);
 | |
|     /* } */
 | |
|     if (res) return res;
 | |
|   }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| TFieldtypes TRectype::type(const char* fieldname) const
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "type");
 | |
|   return (TFieldtypes) CFieldType((char*) fieldname, _i->r);
 | |
| }
 | |
| 
 | |
| 
 | |
| int TRectype::length(const char* fieldname) const
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "length");
 | |
|   return CFieldSize((char*) fieldname, _i->r);
 | |
| }
 | |
| 
 | |
| 
 | |
| int TRectype::ndec(const char* fieldname) const
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "dec");
 | |
|   return CFieldDec((char*) fieldname, _i->r);
 | |
| }
 | |
| 
 | |
| 
 | |
| bool TRectype::exist(const char* fieldname) const
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "exist");
 | |
|   return findfld(_i->r, (char*)fieldname) != -1;
 | |
| }
 | |
| 
 | |
| 
 | |
| const char* TRectype::fieldname(int i) const
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "fieldname");
 | |
|   return i >= 0 && i < _i->r->NFields ? _i->r->Fd[i].Name : NULL;
 | |
| }
 | |
| 
 | |
| 
 | |
| #ifndef FOXPRO
 | |
| 
 | |
| int TRectype::get_int(const char* fieldname) const
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "get_int");
 | |
|   if (CGetFieldBuff((char*) fieldname, _i->r, _rec, __tmp_string) == -1)
 | |
|     UNKNOWN_FIELD(num(), fieldname);
 | |
|   return atoi(__tmp_string);
 | |
| }
 | |
| 
 | |
| 
 | |
| long TRectype::get_long(const char* fieldname) const
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "get_long");
 | |
|   if (CGetFieldBuff((char*) fieldname, _i->r, _rec, __tmp_string) == -1)
 | |
|     UNKNOWN_FIELD(num(), fieldname);
 | |
|   return atol(__tmp_string);
 | |
| }
 | |
| 
 | |
| 
 | |
| word TRectype::get_word(const char* fieldname) const
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "get_word");
 | |
|   if (CGetFieldBuff((char*) fieldname, _i->r, _rec, __tmp_string) == -1)
 | |
|     UNKNOWN_FIELD(num(), fieldname);
 | |
|   return (word)atoi(__tmp_string);
 | |
| }
 | |
| 
 | |
| real TRectype::get_real(const char* fieldname) const
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "get_real");
 | |
|   if (CGetFieldBuff((char*) fieldname, _i->r, _rec, __tmp_string) == -1)
 | |
|     UNKNOWN_FIELD(num(), fieldname);
 | |
|   real r(__tmp_string);
 | |
|   return r;
 | |
| }
 | |
| 
 | |
| 
 | |
| char TRectype::get_char(const char* fieldname) const
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "get_char");
 | |
|   
 | |
|   if (CGetFieldBuff((char*) fieldname, _i->r, _rec, __tmp_string) == -1)
 | |
|     UNKNOWN_FIELD(num(), fieldname);
 | |
|   return *__tmp_string;
 | |
| }
 | |
| 
 | |
| 
 | |
| bool TRectype::get_bool(const char* fieldname) const
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "get_bool");
 | |
|   if (CGetFieldBuff((char*) fieldname, _i->r, _rec, __tmp_string) == -1)
 | |
|     UNKNOWN_FIELD(num(), fieldname);
 | |
|   return *__tmp_string == 'X';
 | |
| }
 | |
| 
 | |
| #endif // FOXPRO
 | |
| 
 | |
| 
 | |
| TDate TRectype::get_date(const char* fieldname) const
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "get_date");
 | |
|   
 | |
|   const TRecfield f((TRectype&)*this, fieldname);
 | |
|   return (TDate) f;
 | |
| }
 | |
| 
 | |
| 
 | |
| const TString& TRectype::get(const char* fieldname) const
 | |
| 
 | |
| {
 | |
|   static TFixed_string s(__tmp_string, 256);
 | |
| 
 | |
|   NOT_LINKED(_i, "get");
 | |
|   if (CFieldType((char*) fieldname, _i->r) == _datefld)
 | |
|   {
 | |
|     const TRecfield f((TRectype&)*this, fieldname);
 | |
| 
 | |
|     s = (const char*) f;
 | |
|   }
 | |
|   else
 | |
|     if (CGetFieldBuff((char*) fieldname, _i->r, _rec, __tmp_string) == -1)
 | |
|       UNKNOWN_FIELD(num(), fieldname);
 | |
|   return s;
 | |
| }
 | |
| 
 | |
| 
 | |
| #ifndef FOXPRO
 | |
| 
 | |
| void TRectype::put(const char* fieldname, int val)
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "put");
 | |
|   if (CPutField((char*) fieldname, _i->r, &val, _rec) == -1)
 | |
|     UNKNOWN_FIELD(num(), fieldname);
 | |
|   setempty(FALSE);
 | |
| }
 | |
| 
 | |
| 
 | |
| void TRectype::put(const char* fieldname, long val)
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "put");
 | |
|   if (CPutField((char*) fieldname, _i->r, &val, _rec) == -1)
 | |
|     UNKNOWN_FIELD(num(), fieldname);
 | |
|   setempty(FALSE);
 | |
| }
 | |
| 
 | |
| 
 | |
| void TRectype::put(const char* fieldname, word val)
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "put");
 | |
|   if (CPutField((char*) fieldname, _i->r, &val, _rec) == -1)
 | |
|     UNKNOWN_FIELD(num(), fieldname);
 | |
|   setempty(FALSE);
 | |
| }
 | |
| 
 | |
| void TRectype::put(const char* fieldname, const real& val)
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "put");
 | |
|   if (CPutField((char*) fieldname, _i->r, val.ptr(), _rec) == -1)
 | |
|     UNKNOWN_FIELD(num(), fieldname);
 | |
|   setempty(FALSE);
 | |
| }
 | |
| 
 | |
| void TRectype::put(const char* fieldname, const TDate& val)
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "put");
 | |
|   TRecfield f(*this, fieldname);
 | |
|   f = val.string(4);
 | |
|   setempty(FALSE);
 | |
| }
 | |
| 
 | |
| void TRectype::put(const char* fieldname, char val)
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "put");
 | |
|   char  w[2] = {val, '\0'};
 | |
|   
 | |
|   if (CPutFieldBuff((char*) fieldname, _i->r, w, _rec) == -1)
 | |
|     UNKNOWN_FIELD(num(), fieldname);
 | |
|   setempty(FALSE);
 | |
| }
 | |
| 
 | |
| 
 | |
| void TRectype::put(const char* fieldname, bool val)
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "put");
 | |
|   char* s = val ? "X" : " ";
 | |
|   if (CPutFieldBuff((char*) fieldname, _i->r, s, _rec) == -1)
 | |
|     UNKNOWN_FIELD(num(), fieldname);
 | |
|   setempty(FALSE);
 | |
| }
 | |
| 
 | |
| #endif // FOXPRO
 | |
| 
 | |
| 
 | |
| void TRectype::put(const char* fieldname, const char* val)
 | |
| 
 | |
| {
 | |
|   NOT_LINKED(_i, "put");
 | |
| 
 | |
|   if (val == NULL || *val == '\0')  // Da provare
 | |
|   {
 | |
|     TRecfield f(*this, fieldname);
 | |
|     if (*f.pos() == '\0') return;
 | |
|   }
 | |
| 
 | |
|   if (CFieldType((char*) fieldname, _i->r) == _datefld)
 | |
|   {
 | |
|     TRecfield f(*this, fieldname);
 | |
|     f = val;
 | |
|   }
 | |
|   else
 | |
|     if (CPutFieldBuff((char*) fieldname, _i->r, (char*) val, _rec) == -1)
 | |
|       UNKNOWN_FIELD(num(), fieldname);
 | |
|   setempty(FALSE);
 | |
| }
 | |
| 
 | |
| 
 | |
| void TRectype::zero(const char* fieldname)
 | |
|   
 | |
| {
 | |
|   NOT_LINKED(_i, "zero");
 | |
|   if (_cod != NULL && strcmp(fieldname , "COD") == 0)
 | |
|     *_cod = _tab;
 | |
|   else
 | |
|     if (CZeroField((char*) fieldname, _i->r, _rec) == -1)
 | |
|       UNKNOWN_FIELD(num(), fieldname);
 | |
| }
 | |
| 
 | |
| 
 | |
| void TRectype::zero()
 | |
|   
 | |
| {
 | |
|   zero('\0');
 | |
| }
 | |
| 
 | |
| 
 | |
| void TRectype::zero(char c)
 | |
|   
 | |
| {
 | |
|   NOT_LINKED(_i, "zero");
 | |
|   recall();
 | |
|   memset(_rec + 1, c, len() - 1);
 | |
| 
 | |
|   if (_cod != NULL)
 | |
|     *_cod = _tab;  
 | |
| 
 | |
|   setempty(TRUE);
 | |
| }
 | |
| 
 | |
| 
 | |
| // Certified 99%
 | |
| TRectype& TRectype::operator =(const TRectype& rec)
 | |
|   
 | |
| {
 | |
|   CHECK(num() == rec.num(), "Can't assign records of different file");
 | |
|   
 | |
|   _i = rec._i;                             // Copy filehndl
 | |
|   memcpy(_rec, rec._rec, _length);         // Copy contents
 | |
|   setempty(rec.empty());                   // Copy emptiness status
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| 
 | |
| // Certified 100%
 | |
| TRectype& TRectype::operator =(const TBaseisamfile& f)
 | |
| {
 | |
|   return *this = f.curr();
 | |
| }
 | |
| 
 | |
| 
 | |
| // Certified 99%
 | |
| TRectype& TRectype::operator =(const char* rec)
 | |
| {
 | |
|   memcpy(_rec, rec, _length);
 | |
|   setempty(FALSE);
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| 
 | |
| const char* TRectype::key(int numkey) const
 | |
| {
 | |
|   NOT_LINKED(_i, "key");
 | |
|   CBuildKey(_i->r, numkey, _rec, __tmp_string);
 | |
|   return __tmp_string;
 | |
| }
 | |
| 
 | |
| 
 | |
| TRec_array::TRec_array(int dimension, TBaseisamfile& i)
 | |
| : TArray(dimension)
 | |
| 
 | |
| {
 | |
|   TRectype r(&i);
 | |
|   for (int j = 0 ; j < size(); j++) add(r, j);
 | |
| }
 | |
| 
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TRecfield (campo/sottocampo di un record)
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| void TRecfield::set(int from, int to)
 | |
| 
 | |
| {
 | |
|   int nf;
 | |
|   const isdef*  bf = _rec->filehnd();
 | |
| 
 | |
|   if ((nf = findfld(bf->r, _name)) == -1)
 | |
|   {
 | |
|     _p = NULL;
 | |
|     _len = 0;
 | |
|     _dec = 0;
 | |
|     _type = _nullfld;
 | |
|     yesnofatal_box("File n. %d unknown field %s", _rec->num(), _name);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     CHECK(from >= 0, "Invalid Start");
 | |
|     _p = _rec->string() + bf->r->Fd[nf].RecOff + from;
 | |
|     _dec = bf->r->Fd[nf].Dec;
 | |
|     _type = bf->r->Fd[nf].TypeF;
 | |
|     if  (to >= 0)
 | |
|     {
 | |
|       CHECK(from <= to && to <= bf->r->Fd[nf].Len,
 | |
|             "Invalid Range");
 | |
|       _len = to - from + 1;
 | |
|     }
 | |
|     else _len = bf->r->Fd[nf].Len - from;
 | |
|   }
 | |
| }
 | |
| 
 | |
| TRecfield::TRecfield(TRectype& rec, const char* name, int from, int to)
 | |
| 
 | |
| {
 | |
|   strcpy(_name, name);
 | |
|   NOT_LINKED(rec.filehnd(), "TRecfield");
 | |
|   _rec = &rec;
 | |
|   set(from, to);
 | |
| }
 | |
| 
 | |
| 
 | |
| HIDDEN void __getfieldbuff(byte l, byte t, const char* recin, char *s)
 | |
| 
 | |
| {
 | |
|   if (recin == NULL)
 | |
|   {
 | |
|     *s = '\0';
 | |
|     return;
 | |
|   }
 | |
|   if ((t != _alfafld) && (t != _datefld))
 | |
|   {
 | |
|     while ((*recin == ' ') && (l))
 | |
|     {
 | |
|       recin++;
 | |
|       l--;
 | |
|     }
 | |
|     if ((t != _realfld) && (t != _charfld) &&
 | |
|         (t != _intzerofld) && (t != _longzerofld))
 | |
|     {
 | |
|       while ((*recin == '0') && (l))
 | |
|       {
 | |
|         recin++;
 | |
|         l--;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   if (l)
 | |
|   {
 | |
|     strncpy(s, recin, l);
 | |
|     while (s[--l] == ' ');
 | |
|     l++;
 | |
|   }
 | |
|   s[l] = '\0';
 | |
|   if (t == _datefld && *s)
 | |
|   {
 | |
|     TDate   dt(atol(s));
 | |
|     strcpy(s, dt.string(4));
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| HIDDEN void  __putfieldbuff(byte l, byte d, byte t, const char* s, char* recout)
 | |
| 
 | |
| {
 | |
|   int                     len, i;
 | |
| 
 | |
|   if (recout == NULL) return;
 | |
| 
 | |
|   char s2[256];
 | |
| 
 | |
|   strcpy(s2, s);
 | |
| 
 | |
|   if (t == _datefld)
 | |
|   {
 | |
|     if (*s2)
 | |
|     {
 | |
|       TDate dt(s2);
 | |
|       sprintf(s2,"%06ld", (long) dt);
 | |
|     }
 | |
|   } else
 | |
|     if (t == _realfld) setdec(s2, d);
 | |
| 
 | |
|   len = strlen(s2);
 | |
|   if (len > l) return ;
 | |
|   if ((t == _intfld) ||
 | |
|       (t == _longfld) ||
 | |
|       (t == _wordfld) ||
 | |
|       (t == _realfld))
 | |
|   {
 | |
|     if (len == 0)
 | |
|     {
 | |
|       strcpy(s2, "0");
 | |
|       len = 1;
 | |
|     }
 | |
|     i = 0;
 | |
|     while (i < l - len - 1) recout[i++] = ' ';
 | |
|     strncpy(&recout[l - len - 1], s2, len) ;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     strncpy(recout, s2, len) ;
 | |
|     while (len < l) recout[len++] = ' ';
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| int TRecfield::operator =(int i)
 | |
| 
 | |
| {
 | |
|   if (_type == _intzerofld)
 | |
|     sprintf(__tmp_string, "%0*d", _len, i);
 | |
|   else
 | |
|     sprintf(__tmp_string, "%d", i);
 | |
|   __putfieldbuff( _len, _dec, _type, __tmp_string, _p);
 | |
|   _rec->setempty(FALSE);
 | |
|   return i;
 | |
| }
 | |
| 
 | |
| 
 | |
| long TRecfield::operator =(long l)
 | |
| 
 | |
| {
 | |
|   if (_type == _longzerofld)
 | |
|     sprintf(__tmp_string, "%0*ld", _len, l);
 | |
|   else
 | |
|     sprintf(__tmp_string, "%ld", l);
 | |
|   __putfieldbuff( _len, _dec, _type, __tmp_string, _p);
 | |
|   _rec->setempty(FALSE);
 | |
|   return l;
 | |
| }
 | |
| 
 | |
| 
 | |
| #ifndef FOXPRO
 | |
| const real& TRecfield::operator =(const real& r)
 | |
|   
 | |
| {
 | |
|   strcpy(__tmp_string, r.string());
 | |
|   __putfieldbuff( _len, _dec, _type, __tmp_string, _p);
 | |
|   _rec->setempty(FALSE);
 | |
|   return r;
 | |
| }
 | |
| #endif // FOXPRO
 | |
| 
 | |
| 
 | |
| const TDate& TRecfield::operator =(const TDate& d)
 | |
|   
 | |
| {
 | |
|   strcpy(__tmp_string, (const char*) d);
 | |
|   __putfieldbuff( _len, _dec, _type, __tmp_string, _p);
 | |
|   _rec->setempty(FALSE);
 | |
|   return d;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| const char* TRecfield::operator =(const char* s)
 | |
| 
 | |
| {
 | |
|   __putfieldbuff( _len, _dec, _type, s, _p);
 | |
|   _rec->setempty(FALSE);
 | |
|   return s;
 | |
| }
 | |
| 
 | |
| 
 | |
| void TRecfield::setptr(TRecnotype r)
 | |
| 
 | |
| {
 | |
|   if (_p == NULL) return;
 | |
|   
 | |
|   bool n = r < 0;
 | |
|   unsigned char*  wp = (unsigned char*) _p;
 | |
| 
 | |
|   if (n) r = -r;
 | |
|   while(wp - (unsigned char*) _p <= 3)
 | |
|   {
 | |
|     *wp = r && 0x000000FF;
 | |
|     r >>= 8;
 | |
|     wp++;
 | |
|   }
 | |
|   if (n) *wp += 128;
 | |
| }
 | |
| 
 | |
| 
 | |
| TRecfield::operator int() const
 | |
| 
 | |
| {
 | |
|   __getfieldbuff( _len, _type, _p, __tmp_string);
 | |
|   return atoi(__tmp_string);
 | |
| }
 | |
| 
 | |
| 
 | |
| TRecfield::operator long() const
 | |
| 
 | |
| {
 | |
|   __getfieldbuff( _len, _type, _p, __tmp_string);
 | |
|   return atol(__tmp_string);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| #ifndef FOXPRO
 | |
| TRecfield::operator const real() const
 | |
| 
 | |
| {
 | |
|   __getfieldbuff( _len, _type, _p, __tmp_string);
 | |
|   real r(__tmp_string);
 | |
|   return r;
 | |
| }
 | |
| #endif // FOXPRO
 | |
| 
 | |
| 
 | |
| TRecfield::operator TDate() const
 | |
| 
 | |
| {
 | |
|   static TDate d;
 | |
|   __getfieldbuff( _len, _type, _p, __tmp_string);
 | |
|   d = __tmp_string;
 | |
|   return d;
 | |
| }
 | |
| 
 | |
| 
 | |
| TRecfield::operator const char*() const
 | |
| 
 | |
| {
 | |
|   __getfieldbuff( _len, _type, _p, __tmp_string);
 | |
|   return __tmp_string;
 | |
| }
 | |
| 
 | |
| 
 | |
| TRecnotype TRecfield::ptr() const
 | |
| 
 | |
| 
 | |
| {
 | |
|   if (_p == NULL) return(-1L);
 | |
|   unsigned char*  wp = (unsigned char*) _p + 3;
 | |
|   TRecnotype   r  = *wp;
 | |
|   bool         n = r > 127;
 | |
| 
 | |
|   if (n) r -= 128;
 | |
|   while(wp-- > (unsigned char*) _p) r = r << 8 + *wp;
 | |
|   return n ? -r : r;
 | |
| }
 | |
| 
 | |
| 
 | |
| void TTransaction::begin()
 | |
| 
 | |
| {
 | |
|   StTrans();
 | |
| }
 | |
| 
 | |
| 
 | |
| void TTransaction::end(bool success)
 | |
| 
 | |
| {
 | |
|   if (success) EndTrans();
 | |
|   else AbTrans();
 | |
| }
 |