3355 lines
		
	
	
		
			79 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			3355 lines
		
	
	
		
			79 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>  
 | 
						|
#include <memo.h>
 | 
						|
#include <codeb.h>  
 | 
						|
#include <varrec.h>
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
#include <process.h>
 | 
						|
#else
 | 
						|
#include <sys/types.h>
 | 
						|
#include <sys/stat.h>
 | 
						|
#include <unistd.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#define NOT_OPEN() CHECKS(_isamfile != NULL, "File chiuso: ", (const char*)name())
 | 
						|
 | 
						|
#define RECLOCKTYPES    0xFF00
 | 
						|
#define READTYPES       0x00FF                                                                       
 | 
						|
#define INVFLD          255
 | 
						|
 | 
						|
isfdptr* openf;
 | 
						|
Str80    cprefix;
 | 
						|
 | 
						|
HIDDEN int error_codes_g[] = {-1,_isnotopen,-1,-1,-1,_islocked,-1,-1,-1,-1,-1,-1,_isfilefull,
 | 
						|
                              -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,_iskeynotfound,_ispatherr,-1,-1,_isdupkey}; 
 | 
						|
 | 
						|
HIDDEN int error_codes_ra[] = {NOERR,NOERR,_iskeynotfound,_iseof,_isbof,_isnrecerr}  ;
 | 
						|
//   Codici da 0 a 9
 | 
						|
HIDDEN int error_codes_rb[] = {-1,-1,_isreinsert,-1,-1,_islocked,-1,_isalropen,_iskeyerr }      ;
 | 
						|
//   Codici da  10 a ...  
 | 
						|
 | 
						|
extern "C" {
 | 
						|
  void CUpString(char*);
 | 
						|
  void crtrim(char*);
 | 
						|
};
 | 
						|
 | 
						|
HIDDEN char _isam_string[257];
 | 
						|
 | 
						|
#define NOALLOC (char **) -1
 | 
						|
 | 
						|
HIDDEN bool __autoload = TRUE;   
 | 
						|
                                    
 | 
						|
// @doc INTERNAL
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
// Funzioni C 
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
int hashfun(const char *s) 
 | 
						|
 | 
						|
{
 | 
						|
  int             l = strlen(s);
 | 
						|
  unsigned short  temp = 0, *pw = (unsigned short *) s;
 | 
						|
 | 
						|
  const unsigned short * end = (unsigned short *) (s + (l - 1));
 | 
						|
  while ((char *) pw < (char *) end)
 | 
						|
  {
 | 
						|
    temp ^= *pw;
 | 
						|
    pw++;
 | 
						|
  }                       
 | 
						|
  if (ODD(l))
 | 
						|
   temp ^= (unsigned short ) (8192 + s[l - 1]);
 | 
						|
  l = (short) (temp % (MaxFields - 3));            
 | 
						|
  CHECKS(l >= 0, "Negative remainder on ", s);
 | 
						|
  return(l);
 | 
						|
}
 | 
						|
 | 
						|
int findfld(const RecDes *recd, const char *s) 
 | 
						|
 | 
						|
{
 | 
						|
  short stp = hashfun(s);
 | 
						|
 | 
						|
  for (byte i = 0 ; i < MaxFields; i++) 
 | 
						|
  {                             
 | 
						|
    if (stp + i >= MaxFields)
 | 
						|
      stp -= MaxFields;
 | 
						|
    byte p = stp + i;
 | 
						|
    const int fp = recd->SortFd[p];
 | 
						|
    
 | 
						|
    if (fp == INVFLD) return(FIELDERR);
 | 
						|
    
 | 
						|
    const int cmp = strcmp(recd->Fd[fp].Name, s);
 | 
						|
    if (!cmp)
 | 
						|
      return (int) fp;
 | 
						|
    else
 | 
						|
      if (cmp > 0) return(FIELDERR);
 | 
						|
  }
 | 
						|
  return(FIELDERR);
 | 
						|
}
 | 
						|
 | 
						|
