home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cslio205.zip / EXAMPLES / 3 / CSADDIO.CPP < prev    next >
C/C++ Source or Header  |  1997-01-06  |  30KB  |  1,083 lines

  1. /////////////////////////////////////////////////////////
  2. //     Implementation file of database class: NAMio.
  3. //                                                          
  4. //     Source generated by: CSDBGEN version 1.6.c.
  5. //     Date of generation:  Monday, 6 January 1997.
  6. //     Time of generation:  09:51:27.
  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: NAMio
  16. record: record
  17. file: csadr.dbf
  18. field: name s 40 T
  19. field: adre s 32
  20. field: city s 23 Y
  21. field: count s 32
  22. field: zip s 9
  23. field: tel s 17
  24. field: update d MDY2
  25. field: birth d DMY4 Y
  26. field: relation s 10 Y
  27. field: info s 70
  28. */
  29. /////////////// End of .def file //////////////////////////////////////////////
  30. /*
  31.  
  32.  
  33.  
  34.  
  35.                  █████     █                       █        
  36.                 ██   ██   ██                      ██        
  37.                 ███      ████     ███   ██ ███   ████       
  38.                   ███     ██        ██   ███ ██   ██        
  39.                     ███   ██     █████   ██       ██        
  40.                 ██   ██   ██ █  ██  ██   ██       ██ █      
  41.                  █████     ██    ███ ██  ██        ██       
  42.                                                             
  43.                                                             
  44.              ████     ████  ██  ██  ██ ███   █████   ████   
  45.             ██       ██  ██ ██  ██   ███ ██ ██   █  ██  ██  
  46.              ████    ██  ██ ██  ██   ██     ██      ██████  
  47.                 ██   ██  ██ ██  ██   ██     ██   █  ██      
  48.              ████     ████   ███ ██  ██      █████   █████  
  49.                                                             
  50.  
  51.  
  52.  
  53. */
  54. //////////////////////////////////////////////////////////////////////////////
  55.  
  56.  
  57. #include "csmess.h"
  58. #include "csendian.h"
  59. #include "csaddio.h"
  60.  
  61. #ifdef _CP_010
  62. extern unsigned _stklen=7000;   // Under DOS, a large stack is needed.
  63. #endif
  64.  
  65.  
  66. #define TD_NAME "\t(),- "     // Token delimiters for field 'name'.
  67. #define TL_NAME 4             // Minimal Token length for field 'name'.
  68.  
  69.  
  70. record *record_p; 
  71.  
  72.  
  73. ///////////////////////////////// Constructor ////////////////////////////////
  74. NAMio::NAMio(void) 
  75.     static_rec=(record *)malloc(sizeof(record));
  76.     if(!static_rec) { csmess_p(" Out of memory "); exit(12); } 
  77.     is_open=FALSE; 
  78.     current=1; 
  79.     NeedSync=TRUE; 
  80.     errnr=0;;
  81.     e_name="NAMio-class";
  82.     _update.format(MDY2); 
  83.     _birth.format(DMY4); 
  84.     use_lock_file(TRUE); 
  85. }
  86.  
  87. ///////////////////////////////// Destructor /////////////////////////////////
  88. NAMio::~NAMio(void) 
  89.     close();
  90.     free(static_rec);
  91. }
  92.  
  93. ///////////////////////////////// Errors /////////////////////////////////////
  94. int NAMio::error_nr(void) 
  95. {
  96.  
  97.     int RC=0;
  98.     int RCT;
  99.  
  100.     RCT=in1.error_nr(); if(RCT) RC=RCT;
  101.     RCT=in2.error_nr(); if(RCT) RC=RCT;
  102.     RCT=in3.error_nr(); if(RCT) RC=RCT;
  103.     RCT=in4.error_nr(); if(RCT) RC=RCT;
  104.  
  105.     RCT=db.error_nr();  if(RCT) RC=RCT;
  106.  
  107.     if(errnr) { RC=errnr; errnr=0; }
  108.  
  109.     return RC; 
  110. }
  111.  
  112. ///////////////////////////////// Display Error //////////////////////////////
  113. U16 NAMio::display_error(void) 
  114. {
  115.  
  116.     int RC;
  117.  
  118.     RC=db.display_error(); 
  119.  
  120.     if(!RC) RC=in1.display_error(); 
  121.     if(!RC) RC=in2.display_error(); 
  122.     if(!RC) RC=in3.display_error(); 
  123.     if(!RC) RC=in4.display_error(); 
  124.  
  125.  
  126.     if(!RC && errnr) { RC=errnr; csmess_p(RC,e_name); }
  127.  
  128.     error_nr();  // Just to reset all error variables.
  129.  
  130.     return RC; 
  131. }
  132.  
  133.  
  134. ///////////////////////////////// Messages ///////////////////////////////////
  135. void NAMio::visible_error(int ErrorNr,char *Parm) 
  136.     csmess_p(ErrorNr,e_name,Parm);
  137.     error_nr(ErrorNr);
  138. }
  139.  
  140. ///////////////////////////////// Test for Empty DB //////////////////////////
  141. void NAMio::te(void) 
  142.     if(numrec()) return;
  143.     visible_error(30010);
  144.     close(); 
  145.     exit(8); 
  146. }
  147.  
  148. ///////////////////////////////// test Begin Of File /////////////////////////
  149. int NAMio::tBOF(void) 
  150. {
  151.     if(!numrec()) return TRUE;  
  152.     if(NeedSync) synch_index();
  153.     return (this->*bof_fun)(); 
  154. }
  155.  
  156. ///////////////////////////////// test End Of File /////////////////////////
  157. int NAMio::tEOF(void) 
  158. {
  159.     if(!numrec()) return TRUE;  
  160.     if(NeedSync) synch_index();
  161.     return (this->*eof_fun)(); 
  162. }
  163.  
  164. ///////////////////////////////// Read Only //////////////////////////////////
  165. int NAMio::read_only(int ToF) 
  166. {
  167.     if(already_open()) { visible_error(30063); return FALSE; }
  168.  
  169.     db.read_only(ToF);
  170.  
  171.     in1.read_only(ToF); 
  172.     in2.read_only(ToF); 
  173.     in3.read_only(ToF); 
  174.     in4.read_only(ToF); 
  175.  
  176.     return TRUE; 
  177. }
  178.  
  179. ///////////////////////////////// Use lock files /////////////////////////////
  180. int NAMio::use_lock_file(int ToF) 
  181. {
  182.  
  183.     db.use_lock_file(ToF);
  184.  
  185.     in1.use_lock_file(FALSE); 
  186.     in2.use_lock_file(FALSE); 
  187.     in3.use_lock_file(FALSE); 
  188.     in4.use_lock_file(FALSE); 
  189.  
  190.     return TRUE; 
  191. }
  192.  
  193. ///////////////////////////////// Lock file exist/////////////////////////////
  194. int NAMio::lock_file_exist(void) 
  195. {
  196.  
  197.     if(db.lock_file_exist("csadr.dbf")) return TRUE; 
  198.  
  199.     return FALSE; 
  200. }
  201.  
  202. ///////////////////////////////// remove lock file ///////////////////////////
  203. int NAMio::remove_lock_file(void) 
  204. {
  205.  
  206.     db.remove_lock_file("csadr.dbf"); 
  207.  
  208.     return TRUE;  
  209. }
  210.  
  211. ///////////////////////////////// Sync Index /////////////////////////////////
  212. void NAMio::synch_index(void) 
  213. {
  214.  
  215.      switch(order())
  216.      {
  217.          case UNSORTED:
  218.                   break; 
  219.          case NAMIO_NAME_INDEX:
  220.                  tokenize(TRUE,static_rec->_name,TD_NAME,TL_NAME,&NAMio::find1); 
  221.                  break; 
  222.          case NAMIO_CITY_INDEX:
  223.                  find2(static_rec->_city); 
  224.                  break; 
  225.          case NAMIO_BIRTH_INDEX:
  226.                  static_rec->__birth=_birth.sem_jul();
  227.                  find3(&static_rec->__birth); 
  228.                  break; 
  229.          case NAMIO_RELATION_INDEX:
  230.                  find4(static_rec->_relation); 
  231.                  break; 
  232.      }
  233.      NeedSync=FALSE; 
  234. }
  235.  
  236. ///////////////////////////////// reindex ////////////////////////////////////
  237. int NAMio::reindex(void) 
  238. {
  239.     if(!already_open()) { visible_error(30051); return FALSE; }
  240.  
  241.     write_rec();
  242.  
  243.     U32 l=current;  
  244.     record *rp;  
  245.  
  246.     in1.empty(); 
  247.     in2.empty(); 
  248.     in3.empty(); 
  249.     in4.empty(); 
  250.     for(current=numrec(); current>0; current--)  
  251.     {                          
  252.        rp=locate_curr(); 
  253.        tokenize(FALSE,rp->_name,TD_NAME,TL_NAME,&NAMio::in1_ins_tok); 
  254.        in2.insert(rp->_city,¤t); 
  255.        in3.insert(&rp->__birth,¤t); 
  256.        in4.insert(rp->_relation,¤t); 
  257.     }                          
  258.     current=l;                 
  259.     NeedSync=TRUE;             
  260.  
  261.     return TRUE;               
  262. }
  263.  
  264. ///////////////////////////////// skip ///////////////////////////////////////
  265. int  NAMio::skip0(int delta) 
  266. {
  267.      long old_current=current; 
  268.      current=pMax(pMin(current+delta,db.numrec()),1); 
  269.      return (int)(current-old_current); 
  270. }
  271.  
  272. int  NAMio::skip(int delta) 
  273. {
  274.      int rc; 
  275.  
  276.      if(numrec()==0) return 0; 
  277.  
  278.      if(NeedSync) synch_index();
  279.  
  280.      write_rec(); 
  281.      rc=(this->*skip_fun)(delta); 
  282.      read_rec(); 
  283.  
  284.      return rc; 
  285. }
  286. /////////////// go_to ////////////////////////////////////////////
  287. int NAMio::go_to(long n) 
  288. {
  289.     if(n<1 || n>numrec()) return FALSE; 
  290.  
  291.     write_rec(); 
  292.     current=n; 
  293.     read_rec(); 
  294.  
  295.     NeedSync=(order()!=UNSORTED);
  296.  
  297.     return TRUE;
  298. }
  299.  
  300. /////////////// bottom() /////////////////////////////////////////
  301. int NAMio::bottom(void ) 
  302. {
  303.     if(numrec()==0) return FALSE; 
  304.  
  305.     write_rec(); 
  306.     (this->*bottom_fun)();
  307.     read_rec(); 
  308.  
  309.     NeedSync=FALSE;
  310.  
  311.     return TRUE;
  312. }
  313.  
  314. /////////////// top() ////////////////////////////////////////////
  315. int NAMio::top(void ) 
  316. {
  317.     if(numrec()==0) return FALSE; 
  318.  
  319.     write_rec(); 
  320.     (this->*top_fun)();
  321.     read_rec(); 
  322.  
  323.     NeedSync=FALSE;
  324.  
  325.     return TRUE;
  326. }
  327.  
  328. /////////////// search() /////////////////////////////////////////
  329. int NAMio::search(void *k) 
  330. {
  331.     if(numrec()==0) return FALSE; 
  332.  
  333.     int RC;      
  334.     write_rec(); 
  335.     if(0==(RC=(this->*search_fun)(k))) bottom(); 
  336.     read_rec(); 
  337.  
  338.     NeedSync=FALSE;
  339.  
  340.     return RC;
  341. }
  342.  
  343. /////////////// append blank//////////////////////////////////////
  344. void NAMio::append_blank(void) 
  345. {
  346.     append();
  347.     tokenize(FALSE,static_rec->_name,TD_NAME,TL_NAME,&NAMio::in1_ins_tok); 
  348.     in2.insert(static_rec->_city,¤t); 
  349.     in3.insert(&static_rec->__birth,¤t); 
  350.     in4.insert(static_rec->_relation,¤t); 
  351.     NeedSync=FALSE;
  352. }
  353.  
  354. ///////////////////////////////// append /////////////////////////////////////
  355. // This function doesn't update the indexes, which can save some 
  356. // disk I/O because you are likely to alter the fields 
  357. // immediately after you have appended the record.
  358. // However, if you have an index on a field you don't update, this 
  359. // record will NOT appear in that particular index! 
  360. // The 'append_blank' function does update all indexes, which 
  361. // makes it a safer, but slower option. 
  362. //  
  363. void NAMio::append(void) 
  364. {
  365.     write_rec();
  366.     memset(static_rec,0,sizeof(record)); 
  367.     current=db.append_rec(static_rec); 
  368.     dirty=TRUE;    
  369.     _update.sem_jul((S32)0);
  370.     _birth.sem_jul((S32)0);
  371.     NeedSync=TRUE;
  372. }
  373.  
  374. ///////////////////////////////// open ///////////////////////////////////////
  375. int NAMio::open(int kBbuf) 
  376. {
  377.      if(already_open()) { visible_error(30061); return FALSE; } 
  378.  
  379.      int   needs_reindex=FALSE;        
  380.      char *iname;        
  381.  
  382.      dirty=FALSE;     
  383.      current=1;       
  384.  
  385.      int fre=kBbuf/9; //kBbuf default = 100 Kb.  
  386.  
  387.      if(!db.open("csadr.dbf",fre)) 
  388.      {
  389.          visible_error(30020,"csadr.dbf");
  390.          error_nr(db.error_nr());
  391.          return FALSE;
  392.      }
  393.      if(db.lengthrec()!=sizeof(record)) 
  394.      {
  395.          visible_error(30030);
  396.          db.close(); 
  397.          exit(1); 
  398.      }
  399.  
  400.      iname="csadr01.idx";
  401.  
  402.      if(!file_exist(iname))
  403.      { 
  404.        in1.multiple_keys(TRUE);
  405.        in1.define(iname,NAMio_NAME_TOK_LENGTH,sizeof(long));
  406.        needs_reindex=TRUE; 
  407.      } 
  408.      if(!in1.open(iname,fre*2))
  409.      { 
  410.          visible_error(30040,iname);
  411.          error_nr(in1.error_nr());
  412.          goto OnOpenError;
  413.      } 
  414.   
  415.  
  416.      iname="csadr02.idx";
  417.  
  418.      if(!file_exist(iname))
  419.      { 
  420.        in2.multiple_keys(TRUE);
  421.        in2.define(iname,NAMio_CITY_LENGTH+1,sizeof(long));
  422.        needs_reindex=TRUE; 
  423.      } 
  424.      if(!in2.open(iname,fre*2))
  425.      { 
  426.          visible_error(30040,iname);
  427.          error_nr(in2.error_nr());
  428.          goto OnOpenError;
  429.      } 
  430.   
  431.  
  432.      iname="csadr03.idx";
  433.  
  434.      if(!file_exist(iname))
  435.      { 
  436.        in3.multiple_keys(TRUE);
  437.        in3.define(iname,sizeof(long),sizeof(long));
  438.        needs_reindex=TRUE; 
  439.      } 
  440.      if(!in3.open(iname,fre*2))
  441.      { 
  442.          visible_error(30040,iname);
  443.          error_nr(in3.error_nr());
  444.          goto OnOpenError;
  445.      } 
  446.   
  447.  
  448.      iname="csadr04.idx";
  449.  
  450.      if(!file_exist(iname))
  451.      { 
  452.        in4.multiple_keys(TRUE);
  453.        in4.define(iname,NAMio_RELATION_LENGTH+1,sizeof(long));
  454.        needs_reindex=TRUE; 
  455.      } 
  456.      if(!in4.open(iname,fre*2))
  457.      { 
  458.          visible_error(30040,iname);
  459.          error_nr(in4.error_nr());
  460.          goto OnOpenError;
  461.      } 
  462.   
  463.      is_open=TRUE; 
  464.      if(needs_reindex) reindex(); 
  465.      read_rec(); 
  466.   
  467.      order(UNSORTED);  
  468.  
  469.      return TRUE;    
  470.   
  471.   
  472.   
  473. OnOpenError: 
  474.  
  475.      close2();
  476.  
  477.      return FALSE;    
  478.  
  479. }
  480.  
  481. ///////////////////////////////// close //////////////////////////////////////
  482. int NAMio::close2(void) 
  483. {
  484.  
  485.      db.close(); 
  486.      in1.close();
  487.      in2.close();
  488.      in3.close();
  489.      in4.close();
  490.  
  491.      return TRUE;   
  492. }
  493.  
  494.  
  495.  
  496. int NAMio::close(void) 
  497. {
  498.      if(!already_open()) return TRUE; 
  499.  
  500.      int RC=close2(); 
  501.  
  502.      is_open=FALSE; 
  503.  
  504.      return RC;   
  505. }
  506.  
  507. ///////////////////////////////// define /////////////////////////////////////
  508. int  NAMio::define(void) 
  509. {
  510.      if(already_open()) { visible_error(30062); return FALSE; }
  511.  
  512.      int RC;
  513.  
  514.      RC=db.define("csadr.dbf",sizeof(record)); 
  515.  
  516.      in1.multiple_keys(TRUE);
  517.      RC&=in1.define("csadr01.idx",NAMio_NAME_TOK_LENGTH,sizeof(long));
  518.      in2.multiple_keys(TRUE);
  519.      RC&=in2.define("csadr02.idx",NAMio_CITY_LENGTH+1,sizeof(long));
  520.      in3.multiple_keys(TRUE);
  521.      RC&=in3.define("csadr03.idx",sizeof(long),sizeof(long));
  522.      in4.multiple_keys(TRUE);
  523.      RC&=in4.define("csadr04.idx",NAMio_RELATION_LENGTH+1,sizeof(long));
  524.  
  525.      if(!RC) visible_error(30070); 
  526.  
  527.      return RC; 
  528. }
  529.  
  530. ///////////////////////////////// pack ///////////////////////////////////////
  531. int NAMio::pack(void) 
  532. {
  533.      if(!is_open) { visible_error(30052); return FALSE; }
  534.  
  535.      write_rec(); 
  536.      db.pack();
  537.      reindex();
  538.      top();
  539.  
  540.      return TRUE;
  541. }
  542.  
  543. ///////////////////////////////// order //////////////////////////////////////
  544. int NAMio::order(int nr) 
  545. {
  546.      if(!is_open) { visible_error(30053); return FALSE; }
  547.  
  548.      switch(nr)
  549.      {
  550.          case UNSORTED:        //Unsorted 
  551.                   bof_fun   =&NAMio::bof0;
  552.                   eof_fun   =&NAMio::eof0;
  553.                   skip_fun  =&NAMio::skip0;
  554.                   top_fun   =&NAMio::top0;
  555.                   bottom_fun=&NAMio::bottom0;
  556.                   search_fun=&NAMio::search0;
  557.                   NeedSync=FALSE;
  558.                   break; 
  559.          case NAMIO_NAME_INDEX:    //Index on field name
  560.                   bof_fun   =&NAMio::bof1;
  561.                   eof_fun   =&NAMio::eof1;
  562.                   skip_fun  =&NAMio::skip1;
  563.                   top_fun   =&NAMio::top1;
  564.                   bottom_fun=&NAMio::bottom1;
  565.                   search_fun=&NAMio::search1;
  566.                   NeedSync=TRUE;
  567.                   break; 
  568.          case NAMIO_CITY_INDEX:    //Index on field city
  569.                   bof_fun   =&NAMio::bof2;
  570.                   eof_fun   =&NAMio::eof2;
  571.                   skip_fun  =&NAMio::skip2;
  572.                   top_fun   =&NAMio::top2;
  573.                   bottom_fun=&NAMio::bottom2;
  574.                   search_fun=&NAMio::search2;
  575.                   NeedSync=TRUE;
  576.                   break; 
  577.          case NAMIO_BIRTH_INDEX:    //Index on field birth
  578.                   bof_fun   =&NAMio::bof3;
  579.                   eof_fun   =&NAMio::eof3;
  580.                   skip_fun  =&NAMio::skip3;
  581.                   top_fun   =&NAMio::top3;
  582.                   bottom_fun=&NAMio::bottom3;
  583.                   search_fun=&NAMio::search3;
  584.                   NeedSync=TRUE;
  585.                   break; 
  586.          case NAMIO_RELATION_INDEX:    //Index on field relation
  587.                   bof_fun   =&NAMio::bof4;
  588.                   eof_fun   =&NAMio::eof4;
  589.                   skip_fun  =&NAMio::skip4;
  590.                   top_fun   =&NAMio::top4;
  591.                   bottom_fun=&NAMio::bottom4;
  592.                   search_fun=&NAMio::search4;
  593.                   NeedSync=TRUE;
  594.                   break; 
  595.          default: { visible_error(30080); return FALSE; }
  596.      }
  597.      iOrder=nr;
  598.  
  599.      return TRUE;
  600. }
  601. /////////////////////////////reading record  ///////////////////////////////
  602. void NAMio::read_rec(void) 
  603. {
  604.     if(numrec()==0) return; 
  605.     *static_rec=*locate_curr(); 
  606.     _update.sem_jul(static_rec->__update); 
  607.     _birth.sem_jul(static_rec->__birth); 
  608. }
  609. /////////////////////////////writing record  ///////////////////////////////
  610. void NAMio::write_rec2(void) 
  611. {
  612.     record *recp=locate_curr(); 
  613.     if(strcmp(recp->_name,static_rec->_name)) 
  614.     { 
  615.       tokenize(FALSE,recp->_name,TD_NAME,TL_NAME,&NAMio::in1_del_tok); 
  616.       tokenize(FALSE,static_rec->_name,TD_NAME,TL_NAME,&NAMio::in1_ins_tok); 
  617.     } 
  618.     if(strcmp(recp->_city,static_rec->_city)) 
  619.     { 
  620.       in2.delet(recp->_city,¤t); 
  621.       in2.insert(static_rec->_city,¤t); 
  622.     } 
  623.     static_rec->__update=_update.sem_jul(); 
  624.     static_rec->__birth=_birth.sem_jul(); 
  625.     if(recp->__birth!=static_rec->__birth) 
  626.     { 
  627.       in3.delet(&recp->__birth,¤t); 
  628.       in3.insert(&static_rec->__birth,¤t); 
  629.     } 
  630.     if(strcmp(recp->_relation,static_rec->_relation)) 
  631.     { 
  632.       in4.delet(recp->_relation,¤t); 
  633.       in4.insert(static_rec->_relation,¤t); 
  634.     } 
  635.     db.write_rec(current,static_rec); 
  636.     dirty=FALSE;   
  637. }
  638.  
  639. ///////////////////////////////// export /////////////////////////////////////
  640. int  NAMio::export(char *s) 
  641. {
  642.      if(!is_open) { visible_error(30054,s); return FALSE; }
  643.  
  644.      write_rec();
  645.  
  646.      FILE *fo=fopen(s,"w"); 
  647.      if(fo==NULL) { visible_error(30071,s); return FALSE; }
  648.  
  649.      fprintf(fo,"class:  NAMio");
  650.      fprintf(fo,"\nrecord: record");
  651.      fprintf(fo,"\nfile:   csadr.dbf");
  652.      fprintf(fo,"\nfield:  name s 40 T   ");
  653.      fprintf(fo,"\nfield:  adre s 32   ");
  654.      fprintf(fo,"\nfield:  city s 23 Y   ");
  655.      fprintf(fo,"\nfield:  count s 32   ");
  656.      fprintf(fo,"\nfield:  zip s 9   ");
  657.      fprintf(fo,"\nfield:  tel s 17   ");
  658.      fprintf(fo,"\nfield:  update d MDY2   ");
  659.      fprintf(fo,"\nfield:  birth d DMY4 Y   ");
  660.      fprintf(fo,"\nfield:  relation s 10 Y   ");
  661.      fprintf(fo,"\nfield:  info s 70   ");
  662.  
  663.      if(ferror(fo)) { fclose(fo); visible_error(30072,s); return FALSE; } 
  664.  
  665.      record *rp;
  666.      csDATE conv;
  667.      conv.format(Y4MD);
  668.      U32 lmax=numrec();
  669.      U32 l;
  670.      for(l=1;l<=lmax;l++) 
  671.      {
  672.         rp=( record * )db.locate_rec(l);
  673.         fprintf(fo,"\n%c",12);
  674.         fprintf(fo,"\n%s",rp->_name);
  675.         fprintf(fo,"\n%s",rp->_adre);
  676.         fprintf(fo,"\n%s",rp->_city);
  677.         fprintf(fo,"\n%s",rp->_count);
  678.         fprintf(fo,"\n%s",rp->_zip);
  679.         fprintf(fo,"\n%s",rp->_tel);
  680.         conv.sem_jul(rp->__update);
  681.         fprintf(fo,"\n%s",(char *)conv);
  682.         conv.sem_jul(rp->__birth);
  683.         fprintf(fo,"\n%s",(char *)conv);
  684.         fprintf(fo,"\n%s",rp->_relation);
  685.         fprintf(fo,"\n%s",rp->_info);
  686.         fprintf(fo,"\n"); //Additional linefeed
  687.  
  688.         if(ferror(fo)) { fclose(fo); visible_error(30072,s); return FALSE; } 
  689.      }
  690.  
  691.      if(fclose(fo)) { visible_error(30072,s); return FALSE; }
  692.  
  693.      return TRUE;  
  694. }
  695.  
  696. ///////////////////////////////// import /////////////////////////////////////
  697. int NAMio::import(char *s) 
  698. {   
  699.  
  700.       if(!is_open) { visible_error(30055,s); return FALSE; }
  701.  
  702.       FILE *fr=fopen(s,"r"); 
  703.       if(fr==NULL) { visible_error(30091,s); return FALSE; }
  704.   
  705.   
  706.       const MAX_NUM_FIELDS= 100;  //Increase this to allow more fields    
  707.       const MAX_FIELD_LEN = 500;  //Increase this to allow longer fields  
  708.  
  709.       int *finu;
  710.       finu=(int *)malloc(MAX_NUM_FIELDS*sizeof(int));
  711.       if(finu==NULL) { fclose(fr); visible_error(30092); return FALSE; }  
  712.  
  713.       char *fibu;    
  714.       fibu=(char *)malloc(MAX_FIELD_LEN);
  715.       if(fibu==NULL) 
  716.       {
  717.          fclose(fr); 
  718.          free(finu); 
  719.          visible_error(30092); 
  720.          return FALSE; 
  721.       }
  722.  
  723.       *fibu=0;  
  724.  
  725.       char *fipo=fibu+strlen("field:");  
  726.       char *cp; 
  727.       int  ifieldnr=0;    
  728.       int  ofieldnr; 
  729.  
  730.       int  RC=TRUE; 
  731.       int  InDef=TRUE; 
  732.       csDATE conv;
  733.       conv.format(Y4MD);
  734.  
  735.       memset(finu,0,MAX_NUM_FIELDS*sizeof(int));
  736.  
  737.       fgets(fibu,MAX_FIELD_LEN,fr); 
  738.       while(!strchr(fibu,12))  
  739.       {    
  740.         if(feof(fr))
  741.         { 
  742.            if(!InDef)   
  743.            visible_error(30093,s); 
  744.            RC=FALSE;
  745.            break; 
  746.         } 
  747.         pStrlwr(fibu);     //Converting to lower case.
  748.         notabs(fibu);      //Removing tabs.
  749.         trim_string(fibu); //Removing heading & trailing spaces.
  750.         if(!strchr(fibu,':') && *fibu) InDef=FALSE;   
  751.         if(strstr(fibu,"field:"))   
  752.         {  
  753.            ifieldnr++;  
  754.            trim_string(fipo);    
  755.            if((cp=strchr(fipo,' '))!=NULL) *cp=0;
  756.            if     (!strcmp(fipo,"name"))    ofieldnr=1;
  757.            else if(!strcmp(fipo,"adre"))    ofieldnr=2;
  758.            else if(!strcmp(fipo,"city"))    ofieldnr=3;
  759.            else if(!strcmp(fipo,"count"))    ofieldnr=4;
  760.            else if(!strcmp(fipo,"zip"))    ofieldnr=5;
  761.            else if(!strcmp(fipo,"tel"))    ofieldnr=6;
  762.            else if(!strcmp(fipo,"update"))    ofieldnr=7;
  763.            else if(!strcmp(fipo,"birth"))    ofieldnr=8;
  764.            else if(!strcmp(fipo,"relation"))    ofieldnr=9;
  765.            else if(!strcmp(fipo,"info"))    ofieldnr=10;
  766.            else ofieldnr=0; 
  767.            finu[ifieldnr]=ofieldnr; 
  768.         }  
  769.         fgets(fibu,MAX_FIELD_LEN,fr);    
  770.       }    
  771.  
  772.  
  773.       if(RC) 
  774.       for(;;)   
  775.       {    
  776.         if(!strchr(fibu,12))   
  777.         {  
  778.            ifieldnr++; 
  779.            if(ifieldnr<MAX_NUM_FIELDS) 
  780.              switch(finu[ifieldnr])   
  781.              {  
  782.                 case 0:  break;
  783.                 case 1:
  784.                          fibu[NAMio_NAME_LENGTH]=0;
  785.                          name(fibu);
  786.                          break;
  787.                 case 2:
  788.                          fibu[NAMio_ADRE_LENGTH]=0;
  789.                          adre(fibu);
  790.                          break;
  791.                 case 3:
  792.                          fibu[NAMio_CITY_LENGTH]=0;
  793.                          city(fibu);
  794.                          break;
  795.                 case 4:
  796.                          fibu[NAMio_COUNT_LENGTH]=0;
  797.                          count(fibu);
  798.                          break;
  799.                 case 5:
  800.                          fibu[NAMio_ZIP_LENGTH]=0;
  801.                          zip(fibu);
  802.                          break;
  803.                 case 6:
  804.                          fibu[NAMio_TEL_LENGTH]=0;
  805.                          tel(fibu);
  806.                          break;
  807.                 case 7:
  808.                          conv=fibu;
  809.                          _update.sem_jul(conv.sem_jul());
  810.                          break;
  811.                 case 8:
  812.                          conv=fibu;
  813.                          _birth.sem_jul(conv.sem_jul());
  814.                          break;
  815.                 case 9:
  816.                          fibu[NAMio_RELATION_LENGTH]=0;
  817.                          relation(fibu);
  818.                          break;
  819.                 case 10:
  820.                          fibu[NAMio_INFO_LENGTH]=0;
  821.                          info(fibu);
  822.                          break;
  823.              }  
  824.         }  
  825.         else    
  826.         {  
  827.            ifieldnr=0; 
  828.            append_blank();
  829.         }  
  830.         if(feof(fr)) break;    
  831.         fgets(fibu,MAX_FIELD_LEN,fr);    
  832.         cp=fibu+(pMax(1,strlen(fibu))-1); 
  833.         if(*cp=='\n') *cp=0;  //removing the line feed 
  834.       }    
  835.  
  836.  
  837.       fclose(fr); 
  838.       free(fibu); 
  839.       free(finu); 
  840.  
  841.       return RC; 
  842.  
  843. }
  844.  
  845. ///////////////////////////////// export to dBASE compatible file. ///////////
  846. int NAMio::to_DBASE(char *s) 
  847. {   
  848.  
  849.       if(!is_open) { visible_error(30056,s); return FALSE; }
  850.  
  851.       char bufje[12];
  852.  
  853.       write_rec(); 
  854.       FILE *fo=fopen(s,"wb"); 
  855.       if(fo==NULL) { visible_error(30095,s); return FALSE; }
  856.   
  857.       int i;
  858.   
  859.       csDATE d_upda;
  860.       d_upda.sem_jul(db.sj_updated());
  861.       fputc(03,fo);  
  862.       
  863.       fputc(d_upda.year()%100,fo);  
  864.       fputc(d_upda.month(),fo);  
  865.       fputc(d_upda.day(),fo);  
  866.  
  867.       long nr_record=numrec(); 
  868.       fwrite(&nr_record,sizeof(long),1,fo); 
  869.       WriteU16l(fo,354);        //Header length 
  870.       WriteU16l(fo,250);        //Length of data record 
  871.       for(i=0;i<20;i++) fputc(0,fo); // 20 dummy bytes 
  872.  
  873.  
  874. // Writing definition of field name to dbase file header.
  875.       memset(bufje,0,11);
  876.       strcpy(bufje,"NAME");
  877.       fwrite(bufje,11,1,fo);
  878.       fputc('C',fo); 
  879.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  880.       fputc(40,fo); 
  881.       fputc(0,fo); 
  882.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  883.  
  884. // Writing definition of field adre to dbase file header.
  885.       memset(bufje,0,11);
  886.       strcpy(bufje,"ADRE");
  887.       fwrite(bufje,11,1,fo);
  888.       fputc('C',fo); 
  889.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  890.       fputc(32,fo); 
  891.       fputc(0,fo); 
  892.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  893.  
  894. // Writing definition of field city to dbase file header.
  895.       memset(bufje,0,11);
  896.       strcpy(bufje,"CITY");
  897.       fwrite(bufje,11,1,fo);
  898.       fputc('C',fo); 
  899.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  900.       fputc(23,fo); 
  901.       fputc(0,fo); 
  902.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  903.  
  904. // Writing definition of field count to dbase file header.
  905.       memset(bufje,0,11);
  906.       strcpy(bufje,"COUNT");
  907.       fwrite(bufje,11,1,fo);
  908.       fputc('C',fo); 
  909.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  910.       fputc(32,fo); 
  911.       fputc(0,fo); 
  912.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  913.  
  914. // Writing definition of field zip to dbase file header.
  915.       memset(bufje,0,11);
  916.       strcpy(bufje,"ZIP");
  917.       fwrite(bufje,11,1,fo);
  918.       fputc('C',fo); 
  919.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  920.       fputc(9,fo); 
  921.       fputc(0,fo); 
  922.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  923.  
  924. // Writing definition of field tel to dbase file header.
  925.       memset(bufje,0,11);
  926.       strcpy(bufje,"TEL");
  927.       fwrite(bufje,11,1,fo);
  928.       fputc('C',fo); 
  929.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  930.       fputc(17,fo); 
  931.       fputc(0,fo); 
  932.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  933.  
  934. // Writing definition of field update to dbase file header.
  935.       memset(bufje,0,11);
  936.       strcpy(bufje,"UPDATE");
  937.       fwrite(bufje,11,1,fo);
  938.       fputc('D',fo); 
  939.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  940.       fputc(8,fo); 
  941.       fputc(0,fo); 
  942.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  943.  
  944. // Writing definition of field birth to dbase file header.
  945.       memset(bufje,0,11);
  946.       strcpy(bufje,"BIRTH");
  947.       fwrite(bufje,11,1,fo);
  948.       fputc('D',fo); 
  949.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  950.       fputc(8,fo); 
  951.       fputc(0,fo); 
  952.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  953.  
  954. // Writing definition of field relation to dbase file header.
  955.       memset(bufje,0,11);
  956.       strcpy(bufje,"RELATION");
  957.       fwrite(bufje,11,1,fo);
  958.       fputc('C',fo); 
  959.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  960.       fputc(10,fo); 
  961.       fputc(0,fo); 
  962.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  963.  
  964. // Writing definition of field info to dbase file header.
  965.       memset(bufje,0,11);
  966.       strcpy(bufje,"INFO");
  967.       fwrite(bufje,11,1,fo);
  968.       fputc('C',fo); 
  969.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  970.       fputc(70,fo); 
  971.       fputc(0,fo); 
  972.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  973.  
  974.  
  975.       fputc(13,fo);  //Field terminator 
  976.       fputc(0,fo); 
  977.  
  978. // By now we have written the definition of the 
  979. // record structure to the file header. 
  980. // From here on we will export the records. 
  981.  
  982.      record *rp;
  983.      U32 lmax=numrec();
  984.      U32 l;
  985.      for(l=1;l<=lmax;l++) 
  986.      {
  987.  
  988.         if(ferror(fo)) 
  989.         { 
  990.            fclose(fo); 
  991.            visible_error(30096,s); 
  992.            return FALSE; 
  993.         } 
  994.  
  995.         rp=(record *)db.locate_rec(l);
  996.  
  997.         if(db.is_delet(l)) fputc(42,fo); 
  998.         else               fputc(32,fo); 
  999.  
  1000. /////////////////////// writing field name /////////////
  1001.         fprintf(fo,"%-40s",rp->_name);
  1002. /////////////////////// writing field adre /////////////
  1003.         fprintf(fo,"%-32s",rp->_adre);
  1004. /////////////////////// writing field city /////////////
  1005.         fprintf(fo,"%-23s",rp->_city);
  1006. /////////////////////// writing field count /////////////
  1007.         fprintf(fo,"%-32s",rp->_count);
  1008. /////////////////////// writing field zip /////////////
  1009.         fprintf(fo,"%-9s",rp->_zip);
  1010. /////////////////////// writing field tel /////////////
  1011.         fprintf(fo,"%-17s",rp->_tel);
  1012. /////////////////////// writing field update /////////////
  1013.         if(rp->__update)
  1014.         { 
  1015.           d_upda.sem_jul(rp->__update);
  1016.           fprintf(fo,"%4d",d_upda.year4());
  1017.           fprintf(fo,"%02d",d_upda.month());
  1018.           fprintf(fo,"%02d",d_upda.day());
  1019.         } 
  1020.         else 
  1021.         { 
  1022.           fprintf(fo,"        "); 
  1023.         } 
  1024. /////////////////////// writing field birth /////////////
  1025.         if(rp->__birth)
  1026.         { 
  1027.           d_upda.sem_jul(rp->__birth);
  1028.           fprintf(fo,"%4d",d_upda.year4());
  1029.           fprintf(fo,"%02d",d_upda.month());
  1030.           fprintf(fo,"%02d",d_upda.day());
  1031.         } 
  1032.         else 
  1033.         { 
  1034.           fprintf(fo,"        "); 
  1035.         } 
  1036. /////////////////////// writing field relation /////////////
  1037.         fprintf(fo,"%-10s",rp->_relation);
  1038. /////////////////////// writing field info /////////////
  1039.         fprintf(fo,"%-70s",rp->_info);
  1040.      }
  1041.      fputc(26,fo);  //End of File 
  1042.      fclose(fo); 
  1043.  
  1044.      if(ferror(fo)) 
  1045.      { 
  1046.         visible_error(30096,s); 
  1047.         return FALSE; 
  1048.      } 
  1049.  
  1050.      return TRUE; 
  1051. }
  1052. ///////////////////////////////// tokenize field ///////////////////////
  1053. void NAMio::tokenize(int once,char *s,const char *delim,int min_len,void(NAMio::*fun)(void *))
  1054. {
  1055.  
  1056.      char *p,*q;
  1057.      char c;
  1058.      int  insert=FALSE;
  1059.  
  1060.      q=p=s;
  1061.  
  1062.      for(;;)
  1063.      {
  1064.        while(*p && !strchr(delim,*p)) p++;
  1065.        if(p-q>=min_len)
  1066.        {
  1067.           c=*p; *p=0;
  1068.           (this->*fun)(q);
  1069.           *p=c;
  1070.           if(once) return;
  1071.           insert=TRUE;
  1072.        }
  1073.        if(!*p) break;
  1074.        q=++p;
  1075.      }
  1076.  
  1077.      if(!insert) (this->*fun)(s);
  1078.  
  1079. }