/////////////////////////////////////////////////////////
//     Implementation file of database class: NAMio.
//                                                          
//     Source generated by: CSDBGEN version 1.6.5.
//     Date of generation:  Monday, 9 June 1997.
//     Time of generation:  10:20:09.
//                                                          
//                                                          
//     The next lines represent the database definition     
//     file used as input for CSDBGEN.                      
//                                                          
//                                                          
////////////// Start of the .def file //////////////////
/*
class: NAMio
record: record
file: csadr.dbf
field: name s 40 T
field: adre s 32
field: city s 23 Y
field: count s 32
field: zip s 9
field: tel s 17
field: update d MDY2
field: birth d DMY4 Y
field: relation s 10 Y
field: info s 70
*/
/////////////// End of .def file //////////////////////////////////////////////
/*




                 ллллл     л                       л        
                лл   лл   лл                      лл        
                ллл      лллл     ллл   лл ллл   лллл       
                  ллл     лл        лл   ллл лл   лл        
                    ллл   лл     ллллл   лл       лл        
                лл   лл   лл л  лл  лл   лл       лл л      
                 ллллл     лл    ллл лл  лл        лл       
                                                            
                                                            
             лллл     лллл  лл  лл  лл ллл   ллллл   лллл   
            лл       лл  лл лл  лл   ллл лл лл   л  лл  лл  
             лллл    лл  лл лл  лл   лл     лл      лллллл  
                лл   лл  лл лл  лл   лл     лл   л  лл      
             лллл     лллл   ллл лл  лл      ллллл   ллллл  
                                                            



*/
//////////////////////////////////////////////////////////////////////////////


#include "csmess.h"
#include "csendian.h"
#include "csaddio.h"

#ifdef _CP_010
extern unsigned _stklen=7000;   // Under DOS, a large stack is needed.
#endif


#define TD_NAME "\t(),- " 	// Token delimiters for field 'name'.
#define TL_NAME 4         	// Minimal Token length for field 'name'.


record *record_p; 


///////////////////////////////// Constructor ////////////////////////////////
NAMio::NAMio(void) 
{ 
    static_rec=(record *)malloc(sizeof(record));
    if(!static_rec) { csmess_p(" Out of memory "); exit(12); } 
    is_open=FALSE; 
    current=1; 
    NeedSync=TRUE; 
    errnr=0;;
    e_name="NAMio-class";
    _update.format(MDY2); 
    _birth.format(DMY4); 
    use_lock_file(TRUE); 
}

///////////////////////////////// Destructor /////////////////////////////////
NAMio::~NAMio(void) 
{ 
    close();
    free(static_rec);
}

///////////////////////////////// Errors /////////////////////////////////////
int NAMio::error_nr(void) 
{

    int RC=0;
    int RCT;

    RCT=in1.error_nr(); if(RCT) RC=RCT;
    RCT=in2.error_nr(); if(RCT) RC=RCT;
    RCT=in3.error_nr(); if(RCT) RC=RCT;
    RCT=in4.error_nr(); if(RCT) RC=RCT;

    RCT=db.error_nr();  if(RCT) RC=RCT;

    if(errnr) { RC=errnr; errnr=0; }

    return RC; 
}

///////////////////////////////// Display Error //////////////////////////////
U16 NAMio::display_error(void) 
{

    int RC;

    RC=db.display_error(); 

    if(!RC) RC=in1.display_error(); 
    if(!RC) RC=in2.display_error(); 
    if(!RC) RC=in3.display_error(); 
    if(!RC) RC=in4.display_error(); 


    if(!RC && errnr) { RC=errnr; csmess_p(RC,e_name); }

    error_nr();  // Just to reset all error variables.

    return RC; 
}


///////////////////////////////// Messages ///////////////////////////////////
void NAMio::visible_error(int ErrorNr,char *Parm) 
{ 
    csmess_p(ErrorNr,e_name,Parm);
    error_nr(ErrorNr);
}