void __getfieldbuff(byte l, byte t, const char * recin, char *s)
 | 
						|
 | 
						|
{     
 | 
						|
  CHECK(recin, "Can't read from a Null record");
 | 
						|
  
 | 
						|
  if (t != _alfafld && t != _datefld)
 | 
						|
  {                   
 | 
						|
    if (t == _intzerofld || t == _longzerofld)
 | 
						|
    {             
 | 
						|
      byte i = 0;
 | 
						|
      for (char* c = (char*)recin; *c == ' ' && i < l; c++, i++)
 | 
						|
        *c = '0';     
 | 
						|
      if (i == l) 
 | 
						|
        l = 0;  
 | 
						|
    }
 | 
						|
    else                            
 | 
						|
    {
 | 
						|
      while ((*recin == ' ') && (l))
 | 
						|
      {
 | 
						|
        recin++;
 | 
						|
        l--;
 | 
						|
      }
 | 
						|
      if ((t != _realfld) && (t != _charfld))
 | 
						|
      {
 | 
						|
        while ((*recin == '0') && (l))
 | 
						|
        {
 | 
						|
          recin++;
 | 
						|
          l--;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }  
 | 
						|
  }
 | 
						|
 | 
						|
  if (l)
 | 
						|
  {
 | 
						|
    while(l > 0 && recin[l - 1] == ' ') l--;
 | 
						|
    if (l)
 | 
						|
      strncpy(s, recin, l);
 | 
						|
  }
 | 
						|
  s[l] = '\0'; 
 | 
						|
  if (l)
 | 
						|
  {
 | 
						|
    if (t == _datefld)
 | 
						|
    {
 | 
						|
      const TDate dt(s);
 | 
						|
      strcpy(s, dt.string(full));
 | 
						|
    }
 | 
						|
    else
 | 
						|
      if (t == _boolfld)
 | 
						|
      {
 | 
						|
        const char ok = toupper(*s);
 | 
						|
        if (ok == 'T' || ok == 'Y' || ok == 'S' || ok == 'X')
 | 
						|
          strcpy(s,"X");
 | 
						|
        else
 | 
						|
          strcpy(s," ");
 | 
						|
      }    
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void  __putfieldbuff(byte l, byte d, byte t, const char* s, char* recout)
 | 
						|
{
 | 
						|
  int len, i;
 | 
						|
 | 
						|
  CHECK(recout, "Can't write null record" );
 | 
						|
 | 
						|
  char s2[40];
 | 
						|
 | 
						|
  if (t == _datefld)
 | 
						|
  {
 | 
						|
    if (*s)
 | 
						|
    {
 | 
						|
      const TDate dt(s);    
 | 
						|
      strcpy(s2, dt.string(ANSI));
 | 
						|
      s = s2;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
    if (t == _boolfld)
 | 
						|
    {           
 | 
						|
      strcpy(s2, (*s && strchr("STXY", toupper(*s)) != NULL) ? "T" : "F");
 | 
						|
      s = s2;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      if (t == _realfld)
 | 
						|
      {
 | 
						|
        real r(s);
 | 
						|
        strcpy(s2, r.string(l, d)); 
 | 
						|
        s = s2;
 | 
						|
      }
 | 
						|
 | 
						|
  len = strlen(s);
 | 
						|
  
 | 
						|
  if (len > l) 
 | 
						|
  {
 | 
						|
    yesnofatal_box("Impossibile scrivere %d caratteri su di un campo di %d", (int)len, (int)l);
 | 
						|
    return;
 | 
						|
  }  
 | 
						|
  
 | 
						|
  if ((t == _intfld)     ||
 | 
						|
      (t == _longfld)    ||
 | 
						|
      (t == _wordfld)    ||
 | 
						|
      (t == _realfld)    ||
 | 
						|
      (t == _intzerofld) ||
 | 
						|
      (t == _longzerofld)
 | 
						|
      )
 | 
						|
  {
 | 
						|
    if (len == 0)
 | 
						|
    {
 | 
						|
      strcpy(s2, "0");
 | 
						|
      s = s2;
 | 
						|
      len = 1;
 | 
						|
    } 
 | 
						|
    
 | 
						|
    const char c = (t == _intzerofld || t == _longzerofld) ? '0' : ' ';
 | 
						|
    for  (i = l - len - 1; i >= 0; i--) recout[i] = c;
 | 
						|
    strncpy(&recout[l - len], s, len) ;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    strncpy(recout, s, len) ;
 | 
						|
    for  (i = l - 1; i >= len; i--) recout[i] = ' ';
 | 
						|
  }
 | 
						|
}      
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
// Funzioni implementate per la gestione file dati tramite Codebase
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
// Inizio(@)
 | 
						|
 | 
						|
// @doc INTERNAL
 | 
						|
 | 
						|
// @func Ritorna una Token_string con in nome dell'indice
 | 
						|
void get_idx_names(
 | 
						|
     int logicnum,    // @parm Numero logico del file di cui riconoscere l'indice
 | 
						|
     TToken_string& i_names)  // @parm Token_string in cui inserire il nome dell'indice
 | 
						|
 | 
						|
// @comm Ritorna il nome con il prefisso corrente
 | 
						|
{
 | 
						|
  long      c = DB_getconf();
 | 
						|
  TDir      d; 
 | 
						|
  TTrec     r;
 | 
						|
  d.get(logicnum);
 | 
						|
  r.get(logicnum);
 | 
						|
  TFilename f(d.name());
 | 
						|
  
 | 
						|
  if ( c & 1) f.ext("cdx");
 | 
						|
  if ( c & 4) f.ext("mdx");
 | 
						|
  i_names.cut(0);
 | 
						|
  i_names.add(f);
 | 
						|
  f.ext("");
 | 
						|
  f.rtrim(1);
 | 
						|
  if (c & 2 || c & 8)    // DBIII or CLIPPER format, returns f_name + .cgp, f_nameX + .n{d|t}x
 | 
						|
    for (int j=1; j<=r.keys();j++)
 | 
						|
    { 
 | 
						|
      TString xx=f.name();
 | 
						|
      if (xx.len()<8)
 | 
						|
        f << ('0' + j);
 | 
						|
      else
 | 
						|
        f[8] = ('0' + j); 
 | 
						|
      if (c & 2) // CLIPPER
 | 
						|
        f.ext("ndx");        
 | 
						|
      else       // DBIII
 | 
						|
        f.ext("ntx");
 | 
						|
      i_names.add(f);
 | 
						|
    }
 | 
						|
  i_names.restart();
 | 
						|
}
 | 
						|
 | 
						|
int get_error(int err)
 | 
						|
{   
 | 
						|
  if (err > 0)  
 | 
						|
  { 
 | 
						|
    if (err >= 10)
 | 
						|
    {
 | 
						|
      if (err > 80 || error_codes_rb[err/10]==-1) return err;
 | 
						|
      else
 | 
						|
        return(error_codes_rb[err/10]);
 | 
						|
    }
 | 
						|
    else
 | 
						|
      return(error_codes_ra[err]);      
 | 
						|
  }
 | 
						|
  else
 | 
						|
    if (err < 0)
 | 
						|
    { 
 | 
						|
      int ierr = DB_get_error();  
 | 
						|
      if (ierr < 0) ierr = -ierr;
 | 
						|
      if (ierr > 340 || error_codes_g[ierr/10]==-1) 
 | 
						|
        return (-ierr);
 | 
						|
      return (error_codes_g[ierr/10]);
 | 
						|
    }                    
 | 
						|
  DB_zero_error();      
 | 
						|
  return(NOERR);
 | 
						|
}
 | 
						|
 | 
						|
HIDDEN bool rec_has_memo( const RecDes * rd )
 | 
						|
{ 
 | 
						|
  for( int i = rd->NFields - 1; i >= 0; i--)
 | 
						|
    if (rd->Fd[i].TypeF == _memofld)
 | 
						|
      return  TRUE;
 | 
						|
  return FALSE;
 | 
						|
}  
 | 
						|
 | 
						|
 | 
						|
HIDDEN bool lf_has_memo( const int lffile )
 | 
						|
{ 
 | 
						|
  TTrec r;
 | 
						|
 | 
						|
  r.get( lffile );    
 | 
						|
  return rec_has_memo(r.rec());
 | 
						|
}  
 | 
						|
 | 
						|
HIDDEN void browse_null(char *start, int nc)
 | 
						|
{                 
 | 
						|
  for (int i = nc - 1; i >= 0 ; i--) // Anche il primo byte(deletion flag) deve essere cambiato. nc comprende il primo byte
 | 
						|
    if (start[i] == '\0') start[i] = ' '; 
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
HIDDEN void getisfd(isfdptr & isfd, int logicnum)
 | 
						|
{    
 | 
						|
  isfd = new isdef ;
 | 
						|
  isfd->r = new RecDes ;
 | 
						|
  isfd->d = new FileDes ;
 | 
						|
  CGetFile(logicnum, isfd->d, _nolock, _nordir);
 | 
						|
  const TFixed_string name(isfd->d->SysName);
 | 
						|
  if (name.not_empty() && name[0] != '$')
 | 
						|
    isfd->ft = _comdir;
 | 
						|
  else
 | 
						|
    isfd->ft = _nordir;
 | 
						|
  COpenFile(logicnum, isfd->d, _nolock, isfd->ft);
 | 
						|
  CGetRec(logicnum, isfd->r, isfd->ft);
 | 
						|
  isfd->ln = logicnum;
 | 
						|
}                                                  
 | 
						|
 | 
						|
 | 
						|
HIDDEN  void relisfd(isfdptr & isfd)
 | 
						|
{
 | 
						|
  if (isfd->ln > 0 && isfd->fhnd >= 0)
 | 
						|
  {
 | 
						|
    TDir d;
 | 
						|
    d.get(isfd->ln, _lock, (TDirtype) isfd->ft, _sysdirop);
 | 
						|
    d.eod() = isfd->d->EOD;
 | 
						|
    d.eox() = isfd->d->EOX;
 | 
						|
    d.put(isfd->ln, (TDirtype) isfd->ft, _sysdirop);
 | 
						|
  }
 | 
						|
  delete isfd->d;
 | 
						|
  delete isfd->r;
 | 
						|
  delete isfd;
 | 
						|
 | 
						|
#ifdef DBG  
 | 
						|
  isfd = NULL;         // Per provocare errori
 | 
						|
#endif  
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
HIDDEN  int __build_key(RecDes *recd, int numkey, RecType recin, char *key, bool build_x_cb)
 | 
						|
  /* *recd;       descrittore record               */
 | 
						|
  /* numkey;      numero chiave                    */
 | 
						|
  /* recin;       buffer contenente il record      */
 | 
						|
  /* *key;        valore della chiave              */
 | 
						|
  /* build_x_cb   flag di costruzione per codebase */
 | 
						|
{           
 | 
						|
  CHECKD(numkey > 0, "Can't build key ", numkey);
 | 
						|
  
 | 
						|
  const char null_char = -1;
 | 
						|
  key[0] = '\0';
 | 
						|
  if (numkey-- <= recd->NKeys)
 | 
						|
  { 
 | 
						|
    int l = 0;                                   
 | 
						|
    for (int i = 0; i < recd->Ky[numkey].NkFields; i++)
 | 
						|
    {                        
 | 
						|
      const KeyDes& kd = recd->Ky[numkey];
 | 
						|
      const bool upp = kd.FieldSeq[i] > MaxFields;
 | 
						|
      const int nf = upp ? kd.FieldSeq[i] - MaxFields : kd.FieldSeq[i];
 | 
						|
      const RecFieldDes& rf = recd->Fd[nf];  
 | 
						|
      const TFieldtypes f = (TFieldtypes) rf.TypeF;
 | 
						|
      
 | 
						|
      int off, len;
 | 
						|
      if (kd.FromCh[i] == 255)
 | 
						|
      {
 | 
						|
        off = rf.RecOff;
 | 
						|
        len = rf.Len;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      { 
 | 
						|
        off = rf.RecOff + kd.FromCh[i];
 | 
						|
        len = kd.ToCh[i] - kd.FromCh[i] + 1;
 | 
						|
      }
 | 
						|
      if ((l + len) > 80)
 | 
						|
      {
 | 
						|
        key[0] = '\0';
 | 
						|
        return(_iskeylenerr);
 | 
						|
      }
 | 
						|
      if (f == _boolfld) 
 | 
						|
      {               
 | 
						|
        const bool on = *(recin + off) > ' ' && strchr("STXY", *(recin + off)) != NULL;
 | 
						|
        key[l] = on ? 'T' : 'F';
 | 
						|
      }  
 | 
						|
      else             
 | 
						|
        strncpy((key + l), (recin + off), len);
 | 
						|
        
 | 
						|
      if (recin[off] == '\0')
 | 
						|
      {
 | 
						|
        memset(key + l, ' ', len);
 | 
						|
        if ((f == _intfld) || (f == _longfld) || (f == _wordfld) || 
 | 
						|
                            (f == _intzerofld) || (f == _longzerofld))
 | 
						|
          key[l + len - 1] = build_x_cb ? '0' : null_char;
 | 
						|
      }
 | 
						|
      else
 | 
						|
        if ((f == _intfld) || (f == _longfld) || (f == _wordfld) || (f == _intzerofld) || (f == _longzerofld))
 | 
						|
        {   
 | 
						|
          int w = l, j = l + len;
 | 
						|
          while (w < j && key[w] == ' ') w++;
 | 
						|
          while (w < j && key[w] == '0') key[w++] = ' ';
 | 
						|
          if (w == j) key[w-1] = build_x_cb ? '0' : 0xFF;
 | 
						|
        } 
 | 
						|
      if (upp)
 | 
						|
        for (int i = l+len-1; i >= l; i--)
 | 
						|
          key[i] = toupper(key[i]);
 | 
						|
 | 
						|
      l += len;
 | 
						|
    }
 | 
						|
    
 | 
						|
    // rtrim            
 | 
						|
    if (build_x_cb)
 | 
						|
    {
 | 
						|
      for (l--; l>=0 && key[l] == ' '; l--);
 | 
						|
      key[l + 1] = '\0';
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      for (l--; l>=0 && (key[l] == ' ' || key[l] == null_char); l--);
 | 
						|
      key[l + 1] = '\0';
 | 
						|
      for (;l >= 0; l--)
 | 
						|
        if (key[l] == null_char)
 | 
						|
          key[l] = '0';
 | 
						|
    }
 | 
						|
    
 | 
						|
    return(NOERR);
 | 
						|
  }
 | 
						|
  return(_ispatherr);
 | 
						|
}
 | 
						|
 | 
						|
HIDDEN int cisstart(isfdptr isfd, int keynum, TRectype & record, unsigned int mode)
 | 
						|
 | 
						|
{ 
 | 
						|
  // It seems quite unuseful... Quando cambio la chiave con setkey, la d4tagselect
 | 
						|
  // seleziona gia' l'indice, rendendo inutile il senso della cisstart
 | 
						|
  return NOERR;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
HIDDEN int cisread(isfdptr isfd, TRectype & record, int mode)
 | 
						|
{
 | 
						|
  int  rmode = (mode & READTYPES), lmode = (mode & RECLOCKTYPES);
 | 
						|
 | 
						|
  // Non usare mai _isnextn o _isprevn, usare il metodo skip!  
 | 
						|
  CHECK (rmode !=_isnextn && rmode !=_isprevn, "_isnextn and _isprevn not supported in cisread");
 | 
						|
 | 
						|
  char     key[128];
 | 
						|
  int err = NOERR ;
 | 
						|
 | 
						|
  do
 | 
						|
  {
 | 
						|
   if (rmode>=_isequal && rmode<=_isgteq)
 | 
						|
    {   
 | 
						|
      err=__build_key(isfd->r, isfd->knum, record.string(),key,TRUE);
 | 
						|
      if (err == NOERR)
 | 
						|
      {
 | 
						|
        err = DB_seek(isfd->fhnd,key); 
 | 
						|
        if (rmode == _isgreat && err == NOERR)  
 | 
						|
          err = DB_next(isfd->fhnd);
 | 
						|
        if (err != NOERR) 
 | 
						|
          err = get_error(err);
 | 
						|
      }
 | 
						|
      if (rmode != _isequal && err == _iskeynotfound) 
 | 
						|
        err = NOERR;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if (rmode==_isfirst)   
 | 
						|
        err=DB_first(isfd->fhnd); else
 | 
						|
          if (rmode==_islast)
 | 
						|
            err=DB_last(isfd->fhnd); else
 | 
						|
              if (rmode==_isnext)
 | 
						|
                err=DB_next(isfd->fhnd); else
 | 
						|
                  if (rmode==_isprev)
 | 
						|
                    err=DB_prev(isfd->fhnd); else
 | 
						|
                      if (rmode==_iscurr)
 | 
						|
                        err=DB_go(isfd->fhnd,DB_recno(isfd->fhnd));  
 | 
						|
      if (err != NOERR) err=get_error(err);       
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (err == _iseof)
 | 
						|
      DB_last(isfd->fhnd);
 | 
						|
    if (err == NOERR && (lmode == _lock || lmode == _testandlock))   // _lock e _testandlock
 | 
						|
    {
 | 
						|
      err=DB_lock(isfd->fhnd);
 | 
						|
      if (err != NOERR) err=get_error(err);
 | 
						|
      if (err == _islocked && lmode == _testandlock) break;
 | 
						|
    }
 | 
						|
    if (err == _islocked)
 | 
						|
    {
 | 
						|
      record = (const char *) DB_getrecord(isfd->fhnd);
 | 
						|
      __build_key(isfd->r, isfd->knum, record.string(), key, TRUE);
 | 
						|
      message_box("Codice %s in uso da parte\ndi un altro utente.", key);
 | 
						|
    } 
 | 
						|
  } while (err ==_islocked);  
 | 
						|
 | 
						|
  if (err == NOERR && lmode == _unlock)            
 | 
						|
  {
 | 
						|
    err=DB_unlock(isfd->fhnd);  
 | 
						|
    if (err != NOERR) err=get_error(err);
 | 
						|
  }
 | 
						|
 | 
						|
  record = (const char *) DB_getrecord(isfd->fhnd);
 | 
						|
  isfd->RecNo = DB_recno(isfd->fhnd);  
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
HIDDEN int delkeys(isfdptr fd, char* record,long recno)
 | 
						|
{  
 | 
						|
  int rt=NOERR,oldkey = fd->knum;
 | 
						|
  
 | 
						|
  for (int i=1; i<=fd->r->NKeys;i++)
 | 
						|
  {            
 | 
						|
    char key[128];
 | 
						|
 | 
						|
    DB_tagselect(fd->fhnd,i);
 | 
						|
    rt=__build_key(fd->r,i,record,key,TRUE);
 | 
						|
    if (rt!=NOERR) break;
 | 
						|
    rt=DB_delkey(fd->fhnd,key,recno);
 | 
						|
    if (rt!=NOERR) break;
 | 
						|
  }
 | 
						|
  
 | 
						|
  DB_tagselect(fd->fhnd,oldkey);    
 | 
						|
  return(rt);
 | 
						|
}
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
// Funzioni implementate per la gestione file dati tramite Codebase
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
// Fine(@)
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @func Setta il valore della variabile <p __autoload>
 | 
						|
void set_autoload_new_files(
 | 
						|
     bool on) // @parm Valore da assegnare
 | 
						|
 | 
						|
// @comm Il valore di <p __autoload> indica il caricamento dei valori standard dei file
 | 
						|
 | 
						|
{
 | 
						|
  __autoload = on;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TExtrectype
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TExtrectype : public TVariable_rectype
 | 
						|
{         
 | 
						|
  RecDes* _rd;
 | 
						|
 | 
						|
protected: // TRectype
 | 
						|
  virtual RecDes* rec_des() const { return _rd; }
 | 
						|
  virtual bool auto_virtual_fields() const { return TRUE; }
 | 
						|
 | 
						|
public:
 | 
						|
 | 
						|
  TExtrectype(const TTrec& r);  // Costruisce il record a partire da r
 | 
						|
  virtual ~TExtrectype() {}
 | 
						|
};
 | 
						|
 | 
						|
TExtrectype::TExtrectype(const TTrec& r) : TVariable_rectype(r.num())
 | 
						|
  
 | 
						|
{
 | 
						|
  delete _rec;
 | 
						|
  _length = r.len();
 | 
						|
  _rec = new char [ _length ];
 | 
						|
  _rd = r.rec();
 | 
						|
  if( rec_has_memo(r.rec()))
 | 
						|
    init_memo(RECORD_NON_FISICO );
 | 
						|
  zero();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TBaseisamfile
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TBaseisamfile::TBaseisamfile(int logicnum, bool linkrecinst)
 | 
						|
 | 
						|
{
 | 
						|
  _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 
 | 
						|
  {       
 | 
						|
    NFCHECK("linkrecinst sparira' quanto prima, poiche' non sicura");
 | 
						|
    _current = openrec[_logicnum - 1];
 | 
						|
    _delrec = FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  
 | 
						|
  //   _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 = RECORD_NON_FISICO, wr1 = RECORD_NON_FISICO;
 | 
						|
  
 | 
						|
  if ((wr0 == flf.ptr()) == RECORD_NON_FISICO) 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
 | 
						|
{                  
 | 
						|
  NOT_OPEN();
 | 
						|
  return(DB_reccount(filehnd()->fhnd));
 | 
						|
}
 | 
						|
 | 
						|
const char* TBaseisamfile::name() const
 | 
						|
{     
 | 
						|
  sprintf(_isam_string, "%d", num());
 | 
						|
  return _isam_string;
 | 
						|
}
 | 
						|
 | 
						|
const char* TBaseisamfile::filename() const
 | 
						|
{
 | 
						|
  if (_isamfile == NULL)
 | 
						|
  {
 | 
						|
    TDir d;
 | 
						|
    d.get(num());
 | 
						|
    strcpy(_isam_string, d.filename());
 | 
						|
  } 
 | 
						|
  else
 | 
						|
  {
 | 
						|
    strcpy(_isam_string, _isamfile->d->SysName);
 | 
						|
    strcat(_isam_string, ".dbf");
 | 
						|
  }
 | 
						|
  return _isam_string;
 | 
						|
}
 | 
						|
 | 
						|
const char* TBaseisamfile::description() const
 | 
						|
{
 | 
						|
  if (_isamfile == NULL)
 | 
						|
  {
 | 
						|
    TDir d;
 | 
						|
    d.get(num());
 | 
						|
    strcpy(_isam_string, d.des());
 | 
						|
    return _isam_string;
 | 
						|
  }
 | 
						|
  return _isamfile->d->Des;
 | 
						|
}
 | 
						|
 | 
						|
TRecnotype TBaseisamfile::eod() const
 | 
						|
{
 | 
						|
  NOT_OPEN();
 | 
						|
  return(DB_reccount(_isamfile->fhnd));
 | 
						|
}                                         
 | 
						|
 | 
						|
void TBaseisamfile::set_curr(TRectype * curr)
 | 
						|
 | 
						|
{ 
 | 
						|
  CHECK(curr != NULL, "You must pass a valid record");
 | 
						|
  if (_current != NULL)
 | 
						|
    delete _current;
 | 
						|
  _current = curr;                     
 | 
						|
}
 | 
						|
 | 
						|
void TBaseisamfile::setkey(int nkey)
 | 
						|
 | 
						|
{
 | 
						|
  CHECKD(nkey > 0 && nkey-1 <= _isamfile->r->NKeys, "Chiave non valida ", nkey);
 | 
						|
  NOT_OPEN();
 | 
						|
 | 
						|
  int rt = DB_tagselect(_isamfile->fhnd,nkey);
 | 
						|
  if (rt>=0) _isamfile->knum=nkey;
 | 
						|
  if (rt!=NOERR)        rt=get_error(rt);           
 | 
						|
  if (_lasterr == NOERR)  setstatus(rt);
 | 
						|
}
 | 
						|
 | 
						|
int TBaseisamfile::getkey() const
 | 
						|
{
 | 
						|
  NOT_OPEN();
 | 
						|
  CHECKD(DB_tagget(_isamfile->fhnd) == _isamfile->knum, "Chiave inconsistente sul file ", _logicnum);
 | 
						|
  return _isamfile->knum;
 | 
						|
}
 | 
						|
 | 
						|
int TBaseisamfile::first(word lockop)
 | 
						|
  
 | 
						|
{
 | 
						|
  NOT_OPEN();
 | 
						|
  curr().setdirty();
 | 
						|
  _lasterr=cisread(_isamfile, curr(), _isfirst + lockop);
 | 
						|
  if (_lasterr != NOERR) _lasterr = get_error(_lasterr);
 | 
						|
  _recno = _isamfile->RecNo;
 | 
						|
  if( curr().has_memo( ) )
 | 
						|
    curr( ).init_memo(_recno);
 | 
						|
  return _lasterr;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::last(word lockop)
 | 
						|
  
 | 
						|
{
 | 
						|
  NOT_OPEN();
 | 
						|
  curr().setdirty();
 | 
						|
  _lasterr=cisread(_isamfile, curr(), _islast + lockop );
 | 
						|
  if (_lasterr != NOERR) _lasterr = get_error(_lasterr);
 | 
						|
  _recno = _isamfile->RecNo;
 | 
						|
  if( curr().has_memo( ) )
 | 
						|
    curr( ).init_memo(_recno);
 | 
						|
  return _lasterr;
 | 
						|
}
 | 
						|
 | 
						|
int TBaseisamfile::_next(word lockop)
 | 
						|
{
 | 
						|
  NOT_OPEN();
 | 
						|
  curr().setdirty();   
 | 
						|
  if (_recno != DB_recno(_isamfile->fhnd))
 | 
						|
  {
 | 
						|
    _lasterr = cisread(_isamfile, curr(), _isgreat + lockop);
 | 
						|
    if (_lasterr != NOERR)
 | 
						|
    { 
 | 
						|
      _lasterr = get_error(_lasterr);
 | 
						|
      if (_lasterr != _islocked && _lasterr != _iseof)
 | 
						|
        fatal_box("Errore nella next %d : non posso riposizionarmi", _lasterr);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    _lasterr=cisread(_isamfile, curr(), _isnext + lockop);
 | 
						|
    if (_lasterr != NOERR) _lasterr = get_error(_lasterr);
 | 
						|
  }
 | 
						|
  _recno = _isamfile->RecNo;  
 | 
						|
  if( curr().has_memo( ) )
 | 
						|
    curr( ).init_memo(_recno );
 | 
						|
  return _lasterr;
 | 
						|
}  
 | 
						|
 | 
						|
int TBaseisamfile::next(word lockop)
 | 
						|
{
 | 
						|
	return curr().next(*this, lockop);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::next(TDate& atdate)
 | 
						|
  
 | 
						|
{ 
 | 
						|
  error_box("TBaseisamfile::next(TDate&) is no more available");
 | 
						|
  return  NOERR;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::prev(word lockop)
 | 
						|
  
 | 
						|
{
 | 
						|
  NOT_OPEN();
 | 
						|
  curr().setdirty();
 | 
						|
  if (_recno != DB_recno(_isamfile->fhnd))
 | 
						|
  {
 | 
						|
    _lasterr = cisread(_isamfile, curr(), _isgteq + _nolock);
 | 
						|
    if (_lasterr != NOERR)
 | 
						|
    { 
 | 
						|
      _lasterr = get_error(_lasterr);
 | 
						|
      if (_lasterr != _islocked && _lasterr != _iseof)
 | 
						|
        fatal_box("Errore nella next %d : non posso riposizionarmi", _lasterr);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  _lasterr=cisread(_isamfile, curr(), _isprev + lockop);
 | 
						|
  if (_lasterr != NOERR) _lasterr = get_error(_lasterr);
 | 
						|
  _recno = _isamfile->RecNo;
 | 
						|
  if(  curr().has_memo( ) )
 | 
						|
    curr( ).init_memo(_recno);
 | 
						|
  return _lasterr;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::prev(TDate& atdate)
 | 
						|
{            
 | 
						|
  error_box("TBaseisamfile::prev(TDate&) is no more available");
 | 
						|
  return NOERR;
 | 
						|
}
 | 
						|
 | 
						|
int TBaseisamfile::reread(word lockop, TDate& atdate)
 | 
						|
  
 | 
						|
{
 | 
						|
  NOT_OPEN();
 | 
						|
  
 | 
						|
  curr().setdirty();
 | 
						|
  _lasterr=cisread(_isamfile, curr(), _iscurr + lockop);
 | 
						|
  if (_lasterr != NOERR) _lasterr = get_error(_lasterr);
 | 
						|
  _recno = _isamfile->RecNo;
 | 
						|
  if(  curr().has_memo( ) )
 | 
						|
     curr( ).init_memo(_recno);
 | 
						|
  return _lasterr;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::reread(TRectype& rec, word lockop, TDate& atdate)
 | 
						|
  
 | 
						|
{
 | 
						|
  NOT_OPEN();
 | 
						|
  rec.setdirty();
 | 
						|
  _lasterr=cisread(_isamfile, rec, _iscurr + lockop);
 | 
						|
  if (_lasterr != NOERR) _lasterr = get_error(_lasterr);
 | 
						|
  _recno = _isamfile->RecNo;
 | 
						|
  if(  rec.has_memo( ) )
 | 
						|
    rec.init_memo(_recno);
 | 
						|
  return _lasterr;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::skip(TRecnotype nrec, word lockop)
 | 
						|
  
 | 
						|
{   
 | 
						|
  char key[128];
 | 
						|
 | 
						|
  NOT_OPEN();
 | 
						|
  if (!nrec) return NOERR;
 | 
						|
  curr().setdirty();  
 | 
						|
  if (_recno != DB_recno(_isamfile->fhnd))
 | 
						|
  {
 | 
						|
    _lasterr = DB_go(_isamfile->fhnd, _recno);
 | 
						|
    if (_lasterr != NOERR)
 | 
						|
    { 
 | 
						|
      _lasterr = get_error(_lasterr);
 | 
						|
      if (_lasterr != _islocked)
 | 
						|
        fatal_box("Errore nella skip %d : non posso riposizionarmi", _lasterr);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  _lasterr=DB_skip(_isamfile->fhnd,nrec);
 | 
						|
  if (_lasterr != NOERR) _lasterr = get_error(_lasterr);
 | 
						|
  do { 
 | 
						|
    if (_lasterr == _islocked)
 | 
						|
    {
 | 
						|
      __build_key(_isamfile->r, DB_tagget(_isamfile->fhnd), curr().string(), key,TRUE);
 | 
						|
      message_box("Codice %s in uso da parte\ndi un altro utente.", key);
 | 
						|
    }
 | 
						|
    _lasterr=cisread(_isamfile,curr(),_iscurr + lockop);
 | 
						|
  } while (_lasterr ==_islocked);  
 | 
						|
  _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd);
 | 
						|
  if(  curr().has_memo( ) )
 | 
						|
    curr( ).init_memo(_recno);
 | 
						|
  return _lasterr;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// funzione  di lettura dei file
 | 
						|
int TBaseisamfile::_read(TRectype& rec, word op, word lockop, TDate& atdate)
 | 
						|
{
 | 
						|
  NOT_OPEN();
 | 
						|
  rec.setdirty();
 | 
						|
  _lasterr=cisread(_isamfile, rec, op + lockop);
 | 
						|
  if (_lasterr != NOERR) _lasterr=get_error(_lasterr);
 | 
						|
  _recno = _isamfile->RecNo;
 | 
						|
  if(  rec.has_memo( ) )
 | 
						|
    rec.init_memo(_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();
 | 
						|
  _lasterr=rec.read(*this, op, lockop, atdate);
 | 
						|
  return _lasterr;
 | 
						|
}
 | 
						|
 | 
						|
int TBaseisamfile::read(word op, word lockop, TDate& atdate)
 | 
						|
  
 | 
						|
{
 | 
						|
//  CHECKD(op >= _iscurr && op <= _isgteq, "Invalid read operation : ", op);
 | 
						|
  return TBaseisamfile::read(curr(),op, lockop, atdate);
 | 
						|
}
 | 
						|
 | 
						|
int TBaseisamfile::readat(TRectype& rec, TRecnotype nrec, word lockop)
 | 
						|
{
 | 
						|
	return rec.readat(*this,nrec,lockop);
 | 
						|
}
 | 
						|
 | 
						|
int TBaseisamfile::readat(TRecnotype nrec, word lockop)
 | 
						|
{
 | 
						|
	return TBaseisamfile::readat(curr(),nrec,lockop);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::_readat(TRectype& rec, TRecnotype nrec, word lockop)
 | 
						|
{
 | 
						|
  NOT_OPEN();
 | 
						|
  rec.setdirty();
 | 
						|
  _lasterr=DB_go(_isamfile->fhnd,nrec);                             
 | 
						|
  if (_lasterr != NOERR) 
 | 
						|
    _lasterr = get_error(_lasterr);
 | 
						|
  else
 | 
						|
    rec = (const char *) DB_getrecord(_isamfile->fhnd);
 | 
						|
  	_recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd);
 | 
						|
  if(  rec.has_memo( ) )
 | 
						|
    rec.init_memo( _recno );
 | 
						|
  return _lasterr;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::_write(const TRectype& rec, TDate& atdate)
 | 
						|
{
 | 
						|
/*
 | 
						|
  NOT_OPEN();
 | 
						|
  TRectype save_rec(curr());                  
 | 
						|
  
 | 
						|
  const int cur_key = getkey();
 | 
						|
  setkey(1);
 | 
						|
  _lasterr = cisread(_isamfile, save_rec, _isequal + _nolock); // Si Posiziona per sicurezza...
 | 
						|
  setkey(cur_key);
 | 
						|
  if (_lasterr == NOERR)
 | 
						|
  {                        
 | 
						|
    const int len = DB_reclen(_isamfile->fhnd);
 | 
						|
    
 | 
						|
    browse_null(curr().string(), len);
 | 
						|
    if (memcmp(curr().string(),save_rec.string(), len) != 0)
 | 
						|
    {
 | 
						|
      memcpy(DB_getrecord(_isamfile->fhnd), curr().string(), len);
 | 
						|
      _lasterr = DB_rewrite(_isamfile->fhnd);
 | 
						|
      if (_lasterr != NOERR) _lasterr = get_error(_lasterr);
 | 
						|
    }                    
 | 
						|
    else
 | 
						|
      DB_unlock(_isamfile->fhnd);  
 | 
						|
      
 | 
						|
    _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd);
 | 
						|
    if(_lasterr == NOERR && curr().has_memo( ))
 | 
						|
      curr( ).write_memo( _isamfile, _recno );
 | 
						|
  }  
 | 
						|
  return _lasterr;
 | 
						|
*/
 | 
						|
  CHECK(!rec.empty(), "Can't write an empty record");
 | 
						|
 | 
						|
  NOT_OPEN();
 | 
						|
  int oldkey=getkey();
 | 
						|
  browse_null(rec.string(),DB_reclen(_isamfile->fhnd));
 | 
						|
 | 
						|
  setkey(1);
 | 
						|
  memcpy(DB_getrecord(_isamfile->fhnd),rec.string(),DB_reclen(_isamfile->fhnd));                             
 | 
						|
  _lasterr = DB_add(_isamfile->fhnd);
 | 
						|
  if (_lasterr != NOERR) _lasterr = get_error(_lasterr);
 | 
						|
  setkey(oldkey);
 | 
						|
  _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd);
 | 
						|
  if (_lasterr == NOERR && rec.has_memo())
 | 
						|
    ((TRectype &)rec).write_memo( _isamfile, _recno );
 | 
						|
  return _lasterr;
 | 
						|
}
 | 
						|
 | 
						|
int TBaseisamfile::write(const TRectype& rec, TDate& atdate)
 | 
						|
{
 | 
						|
//  CHECK(!rec.empty(), "Can't write an empty record");
 | 
						|
  return rec.write(*this, atdate);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::write(TDate& atdate)
 | 
						|
{                 
 | 
						|
//  CHECK(!curr().empty(), "Can't write an empty record");
 | 
						|
	return TBaseisamfile::write(curr(),atdate);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::_rewrite(const TRectype& rec, TDate& atdate)
 | 
						|
{
 | 
						|
  CHECK(!rec.empty(), "Can't write an empty record");
 | 
						|
 | 
						|
  NOT_OPEN(); 
 | 
						|
  TRectype save_rec(rec);
 | 
						|
  const int cur_key = getkey();
 | 
						|
  setkey(1);
 | 
						|
  _lasterr = cisread(_isamfile, save_rec, _isequal + _nolock); // Si Posiziona per sicurezza...
 | 
						|
  setkey(cur_key);
 | 
						|
  if (_lasterr == NOERR)
 | 
						|
  {
 | 
						|
    const int len = DB_reclen(_isamfile->fhnd);
 | 
						|
 | 
						|
    browse_null(rec.string(), len);
 | 
						|
    if (memcmp(rec.string(), save_rec.string(), len) != 0)
 | 
						|
    {
 | 
						|
      memcpy(DB_getrecord(_isamfile->fhnd), rec.string(), len); 
 | 
						|
      _lasterr = DB_rewrite(_isamfile->fhnd);
 | 
						|
      if (_lasterr != NOERR) _lasterr = get_error(_lasterr);
 | 
						|
    }
 | 
						|
    else
 | 
						|
      DB_unlock(_isamfile->fhnd);  
 | 
						|
    _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd);
 | 
						|
    if(_lasterr == NOERR && curr().has_memo( ))
 | 
						|
      ((TRectype &)rec).write_memo( _isamfile, _recno );
 | 
						|
  }    
 | 
						|
  return _lasterr;
 | 
						|
}
 | 
						|
 | 
						|
int TBaseisamfile::rewrite(const TRectype& rec, TDate& atdate)
 | 
						|
  
 | 
						|
{
 | 
						|
//  CHECK(!rec.empty(), "Can't write an empty record");
 | 
						|
	return rec.rewrite(*this,atdate);
 | 
						|
}
 | 
						|
 | 
						|
int TBaseisamfile::rewrite(TDate& atdate)
 | 
						|
{
 | 
						|
//	CHECK(!curr().empty(), "Can't rewrite an empty record");
 | 
						|
  return TBaseisamfile::rewrite(curr(),atdate);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::rewriteat(const TRectype& rec, TRecnotype nrec)
 | 
						|
 | 
						|
{
 | 
						|
  NOT_OPEN();
 | 
						|
  if ((_lasterr=DB_go(_isamfile->fhnd,nrec))== NOERR)
 | 
						|
  {                                      
 | 
						|
    browse_null(rec.string(),DB_reclen(_isamfile->fhnd));
 | 
						|
    memcpy(DB_getrecord(_isamfile->fhnd),rec.string(),DB_reclen(_isamfile->fhnd));
 | 
						|
    _lasterr=DB_rewrite(_isamfile->fhnd);
 | 
						|
    if (_lasterr != NOERR) _lasterr = get_error(_lasterr);
 | 
						|
  } else
 | 
						|
    _lasterr = get_error(_lasterr);
 | 
						|
  _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd);
 | 
						|
  if(_lasterr == NOERR && curr().has_memo( ))
 | 
						|
    ((TRectype &)rec).write_memo( _isamfile, _recno );
 | 
						|
  return _lasterr;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::rewriteat(TRecnotype nrec)
 | 
						|
  
 | 
						|
{
 | 
						|
  return TBaseisamfile::rewriteat(curr(),nrec);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::_remove(const TRectype& rec, TDate& atdate)
 | 
						|
{
 | 
						|
  CHECK(!rec.empty(), "Can't remove an empty record");
 | 
						|
 | 
						|
  NOT_OPEN();
 | 
						|
  memcpy(DB_getrecord(_isamfile->fhnd),rec.string(),DB_reclen(_isamfile->fhnd)); 
 | 
						|
  if ((_lasterr=cisread(_isamfile, (TRectype&) rec, _isequal + _nolock))==NOERR)
 | 
						|
  {
 | 
						|
    _lasterr = DB_delete(_isamfile->fhnd);  // Put only deletion flag on record, must remove keys too!
 | 
						|
    if (_lasterr != NOERR)
 | 
						|
      _lasterr = get_error(_lasterr);             
 | 
						|
    else        
 | 
						|
    {
 | 
						|
      _lasterr=delkeys(_isamfile,rec.string(),_isamfile->RecNo);
 | 
						|
      if (_lasterr != NOERR) 
 | 
						|
      {
 | 
						|
        DB_recall(_isamfile->fhnd);
 | 
						|
        _lasterr = get_error(_lasterr);           
 | 
						|
      }
 | 
						|
    }   
 | 
						|
  }
 | 
						|
 | 
						|
  if(_lasterr == NOERR && curr().has_memo())
 | 
						|
    curr().memo_recno();
 | 
						|
 | 
						|
  _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd);
 | 
						|
  return _lasterr;
 | 
						|
}
 | 
						|
 | 
						|
int TBaseisamfile::remove(const TRectype& rec, TDate& atdate)
 | 
						|
{
 | 
						|
	/* old version:
 | 
						|
  CHECK(!rec.empty(), "Can't remove an empty record");
 | 
						|
 | 
						|
  NOT_OPEN();
 | 
						|
  memcpy(DB_getrecord(_isamfile->fhnd),rec.string(),DB_reclen(_isamfile->fhnd)); 
 | 
						|
  if ((_lasterr=cisread(_isamfile, (TRectype&) rec, _isequal + _nolock))==NOERR)
 | 
						|
  {
 | 
						|
    _lasterr = DB_delete(_isamfile->fhnd);  // Put only deletion flag on record, must remove keys too!
 | 
						|
    if (_lasterr != NOERR)
 | 
						|
      _lasterr = get_error(_lasterr);             
 | 
						|
    else        
 | 
						|
    {
 | 
						|
      _lasterr=delkeys(_isamfile,rec.string(),_isamfile->RecNo);
 | 
						|
      if (_lasterr != NOERR) 
 | 
						|
      {
 | 
						|
        DB_recall(_isamfile->fhnd);
 | 
						|
        _lasterr = get_error(_lasterr);           
 | 
						|
      }
 | 
						|
    }   
 | 
						|
  }
 | 
						|
 | 
						|
  if(_lasterr == NOERR && curr().has_memo())
 | 
						|
    curr().memo_recno();
 | 
						|
 | 
						|
  _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd);
 | 
						|
  return _lasterr;
 | 
						|
  */
 | 
						|
  // new version:
 | 
						|
	return rec.remove(*this, atdate);  
 | 
						|
}
 | 
						|
 | 
						|
int TBaseisamfile::remove(TDate& atdate)
 | 
						|
{
 | 
						|
/* old version:
 | 
						|
  CHECK(!curr().empty(), "Can't remove empty record");
 | 
						|
 | 
						|
  NOT_OPEN();
 | 
						|
  
 | 
						|
  if ((_lasterr=cisread(_isamfile, curr(), _isequal + _nolock)) == NOERR)
 | 
						|
  {
 | 
						|
    _lasterr = DB_delete(_isamfile->fhnd);   // Put only deletion flag on record, must remove keys too!
 | 
						|
    if (_lasterr != NOERR)
 | 
						|
      _lasterr = get_error(_lasterr);
 | 
						|
    else
 | 
						|
    {
 | 
						|
      _lasterr=delkeys(_isamfile,curr().string(), _isamfile->RecNo);
 | 
						|
      if (_lasterr != NOERR)
 | 
						|
      {
 | 
						|
        DB_recall(_isamfile->fhnd);
 | 
						|
        _lasterr = get_error(_lasterr);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if(_lasterr == NOERR && curr().has_memo())
 | 
						|
    curr().memo_recno();
 | 
						|
  
 | 
						|
  _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd);
 | 
						|
  return _lasterr;
 | 
						|
  */
 | 
						|
  // new version:
 | 
						|
  return TBaseisamfile::remove(curr(),atdate);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::lock()
 | 
						|
{
 | 
						|
  NOT_OPEN();
 | 
						|
  _lasterr = DB_lockfile(_isamfile->fhnd);
 | 
						|
  if (_lasterr != NOERR) _lasterr = get_error(_lasterr);
 | 
						|
  return _lasterr;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::unlock()
 | 
						|
  
 | 
						|
{
 | 
						|
  NOT_OPEN();
 | 
						|
  _lasterr = DB_unlock(_isamfile->fhnd);
 | 
						|
  if (_lasterr != NOERR) _lasterr = get_error(_lasterr);
 | 
						|
  return (_lasterr);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TBaseisamfile::indexon()
 | 
						|
  
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TBaseisamfile::empty()
 | 
						|
  
 | 
						|
{ 
 | 
						|
  return (DB_reccount(_isamfile->fhnd) == 0);
 | 
						|
}
 | 
						|
 | 
						|
void TBaseisamfile::indexoff()
 | 
						|
  
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Apre il file isam di base con lock
 | 
						|
//
 | 
						|
// @rdesc Ritorna NOERR se e' riuscita ad aprire il file, altrimenti ritorna il numero di errore
 | 
						|
//    generato (vedi <t TIsamerr>).
 | 
						|
int TBaseisamfile::_open(
 | 
						|
    unsigned int mode) // @parm Indica il modo di apertura del file (default _manulock)
 | 
						|
 | 
						|
// @comm Il parametro <p mode> puo' assumere i valori:
 | 
						|
//
 | 
						|
// @flag _manulock | Il lock dei record viene fatto manualmente
 | 
						|
// @flag _exclock | Il file viene aperte in modo esclusivo
 | 
						|
// @flag _autolock | Il lock dei record viene fatto in modo automatico
 | 
						|
  
 | 
						|
{
 | 
						|
  CHECKS(filehnd() == NULL, "File already open ", (const char*)filename());
 | 
						|
  
 | 
						|
  getisfd(_isamfile,num()); 
 | 
						|
  if ((filehnd()->fhnd = DB_open(filehnd()->d->SysName,mode==_excllock)) >= 0)
 | 
						|
  {                       
 | 
						|
    TRecnotype n=DB_reccount(filehnd()->fhnd);
 | 
						|
    TDir d;
 | 
						|
    d.get(num(),_nolock,_nordir,_sysdirop);
 | 
						|
    if (d.is_com()) d.get(num(),_nolock,_comdir,_sysdirop);
 | 
						|
    if ((filehnd()->d->EOD != n && n > 0) || (n > d.eox()))
 | 
						|
    {
 | 
						|
      filehnd()->d->EOD = d.eod() = n;
 | 
						|
      filehnd()->d->EOX = d.eox() = n; 
 | 
						|
      if (d.is_com())
 | 
						|
        d.put(num(),_comdir,_sysdirop); 
 | 
						|
      else
 | 
						|
        d.put(num(),_nordir,_sysdirop);
 | 
						|
    }
 | 
						|
    filehnd()->ln = num();
 | 
						|
    openf[num() - 1] = filehnd();
 | 
						|
    _recno = RECORD_NON_FISICO;
 | 
						|
    
 | 
						|
    CHECKD(filehnd()->r->NKeys > 0, "File senza indici: ", num());
 | 
						|
    setkey(1);
 | 
						|
    _lasterr = NOERR;
 | 
						|
  }  
 | 
						|
  else            
 | 
						|
  {   
 | 
						|
    TString e_msg;
 | 
						|
    _lasterr = get_error(filehnd()->fhnd);
 | 
						|
    if (_lasterr == -60)
 | 
						|
    {
 | 
						|
      int rc = access(filename(),0); // check for existance
 | 
						|
      if (rc!=0)
 | 
						|
        e_msg.format("Il file %d(%s) non esiste, errore %d",num(),filename(),_lasterr);
 | 
						|
      else
 | 
						|
          e_msg.format("Il file %d(%s) e' aperto in modo esclusivo da un'altra applicazione",
 | 
						|
                        num(), filename());
 | 
						|
    }
 | 
						|
    if (e_msg.empty())
 | 
						|
      e_msg.format("Il file %d(%s) non puo' essere aperto, errore %d",num(),filename(),_lasterr);
 | 
						|
    relisfd(_isamfile);  
 | 
						|
    fatal_box((const char*) e_msg);
 | 
						|
  }
 | 
						|
  return (_lasterr);            
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TBaseisamfile::_close()
 | 
						|
  
 | 
						|
{
 | 
						|
  int err = NOERR;
 | 
						|
  
 | 
						|
  if (filehnd() != NULL)
 | 
						|
  {
 | 
						|
    if (num() > 0)
 | 
						|
    {                   
 | 
						|
      TDir d;
 | 
						|
      TRecnotype n=DB_reccount(filehnd()->fhnd);
 | 
						|
      d.get(num(),_nolock,_nordir,_sysdirop);
 | 
						|
      if (d.is_com()) d.get(num(),_nolock,_comdir,_sysdirop);
 | 
						|
      if ((filehnd()->d->EOD != n && n > 0) || (n > d.eox()))
 | 
						|
      {
 | 
						|
        filehnd()->d->EOD = d.eod() = n;             
 | 
						|
        filehnd()->d->EOX = d.eox() = n;
 | 
						|
        if (d.is_com())
 | 
						|
          d.put(num(),_comdir,_sysdirop); 
 | 
						|
        else
 | 
						|
          d.put(num(),_nordir,_sysdirop);
 | 
						|
      }
 | 
						|
      CHECK(openf[num() - 1] != NULL, "Open file array corrupted");
 | 
						|
      err=DB_close(filehnd()->fhnd);
 | 
						|
      if (err != NOERR) err = get_error(err);
 | 
						|
      if ((err == NOERR) && (num() > 0))
 | 
						|
        openf[num() - 1] = NULL ;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      if (filehnd() == NULL)
 | 
						|
      {
 | 
						|
        err = _isnotopen;
 | 
						|
        error_box("File n. %d close : Error n. %d ", num(), err);
 | 
						|
      }
 | 
						|
    if (err == NOERR)
 | 
						|
    {
 | 
						|
      relisfd(_isamfile);
 | 
						|
      clearfilehnd();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  setstatus(err);
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
int TBaseisamfile::is_valid()
 | 
						|
{ // Ritorna 0 se il file puo' essere aperto senza errori
 | 
						|
  CHECKS(filehnd() == NULL, "File already open ", (const char*)filename());
 | 
						|
  int err = NOERR;
 | 
						|
  getisfd(_isamfile,num()); 
 | 
						|
  if ((filehnd()->fhnd = DB_open(filehnd()->d->SysName,0)) >= 0)
 | 
						|
  {
 | 
						|
    if (DB_tagget(filehnd()->fhnd) == -1) err = _ispatherr;
 | 
						|
    DB_close(filehnd()->fhnd);
 | 
						|
  }
 | 
						|
  else 
 | 
						|
    err = get_error(filehnd()->fhnd);
 | 
						|
  relisfd(_isamfile);  
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TLocalisamfile
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Costruttore
 | 
						|
//
 | 
						|
// @rdesc Ritorna l'oggetto <c TLocalisamfile>
 | 
						|
TLocalisamfile::TLocalisamfile(
 | 
						|
                int logicnum,     // @parm Numero del logico del file
 | 
						|
                bool linkrecinst) // @parm Puo assumere i valori:
 | 
						|
                          //
 | 
						|
                          // @flag 0 | Istanzio un nuovo file fisico (default)
 | 
						|
                          // @flag 1 | Utilizza, se possibile, un file gia' esistente
 | 
						|
                          // @flag 2 | Crea un file temporaneo
 | 
						|
: TBaseisamfile(logicnum, linkrecinst == TRUE)
 | 
						|
 | 
						|
// @comm ATTENZIONE: <p linkrecinst> puo' valere 0, 1, 2.
 | 
						|
//     Se vale 2 significa che si sta costruendo un file temporaneo
 | 
						|
//       per cui linkrecinst va' considerato FALSE         
 | 
						|
 | 
						|
{             
 | 
						|
  if (linkrecinst <= TRUE)
 | 
						|
  {
 | 
						|
    open();
 | 
						|
    if (_was_open)
 | 
						|
      _oldkey = getkey();
 | 
						|
    setkey(1); 
 | 
						|
  }
 | 
						|
  else _was_open = FALSE;  
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TLocalisamfile::~TLocalisamfile()
 | 
						|
{         
 | 
						|
  if (_was_open)
 | 
						|
    setkey(_oldkey);
 | 
						|
  close();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TLocalisamfile::close()
 | 
						|
{
 | 
						|
  int err = NOERR;
 | 
						|
 | 
						|
  if (!_was_open)
 | 
						|
  {
 | 
						|
    clearfilehnd();
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    if (_isamfile)
 | 
						|
    {                                 
 | 
						|
      TRecnotype n = DB_reccount(filehnd()->fhnd);
 | 
						|
      TDir d;
 | 
						|
      d.get(num(),_nolock,_nordir,_sysdirop);
 | 
						|
      if (d.is_com()) d.get(num(),_nolock,_comdir,_sysdirop);
 | 
						|
      if ((filehnd()->d->EOD!=n  && n > 0) || (n > d.eox()))
 | 
						|
      {
 | 
						|
        filehnd()->d->EOD = d.eod() = n;
 | 
						|
        filehnd()->d->EOX = d.eox() = n;
 | 
						|
        if (d.is_com())
 | 
						|
          d.put(num(),_comdir,_sysdirop);
 | 
						|
        else
 | 
						|
          d.put(num(),_nordir,_sysdirop);
 | 
						|
      }
 | 
						|
      err = DB_close(_isamfile->fhnd);
 | 
						|
      _isamfile->fhnd = -1;
 | 
						|
      if (err != NOERR) err = get_error(err);  
 | 
						|
      relisfd(_isamfile);
 | 
						|
      _isamfile=NULL;
 | 
						|
    }  
 | 
						|
    openf[num() -1] = 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];
 | 
						|
  }
 | 
						|
  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();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Aggiorna i flags associati al file
 | 
						|
//
 | 
						|
// @rdesc Ritorna NOERR se e' riuscita ad eseguiore l'operazione, altrimenti ritorna il numero 
 | 
						|
//    di errore generato (vedi <t TIsamerr>).
 | 
						|
int TIsamfile::flags(
 | 
						|
    bool updateeod) // @parm Indica se aggiornare anche l'EOD del file
 | 
						|
  
 | 
						|
{
 | 
						|
  TDir d;
 | 
						|
  int err = NOERR;
 | 
						|
 | 
						|
  if (filehnd()->ln <= 0) return NOERR ;
 | 
						|
  NOT_OPEN();
 | 
						|
  
 | 
						|
  const TDirtype dirtype = (TDirtype) filehnd()->ft;
 | 
						|
 | 
						|
  d.get(num(), _lock, dirtype);
 | 
						|
  if ((err = d.status(dirtype)) == NOERR)
 | 
						|
  {
 | 
						|
    d.flags() = filehnd()->d->Flags;
 | 
						|
    if (updateeod) d.eod() = filehnd()->d->EOD;
 | 
						|
    d.put(num(), dirtype);
 | 
						|
  }
 | 
						|
  setstatus(err);
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TIsamtempfile
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TIsamtempfile::TIsamtempfile(int logicnum, const char* radix, bool create)
 | 
						|
: TLocalisamfile(logicnum, 2) 
 | 
						|
{                             
 | 
						|
  TRecnotype eod = 0;
 | 
						|
  TRecnotype eox = 100;
 | 
						|
 | 
						|
  TFilename n; 
 | 
						|
  
 | 
						|
  if (radix && *radix)
 | 
						|
  {
 | 
						|
    if (*radix == '%') 
 | 
						|
      n = radix;
 | 
						|
    else
 | 
						|
    {
 | 
						|
      n.tempdir(); 
 | 
						|
      n << '/' << radix; 
 | 
						|
    }
 | 
						|
  }  
 | 
						|
  
 | 
						|
  n.ext("dbf");
 | 
						|
  
 | 
						|
  if (!create)
 | 
						|
  {      
 | 
						|
    TDir dir; dir.get(logicnum);
 | 
						|
    const word& len = dir.len();  
 | 
						|
 | 
						|
    // Tolgo il % senno' che fa la fopen ?
 | 
						|
    if (n[0] == '%') 
 | 
						|
      n = n.sub(1);
 | 
						|
    
 | 
						|
    FILE* f = fopen(n, "r");
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN || XVT_OS == XVT_OS_NT
 | 
						|
    CHECKS(f, "Can't open temporary file ", (const char*)_strerror(NULL));
 | 
						|
#else    
 | 
						|
    CHECKS(f, "Can't open temporary file ", (const char*)n);
 | 
						|
#endif    
 | 
						|
 | 
						|
    fseek(f, 0, SEEK_END);
 | 
						|
    eod = eox = ftell(f) / len;
 | 
						|
    fclose(f);
 | 
						|
  }
 | 
						|
  
 | 
						|
  _autodel = create > TRUE;
 | 
						|
 | 
						|
  n.ext("");        
 | 
						|
 | 
						|
  // Ci rimetto il % se prima l'avevo tolto, senno' che fa la open ?
 | 
						|
  if (n[0] != '%')
 | 
						|
    n.insert("%", 0);
 | 
						|
  
 | 
						|
  open(n, create, eod, eox);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TIsamtempfile::~TIsamtempfile()
 | 
						|
{
 | 
						|
  close();
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Apre il file
 | 
						|
//
 | 
						|
// @rdesc Ritorna NOERR se e' riuscita ad aprire il file, altrimenti ritorna il numero di errore
 | 
						|
//    generato (vedi <t TIsamerr>).
 | 
						|
int TIsamtempfile::open(
 | 
						|
    const char* radix,  // @parm Radice del path del file
 | 
						|
    bool create,  // @parm Indica se va creatoun nuovo file (se FALSE il file esiste gia')
 | 
						|
    TRecnotype eod,   // @parm Numero di record presenti nel file
 | 
						|
    TRecnotype eox) // @parm Numero di record da aggiungere al file
 | 
						|
 | 
						|
// @comm Nel case <p create> sia TRUE allora viene settato automaticamente il valore di <p _autodel>
 | 
						|
//   a TRUE, cioe' viene abilitata l'eliminazione del file in chiusura.
 | 
						|
  
 | 
						|
{
 | 
						|
  int err = NOERR;
 | 
						|
  TFilename tmpname;
 | 
						|
 | 
						|
  CHECKS(filehnd() == NULL, "File already open", (const char*)filename());
 | 
						|
  
 | 
						|
  if (radix[0] == '%')
 | 
						|
    tmpname << &radix[1] ;
 | 
						|
  else
 | 
						|
    tmpname.temp(radix);
 | 
						|
  getisfd (_isamfile, num());
 | 
						|
  strcpy(filehnd()->d->SysName, (const char*)tmpname);
 | 
						|
  filehnd()->d->EOX = eox;
 | 
						|
  if (create)
 | 
						|
  {
 | 
						|
    err=DB_build(filehnd()->d->SysName, filehnd()->r) ;
 | 
						|
    if (err == NOERR) 
 | 
						|
      filehnd()->d->EOD = 0L;
 | 
						|
    else
 | 
						|
    {                 
 | 
						|
      err = get_error(err);     
 | 
						|
      relisfd(_isamfile);
 | 
						|
      fatal_box("Create temporary file: Error n. %d", err);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
    filehnd()->d->EOD = eod;
 | 
						|
  filehnd()->fhnd = DB_open(filehnd()->d->SysName, 0);
 | 
						|
  if (filehnd()->fhnd < 0) 
 | 
						|
    err = get_error(filehnd()->fhnd);
 | 
						|
  if (err != NOERR)
 | 
						|
  {
 | 
						|
    relisfd(_isamfile);
 | 
						|
    fatal_box("Open temporary file: Error n. %d ",err);
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    filehnd()->ln = -num();
 | 
						|
    filehnd()->knum = 1;
 | 
						|
  }
 | 
						|
  _recno = RECORD_NON_FISICO;
 | 
						|
  setstatus(err);
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TIsamtempfile::close()
 | 
						|
{
 | 
						|
  int err = NOERR;
 | 
						|
  
 | 
						|
  if (filehnd() != NULL)
 | 
						|
  {
 | 
						|
    err=DB_close(filehnd()->fhnd);
 | 
						|
    if (err != NOERR) err = get_error(err);
 | 
						|
    if (_autodel && err==NOERR)
 | 
						|
    {
 | 
						|
      TFilename f(filehnd()->d->SysName);
 | 
						|
      long c = DB_getconf();
 | 
						|
 | 
						|
      f.ext("dbf");
 | 
						|
      ::remove((const char*)f);
 | 
						|
      if (c & 1)                                // FOXPRO format
 | 
						|
        f.ext("cdx"); 
 | 
						|
      if (c & 4)                                // DBIV format
 | 
						|
        f.ext("mdx");
 | 
						|
      if (c & 8 || c & 2)                       // CLIPPER and DBIII format
 | 
						|
      {
 | 
						|
        f.ext("cgp");
 | 
						|
        FILE *fp=fopen((const char*)f,"r");
 | 
						|
        char in[16];
 | 
						|
        while (fgets(in,16,fp)!=NULL)
 | 
						|
        {
 | 
						|
          TFilename a(in);
 | 
						|
          if (c & 8)                    // DBIII format
 | 
						|
            a.ext("ndx");
 | 
						|
          else
 | 
						|
            a.ext("ntx");       // CLIPPER format
 | 
						|
          ::remove((const char *)a);
 | 
						|
        }
 | 
						|
        fclose(fp);
 | 
						|
      }
 | 
						|
      ::remove((const char *)f);        
 | 
						|
    }
 | 
						|
    relisfd(_isamfile);
 | 
						|
    clearfilehnd();
 | 
						|
  }
 | 
						|
  setstatus(err);
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TSystemsamfile
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
int TSystemisamfile::build(TRecnotype eox)
 | 
						|
  
 | 
						|
{
 | 
						|
  CHECKS(filehnd() == NULL, "Can't build open file", (const char*)filename());
 | 
						|
  int err=NOERR;
 | 
						|
  TDir d;
 | 
						|
  TTrec r;
 | 
						|
  
 | 
						|
  d.get(num());
 | 
						|
  r.get(num());
 | 
						|
  CHECK(r.len() != 0, "Can't create a file with empty field info");
 | 
						|
  
 | 
						|
  TFilename f(d.name());
 | 
						|
 | 
						|
  f = f.path(); if (!is_not_slash(f.right(1)[0])) f.rtrim(1);
 | 
						|
  if (!fexist(f)) 
 | 
						|
    make_dir(f);
 | 
						|
  if (r.len() != 0)
 | 
						|
  {  
 | 
						|
    err=DB_build(d.name(),r.rec());
 | 
						|
    if (err == NOERR) 
 | 
						|
    {
 | 
						|
      isfdptr i;
 | 
						|
      getisfd(i,num()); 
 | 
						|
      i->d->EOX = eox;    
 | 
						|
      i->fhnd = 0; // So relisfd() will record the EOX just set
 | 
						|
      relisfd(i);
 | 
						|
    }
 | 
						|
    else
 | 
						|
      err = get_error(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 = NOERR;
 | 
						|
  isfdptr i;
 | 
						|
  
 | 
						|
  CHECKS(filehnd() == NULL, "Can't extend open file ", (const char*)filename());
 | 
						|
  getisfd(i,num());
 | 
						|
  if (num() > 0) 
 | 
						|
  {
 | 
						|
    if (eox < i->d->EOD) 
 | 
						|
      err = _ispathfull;
 | 
						|
    else 
 | 
						|
    {
 | 
						|
      i->d->EOX = eox;
 | 
						|
      i->fhnd = 0; // So relisfd() will write the EOX just set.
 | 
						|
    }
 | 
						|
  }                
 | 
						|
  relisfd(i);
 | 
						|
  setstatus(err);
 | 
						|
  clearfilehnd();
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
long TSystemisamfile::size(TRecnotype eox)
 | 
						|
{
 | 
						|
  return 51200L;
 | 
						|
}
 | 
						|
 | 
						|
#ifndef FOXPRO
 | 
						|
 | 
						|
// @doc INTERNAL
 | 
						|
 | 
						|
// @mfunc Esegue la conversione del file
 | 
						|
//
 | 
						|
// @rdesc Ritorna il rusultato dell'operazione
 | 
						|
//
 | 
						|
// @flag TRUE | Se la conversione e' stata effettuata correttamente
 | 
						|
// @flag FALSE | Se h stato rilevato un errore durante la conversione (viene emesso un <f error_box>)
 | 
						|
int TSystemisamfile::exec_convapp(
 | 
						|
     long flev,   // @parm Livello a cui aggiornare l'archivio
 | 
						|
     const bool before) // @parm Indica se viene chiamata prima o dopo la conversione
 | 
						|
  
 | 
						|
{
 | 
						|
  const char * const v = before ? "BCNV" : "ACNV";
 | 
						|
  int err = 0;
 | 
						|
 | 
						|
  if (flev == 0) flev = 199401;
 | 
						|
  else flev++;
 | 
						|
  for (long l = flev; err == 0 && l <= get_std_level(); l++)
 | 
						|
  {
 | 
						|
    TString16 paragraph(format("%06ld", l));
 | 
						|
    TConfig conv(CONFIG_FCONV, paragraph);
 | 
						|
 | 
						|
    if (!conv.new_paragraph() && conv.exist(v, num()))
 | 
						|
    {
 | 
						|
      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 && err != 8)
 | 
						|
        return error_box("Impossibile eseguire il programma di %sconversione\ndel livello %ld/%ld\nErrore n.ro %d", before ? "pre" : "post", l / 100, l % 100, err); 
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
// @doc INTERNAL
 | 
						|
 | 
						|
// @mfunc Recupera le conversioni logiche da effettuare sul file
 | 
						|
//
 | 
						|
// @rdesc Ritorna TRUE se occorre effettuare la conversione sul file
 | 
						|
bool TSystemisamfile::getlcf(
 | 
						|
     long flev)  // @parm livello archivi di partenza della convesione
 | 
						|
     
 | 
						|
// @comm Recupera le conversioni logiche da effettuare sul file per per passare dal
 | 
						|
//       livello archivi <p flev> a quello attuale degli archivi standard.
 | 
						|
  
 | 
						|
{
 | 
						|
  _flds.destroy();
 | 
						|
  _exps.destroy();
 | 
						|
  if (flev == 0) flev = 199401;
 | 
						|
  else flev++;
 | 
						|
  for (long l = flev; l <= get_std_level(); 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);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Esegue la conversione del tracciato record del file
 | 
						|
//
 | 
						|
// @rdesc Ritorna il risulato della conversione, altrimenti il codice di errore generato 
 | 
						|
//        (vedi <t TIsamerr>)
 | 
						|
int TSystemisamfile::update(
 | 
						|
    const TTrec& newrec, // @parm Nuovo tracciato record con cui aggiornare il file
 | 
						|
    bool vis)      // @parm Indica se visualizzare lo stato dell'operazione
 | 
						|
  
 | 
						|
{        
 | 
						|
  CHECKS(filehnd() == NULL, "Can't update open file", (const char*)filename());
 | 
						|
  CHECK(newrec.len() != 0, "Can't update to file with empty field info");
 | 
						|
  
 | 
						|
  TTrec wrec(newrec);
 | 
						|
  TDir dir;
 | 
						|
 | 
						|
  dir.get(num(), _unlock, _nordir, _sysdirop);
 | 
						|
  const bool is_com = prefix().is_com();
 | 
						|
  const bool toconvert = is_com ? dir.is_com() : dir.is_firm();
 | 
						|
 | 
						|
  int err = NOERR;
 | 
						|
  TTrec  oldrec;
 | 
						|
 | 
						|
  oldrec.get(num());
 | 
						|
  if (wrec.len() != 0)
 | 
						|
  {
 | 
						|
    const long lev = prefix().filelevel();
 | 
						|
    const bool lcf = getlcf(lev);
 | 
						|
 | 
						|
    err = exec_convapp(lev, TRUE);
 | 
						|
    if (err != NOERR)
 | 
						|
    {
 | 
						|
      setstatus(err);
 | 
						|
      return err;
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (!lcf && wrec == oldrec)
 | 
						|
    {
 | 
						|
      err = exec_convapp(lev, FALSE);
 | 
						|
      setstatus(err);
 | 
						|
      return err;
 | 
						|
    }
 | 
						|
    
 | 
						|
    const TRecnotype nitems = dir.eod();
 | 
						|
    const unsigned int lenr = wrec.len();
 | 
						|
    
 | 
						|
    if (!toconvert && dir.eox() > 0L)
 | 
						|
    {
 | 
						|
      dir.eod() = 0L; 
 | 
						|
      dir.eox() = 0L;
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (toconvert && dir.eox() > 0L)
 | 
						|
    {
 | 
						|
      TRecnotype ni = 0L;     
 | 
						|
      isfdptr i0;  
 | 
						|
      TFilename tmpfname("tmpf");  
 | 
						|
      
 | 
						|
      open(_excllock);
 | 
						|
      getisfd(i0, num());
 | 
						|
      err=DB_build((const char*) tmpfname, wrec.rec());
 | 
						|
      if (err != NOERR) 
 | 
						|
      {
 | 
						|
        err=get_error(err);
 | 
						|
        return (err);
 | 
						|
      }
 | 
						|
      i0->fhnd=DB_open((const char*)tmpfname,0);
 | 
						|
      if (i0->fhnd < 0 ) err=get_error(i0->fhnd);
 | 
						|
      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(wrec);
 | 
						|
      TRecnotype i = 0;
 | 
						|
                            
 | 
						|
      for (int j = 0; j < nflds; j++)
 | 
						|
        fld.add(TString(curr().fieldname(j)), j);
 | 
						|
      
 | 
						|
      for (first(); good(); next())
 | 
						|
      {
 | 
						|
        if ((i++ % 50) == 0) p.setstatus(i + 1);
 | 
						|
        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);
 | 
						|
        browse_null(nrec.string(),DB_reclen(i0->fhnd)); 
 | 
						|
        memcpy(DB_getrecord(i0->fhnd),nrec.string(),DB_reclen(i0->fhnd));  
 | 
						|
        err=DB_add(i0->fhnd);
 | 
						|
        if ( err == NOERR && nrec.has_memo())
 | 
						|
          nrec.write_memo( i0, DB_recno(i0->fhnd)); 
 | 
						|
        if (err != NOERR) err=get_error(err);
 | 
						|
        setstatus(err);
 | 
						|
      }
 | 
						|
      const int werr=DB_close(i0->fhnd);      
 | 
						|
      close();
 | 
						|
      if (err!=NOERR) err=get_error(err);
 | 
						|
      relisfd(i0);
 | 
						|
      p.setstatus(nitems);
 | 
						|
      if (err == NOERR)
 | 
						|
      {           
 | 
						|
        long c = DB_getconf();
 | 
						|
        fname.ext("dbf");
 | 
						|
        tmpfname.ext("dbf");
 | 
						|
        fcopy((const char*)tmpfname,(const char*)fname);
 | 
						|
        ::remove((const char*)tmpfname);
 | 
						|
        if (c & 1)
 | 
						|
          tmpfname.ext("fpt");
 | 
						|
        else
 | 
						|
          tmpfname.ext("dbt");
 | 
						|
        if (fexist((const char *) tmpfname))
 | 
						|
        {
 | 
						|
          if (c & 1)
 | 
						|
            fname.ext("fpt");
 | 
						|
          else
 | 
						|
            fname.ext("dbt");
 | 
						|
          fcopy((const char*)tmpfname,(const char*)fname);
 | 
						|
          ::remove((const char*)tmpfname);
 | 
						|
        }
 | 
						|
        if (c & 1)                        // FOXPRO format
 | 
						|
          tmpfname.ext("cdx");
 | 
						|
        if (c & 4)                        // DBIV format
 | 
						|
          tmpfname.ext("mdx");
 | 
						|
        if (c & 8 || c & 2)
 | 
						|
        {                   
 | 
						|
          tmpfname.ext("cgp");
 | 
						|
          char in[16];    
 | 
						|
          FILE *fp=fopen((const char *) tmpfname,"r");
 | 
						|
          while (fgets(in,16,fp)!=NULL)
 | 
						|
          {
 | 
						|
            TFilename a(in);          
 | 
						|
            a.rtrim(1); // Cut \n
 | 
						|
            if (c & 8)                    // DBIII format
 | 
						|
              a.ext("ndx");
 | 
						|
            else
 | 
						|
              a.ext("ntx");       // CLIPPER format
 | 
						|
            ::remove((const char *)a);
 | 
						|
          }
 | 
						|
          fclose(fp);
 | 
						|
        }
 | 
						|
        ::remove((const char*)tmpfname);            
 | 
						|
        dir.eod() = ni;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    dir.set_len(lenr);
 | 
						|
    dir.put(num(), _nordir, _sysdirop);
 | 
						|
    wrec.put(num());
 | 
						|
    if (toconvert && dir.eox() > 0L) packindex();
 | 
						|
    if (err == NOERR)
 | 
						|
      err = exec_convapp(lev, FALSE);            
 | 
						|
  }
 | 
						|
  setstatus(err);
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Rimuove fisicamente i record cancellati
 | 
						|
//
 | 
						|
// @rdesc Ritorna NOERR se l'operazione di compattamento e' riuscita, altrimenti il codice di
 | 
						|
//    di errore generato (vedi <t TIsamerr>).
 | 
						|
int TSystemisamfile::packfile(
 | 
						|
    bool vis) // @parm Indica se visualizzare lo stato dell'operazione
 | 
						|
 | 
						|
// @xref <mf TSystemisamfile::packindex>
 | 
						|
  
 | 
						|
{
 | 
						|
  int err=NOERR;  
 | 
						|
  TDir d;
 | 
						|
  
 | 
						|
  d.get(num(),_nolock, _nordir,_sysdirop);
 | 
						|
  d.get(num(),_nolock, (d.is_com()) ? _comdir : _nordir);
 | 
						|
  CHECKS(filehnd() == NULL, "Can't pack open file", (const char*)filename());
 | 
						|
  err=DB_packfile(vis,d.name(),d.eod());
 | 
						|
  if (err == NOERR && curr().has_memo())
 | 
						|
    err = DB_packmemo(vis,d.name());
 | 
						|
  if (err != NOERR) err = get_error(err);
 | 
						|
  if (err != NOERR) error_box("Errore in compattamento dati.\nFile %d : %d", num(),err);
 | 
						|
  setstatus(err);
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Rimuove fisicamente gli indici cancellati
 | 
						|
//
 | 
						|
// @rdesc Ritorna NOERR se l'operazione di compattamento e' riuscita, altrimenti il codice di
 | 
						|
//    di errore generato (vedi <t TIsamerr>).
 | 
						|
int TSystemisamfile::packindex(
 | 
						|
    bool vis, // @parm Indica se visualizzare lo stato dell'operazione
 | 
						|
    bool ask) // @parm Indica se chiedere il recupero dei record duplicati
 | 
						|
 | 
						|
// @xref <mf TSystemisamfile::packfile>
 | 
						|
  
 | 
						|
{
 | 
						|
  int err=NOERR;
 | 
						|
  TRecnotype peod;
 | 
						|
  TTrec r;
 | 
						|
  TDir  d;
 | 
						|
  
 | 
						|
  CHECKS(filehnd() == NULL, "Can't pack index of open file", (const char*)filename());
 | 
						|
  
 | 
						|
  r.get(num());                
 | 
						|
  d.get(num(),_nolock, _nordir,_sysdirop);               
 | 
						|
  bool is_com = d.is_com();
 | 
						|
  d.get(num(),_nolock, is_com ? _comdir : _nordir);
 | 
						|
  err=DB_packindex(vis,d.name(),r.rec(),&peod,ask);
 | 
						|
  if (err != NOERR) err = get_error(err);
 | 
						|
  if (err != NOERR) error_box("Errore in compattamento indici.\nFile %d : %d", num(),err);
 | 
						|
  else
 | 
						|
    if (peod >= 0 && peod != d.eod())
 | 
						|
    {
 | 
						|
      d.eod() = peod;
 | 
						|
      d.put(num(), is_com ? _comdir : _nordir);
 | 
						|
    }
 | 
						|
  setstatus(err);
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
int TSystemisamfile::pack(bool vis, bool ask)
 | 
						|
{
 | 
						|
  int err=NOERR;
 | 
						|
  
 | 
						|
  if ((err=packfile(vis))==NOERR)
 | 
						|
    err=packindex(vis,ask); 
 | 
						|
  setstatus(err);       
 | 
						|
  return err;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Importa un file ascii
 | 
						|
//
 | 
						|
// @rdesc Ritorna NOERR se l'operazione di lettura e' riuscita, altrimenti il codice di
 | 
						|
//    di errore generato (vedi <t TIsamerr>).
 | 
						|
int TSystemisamfile::load(
 | 
						|
    const char* from, // @parm Nome del file da importare 
 | 
						|
    char fs,    // @parm Carattere separatore di campo (default <pipe>)
 | 
						|
    char fd,            // @parm Carattere delimitatore di campi (default '\\0')
 | 
						|
    char rs,            // @parm Carattere separatore di record (default '\\n')
 | 
						|
    bool vis,     // @parm Indica se visualizzare lo stato dell'operazione (default TRUE)
 | 
						|
    bool extended)  // @parm Indica se interpretare alcune stringhe come macro (default FALSE)
 | 
						|
    
 | 
						|
// @comm Se <p extended> e' TRUE e trova alcune stringhe col formato %stringa% (es. %frm%)
 | 
						|
//       ne sostituisce i valori (es. ditta corrente).
 | 
						|
                                      
 | 
						|
// @xref <mf TSystemisamfile::dump>
 | 
						|
  
 | 
						|
{
 | 
						|
  FILE* fl = fopen(from, "r");
 | 
						|
  int err=NOERR;
 | 
						|
  if (fl == NULL) 
 | 
						|
  {
 | 
						|
    error_box("Non riesco ad aprire il file %s",from);
 | 
						|
    return 2;
 | 
						|
  }
 | 
						|
  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 > get_std_level())
 | 
						|
      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, get_std_level()/100, get_std_level()%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 
 | 
						|
    {
 | 
						|
#ifdef DBG
 | 
						|
      yesnofatal_box("Numero linea relativa all'errore: %ld",r+e+1);
 | 
						|
#endif    
 | 
						|
      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;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Esporta VERSO un file ascii. 
 | 
						|
//
 | 
						|
// @rdesc Ritorna NOERR se l'operazione di esportazione e' riuscita, altrimenti il codice di
 | 
						|
//    di errore generato (vedi <t TIsamerr>).
 | 
						|
int TSystemisamfile::dump(
 | 
						|
    const char* to, // @parm Nome del file verso quale esportare
 | 
						|
    int nkey,     // @parm Numero della chiave di ordinamento con cui scaricare i dati (defualt 1)
 | 
						|
    char fs,    // @parm Carattere seperatore di campo (defualt <pipe>)
 | 
						|
    char fd,            // @parm Carattere delimitatore di campo (default '\\0')
 | 
						|
    char rs,            // @parm Carattere separatore di record (default '\\n')
 | 
						|
    bool vis,     // @parm Indica se visualizzare lo stato dell'operazione (defualt TRUE)
 | 
						|
    bool withdeleted) // @parm Indica se scaricare anche i record cancellati (dafault FALSE)
 | 
						|
 | 
						|
// @xref <mf TSystemisamfile::load>
 | 
						|
 | 
						|
{
 | 
						|
  FILE* f = fopen(to, "w");
 | 
						|
 | 
						|
  if (f == NULL) 
 | 
						|
  {
 | 
						|
    setstatus(2);
 | 
						|
    return 2;
 | 
						|
  }
 | 
						|
 | 
						|
  if (withdeleted) nkey = 0;
 | 
						|
  int err = ferror(f);
 | 
						|
  
 | 
						|
  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", prefix().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()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////
 | 
						|
//      TRectype
 | 
						|
////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TRectype::TRectype(int logicnum)
 | 
						|
         : _cod(NULL), _memo_data(NULL), _memo_dirty(NULL)
 | 
						|
  
 | 
						|
{
 | 
						|
  bool has_memo_fld = FALSE;
 | 
						|
 | 
						|
  _logicnum = logicnum;
 | 
						|
  if (openf[_logicnum - 1] != NULL)
 | 
						|
  {
 | 
						|
    _length = DB_reclen(openf[logicnum - 1]->fhnd);
 | 
						|
    has_memo_fld = rec_has_memo(rec_des());
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    TDir wdir;
 | 
						|
    wdir.get(_logicnum, _nolock, _nordir, _sysdirop);
 | 
						|
    if (wdir.is_com())
 | 
						|
      wdir.get(_logicnum, _nolock, _comdir, _sysdirop);
 | 
						|
    _length = wdir.len();
 | 
						|
    has_memo_fld = _length > 0 && lf_has_memo(_logicnum);
 | 
						|
  }                                                                               
 | 
						|
  _rec = new char [ _length ];
 | 
						|
  *_tab = '\0';
 | 
						|
  if (_length)
 | 
						|
    zero();
 | 
						|
  else
 | 
						|
    setempty(TRUE);
 | 
						|
  if(has_memo_fld)
 | 
						|
    init_memo(RECORD_NON_FISICO );
 | 
						|
}
 | 
						|
 | 
						|
TRectype::TRectype(const TBaseisamfile* i)
 | 
						|
         : _cod(NULL), _memo_data(NULL), _memo_dirty(NULL)
 | 
						|
 | 
						|
{
 | 
						|
  bool has_memo_fld = FALSE;
 | 
						|
 | 
						|
  _logicnum = i->num();
 | 
						|
  if (i->filehnd() != NULL)
 | 
						|
  {
 | 
						|
    _length = DB_reclen(i->filehnd()->fhnd);
 | 
						|
    has_memo_fld = rec_has_memo(rec_des());
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    TDir wdir;
 | 
						|
 | 
						|
    wdir.get(_logicnum, _nolock, _nordir, _sysdirop);
 | 
						|
    if (wdir.is_com())
 | 
						|
      wdir.get(_logicnum, _nolock, _comdir, _sysdirop);
 | 
						|
    _length = wdir.len();
 | 
						|
    has_memo_fld = _length > 0 && lf_has_memo(_logicnum);
 | 
						|
  }
 | 
						|
  *_tab = '\0'; 
 | 
						|
  _rec = new char [ _length ];
 | 
						|
  if (_length) 
 | 
						|
    zero();
 | 
						|
  else
 | 
						|
    setempty(TRUE);
 | 
						|
    
 | 
						|
  if(has_memo_fld)
 | 
						|
    init_memo(RECORD_NON_FISICO );
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TRectype::TRectype(const TRectype& r)
 | 
						|
         : _cod(NULL), _memo_data(NULL), _memo_dirty(NULL)
 | 
						|
  
 | 
						|
{
 | 
						|
  _logicnum = r._logicnum;
 | 
						|
  if (r._memo_data)
 | 
						|
  {
 | 
						|
    init_memo();                           
 | 
						|
    *_memo_data = *r._memo_data;
 | 
						|
    CHECK(r._memo_dirty, "memo_dirty NULL con memo_data valido");
 | 
						|
    *_memo_dirty= *r._memo_dirty;
 | 
						|
  }               
 | 
						|
  _length = r.len();
 | 
						|
  _rec = new char [ _length ];
 | 
						|
  _rec[0] = r._rec[0];
 | 
						|
  memcpy(_rec + 1, r._rec + 1, _length - 1);
 | 
						|
  strcpy(_tab, r._tab);
 | 
						|
  if (r._cod != NULL)
 | 
						|
    _cod = new TRecfield(*this, "COD");
 | 
						|
  setempty(r.empty());
 | 
						|
}
 | 
						|
 | 
						|
TRectype::~TRectype()
 | 
						|
  
 | 
						|
{
 | 
						|
  if (_cod != NULL) delete _cod;
 | 
						|
  if (_rec != NULL) delete _rec;
 | 
						|
  if (_memo_data != NULL ) delete _memo_data;
 | 
						|
  if (_memo_dirty != NULL ) delete _memo_dirty;
 | 
						|
}
 | 
						|
 | 
						|
void TRectype::unknown_field(const char* name) const 
 | 
						|
{
 | 
						|
  yesnofatal_box("Il campo '%s' non appartiene al file %d", name, _logicnum);
 | 
						|
}
 | 
						|
                    
 | 
						|
void TRectype::write_memo(isdef * file, const TRecnotype recno)
 | 
						|
{   
 | 
						|
  memo_recno(recno);
 | 
						|
  CHECK( _memo_recno > 0,  "Maiale! Non fare le GO con _recno < 0 " );
 | 
						|
  DB_go( file->fhnd, _memo_recno );
 | 
						|
  RecDes *r = rec_des( );
 | 
						|
  for( int i = _memo_data->last( ); i > 0; i = _memo_data->pred( i ) )
 | 
						|
    DB_memowrite( file->fhnd, r->Fd[ i ].Name, ( char * )( const char * )_memo_data->row( i ) );
 | 
						|
  *this = (const char *) DB_getrecord(file->fhnd);
 | 
						|
  init_memo(recno);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TRectype::init_memo( const TRecnotype recno)
 | 
						|
{  
 | 
						|
  memo_recno(recno);
 | 
						|
  if (_memo_data == NULL)
 | 
						|
    _memo_data = new TString_array();
 | 
						|
  else
 | 
						|
    _memo_data->destroy();
 | 
						|
  if (_memo_dirty == NULL)
 | 
						|
    _memo_dirty = new TBit_array();
 | 
						|
  else
 | 
						|
    _memo_dirty->reset();
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
const char* TRectype::build_key(int num) const
 | 
						|
{
 | 
						|
  __build_key(rec_des(), num, string(), __tmp_string, TRUE);
 | 
						|
  return __tmp_string;
 | 
						|
}
 | 
						|
 | 
						|
const char* TRectype::last_key_field(int key) const
 | 
						|
{
 | 
						|
  const KeyDes& kd = rec_des()->Ky[key];
 | 
						|
  const int last = kd.NkFields-1;
 | 
						|
  const bool upp = kd.FieldSeq[last] > MaxFields;
 | 
						|
  const int nf = upp ? kd.FieldSeq[last] - MaxFields : kd.FieldSeq[last];
 | 
						|
  const RecFieldDes& rf = rec_des()->Fd[nf];  
 | 
						|
  return rf.Name;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Confronta le chiavi di due record
 | 
						|
//
 | 
						|
// @rdesc Ritorna il risultato di una <f strcmp>:
 | 
						|
//
 | 
						|
// @flag 0 | Se le due chiavi sono uguali
 | 
						|
// @flag <lt><gt>0 | Se le due chiavi sono diverse
 | 
						|
int TRectype::compare_key(
 | 
						|
    const TRectype& rec, // @parm Record di cui confrontare le chiavi
 | 
						|
    int key,             // @parm Numero della chiave del presente record (defautl 1)
 | 
						|
    int skip_last) const // @parm Numero di campi da ignorare nella comparazione a partire dall'ultimo
 | 
						|
 | 
						|
// @xref <mf TRectype::build_key>
 | 
						|
{
 | 
						|
  TString256 key1= build_key(key);
 | 
						|
  TString256 key2 = rec.build_key(key);
 | 
						|
  if (skip_last > 0)
 | 
						|
  {                
 | 
						|
    const KeyDes& kd = rec_des()->Ky[key-1];
 | 
						|
    const int last = kd.NkFields-1;
 | 
						|
    CHECKD(last >= skip_last, "Can't ignore so many fields in key: ", skip_last);
 | 
						|
    for (int l = 0; l < skip_last; l++)
 | 
						|
    {
 | 
						|
      int nf = kd.FieldSeq[last-l]; 
 | 
						|
      if (nf > MaxFields) nf -= MaxFields;
 | 
						|
      const RecFieldDes& rf = rec_des()->Fd[nf];  
 | 
						|
      key1.rtrim(rf.Len);
 | 
						|
      key2.rtrim(rf.Len);
 | 
						|
    }  
 | 
						|
  }
 | 
						|
  const int res = strcmp(key1, key2);
 | 
						|
  return res;
 | 
						|
}
 | 
						|
 | 
						|
HIDDEN bool fld_empty(const char* s, int len, bool number)
 | 
						|
{
 | 
						|
  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)
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
RecDes* TRectype::rec_des() const
 | 
						|
{        
 | 
						|
  const isdef* i = openf[_logicnum-1];
 | 
						|
  CHECKD(i, "Can't use a record of closed file ", _logicnum);
 | 
						|
  RecDes* r = i->r;
 | 
						|
  CHECKD(r, "Missing record description of file", _logicnum);
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
int TRectype::items() const
 | 
						|
 | 
						|
{
 | 
						|
  return rec_des()->NFields;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
const char* TRectype::start(int nf) const
 | 
						|
 | 
						|
{
 | 
						|
  return string() + rec_des()->Fd[nf].RecOff;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TRectype::compare(const TSortable& s) const
 | 
						|
 | 
						|
{
 | 
						|
  const TRectype& br = (const TRectype&) s;
 | 
						|
  int res = 0;
 | 
						|
 | 
						|
  if (br.empty()) return UNDEFINED;
 | 
						|
  
 | 
						|
  const RecDes& rd = *rec_des();
 | 
						|
  for (int i = 0; i < items() ; i++)
 | 
						|
  {
 | 
						|
    const char* b = br.start(i);
 | 
						|
    const char* a = start(i);
 | 
						|
    const byte typ = rd.Fd[i].TypeF;
 | 
						|
    const int  sz  = rd.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
 | 
						|
 | 
						|
{
 | 
						|
  int     p;
 | 
						|
  const RecDes * recd = rec_des();
 | 
						|
 | 
						|
  if ((p = findfld(recd, fieldname)) != -1) return (TFieldtypes) recd->Fd[p].TypeF;
 | 
						|
  else return _nullfld;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TRectype::length(const char* fieldname) const
 | 
						|
 | 
						|
{
 | 
						|
  int     p; 
 | 
						|
  const RecDes * recd = rec_des();
 | 
						|
 | 
						|
  if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].Len);
 | 
						|
  else return(0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TRectype::ndec(const char* fieldname) const
 | 
						|
 | 
						|
{
 | 
						|
  int     p;
 | 
						|
  const RecDes * recd = rec_des();
 | 
						|
 | 
						|
  if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].Dec);
 | 
						|
  else return(0);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TRectype::exist(const char* fieldname) const
 | 
						|
{                   
 | 
						|
  const bool ok = findfld(rec_des(), (char*)fieldname) != FIELDERR;
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
const char* TRectype::fieldname(int i) const
 | 
						|
{
 | 
						|
  const RecDes * recd = rec_des();
 | 
						|
  return i >= 0 && i < recd->NFields ? recd->Fd[i].Name : NULL;
 | 
						|
}                            
 | 
						|
 | 
						|
const TString & TRectype::get_str(const char* fieldname) const
 | 
						|
{     
 | 
						|
  char * s = _isam_string;
 | 
						|
  static TFixed_string tmp(_isam_string, sizeof(_isam_string));
 | 
						|
  const RecDes * recd = rec_des();
 | 
						|
  int nf = findfld(recd, fieldname);
 | 
						|
 | 
						|
  if (nf == FIELDERR)
 | 
						|
  { 
 | 
						|
    unknown_field(fieldname);
 | 
						|
    *s = '\0';
 | 
						|
  }
 | 
						|
  else
 | 
						|
    __getfieldbuff(recd->Fd[nf].Len, recd->Fd[nf].TypeF, 
 | 
						|
                   _rec + recd->Fd[nf].RecOff, s);
 | 
						|
  return tmp;
 | 
						|
}
 | 
						|
 | 
						|
#ifndef FOXPRO
 | 
						|
 | 
						|
const TString& TRectype::get(const char* fieldname) const
 | 
						|
{          
 | 
						|
  if(type( fieldname ) == _memofld )
 | 
						|
  {
 | 
						|
    int index( findfld( rec_des( ), ( char * )fieldname ) );  
 | 
						|
    if ( _memo_data->objptr( index ) && (*_memo_dirty)[ index ] )
 | 
						|
      return _memo_data->row( index );    
 | 
						|
    if( _memo_recno >=  0L )
 | 
						|
    {
 | 
						|
      TLocalisamfile posfile( num() );
 | 
						|
      isdef * def = posfile.filehnd( );
 | 
						|
      DB_go( def->fhnd, _memo_recno );
 | 
						|
      _memo_data->add( DB_memoptr( def->fhnd, fieldname ), index );    
 | 
						|
    }
 | 
						|
    else
 | 
						|
      _memo_data->add( "", index );
 | 
						|
    return _memo_data->row( index );
 | 
						|
  }  
 | 
						|
  return get_str(fieldname);
 | 
						|
}
 | 
						|
 | 
						|
int TRectype::get_int(const char* fieldname) const
 | 
						|
{
 | 
						|
  
 | 
						|
  return atoi(get_str(fieldname));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
long TRectype::get_long(const char* fieldname) const
 | 
						|
{
 | 
						|
  return atol(get_str(fieldname));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
word TRectype::get_word(const char* fieldname) const
 | 
						|
 | 
						|
{
 | 
						|
  return (word)atoi(get_str(fieldname));
 | 
						|
}
 | 
						|
 | 
						|
real TRectype::get_real(const char* fieldname) const
 | 
						|
 | 
						|
{
 | 
						|
  real r(get_str(fieldname));
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
char TRectype::get_char(const char* fieldname) const
 | 
						|
 | 
						|
{
 | 
						|
  return *(get_str(fieldname));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TRectype::get_bool(const char* fieldname) const
 | 
						|
 | 
						|
{
 | 
						|
  return *(get_str(fieldname)) == 'X';
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Ritorna il contenuto di un campo memo
 | 
						|
//
 | 
						|
// @rdesc Ritorna sempre TRUE
 | 
						|
bool TRectype::get_memo(
 | 
						|
     const char* fieldname, // @parm Nome del campo da cui estrarre il contenuto
 | 
						|
     TTextfile& txt) const  // @parm Reference della variabile a cui assegnare il contenuto dell campo
 | 
						|
{
 | 
						|
  TToken_string memo( get( fieldname ), '\n' );
 | 
						|
  const int last = memo.items( );
 | 
						|
  for( int i = 0; i < last; i ++ )
 | 
						|
  {
 | 
						|
     TString m(memo.get(i));
 | 
						|
     const int l = m.len() > 0 ? m.len()-1 : 0;
 | 
						|
     if (m[l] == '\r') m.cut(l);
 | 
						|
     txt.append( m );
 | 
						|
  }
 | 
						|
  return TRUE;
 | 
						|
}                   
 | 
						|
 | 
						|
#endif // FOXPRO
 | 
						|
 | 
						|
 | 
						|
TDate TRectype::get_date(const char* fieldname) const
 | 
						|
 | 
						|
{
 | 
						|
  TDate d(get_str(fieldname));
 | 
						|
  return d;
 | 
						|
}
 | 
						|
 | 
						|
#ifndef FOXPRO
 | 
						|
 | 
						|
void TRectype::put(const char* fieldname, int val)
 | 
						|
 | 
						|
{           
 | 
						|
  sprintf(_isam_string, "%d", val);
 | 
						|
  put_str( fieldname, _isam_string);
 | 
						|
  setempty(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TRectype::put(const char* fieldname, long val)
 | 
						|
 | 
						|
{
 | 
						|
  sprintf(_isam_string, "%ld", val);
 | 
						|
  put_str( fieldname, _isam_string);
 | 
						|
  setempty(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
void TRectype::put(const char* fieldname, TTextfile& txt)
 | 
						|
{
 | 
						|
  long val = get_long(fieldname);
 | 
						|
  bool isnew = val == 0;
 | 
						|
  TLocalisamfile f(_logicnum);  
 | 
						|
  
 | 
						|
  TMemo_file memo(f.filename());
 | 
						|
 | 
						|
  long id = memo.set_field(txt, isnew ? FIELDERR : val);
 | 
						|
  if (isnew) val = id;
 | 
						|
 | 
						|
  sprintf(_isam_string, "%ld", val);
 | 
						|
  put_str( fieldname, _isam_string);
 | 
						|
  setempty(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TRectype::put(const char* fieldname, word val)
 | 
						|
 | 
						|
{
 | 
						|
  sprintf(_isam_string, "%u", val);
 | 
						|
  put_str( fieldname, _isam_string);
 | 
						|
  setempty(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
void TRectype::put(const char* fieldname, const real& val)
 | 
						|
{
 | 
						|
  put_str( fieldname, val.string());
 | 
						|
  setempty(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
void TRectype::put(const char* fieldname, const TDate& val)
 | 
						|
{            
 | 
						|
  put_str( fieldname, val.string(full));
 | 
						|
  setempty(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
void TRectype::put(const char* fieldname, char val)
 | 
						|
 | 
						|
{
 | 
						|
  const char  w[2] = {val, '\0'};
 | 
						|
  
 | 
						|
  put_str( fieldname, w);
 | 
						|
  setempty(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TRectype::put(const char* fieldname, bool val)
 | 
						|
 | 
						|
{
 | 
						|
  char s[2] = { val ? 'T' : 'F', '\0'};
 | 
						|
  put_str( fieldname, s);
 | 
						|
  setempty(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
#endif // FOXPRO
 | 
						|
 | 
						|
 | 
						|
void TRectype::put_str(const char* fieldname, const char* val)
 | 
						|
{                                            
 | 
						|
  const TFieldtypes ft = type(fieldname);
 | 
						|
  if (val == NULL)
 | 
						|
    val = "";
 | 
						|
  if (ft == _boolfld)                            
 | 
						|
    val = (*val && strchr("1STXY", toupper(*val)) != NULL) ? "T" : "F";
 | 
						|
  if (*val == '\0')  // Da provare
 | 
						|
  {
 | 
						|
    TRecfield f(*this, fieldname);
 | 
						|
    if (*f.pos() == '\0') return;
 | 
						|
  }
 | 
						|
 | 
						|
  if(type(fieldname)  == _memofld)
 | 
						|
  {
 | 
						|
    int index( findfld( rec_des( ), ( char * ) fieldname ) );
 | 
						|
    _memo_dirty->set( index );
 | 
						|
    _memo_data->add( val, index ); 
 | 
						|
  }  
 | 
						|
  else
 | 
						|
  {
 | 
						|
   const RecDes * recd = rec_des();
 | 
						|
   int nf = findfld(recd, fieldname);
 | 
						|
   
 | 
						|
   if (nf == FIELDERR)
 | 
						|
     unknown_field(fieldname);
 | 
						|
   else
 | 
						|
     __putfieldbuff(recd->Fd[nf].Len, recd->Fd[nf].Dec, recd->Fd[nf].TypeF, val,
 | 
						|
                    _rec + recd->Fd[nf].RecOff);
 | 
						|
  }
 | 
						|
  setempty(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
void TRectype::zero(const char* fieldname)
 | 
						|
  
 | 
						|
{
 | 
						|
  if (_cod != NULL && strcmp(fieldname , "COD") == 0)
 | 
						|
    *_cod = _tab;
 | 
						|
  else 
 | 
						|
  {
 | 
						|
    const RecDes * recd = rec_des();
 | 
						|
    int nf = findfld(recd, fieldname);
 | 
						|
    if (nf == FIELDERR)
 | 
						|
      unknown_field(fieldname);
 | 
						|
    else
 | 
						|
    {
 | 
						|
      const int recoff = recd->Fd[nf].RecOff;
 | 
						|
      char * p = _rec + recoff;
 | 
						|
      const byte len = recd->Fd[nf].Len; 
 | 
						|
      const byte dec = recd->Fd[nf].Dec; 
 | 
						|
      const TFieldtypes type = (TFieldtypes) recd->Fd[nf].TypeF;
 | 
						|
      if (type == _datefld)
 | 
						|
        __putfieldbuff(len, dec, _datefld, "", p);
 | 
						|
      else
 | 
						|
      {
 | 
						|
        memset(p, ' ', len);
 | 
						|
        if ((type == _intfld) || (type == _longfld) || (type == _wordfld))
 | 
						|
          *(p + len - 1) = '0';
 | 
						|
        else
 | 
						|
          if (type == _realfld)
 | 
						|
          {
 | 
						|
            if (dec)
 | 
						|
            {
 | 
						|
              memset(p + len - dec - 2, '0', dec + 2);
 | 
						|
              *(p + len - dec - 1) = '.';
 | 
						|
            }
 | 
						|
            else
 | 
						|
              *(p + len - 1) = '0';
 | 
						|
          }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TRectype::zero(char c)
 | 
						|
  
 | 
						|
{
 | 
						|
  recall();
 | 
						|
  memset(_rec + 1, c, len() - 1);
 | 
						|
 | 
						|
  if (_cod != NULL)
 | 
						|
    *_cod = _tab;
 | 
						|
  
 | 
						|
  if(has_memo())
 | 
						|
    init_memo( RECORD_NON_FISICO );
 | 
						|
  setempty(TRUE);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 99%
 | 
						|
TRectype& TRectype::operator =(const TRectype& rec)
 | 
						|
  
 | 
						|
{
 | 
						|
  CHECK(num() == rec.num(), "Can't assign records of different file");
 | 
						|
 | 
						|
  memcpy(_rec, rec._rec, _length);       // Copy contents
 | 
						|
  if (rec._memo_data)
 | 
						|
  {    
 | 
						|
    init_memo(rec._memo_recno);//   ??                          
 | 
						|
    *_memo_data = *rec._memo_data;
 | 
						|
    CHECK(rec._memo_dirty, "memo_dirty NULL con memo_data valido");
 | 
						|
    *_memo_dirty= *rec._memo_dirty;
 | 
						|
  }
 | 
						|
  setempty(rec.empty());                   // Copy emptiness status
 | 
						|
  return *this;
 | 
						|
}
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TRectype& TRectype::operator =(const TBaseisamfile& f)
 | 
						|
{
 | 
						|
  return *this = f.curr();
 | 
						|
}
 | 
						|
 | 
						|
// Certified  ??%
 | 
						|
int TRectype::read(TBaseisamfile& f, word op, word lockop, TDate& atdate)
 | 
						|
{ 
 | 
						|
  return f._read(*this,op,lockop,atdate) ;
 | 
						|
}
 | 
						|
 | 
						|
int TRectype::readat(TBaseisamfile& f, TRecnotype nrec, word lockop)
 | 
						|
{
 | 
						|
	return f._readat(*this,nrec,lockop);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
int TRectype::next(TBaseisamfile& f,word lockop)
 | 
						|
{ 
 | 
						|
  const int err = f._next(lockop); 
 | 
						|
  *this = f.curr();
 | 
						|
  return err;  
 | 
						|
}
 | 
						|
 | 
						|
// Certified ??%
 | 
						|
int TRectype::write(TBaseisamfile& f, TDate& atdate ) const
 | 
						|
{ return f._write(*this,atdate); }
 | 
						|
 | 
						|
// Certified ??%
 | 
						|
int TRectype::rewrite(TBaseisamfile& f, TDate& atdate) const
 | 
						|
{ 
 | 
						|
  return f._rewrite(*this,atdate); 
 | 
						|
}
 | 
						|
 | 
						|
// Certified ??%
 | 
						|
int TRectype::remove(TBaseisamfile& f, TDate& atdate) const
 | 
						|
{ 
 | 
						|
  return f._remove(*this,atdate); 
 | 
						|
}
 | 
						|
 | 
						|
void TRectype::renum_key(const char* field, const char* val)
 | 
						|
{
 | 
						|
  put(field, val);
 | 
						|
}
 | 
						|
 | 
						|
// Certified 99%
 | 
						|
TRectype& TRectype::operator =(const char* rec)
 | 
						|
{
 | 
						|
  memcpy(_rec, rec, _length);
 | 
						|
  setempty(FALSE);
 | 
						|
  return *this;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
const char* TRectype::key(int numkey) const
 | 
						|
{
 | 
						|
  __build_key(rec_des(), numkey, _rec, _isam_string,FALSE);
 | 
						|
  return _isam_string;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TRecfield (campo/sottocampo di un record)
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
void TRecfield::set(int from, int to)
 | 
						|
 | 
						|
{
 | 
						|
  int nf;
 | 
						|
  RecDes* rd = _rec->rec_des();
 | 
						|
 | 
						|
  if ((nf = findfld(rd, _name)) == FIELDERR)
 | 
						|
  {
 | 
						|
    _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() + rd->Fd[nf].RecOff + from;
 | 
						|
    _dec = rd->Fd[nf].Dec;
 | 
						|
    _type = (TFieldtypes)rd->Fd[nf].TypeF;
 | 
						|
    if  (to >= 0)
 | 
						|
    {
 | 
						|
      CHECK(from <= to && to <= rd->Fd[nf].Len, "Invalid Range");
 | 
						|
      _len = to - from + 1;
 | 
						|
    }
 | 
						|
    else _len = rd->Fd[nf].Len - from;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
TRecfield::TRecfield(TRectype& rec, const char* name, int from, int to)
 | 
						|
 | 
						|
{
 | 
						|
  strcpy(_name, name);
 | 
						|
  _rec = &rec;
 | 
						|
  set(from, to);
 | 
						|
}
 | 
						|
 | 
						|
int TRecfield::operator =(int i)
 | 
						|
 | 
						|
{
 | 
						|
  sprintf(_isam_string, "%d", i);
 | 
						|
  __putfieldbuff( _len, _dec, _type, _isam_string, _p);
 | 
						|
  _rec->setempty(FALSE);
 | 
						|
  return i;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
long TRecfield::operator =(long l)
 | 
						|
 | 
						|
{
 | 
						|
  sprintf(_isam_string, "%ld", l);
 | 
						|
  __putfieldbuff( _len, _dec, _type, _isam_string, _p);
 | 
						|
  _rec->setempty(FALSE);
 | 
						|
  return l;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#ifndef FOXPRO
 | 
						|
 | 
						|
const real& TRecfield::operator =(const real& r)
 | 
						|
{
 | 
						|
  strcpy(_isam_string, r.string());
 | 
						|
  __putfieldbuff( _len, _dec, _type, _isam_string, _p);
 | 
						|
  _rec->setempty(FALSE);
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
#endif // FOXPRO
 | 
						|
 | 
						|
 | 
						|
const TDate& TRecfield::operator =(const TDate& d)
 | 
						|
{
 | 
						|
  strcpy(_isam_string, (const char*)d);
 | 
						|
  __putfieldbuff( _len, _dec, _type, _isam_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
 | 
						|
{
 | 
						|
  if (_type == _intfld || _type == _intzerofld || _type == _longfld || _type == _longzerofld)
 | 
						|
  {
 | 
						|
    strncpy(_isam_string, _p, _len);
 | 
						|
    _isam_string[_len] = '\0';
 | 
						|
  }  
 | 
						|
  else
 | 
						|
    __getfieldbuff( _len, _type, _p, _isam_string);
 | 
						|
  return atoi(_isam_string);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TRecfield::operator long() const
 | 
						|
{
 | 
						|
  if (_type == _longfld || _type == _longzerofld || _type == _intfld || _type == _intzerofld)
 | 
						|
  {
 | 
						|
    strncpy(_isam_string, _p, _len);
 | 
						|
    _isam_string[_len] = '\0';
 | 
						|
  }
 | 
						|
  else  
 | 
						|
    __getfieldbuff( _len, _type, _p, _isam_string);
 | 
						|
  
 | 
						|
  return atol(_isam_string);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
#ifndef FOXPRO
 | 
						|
 | 
						|
TRecfield::operator const real() const
 | 
						|
{
 | 
						|
  if (_type == _realfld)
 | 
						|
  {
 | 
						|
    strncpy(_isam_string, _p, _len);
 | 
						|
    _isam_string[_len] = '\0';
 | 
						|
  }
 | 
						|
  else
 | 
						|
    __getfieldbuff( _len, _type, _p, _isam_string);
 | 
						|
  real r(_isam_string);
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
#endif // FOXPRO
 | 
						|
 | 
						|
 | 
						|
TRecfield::operator TDate() const
 | 
						|
{    
 | 
						|
  if (_type == _datefld)                          
 | 
						|
  {
 | 
						|
    strncpy(_isam_string, _p, 8);
 | 
						|
    _isam_string[8] = '\0';
 | 
						|
    return TDate(atol(_isam_string));
 | 
						|
  }  
 | 
						|
  __getfieldbuff(_len, _type, _p, _isam_string);
 | 
						|
  return TDate(_isam_string);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TRecfield::operator const char*() const
 | 
						|
{    
 | 
						|
  if (_type == _memofld)
 | 
						|
    return _rec->get(_name);
 | 
						|
 | 
						|
  __getfieldbuff(_len, _type, _p, _isam_string);
 | 
						|
  return _isam_string;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TRecnotype TRecfield::ptr() const
 | 
						|
{
 | 
						|
  if (_p == NULL) return(RECORD_NON_FISICO);
 | 
						|
  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;
 | 
						|
}
 | 
						|
 |