home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cslio205.zip / EXAMPLES / 2 / DEMODB.CPP < prev    next >
C/C++ Source or Header  |  1996-10-09  |  20KB  |  771 lines

  1. /////////////////////////////////////////////////////////
  2. //     Implementation file of database class: DEMO.
  3. //                                                          
  4. //     Source generated by: CSDBGEN version 1.6.b.
  5. //     Date of generation:  Wednesday, 9 October 1996.
  6. //     Time of generation:  10:19:28.
  7. //                                                          
  8. //                                                          
  9. //     The next lines represent the database definition     
  10. //     file used as input for CSDBGEN.                      
  11. //                                                          
  12. //                                                          
  13. ////////////// Start of the .def file //////////////////
  14. /*
  15. class: DEMO
  16. record: Record
  17. file: DBdemo
  18. field: name s 50 Y
  19. field: data s 32 Y
  20. */
  21. /////////////// End of .def file //////////////////////////////////////////////
  22. /*
  23.  
  24.  
  25.  
  26.  
  27.                  █████     █                       █        
  28.                 ██   ██   ██                      ██        
  29.                 ███      ████     ███   ██ ███   ████       
  30.                   ███     ██        ██   ███ ██   ██        
  31.                     ███   ██     █████   ██       ██        
  32.                 ██   ██   ██ █  ██  ██   ██       ██ █      
  33.                  █████     ██    ███ ██  ██        ██       
  34.                                                             
  35.                                                             
  36.              ████     ████  ██  ██  ██ ███   █████   ████   
  37.             ██       ██  ██ ██  ██   ███ ██ ██   █  ██  ██  
  38.              ████    ██  ██ ██  ██   ██     ██      ██████  
  39.                 ██   ██  ██ ██  ██   ██     ██   █  ██      
  40.              ████     ████   ███ ██  ██      █████   █████  
  41.                                                             
  42.  
  43.  
  44.  
  45. */
  46. //////////////////////////////////////////////////////////////////////////////
  47.  
  48.  
  49. #include "csmess.h"
  50. #include "csendian.h"
  51. #include "demodb.h"
  52.  
  53. #ifdef _CP_010
  54. extern unsigned _stklen=7000;   // Under DOS, a large stack is needed.
  55. #endif
  56.  
  57.  
  58.  
  59. Record *record_p; 
  60.  
  61.  
  62. ///////////////////////////////// Constructor ////////////////////////////////
  63. DEMO::DEMO(void) 
  64.     static_rec=(Record *)malloc(sizeof(Record));
  65.     if(!static_rec) { csmess_p(" Out of memory "); exit(12); } 
  66.     is_open=FALSE; 
  67.     current=1; 
  68.     NeedSync=TRUE; 
  69.     errnr=0;;
  70.     e_name="DEMO-class";
  71.     use_lock_file(TRUE); 
  72. }
  73.  
  74. ///////////////////////////////// Destructor /////////////////////////////////
  75. DEMO::~DEMO(void) 
  76.     close();
  77.     free(static_rec);
  78. }
  79.  
  80. ///////////////////////////////// Errors /////////////////////////////////////
  81. int DEMO::error_nr(void) 
  82. {
  83.  
  84.     int RC=0;
  85.     int RCT;
  86.  
  87.     RCT=in1.error_nr(); if(RCT) RC=RCT;
  88.     RCT=in2.error_nr(); if(RCT) RC=RCT;
  89.  
  90.     RCT=db.error_nr();  if(RCT) RC=RCT;
  91.  
  92.     if(errnr) { RC=errnr; errnr=0; }
  93.  
  94.     return RC; 
  95. }
  96.  
  97. ///////////////////////////////// Display Error //////////////////////////////
  98. U16 DEMO::display_error(void) 
  99. {
  100.  
  101.     int RC;
  102.  
  103.     RC=db.display_error(); 
  104.  
  105.     if(!RC) RC=in1.display_error(); 
  106.     if(!RC) RC=in2.display_error(); 
  107.  
  108.  
  109.     if(!RC && errnr) { RC=errnr; csmess_p(RC,e_name); }
  110.  
  111.     error_nr();  // Just to reset all error variables.
  112.  
  113.     return RC; 
  114. }
  115.  
  116.  
  117. ///////////////////////////////// Messages ///////////////////////////////////
  118. void DEMO::visible_error(int ErrorNr,char *Parm) 
  119.     csmess_p(ErrorNr,e_name,Parm);
  120.     error_nr(ErrorNr);
  121. }
  122.  
  123. ///////////////////////////////// Test for Empty DB //////////////////////////
  124. void DEMO::te(void) 
  125.     if(numrec()) return;
  126.     visible_error(30010);
  127.     close(); 
  128.     exit(8); 
  129. }
  130.  
  131. ///////////////////////////////// test Begin Of File /////////////////////////
  132. int DEMO::tBOF(void) 
  133. {
  134.     if(!numrec()) return TRUE;  
  135.     if(NeedSync) synch_index();
  136.     return (this->*bof_fun)(); 
  137. }
  138.  
  139. ///////////////////////////////// test End Of File /////////////////////////
  140. int DEMO::tEOF(void) 
  141. {
  142.     if(!numrec()) return TRUE;  
  143.     if(NeedSync) synch_index();
  144.     return (this->*eof_fun)(); 
  145. }
  146.  
  147. ///////////////////////////////// Read Only //////////////////////////////////
  148. int DEMO::read_only(int ToF) 
  149. {
  150.     if(already_open()) { visible_error(30063); return FALSE; }
  151.  
  152.     db.read_only(ToF);
  153.  
  154.     in1.read_only(ToF); 
  155.     in2.read_only(ToF); 
  156.  
  157.     return TRUE; 
  158. }
  159.  
  160. ///////////////////////////////// Use lock files /////////////////////////////
  161. int DEMO::use_lock_file(int ToF) 
  162. {
  163.  
  164.     db.use_lock_file(ToF);
  165.  
  166.     in1.use_lock_file(FALSE); 
  167.     in2.use_lock_file(FALSE); 
  168.  
  169.     return TRUE; 
  170. }
  171.  
  172. ///////////////////////////////// Lock file exist/////////////////////////////
  173. int DEMO::lock_file_exist(void) 
  174. {
  175.  
  176.     if(db.lock_file_exist("DBdemo.dbf")) return TRUE; 
  177.  
  178.     return FALSE; 
  179. }
  180.  
  181. ///////////////////////////////// remove lock file ///////////////////////////
  182. int DEMO::remove_lock_file(void) 
  183. {
  184.  
  185.     db.remove_lock_file("DBdemo.dbf"); 
  186.  
  187.     return TRUE;  
  188. }
  189.  
  190. ///////////////////////////////// Sync Index /////////////////////////////////
  191. void DEMO::synch_index(void) 
  192. {
  193.  
  194.      switch(order())
  195.      {
  196.          case UNSORTED:
  197.                   break; 
  198.          case DEMO_NAME_INDEX:
  199.                  find1(static_rec->_name); 
  200.                  break; 
  201.          case DEMO_DATA_INDEX:
  202.                  find2(static_rec->_data); 
  203.                  break; 
  204.      }
  205.      NeedSync=FALSE; 
  206. }
  207.  
  208. ///////////////////////////////// reindex ////////////////////////////////////
  209. int DEMO::reindex(void) 
  210. {
  211.     if(!already_open()) { visible_error(30051); return FALSE; }
  212.  
  213.     write_rec();
  214.  
  215.     U32 l=current;  
  216.     Record *rp;  
  217.  
  218.     in1.empty(); 
  219.     in2.empty(); 
  220.     for(current=numrec(); current>0; current--)  
  221.     {                          
  222.        rp=locate_curr(); 
  223.        in1.insert(rp->_name,¤t); 
  224.        in2.insert(rp->_data,¤t); 
  225.     }                          
  226.     current=l;                 
  227.     NeedSync=TRUE;             
  228.  
  229.     return TRUE;               
  230. }
  231.  
  232. ///////////////////////////////// skip ///////////////////////////////////////
  233. int  DEMO::skip0(int delta) 
  234. {
  235.      long old_current=current; 
  236.      current=pMax(pMin(current+delta,db.numrec()),1); 
  237.      return (int)(current-old_current); 
  238. }
  239.  
  240. int  DEMO::skip(int delta) 
  241. {
  242.      int rc; 
  243.  
  244.      if(numrec()==0) return 0; 
  245.  
  246.      if(NeedSync) synch_index();
  247.  
  248.      write_rec(); 
  249.      rc=(this->*skip_fun)(delta); 
  250.      read_rec(); 
  251.  
  252.      return rc; 
  253. }
  254. /////////////// go_to ////////////////////////////////////////////
  255. int DEMO::go_to(long n) 
  256. {
  257.     if(n<1 || n>numrec()) return FALSE; 
  258.  
  259.     write_rec(); 
  260.     current=n; 
  261.     read_rec(); 
  262.  
  263.     NeedSync=(order()!=UNSORTED);
  264.  
  265.     return TRUE;
  266. }
  267.  
  268. /////////////// bottom() /////////////////////////////////////////
  269. int DEMO::bottom(void ) 
  270. {
  271.     if(numrec()==0) return FALSE; 
  272.  
  273.     write_rec(); 
  274.     (this->*bottom_fun)();
  275.     read_rec(); 
  276.  
  277.     NeedSync=FALSE;
  278.  
  279.     return TRUE;
  280. }
  281.  
  282. /////////////// top() ////////////////////////////////////////////
  283. int DEMO::top(void ) 
  284. {
  285.     if(numrec()==0) return FALSE; 
  286.  
  287.     write_rec(); 
  288.     (this->*top_fun)();
  289.     read_rec(); 
  290.  
  291.     NeedSync=FALSE;
  292.  
  293.     return TRUE;
  294. }
  295.  
  296. /////////////// search() /////////////////////////////////////////
  297. int DEMO::search(void *k) 
  298. {
  299.     if(numrec()==0) return FALSE; 
  300.  
  301.     int RC;      
  302.     write_rec(); 
  303.     if(0==(RC=(this->*search_fun)(k))) bottom(); 
  304.     read_rec(); 
  305.  
  306.     NeedSync=FALSE;
  307.  
  308.     return RC;
  309. }
  310.  
  311. /////////////// append blank//////////////////////////////////////
  312. void DEMO::append_blank(void) 
  313. {
  314.     append();
  315.     in1.insert(static_rec->_name,¤t); 
  316.     in2.insert(static_rec->_data,¤t); 
  317.     NeedSync=FALSE;
  318. }
  319.  
  320. ///////////////////////////////// append /////////////////////////////////////
  321. // This function doesn't update the indexes, which can save some 
  322. // disk I/O because you are likely to alter the fields 
  323. // immediately after you have appended the record.
  324. // However, if you have an index on a field you don't update, this 
  325. // record will NOT appear in that particular index! 
  326. // The 'append_blank' function does update all indexes, which 
  327. // makes it a safer, but slower option. 
  328. //  
  329. void DEMO::append(void) 
  330. {
  331.     write_rec();
  332.     memset(static_rec,0,sizeof(Record)); 
  333.     current=db.append_rec(static_rec); 
  334.     dirty=TRUE;    
  335.     NeedSync=TRUE;
  336. }
  337.  
  338. ///////////////////////////////// open ///////////////////////////////////////
  339. int DEMO::open(int kBbuf) 
  340. {
  341.      if(already_open()) { visible_error(30061); return FALSE; } 
  342.  
  343.      int   needs_reindex=FALSE;        
  344.      char *iname;        
  345.  
  346.      dirty=FALSE;     
  347.      current=1;       
  348.  
  349.      int fre=kBbuf/5; //kBbuf default = 100 Kb.  
  350.  
  351.      if(!db.open("DBdemo.dbf",fre)) 
  352.      {
  353.          visible_error(30020,"DBdemo.dbf");
  354.          error_nr(db.error_nr());
  355.          return FALSE;
  356.      }
  357.      if(db.lengthrec()!=sizeof(Record)) 
  358.      {
  359.          visible_error(30030);
  360.          db.close(); 
  361.          exit(1); 
  362.      }
  363.  
  364.      iname="DBdemo01.idx";
  365.  
  366.      if(!file_exist(iname))
  367.      { 
  368.        in1.multiple_keys(TRUE);
  369.        in1.define(iname,DEMO_NAME_LENGTH+1,sizeof(long));
  370.        needs_reindex=TRUE; 
  371.      } 
  372.      if(!in1.open(iname,fre*2))
  373.      { 
  374.          visible_error(30040,iname);
  375.          error_nr(in1.error_nr());
  376.          goto OnOpenError;
  377.      } 
  378.   
  379.  
  380.      iname="DBdemo02.idx";
  381.  
  382.      if(!file_exist(iname))
  383.      { 
  384.        in2.multiple_keys(TRUE);
  385.        in2.define(iname,DEMO_DATA_LENGTH+1,sizeof(long));
  386.        needs_reindex=TRUE; 
  387.      } 
  388.      if(!in2.open(iname,fre*2))
  389.      { 
  390.          visible_error(30040,iname);
  391.          error_nr(in2.error_nr());
  392.          goto OnOpenError;
  393.      } 
  394.   
  395.      is_open=TRUE; 
  396.      if(needs_reindex) reindex(); 
  397.      read_rec(); 
  398.   
  399.      order(UNSORTED);  
  400.  
  401.      return TRUE;    
  402.   
  403.   
  404.   
  405. OnOpenError: 
  406.  
  407.      close2();
  408.  
  409.      return FALSE;    
  410.  
  411. }
  412.  
  413. ///////////////////////////////// close //////////////////////////////////////
  414. int DEMO::close2(void) 
  415. {
  416.  
  417.      db.close(); 
  418.      in1.close();
  419.      in2.close();
  420.  
  421.      return TRUE;   
  422. }
  423.  
  424.  
  425.  
  426. int DEMO::close(void) 
  427. {
  428.      if(!already_open()) return TRUE; 
  429.  
  430.      int RC=close2(); 
  431.  
  432.      is_open=FALSE; 
  433.  
  434.      return RC;   
  435. }
  436.  
  437. ///////////////////////////////// define /////////////////////////////////////
  438. int  DEMO::define(void) 
  439. {
  440.      if(already_open()) { visible_error(30062); return FALSE; }
  441.  
  442.      int RC;
  443.  
  444.      RC=db.define("DBdemo.dbf",sizeof(Record)); 
  445.  
  446.      in1.multiple_keys(TRUE);
  447.      RC&=in1.define("DBdemo01.idx",DEMO_NAME_LENGTH+1,sizeof(long));
  448.      in2.multiple_keys(TRUE);
  449.      RC&=in2.define("DBdemo02.idx",DEMO_DATA_LENGTH+1,sizeof(long));
  450.  
  451.      if(!RC) visible_error(30070); 
  452.  
  453.      return RC; 
  454. }
  455.  
  456. ///////////////////////////////// pack ///////////////////////////////////////
  457. int DEMO::pack(void) 
  458. {
  459.      if(!is_open) { visible_error(30052); return FALSE; }
  460.  
  461.      write_rec(); 
  462.      db.pack();
  463.      reindex();
  464.      top();
  465.  
  466.      return TRUE;
  467. }
  468.  
  469. ///////////////////////////////// order //////////////////////////////////////
  470. int DEMO::order(int nr) 
  471. {
  472.      if(!is_open) { visible_error(30053); return FALSE; }
  473.  
  474.      switch(nr)
  475.      {
  476.          case UNSORTED:        //Unsorted 
  477.                   bof_fun   =&DEMO::bof0;
  478.                   eof_fun   =&DEMO::eof0;
  479.                   skip_fun  =&DEMO::skip0;
  480.                   top_fun   =&DEMO::top0;
  481.                   bottom_fun=&DEMO::bottom0;
  482.                   search_fun=&DEMO::search0;
  483.                   NeedSync=FALSE;
  484.                   break; 
  485.          case DEMO_NAME_INDEX:    //Index on field name
  486.                   bof_fun   =&DEMO::bof1;
  487.                   eof_fun   =&DEMO::eof1;
  488.                   skip_fun  =&DEMO::skip1;
  489.                   top_fun   =&DEMO::top1;
  490.                   bottom_fun=&DEMO::bottom1;
  491.                   search_fun=&DEMO::search1;
  492.                   NeedSync=TRUE;
  493.                   break; 
  494.          case DEMO_DATA_INDEX:    //Index on field data
  495.                   bof_fun   =&DEMO::bof2;
  496.                   eof_fun   =&DEMO::eof2;
  497.                   skip_fun  =&DEMO::skip2;
  498.                   top_fun   =&DEMO::top2;
  499.                   bottom_fun=&DEMO::bottom2;
  500.                   search_fun=&DEMO::search2;
  501.                   NeedSync=TRUE;
  502.                   break; 
  503.          default: { visible_error(30080); return FALSE; }
  504.      }
  505.      iOrder=nr;
  506.  
  507.      return TRUE;
  508. }
  509. /////////////////////////////reading record  ///////////////////////////////
  510. void DEMO::read_rec(void) 
  511. {
  512.     if(numrec()==0) return; 
  513.     *static_rec=*locate_curr(); 
  514. }
  515. /////////////////////////////writing record  ///////////////////////////////
  516. void DEMO::write_rec2(void) 
  517. {
  518.     Record *recp=locate_curr(); 
  519.     if(strcmp(recp->_name,static_rec->_name)) 
  520.     { 
  521.       in1.delet(recp->_name,¤t); 
  522.       in1.insert(static_rec->_name,¤t); 
  523.     } 
  524.     if(strcmp(recp->_data,static_rec->_data)) 
  525.     { 
  526.       in2.delet(recp->_data,¤t); 
  527.       in2.insert(static_rec->_data,¤t); 
  528.     } 
  529.     db.write_rec(current,static_rec); 
  530.     dirty=FALSE;   
  531. }
  532.  
  533. ///////////////////////////////// export /////////////////////////////////////
  534. int  DEMO::export(char *s) 
  535. {
  536.      if(!is_open) { visible_error(30054,s); return FALSE; }
  537.  
  538.      write_rec();
  539.  
  540.      FILE *fo=fopen(s,"w"); 
  541.      if(fo==NULL) { visible_error(30071,s); return FALSE; }
  542.  
  543.      fprintf(fo,"class:  DEMO");
  544.      fprintf(fo,"\nrecord: Record");
  545.      fprintf(fo,"\nfile:   DBdemo");
  546.      fprintf(fo,"\nfield:  name s 50 Y   ");
  547.      fprintf(fo,"\nfield:  data s 32 Y   ");
  548.  
  549.      if(ferror(fo)) { fclose(fo); visible_error(30072,s); return FALSE; } 
  550.  
  551.      Record *rp;
  552.      U32 lmax=numrec();
  553.      U32 l;
  554.      for(l=1;l<=lmax;l++) 
  555.      {
  556.         rp=( Record * )db.locate_rec(l);
  557.         fprintf(fo,"\n%c",12);
  558.         fprintf(fo,"\n%s",rp->_name);
  559.         fprintf(fo,"\n%s",rp->_data);
  560.         fprintf(fo,"\n"); //Additional linefeed
  561.  
  562.         if(ferror(fo)) { fclose(fo); visible_error(30072,s); return FALSE; } 
  563.      }
  564.  
  565.      if(fclose(fo)) { visible_error(30072,s); return FALSE; }
  566.  
  567.      return TRUE;  
  568. }
  569.  
  570. ///////////////////////////////// import /////////////////////////////////////
  571. int DEMO::import(char *s) 
  572. {   
  573.  
  574.       if(!is_open) { visible_error(30055,s); return FALSE; }
  575.  
  576.       FILE *fr=fopen(s,"r"); 
  577.       if(fr==NULL) { visible_error(30091,s); return FALSE; }
  578.   
  579.   
  580.       const MAX_NUM_FIELDS= 100;  //Increase this to allow more fields    
  581.       const MAX_FIELD_LEN = 500;  //Increase this to allow longer fields  
  582.  
  583.       int *finu;
  584.       finu=(int *)malloc(MAX_NUM_FIELDS*sizeof(int));
  585.       if(finu==NULL) { fclose(fr); visible_error(30092); return FALSE; }  
  586.  
  587.       char *fibu;    
  588.       fibu=(char *)malloc(MAX_FIELD_LEN);
  589.       if(fibu==NULL) 
  590.       {
  591.          fclose(fr); 
  592.          free(finu); 
  593.          visible_error(30092); 
  594.          return FALSE; 
  595.       }
  596.  
  597.       *fibu=0;  
  598.  
  599.       char *fipo=fibu+strlen("field:");  
  600.       char *cp; 
  601.       int  ifieldnr=0;    
  602.       int  ofieldnr; 
  603.  
  604.       int  RC=TRUE; 
  605.       int  InDef=TRUE; 
  606.  
  607.       memset(finu,0,MAX_NUM_FIELDS*sizeof(int));
  608.  
  609.       fgets(fibu,MAX_FIELD_LEN,fr); 
  610.       while(!strchr(fibu,12))  
  611.       {    
  612.         if(feof(fr))
  613.         { 
  614.            if(!InDef)   
  615.            visible_error(30093,s); 
  616.            RC=FALSE;
  617.            break; 
  618.         } 
  619.         pStrlwr(fibu);     //Converting to lower case.
  620.         notabs(fibu);      //Removing tabs.
  621.         trim_string(fibu); //Removing heading & trailing spaces.
  622.         if(!strchr(fibu,':') && *fibu) InDef=FALSE;   
  623.         if(strstr(fibu,"field:"))   
  624.         {  
  625.            ifieldnr++;  
  626.            trim_string(fipo);    
  627.            if((cp=strchr(fipo,' '))!=NULL) *cp=0;
  628.            if     (!strcmp(fipo,"name"))    ofieldnr=1;
  629.            else if(!strcmp(fipo,"data"))    ofieldnr=2;
  630.            else ofieldnr=0; 
  631.            finu[ifieldnr]=ofieldnr; 
  632.         }  
  633.         fgets(fibu,MAX_FIELD_LEN,fr);    
  634.       }    
  635.  
  636.  
  637.       if(RC) 
  638.       for(;;)   
  639.       {    
  640.         if(!strchr(fibu,12))   
  641.         {  
  642.            ifieldnr++; 
  643.            if(ifieldnr<MAX_NUM_FIELDS) 
  644.              switch(finu[ifieldnr])   
  645.              {  
  646.                 case 0:  break;
  647.                 case 1:
  648.                          fibu[DEMO_NAME_LENGTH]=0;
  649.                          name(fibu);
  650.                          break;
  651.                 case 2:
  652.                          fibu[DEMO_DATA_LENGTH]=0;
  653.                          data(fibu);
  654.                          break;
  655.              }  
  656.         }  
  657.         else    
  658.         {  
  659.            ifieldnr=0; 
  660.            append_blank();
  661.         }  
  662.         if(feof(fr)) break;    
  663.         fgets(fibu,MAX_FIELD_LEN,fr);    
  664.         cp=fibu+(pMax(1,strlen(fibu))-1); 
  665.         if(*cp=='\n') *cp=0;  //removing the line feed 
  666.       }    
  667.  
  668.  
  669.       fclose(fr); 
  670.       free(fibu); 
  671.       free(finu); 
  672.  
  673.       return RC; 
  674.  
  675. }
  676.  
  677. ///////////////////////////////// export to dBASE compatible file. ///////////
  678. int DEMO::to_DBASE(char *s) 
  679. {   
  680.  
  681.       if(!is_open) { visible_error(30056,s); return FALSE; }
  682.  
  683.       char bufje[12];
  684.  
  685.       write_rec(); 
  686.       FILE *fo=fopen(s,"wb"); 
  687.       if(fo==NULL) { visible_error(30095,s); return FALSE; }
  688.   
  689.       int i;
  690.   
  691.       csDATE d_upda;
  692.       d_upda.sem_jul(db.sj_updated());
  693.       fputc(03,fo);  
  694.       
  695.       fputc(d_upda.year()%100,fo);  
  696.       fputc(d_upda.month(),fo);  
  697.       fputc(d_upda.day(),fo);  
  698.  
  699.       long nr_record=numrec(); 
  700.       fwrite(&nr_record,sizeof(long),1,fo); 
  701.       WriteU16l(fo,98);        //Header length 
  702.       WriteU16l(fo,83);        //Length of data record 
  703.       for(i=0;i<20;i++) fputc(0,fo); // 20 dummy bytes 
  704.  
  705.  
  706. // Writing definition of field name to dbase file header.
  707.       memset(bufje,0,11);
  708.       strcpy(bufje,"NAME");
  709.       fwrite(bufje,11,1,fo);
  710.       fputc('C',fo); 
  711.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  712.       fputc(50,fo); 
  713.       fputc(0,fo); 
  714.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  715.  
  716. // Writing definition of field data to dbase file header.
  717.       memset(bufje,0,11);
  718.       strcpy(bufje,"DATA");
  719.       fwrite(bufje,11,1,fo);
  720.       fputc('C',fo); 
  721.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  722.       fputc(32,fo); 
  723.       fputc(0,fo); 
  724.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  725.  
  726.  
  727.       fputc(13,fo);  //Field terminator 
  728.       fputc(0,fo); 
  729.  
  730. // By now we have written the definition of the 
  731. // record structure to the file header. 
  732. // From here on we will export the records. 
  733.  
  734.      Record *rp;
  735.      U32 lmax=numrec();
  736.      U32 l;
  737.      for(l=1;l<=lmax;l++) 
  738.      {
  739.  
  740.         if(ferror(fo)) 
  741.         { 
  742.            fclose(fo); 
  743.            visible_error(30096,s); 
  744.            return FALSE; 
  745.         } 
  746.  
  747.         rp=(Record *)db.locate_rec(l);
  748.  
  749.         if(db.is_delet(l)) fputc(42,fo); 
  750.         else               fputc(32,fo); 
  751.  
  752. /////////////////////// writing field name /////////////
  753.         fprintf(fo,"%-50s",rp->_name);
  754. /////////////////////// writing field data /////////////
  755.         fprintf(fo,"%-32s",rp->_data);
  756.      }
  757.      fputc(26,fo);  //End of File 
  758.      fclose(fo); 
  759.  
  760.      if(ferror(fo)) 
  761.      { 
  762.         visible_error(30096,s); 
  763.         return FALSE; 
  764.      } 
  765.  
  766.      return TRUE; 
  767. }