///////////////////////////////// Test for Empty DB //////////////////////////
void NAMio::te(void) 
{ 
    if(numrec()) return;
    visible_error(30010);
    close(); 
    exit(8); 
}

///////////////////////////////// test Begin Of File /////////////////////////
int NAMio::tBOF(void) 
{
    if(!numrec()) return TRUE;  
    if(NeedSync) synch_index();
    return (this->*bof_fun)(); 
}

///////////////////////////////// test End Of File /////////////////////////
int NAMio::tEOF(void) 
{
    if(!numrec()) return TRUE;  
    if(NeedSync) synch_index();
    return (this->*eof_fun)(); 
}

///////////////////////////////// Read Only //////////////////////////////////
int NAMio::read_only(int ToF) 
{
    if(already_open()) { visible_error(30063); return FALSE; }

    db.read_only(ToF);

    in1.read_only(ToF); 
    in2.read_only(ToF); 
    in3.read_only(ToF); 
    in4.read_only(ToF); 

    return TRUE; 
}

///////////////////////////////// Use lock files /////////////////////////////
int NAMio::use_lock_file(int ToF) 
{

    db.use_lock_file(ToF);

    in1.use_lock_file(FALSE); 
    in2.use_lock_file(FALSE); 
    in3.use_lock_file(FALSE); 
    in4.use_lock_file(FALSE); 

    return TRUE; 
}

///////////////////////////////// Lock file exist/////////////////////////////
int NAMio::lock_file_exist(void) 
{

    if(db.lock_file_exist("csadr.dbf")) return TRUE; 

    return FALSE; 
}

///////////////////////////////// remove lock file ///////////////////////////
int NAMio::remove_lock_file(void) 
{

    db.remove_lock_file("csadr.dbf"); 

    return TRUE;  
}

///////////////////////////////// Sync Index /////////////////////////////////
void NAMio::synch_index(void) 
{

     switch(order())
     {
         case UNSORTED:
                  break; 
         case NAMIO_NAME_INDEX:
                 tokenize(TRUE,static_rec->_name,TD_NAME,TL_NAME,&NAMio::find1); 
                 break; 
         case NAMIO_CITY_INDEX:
                 find2(static_rec->_city); 
                 break; 
         case NAMIO_BIRTH_INDEX:
                 static_rec->__birth=_birth.sem_jul();
                 find3(&static_rec->__birth); 
                 break; 
         case NAMIO_RELATION_INDEX:
                 find4(static_rec->_relation); 
                 break; 
     }
     NeedSync=FALSE; 
}

///////////////////////////////// reindex ////////////////////////////////////
int NAMio::reindex(void) 
{
    if(!already_open()) { visible_error(30051); return FALSE; }

    write_rec();

    U32 l=current;  
    record *rp;  

    in1.empty(); 
    in2.empty(); 
    in3.empty(); 
    in4.empty(); 
    for(current=numrec(); current>0; current--)  
    {                          
       rp=locate_curr(); 
       tokenize(FALSE,rp->_name,TD_NAME,TL_NAME,&NAMio::in1_ins_tok); 
       in2.insert(rp->_city,&current); 
       in3.insert(&rp->__birth,&current); 
       in4.insert(rp->_relation,&current); 
    }                          
    current=l;                 
    NeedSync=TRUE;             

    return TRUE;               
}

///////////////////////////////// skip ///////////////////////////////////////
int  NAMio::skip0(int delta) 
{
     long old_current=current; 
     current=pMax(pMin(current+delta,db.numrec()),1); 
     return (int)(current-old_current); 
}

int  NAMio::skip(int delta) 
{
     int rc; 

     if(numrec()==0) return 0; 

     if(NeedSync) synch_index();

     write_rec(); 
     rc=(this->*skip_fun)(delta); 
     read_rec(); 

     return rc; 
}
/////////////// go_to ////////////////////////////////////////////
int NAMio::go_to(long n) 
{
    if(n<1 || n>numrec()) return FALSE; 

    write_rec(); 
    current=n; 
    read_rec(); 

    NeedSync=(order()!=UNSORTED);

    return TRUE;
}

