home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / DBASEOS2.ZIP / RDDBASE.C next >
C/C++ Source or Header  |  1990-05-01  |  9KB  |  319 lines

  1. /* ---------- "C source to read dBASE files" ---------- */
  2. /* Here is the C code that allows you to read a DBASE-III file. I verified
  3. that it works under Microsoft C v4.0. Hope it does every thing you need.
  4. I am not sure where it came from, so hopefully I am not violating anyones
  5. copyrights :-). Have fun.
  6.  
  7. Greg Twaites
  8. SICOM Inc.
  9. !ihnp4!sun!sunburn!sicom!twaites
  10. */
  11.  
  12. /*                                         */
  13. /*                                         */
  14. /* changed IO and MEMORY calls to OS/2 calls by Joe McVerry 919-846-2014     */
  15. /*                                         */
  16. /* compiled with MSC 5.1 - use the /AL or some form of far pointer allocation*/
  17. /*                                         */
  18. /*                                         */
  19.  
  20.  
  21. /*
  22.  * These functions are used to read dbase files.
  23.  *
  24.  * These functions are provided by Valour Software as a gift.
  25.  *
  26.  * The program is for test purposes only.  No warranty is expressed nor
  27.  * implied. USE AT YOUR OWN RISK!
  28.  *
  29.  *
  30.  */
  31.  
  32. #define LINT_ARGS
  33.  
  34. #define INCL_BASE
  35. #include <os2.h>
  36. #include <dos.h>
  37. #include <stdio.h>
  38.  
  39. HFILE  dbfile;
  40. PHFILE p_file = &dbfile;
  41.  
  42. USHORT f_result;
  43. PUSHORT pf_result = &f_result;
  44.  
  45. long rec_selector;
  46. short subrec_selector;
  47.  
  48. long fld_selector;
  49. short subfld_selector;
  50.  
  51. typedef  struct dbase_head {
  52.     unsigned char   version;     /*03 for dbIII and 83 for dbIII w/memo file*/
  53.     unsigned char   l_update[3];                    /*yymmdd for last update*/
  54.     unsigned long   count;                       /*number of records in file*/
  55.     unsigned int    header;                           /*length of the header
  56.                                                        *includes the \r at end
  57.                                                        */
  58.     unsigned int    lrecl;                            /*length of a record
  59.                                                        *includes the delete
  60.                                                        *byte
  61.                                                        */
  62.     unsigned char   reserv[20];
  63.     } DBASE_HEAD;
  64.  
  65. typedef struct dbase_fld {
  66.     char    name[11];                                           /*field name*/
  67.     char    type;                                               /*field type*/
  68. #define DB_FLD_CHAR  'C'
  69. #define DB_FLD_NUM   'N'
  70. #define DB_FLD_LOGIC 'L'
  71. #define DB_FLD_MEMO  'M'
  72. #define DB_FLD_DATE  'D'
  73.     /* A-T uses large data model but drop it for now */
  74.     char far        *data_ptr;                         /*pointer into buffer*/
  75.     unsigned char   length;                                   /*field length*/
  76.     unsigned char   dec_point;                         /*field decimal point*/
  77.     unsigned char   fill[14];
  78.     } DBASE_FIELD;
  79.  
  80. typedef struct fld_list {
  81.     struct fld_list *next;
  82.     DBASE_FIELD     *fld;
  83.     char            *data;
  84.     } FLD_LIST;
  85.  
  86. DBASE_HEAD  dbhead={0};
  87. FLD_LIST    *db_fld_root=0;
  88. char        *Buffer;
  89. char        buf_work[255];
  90. int        rc;
  91.  
  92. /*------------------------------------------------------------code-------*/
  93. main(argc,argv)
  94. int     argc;
  95. char    *argv[];
  96. {
  97.     if(argc!=2)
  98.        {
  99.     printf("Usage is db_dump filename.dbf");
  100.     exit(100);
  101.        }
  102.     rc = DosOpen(argv[1],
  103.           p_file,pf_result,(ULONG)0,0,0x01,0x00c0,(ULONG)0);
  104.     if(rc)
  105.        {
  106.     printf("Dos open error %3.3d for file %s ",rc,argv[1]);
  107.     exit(150);
  108.        }
  109.     db3_read_dic();
  110.     db3_print_recs(dbhead.count);
  111.     printf("\n\n\t\t\tProcessing complete");
  112.     DosClose(dbfile);
  113.     exit(0);
  114. }
  115.  
  116.  
  117. /******************************************************
  118.                                          db3_read_dic()
  119. This function is called with a file name to
  120. read to create a record type to support the
  121. dbase file
  122. ******************************************************/
  123.  
  124. db3_read_dic()
  125. {
  126.     int         len;
  127.     int             fields;
  128.     DBASE_FIELD     *fld;
  129.  
  130.     int         alloc_size;
  131.  
  132.     if(p_file == NULL) {
  133.         printf("open failed");
  134.         exit(200);
  135.         }
  136.     rc = DosRead(dbfile,&dbhead,sizeof(DBASE_HEAD),&len);
  137.     if (rc)
  138.       {
  139.     printf("\n\aUnable to read file rc = %3.3d",rc);
  140.     exit(205);
  141.       }
  142.     if( (dbhead.version!=3 && dbhead.version!=0x83) )
  143.        {
  144.     printf("\n\aVersion %d not supported",dbhead.version);
  145.     exit(300);
  146.        }
  147.  
  148.     printf("update year    %3d\n",dbhead.l_update[0]);
  149.     printf("update mon     %3d\n",dbhead.l_update[1]);
  150.     printf("update day     %3d\n",dbhead.l_update[2]);
  151.     printf("number of recs %3d\n",dbhead.count);
  152.     printf("header length  %3d\n",dbhead.header);
  153.     printf("record length  %3d\n",dbhead.lrecl);
  154.  
  155.     fields=(dbhead.header-1)/32-1;
  156.  
  157.     /* allocate space for file buffer area */
  158.     rc = DosAllocSeg(dbhead.lrecl,(PSEL)&rec_selector,0);
  159.     if (rc)
  160.        {
  161.     printf("\n\aUnable to allocate memory rc = %3.3d",rc);
  162.     exit(400);
  163.        }
  164.  
  165.     FP_SEG(Buffer) = rec_selector;
  166.     FP_OFF(Buffer) = 0;
  167.  
  168.     /* allocate space and sub area for record buffer area
  169.        reuse selector but don't corrupt it again or you're in big trouble */
  170.  
  171.     alloc_size = (fields+1) * sizeof(FLD_LIST);
  172.  
  173.     rc = DosAllocSeg(alloc_size,(PSEL)&rec_selector,0);
  174.     if (rc)
  175.        {
  176.     printf("\n\aUnable to allocate record memory rc = %3.3d",rc);
  177.     exit(500);
  178.        }
  179.  
  180.     DosSubSet(rec_selector,1,alloc_size);
  181.     if (rc)
  182.       {
  183.     printf("\n\aUnable to set suballocated record memory rc = %3.3d",rc);
  184.     exit(505);
  185.       }
  186.  
  187.     // allocate space for data to stored in
  188.  
  189.     alloc_size = (fields+1) * sizeof(DBASE_FIELD);
  190.  
  191.     rc = DosAllocSeg(alloc_size,(PSEL)&fld_selector,0);
  192.     if (rc)
  193.       {
  194.     printf("\n\aUnable to allocate field memory rc = %3.3d",rc);
  195.     exit(600);
  196.       }
  197.  
  198.     DosSubSet(fld_selector,1,alloc_size);
  199.     if (rc)
  200.       {
  201.     printf("\n\aUnable to set suballocated field memory rc = %3.3d",rc);
  202.     exit(605);
  203.       }
  204.  
  205.     printf("\nField Name\tType\tLength\tDecimal Pos\n");
  206.     while(fields--) {
  207.     rc = DosSubAlloc(fld_selector,(PUSHORT)&subfld_selector,sizeof(DBASE_FIELD));
  208.     if (rc)
  209.       {
  210.         printf("\n\aUnable to suballocate field memory rc = %3.3d",rc);
  211.         exit(610);
  212.       }
  213.  
  214.     FP_SEG(fld) = fld_selector;
  215.     FP_OFF(fld) = subfld_selector;
  216.  
  217.     rc = DosRead(dbfile,fld,sizeof(DBASE_FIELD),&len);
  218.     if (rc)
  219.       {
  220.         printf("\n\aUnable to read file rc = %3.3d",rc);
  221.         exit(620);
  222.       }
  223.     printf("%-10s\t  %c\t  %3d\t  %3d\n",fld->name,fld->type,
  224.                                      fld->length,fld->dec_point);
  225.     stack_field(fld);
  226.     }
  227.     rc = DosRead(dbfile,Buffer,1,&len);     /*read the silly little \r character*/
  228.     if (rc)
  229.       {
  230.        printf("\n\aUnable to read file rc = %3.3d",rc);
  231.        exit(630);
  232.       }
  233.     return;
  234. }
  235.  
  236. /******************************************************
  237.                                         db3_print_recs()
  238. Read records and print the data
  239. ******************************************************/
  240.  
  241. db3_print_recs(cnt)
  242. int     cnt;
  243. {
  244.     int     bytes;
  245.  
  246.     while(cnt) {
  247.     rc=DosRead(dbfile,Buffer,dbhead.lrecl,&bytes);
  248.     if (rc)
  249.       {
  250.         printf("\n\aUnable to read file rc = %3.3d",rc);
  251.         exit(700);
  252.       }
  253.         if(bytes!=dbhead.lrecl)
  254.             break;
  255.         if(Buffer[0]!='*') {
  256.             db3_print();
  257.             cnt--;
  258.             }
  259.         }
  260.     return;
  261. }
  262.  
  263.  
  264. /******************************************************
  265.                                           db3_print()
  266. Print a single record
  267. ******************************************************/
  268.  
  269. db3_print()
  270. {
  271.     FLD_LIST    *list, *temp;
  272.  
  273.     temp=db_fld_root;
  274.     printf("\n");
  275.     while(temp) {
  276.         memcpy(buf_work,temp->data,temp->fld->length);
  277.         buf_work[temp->fld->length]='\0';
  278.         printf("%-10s=%s\n",temp->fld->name,buf_work);
  279.         temp=temp->next;
  280.         }
  281.     return;
  282. }
  283.  
  284. /******************************************************
  285.                                          stack_field()
  286. Add a field to the linked list of fields
  287. ******************************************************/
  288.  
  289. stack_field(fld)
  290. DBASE_FIELD *fld;
  291. {
  292.     FLD_LIST    *list, *temp;
  293.     long fld_selector;
  294.     rc = DosSubAlloc(rec_selector,(PUSHORT)&subrec_selector,sizeof(FLD_LIST));
  295.     if (rc)
  296.        {
  297.     printf("\n\aUnable to suballocate record memory rc = %3.3d",rc);
  298.     exit(800);
  299.        }
  300.     FP_SEG(list) = rec_selector;
  301.     FP_OFF(list) = subrec_selector;
  302.     list->next = NULL;
  303.     list->fld=fld;
  304.     if(!db_fld_root) {
  305.         list->data=Buffer+1;                            /*skip delete byte*/
  306.         db_fld_root=list;
  307.         return;
  308.         }
  309.     temp=db_fld_root;
  310.     while(temp->next)
  311.         temp=temp->next;
  312.     temp->next=list;
  313.     list->data=temp->data + temp->fld->length;
  314.     return;
  315. }
  316.  
  317.  
  318. /* End of text from inmet:comp.sys.ibm.pc */
  319.