/////////////// bottom() /////////////////////////////////////////
int NAMio::bottom(void ) 
{
    if(numrec()==0) return FALSE; 

    write_rec(); 
    (this->*bottom_fun)();
    read_rec(); 

    NeedSync=FALSE;

    return TRUE;
}

/////////////// top() ////////////////////////////////////////////
int NAMio::top(void ) 
{
    if(numrec()==0) return FALSE; 

    write_rec(); 
    (this->*top_fun)();
    read_rec(); 

    NeedSync=FALSE;

    return TRUE;
}

/////////////// search() /////////////////////////////////////////
int NAMio::search(void *k) 
{
    if(numrec()==0) return FALSE; 

    int RC;      
    write_rec(); 
    if(0==(RC=(this->*search_fun)(k))) bottom(); 
    read_rec(); 

    NeedSync=FALSE;

    return RC;
}

/////////////// append blank//////////////////////////////////////
void NAMio::append_blank(void) 
{
    append();
    tokenize(FALSE,static_rec->_name,TD_NAME,TL_NAME,&NAMio::in1_ins_tok); 
    in2.insert(static_rec->_city,&current); 
    in3.insert(&static_rec->__birth,&current); 
    in4.insert(static_rec->_relation,&current); 
    NeedSync=FALSE;
}

///////////////////////////////// append /////////////////////////////////////
// This function doesn't update the indexes, which can save some 
// disk I/O because you are likely to alter the fields 
// immediately after you have appended the record.
// However, if you have an index on a field you don't update, this 
// record will NOT appear in that particular index! 
// The 'append_blank' function does update all indexes, which 
// makes it a safer, but slower option. 
//  
void NAMio::append(void) 
{
    write_rec();
    memset(static_rec,0,sizeof(record)); 
    current=db.append_rec(static_rec); 
    dirty=TRUE;    
    _update.sem_jul((S32)0);
    _birth.sem_jul((S32)0);
    NeedSync=TRUE;
}

///////////////////////////////// open ///////////////////////////////////////
int NAMio::open(int kBbuf) 
{
     if(already_open()) { visible_error(30061); return FALSE; } 

     int   needs_reindex=FALSE;        
     char *iname;        

     dirty=FALSE;     
     current=1;       

     int fre=kBbuf/9; //kBbuf default = 100 Kb.  

     if(!db.open("csadr.dbf",fre)) 
     {
         visible_error(30020,"csadr.dbf");
         error_nr(db.error_nr());
         return FALSE;
     }
     if(db.lengthrec()!=sizeof(record)) 
     {
         visible_error(30030);
         db.close(); 
         exit(1); 
     }

     iname="csadr01.idx";

     if(!file_exist(iname))
     { 
       in1.multiple_keys(TRUE);
       in1.define(iname,NAMio_NAME_TOK_LENGTH,sizeof(long));
       needs_reindex=TRUE; 
     } 
     if(!in1.open(iname,fre*2))
     { 
         visible_error(30040,iname);
         error_nr(in1.error_nr());
         goto OnOpenError;
     } 
  

     iname="csadr02.idx";

     if(!file_exist(iname))
     { 
       in2.multiple_keys(TRUE);
       in2.define(iname,NAMio_CITY_LENGTH+1,sizeof(long));
       needs_reindex=TRUE; 
     } 
     if(!in2.open(iname,fre*2))
     { 
         visible_error(30040,iname);
         error_nr(in2.error_nr());
         goto OnOpenError;
     } 
  

     iname="csadr03.idx";

     if(!file_exist(iname))
     { 
       in3.multiple_keys(TRUE);
       in3.define(iname,sizeof(long),sizeof(long));
       needs_reindex=TRUE; 
     } 
     if(!in3.open(iname,fre*2))
     { 
         visible_error(30040,iname);
         error_nr(in3.error_nr());
         goto OnOpenError;
     } 
  

     iname="csadr04.idx";

     if(!file_exist(iname))
     { 
       in4.multiple_keys(TRUE);
       in4.define(iname,NAMio_RELATION_LENGTH+1,sizeof(long));
       needs_reindex=TRUE; 
     } 
     if(!in4.open(iname,fre*2))
     { 
         visible_error(30040,iname);
         error_nr(in4.error_nr());
         goto OnOpenError;
     } 
  
     is_open=TRUE; 
     if(needs_reindex) reindex(); 
     read_rec(); 
  
     order(UNSORTED);  

     return TRUE;    
  
  
  
OnOpenError: 

     close2();

     return FALSE;    

}

///////////////////////////////// close //////////////////////////////////////
int NAMio::close2(void) 
{

     write_rec();
     db.close(); 
     in1.close();
     in2.close();
     in3.close();
     in4.close();

     return TRUE;   
}



int NAMio::close(void) 
{
     if(!already_open()) return TRUE; 

     int RC=close2(); 

     is_open=FALSE; 

     return RC;   
}

///////////////////////////////// define /////////////////////////////////////
int  NAMio::define(void) 
{
     if(already_open()) { visible_error(30062); return FALSE; }

     int RC;

     RC=db.define("csadr.dbf",sizeof(record)); 

     in1.multiple_keys(TRUE);
     RC&=in1.define("csadr01.idx",NAMio_NAME_TOK_LENGTH,sizeof(long));
     in2.multiple_keys(TRUE);
     RC&=in2.define("csadr02.idx",NAMio_CITY_LENGTH+1,sizeof(long));
     in3.multiple_keys(TRUE);
     RC&=in3.define("csadr03.idx",sizeof(long),sizeof(long));
     in4.multiple_keys(TRUE);
     RC&=in4.define("csadr04.idx",NAMio_RELATION_LENGTH+1,sizeof(long));

     if(!RC) visible_error(30070); 

     return RC; 
}

///////////////////////////////// pack ///////////////////////////////////////
int NAMio::pack(void) 
{
     if(!is_open) { visible_error(30052); return FALSE; }

     write_rec(); 
     db.pack();
     reindex();
     top();

     return TRUE;
}

///////////////////////////////// order //////////////////////////////////////
int NAMio::order(int nr) 
{
     if(!is_open) { visible_error(30053); return FALSE; }

     switch(nr)
     {
         case UNSORTED:		//Unsorted 
                  bof_fun   =&NAMio::bof0;
                  eof_fun   =&NAMio::eof0;
                  skip_fun  =&NAMio::skip0;
                  top_fun   =&NAMio::top0;
                  bottom_fun=&NAMio::bottom0;
                  search_fun=&NAMio::search0;
                  NeedSync=FALSE;
                  break; 
         case NAMIO_NAME_INDEX:	//Index on field name
                  bof_fun   =&NAMio::bof1;
                  eof_fun   =&NAMio::eof1;
                  skip_fun  =&NAMio::skip1;
                  top_fun   =&NAMio::top1;
                  bottom_fun=&NAMio::bottom1;
                  search_fun=&NAMio::search1;
                  NeedSync=TRUE;
                  break; 
         case NAMIO_CITY_INDEX:	//Index on field city
                  bof_fun   =&NAMio::bof2;
                  eof_fun   =&NAMio::eof2;
                  skip_fun  =&NAMio::skip2;
                  top_fun   =&NAMio::top2;
                  bottom_fun=&NAMio::bottom2;
                  search_fun=&NAMio::search2;
                  NeedSync=TRUE;
                  break; 
         case NAMIO_BIRTH_INDEX:	//Index on field birth
                  bof_fun   =&NAMio::bof3;
                  eof_fun   =&NAMio::eof3;
                  skip_fun  =&NAMio::skip3;
                  top_fun   =&NAMio::top3;
                  bottom_fun=&NAMio::bottom3;
                  search_fun=&NAMio::search3;
                  NeedSync=TRUE;
                  break; 
         case NAMIO_RELATION_INDEX:	//Index on field relation
                  bof_fun   =&NAMio::bof4;
                  eof_fun   =&NAMio::eof4;
                  skip_fun  =&NAMio::skip4;
                  top_fun   =&NAMio::top4;
                  bottom_fun=&NAMio::bottom4;
                  search_fun=&NAMio::search4;
                  NeedSync=TRUE;
                  break; 
         default: { visible_error(30080); return FALSE; }
     }
     iOrder=nr;

     return TRUE;
}
/////////////////////////////reading record  ///////////////////////////////
void NAMio::read_rec(void) 
{
    if(numrec()==0) return; 
    *static_rec=*locate_curr(); 
    _update.sem_jul(static_rec->__update); 
    _birth.sem_jul(static_rec->__birth); 
}
/////////////////////////////writing record  ///////////////////////////////
void NAMio::write_rec2(void) 
{
    record *recp=locate_curr(); 
    if(strcmp(recp->_name,static_rec->_name)) 
    { 
      tokenize(FALSE,recp->_name,TD_NAME,TL_NAME,&NAMio::in1_del_tok); 
      tokenize(FALSE,static_rec->_name,TD_NAME,TL_NAME,&NAMio::in1_ins_tok); 
    } 
    if(strcmp(recp->_city,static_rec->_city)) 
    { 
      in2.delet(recp->_city,&current); 
      in2.insert(static_rec->_city,&current); 
    } 
    static_rec->__update=_update.sem_jul(); 
    static_rec->__birth=_birth.sem_jul(); 
    if(recp->__birth!=static_rec->__birth) 
    { 
      in3.delet(&recp->__birth,&current); 
      in3.insert(&static_rec->__birth,&current); 
    } 
    if(strcmp(recp->_relation,static_rec->_relation)) 
    { 
      in4.delet(recp->_relation,&current); 
      in4.insert(static_rec->_relation,&current); 
    } 
    db.write_rec(current,static_rec); 
    dirty=FALSE;   
}

///////////////////////////////// export /////////////////////////////////////
int  NAMio::export(char *s) 
{
     if(!is_open) { visible_error(30054,s); return FALSE; }

     write_rec();

     FILE *fo=fopen(s,"w"); 
     if(fo==NULL) { visible_error(30071,s); return FALSE; }

     fprintf(fo,"class:  NAMio");
     fprintf(fo,"\nrecord: record");
     fprintf(fo,"\nfile:   csadr.dbf");
     fprintf(fo,"\nfield:  name s 40 T   ");
     fprintf(fo,"\nfield:  adre s 32   ");
     fprintf(fo,"\nfield:  city s 23 Y   ");
     fprintf(fo,"\nfield:  count s 32   ");
     fprintf(fo,"\nfield:  zip s 9   ");
     fprintf(fo,"\nfield:  tel s 17   ");
     fprintf(fo,"\nfield:  update d MDY2   ");
     fprintf(fo,"\nfield:  birth d DMY4 Y   ");
     fprintf(fo,"\nfield:  relation s 10 Y   ");
     fprintf(fo,"\nfield:  info s 70   ");

     if(ferror(fo)) { fclose(fo); visible_error(30072,s); return FALSE; } 

     record *rp;
     csDATE conv;
     conv.format(Y4MD);
     U32 lmax=numrec();
     U32 l;
     for(l=1;l<=lmax;l++) 
     {
        rp=( record * )db.locate_rec(l);
        fprintf(fo,"\n%c",12);
        fprintf(fo,"\n%s",rp->_name);
        fprintf(fo,"\n%s",rp->_adre);
        fprintf(fo,"\n%s",rp->_city);
        fprintf(fo,"\n%s",rp->_count);
        fprintf(fo,"\n%s",rp->_zip);
        fprintf(fo,"\n%s",rp->_tel);
        conv.sem_jul(rp->__update);
        fprintf(fo,"\n%s",(char *)conv);
        conv.sem_jul(rp->__birth);
        fprintf(fo,"\n%s",(char *)conv);
        fprintf(fo,"\n%s",rp->_relation);
        fprintf(fo,"\n%s",rp->_info);
        fprintf(fo,"\n"); //Additional linefeed

        if(ferror(fo)) { fclose(fo); visible_error(30072,s); return FALSE; } 
     }

     if(fclose(fo)) { visible_error(30072,s); return FALSE; }

     return TRUE;  
}

///////////////////////////////// import /////////////////////////////////////
int NAMio::import(char *s) 
{   
 
      if(!is_open) { visible_error(30055,s); return FALSE; }

      FILE *fr=fopen(s,"r"); 
      if(fr==NULL) { visible_error(30091,s); return FALSE; }
  
  
      const MAX_NUM_FIELDS= 100;  //Increase this to allow more fields    
      const MAX_FIELD_LEN = 500;  //Increase this to allow longer fields  
 
      int *finu;
      finu=(int *)malloc(MAX_NUM_FIELDS*sizeof(int));
      if(finu==NULL) { fclose(fr); visible_error(30092); return FALSE; }  
 
      char *fibu;    
      fibu=(char *)malloc(MAX_FIELD_LEN);
      if(fibu==NULL) 
      {
         fclose(fr); 
         free(finu); 
         visible_error(30092); 
         return FALSE; 
      }
 
      *fibu=0;  
 
      char *fipo=fibu+strlen("field:");  
      char *cp; 
      int  ifieldnr=0;    
      int  ofieldnr; 
 
      int  RC=TRUE; 
      int  InDef=TRUE; 
      csDATE conv;
      conv.format(Y4MD);
 
      memset(finu,0,MAX_NUM_FIELDS*sizeof(int));
 
      fgets(fibu,MAX_FIELD_LEN,fr); 
      while(!strchr(fibu,12))  
      {    
        if(feof(fr))
        { 
           if(!InDef)   
           visible_error(30093,s); 
           RC=FALSE;
           break; 
        } 
        pStrlwr(fibu);     //Converting to lower case.
        notabs(fibu);      //Removing tabs.
        trim_string(fibu); //Removing heading & trailing spaces.
        if(!strchr(fibu,':') && *fibu) InDef=FALSE;   
        if(strstr(fibu,"field:"))   
        {  
           ifieldnr++;  
           trim_string(fipo);    
           if((cp=strchr(fipo,' '))!=NULL) *cp=0;
           if     (!strcmp(fipo,"name"))	ofieldnr=1;
           else if(!strcmp(fipo,"adre"))	ofieldnr=2;
           else if(!strcmp(fipo,"city"))	ofieldnr=3;
           else if(!strcmp(fipo,"count"))	ofieldnr=4;
           else if(!strcmp(fipo,"zip"))	ofieldnr=5;
           else if(!strcmp(fipo,"tel"))	ofieldnr=6;
           else if(!strcmp(fipo,"update"))	ofieldnr=7;
           else if(!strcmp(fipo,"birth"))	ofieldnr=8;
           else if(!strcmp(fipo,"relation"))	ofieldnr=9;
           else if(!strcmp(fipo,"info"))	ofieldnr=10;
           else ofieldnr=0; 
           finu[ifieldnr]=ofieldnr; 
        }  
        fgets(fibu,MAX_FIELD_LEN,fr);    
      }    
 
 
      if(RC) 
      for(;;)   
      {    
        if(!strchr(fibu,12))   
        {  
           ifieldnr++; 
           if(ifieldnr<MAX_NUM_FIELDS) 
             switch(finu[ifieldnr])   
             {  
                case 0:  break;
                case 1:
                         fibu[NAMio_NAME_LENGTH]=0;
                         name(fibu);
                         break;
                case 2:
                         fibu[NAMio_ADRE_LENGTH]=0;
                         adre(fibu);
                         break;
                case 3:
                         fibu[NAMio_CITY_LENGTH]=0;
                         city(fibu);
                         break;
                case 4:
                         fibu[NAMio_COUNT_LENGTH]=0;
                         count(fibu);
                         break;
                case 5:
                         fibu[NAMio_ZIP_LENGTH]=0;
                         zip(fibu);
                         break;
                case 6:
                         fibu[NAMio_TEL_LENGTH]=0;
                         tel(fibu);
                         break;
                case 7:
                         conv=fibu;
                         _update.sem_jul(conv.sem_jul());
                         break;
                case 8:
                         conv=fibu;
                         _birth.sem_jul(conv.sem_jul());
                         break;
                case 9:
                         fibu[NAMio_RELATION_LENGTH]=0;
                         relation(fibu);
                         break;
                case 10:
                         fibu[NAMio_INFO_LENGTH]=0;
                         info(fibu);
                         break;
             }  
        }  
        else    
        {  
           ifieldnr=0; 
           append_blank();
        }  
        if(feof(fr)) break;    
        fgets(fibu,MAX_FIELD_LEN,fr);    
        cp=fibu+(pMax(1,strlen(fibu))-1); 
        if(*cp=='\n') *cp=0;  //removing the line feed 
      }    
 
 
      fclose(fr); 
      free(fibu); 
      free(finu); 
 
      return RC; 
 
}

///////////////////////////////// export to dBASE compatible file. ///////////
int NAMio::to_DBASE(char *s) 
{   
 
      if(!is_open) { visible_error(30056,s); return FALSE; }
 
      char bufje[12];
 
      write_rec(); 
      FILE *fo=fopen(s,"wb"); 
      if(fo==NULL) { visible_error(30095,s); return FALSE; }
  
      int i;
  
      csDATE d_upda;
      d_upda.sem_jul(db.sj_updated());
      fputc(03,fo);  
      
      fputc(d_upda.year() % 100,fo);  
      fputc(d_upda.month(),fo);  
      fputc(d_upda.day(),fo);  
 
      long nr_record=numrec(); 
      fwrite(&nr_record,sizeof(long),1,fo); 
      WriteU16l(fo,354);		//Header length 
      WriteU16l(fo,250);		//Length of data record 
      for(i=0;i<20;i++) fputc(0,fo); // 20 dummy bytes 


// Writing definition of field name to dbase file header.
      memset(bufje,0,11);
      strcpy(bufje,"NAME");
      fwrite(bufje,11,1,fo);
      fputc('C',fo); 
      for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
      fputc(40,fo); 
      fputc(0,fo); 
      for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 

// Writing definition of field adre to dbase file header.
      memset(bufje,0,11);
      strcpy(bufje,"ADRE");
      fwrite(bufje,11,1,fo);
      fputc('C',fo); 
      for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
      fputc(32,fo); 
      fputc(0,fo); 
      for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 

// Writing definition of field city to dbase file header.
      memset(bufje,0,11);
      strcpy(bufje,"CITY");
      fwrite(bufje,11,1,fo);
      fputc('C',fo); 
      for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
      fputc(23,fo); 
      fputc(0,fo); 
      for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 

// Writing definition of field count to dbase file header.
      memset(bufje,0,11);
      strcpy(bufje,"COUNT");
      fwrite(bufje,11,1,fo);
      fputc('C',fo); 
      for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
      fputc(32,fo); 
      fputc(0,fo); 
      for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 

// Writing definition of field zip to dbase file header.
      memset(bufje,0,11);
      strcpy(bufje,"ZIP");
      fwrite(bufje,11,1,fo);
      fputc('C',fo); 
      for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
      fputc(9,fo); 
      fputc(0,fo); 
      for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 

// Writing definition of field tel to dbase file header.
      memset(bufje,0,11);
      strcpy(bufje,"TEL");
      fwrite(bufje,11,1,fo);
      fputc('C',fo); 
      for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
      fputc(17,fo); 
      fputc(0,fo); 
      for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 

// Writing definition of field update to dbase file header.
      memset(bufje,0,11);
      strcpy(bufje,"UPDATE");
      fwrite(bufje,11,1,fo);
      fputc('D',fo); 
      for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
      fputc(8,fo); 
      fputc(0,fo); 
      for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 

// Writing definition of field birth to dbase file header.
      memset(bufje,0,11);
      strcpy(bufje,"BIRTH");
      fwrite(bufje,11,1,fo);
      fputc('D',fo); 
      for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
      fputc(8,fo); 
      fputc(0,fo); 
      for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 

// Writing definition of field relation to dbase file header.
      memset(bufje,0,11);
      strcpy(bufje,"RELATION");
      fwrite(bufje,11,1,fo);
      fputc('C',fo); 
      for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
      fputc(10,fo); 
      fputc(0,fo); 
      for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 

// Writing definition of field info to dbase file header.
      memset(bufje,0,11);
      strcpy(bufje,"INFO");
      fwrite(bufje,11,1,fo);
      fputc('C',fo); 
      for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
      fputc(70,fo); 
      fputc(0,fo); 
      for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 


      fputc(13,fo);  //Field terminator 
      fputc(0,fo); 

// By now we have written the definition of the 
// record structure to the file header. 
// From here on we will export the records. 

     record *rp;
     U32 lmax=numrec();
     U32 l;
     for(l=1;l<=lmax;l++) 
     {

        if(ferror(fo)) 
        { 
           fclose(fo); 
           visible_error(30096,s); 
           return FALSE; 
        } 

        rp=(record *)db.locate_rec(l);

        if(db.is_delet(l)) fputc(42,fo); 
        else               fputc(32,fo); 

/////////////////////// writing field name /////////////
        fprintf(fo,"%-40s",rp->_name);
/////////////////////// writing field adre /////////////
        fprintf(fo,"%-32s",rp->_adre);
/////////////////////// writing field city /////////////
        fprintf(fo,"%-23s",rp->_city);
/////////////////////// writing field count /////////////
        fprintf(fo,"%-32s",rp->_count);
/////////////////////// writing field zip /////////////
        fprintf(fo,"%-9s",rp->_zip);
/////////////////////// writing field tel /////////////
        fprintf(fo,"%-17s",rp->_tel);
/////////////////////// writing field update /////////////
        if(rp->__update)
        { 
          d_upda.sem_jul(rp->__update);
          fprintf(fo,"%4d",d_upda.year4());
          fprintf(fo,"%02d",d_upda.month());
          fprintf(fo,"%02d",d_upda.day());
        } 
        else 
        { 
          fprintf(fo,"        "); 
        } 
/////////////////////// writing field birth /////////////
        if(rp->__birth)
        { 
          d_upda.sem_jul(rp->__birth);
          fprintf(fo,"%4d",d_upda.year4());
          fprintf(fo,"%02d",d_upda.month());
          fprintf(fo,"%02d",d_upda.day());
        } 
        else 
        { 
          fprintf(fo,"        "); 
        } 
/////////////////////// writing field relation /////////////
        fprintf(fo,"%-10s",rp->_relation);
/////////////////////// writing field info /////////////
        fprintf(fo,"%-70s",rp->_info);
     }
     fputc(26,fo);  //End of File 
     fclose(fo); 
 
     if(ferror(fo)) 
     { 
        visible_error(30096,s); 
        return FALSE; 
     } 
 
     return TRUE; 
}
///////////////////////////////// tokenize field ///////////////////////
void NAMio::tokenize(int once,char *s,const char *delim,int min_len,void(NAMio::*fun)(void *))
{

     char *p,*q;
     char c;
     int  insert=FALSE;

     q=p=s;

     for(;;)
     {
       while(*p && !strchr(delim,*p)) p++;
       if(p-q>=min_len)
       {
          c=*p; *p=0;
          (this->*fun)(q);
          *p=c;
          if(once) return;
          insert=TRUE;
       }
       if(!*p) break;
       q=++p;
     }

     if(!insert) (this->*fun)(s);

}