home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / formats / off / code / readinde.c < prev    next >
C/C++ Source or Header  |  1994-06-20  |  6KB  |  242 lines

  1.  
  2. /*
  3.  *
  4.  * Description
  5.  *    Read an indexed data file.
  6.  *
  7.  * Output
  8.  *
  9.  * Input
  10.  *    pProp        Pointer to property structure in which to store data
  11.  *    fname        Full path/file name of file to be read.
  12.  *
  13.  * Diagnostics
  14.  *    Returns 0 if successful, -1 if unsuccessful for any reason.
  15.  *
  16.  * Author
  17.  *    Randi J. Rost
  18.  *    Digital Equipment Corp.
  19.  *    Workstation Systems Engineering
  20.  *    Palo Alto, CA
  21.  *
  22.  * History
  23.  *    11-Oct-89    Created
  24.  *
  25.  */
  26.  
  27.  
  28. #include <stdio.h>
  29. #include <sys/file.h>
  30. #include "off.h"
  31.  
  32. #define MAX_DATA_ITEMS        30
  33.  
  34. OFFReadIndexed(pProp, fname)
  35.     OFFProperty    *pProp;
  36.     char    *fname;
  37.  
  38.     {
  39.     FILE    *ascfd;
  40.     int        binfd;
  41.     int        code;
  42.     char    *ptr;
  43.     int        i, j;
  44.     long    nitems, nindices;
  45.     long    *lptr;
  46.     char    format[MAX_DATA_ITEMS][10];
  47.     int        padding[MAX_DATA_ITEMS];
  48.     int        size[MAX_DATA_ITEMS];
  49.     int        datasize = 0;
  50.     int        type = OFF_BINARY;
  51.     char    ch;
  52.     char    bigstr[OFF_BIGSTR];
  53.     int        nostrings = 1;
  54.     int        strlength;
  55.     int        endpad;
  56.     long    junk;
  57.  
  58.  
  59. /*  Try opening the file as if it were binary first  */
  60.     binfd = open(fname, O_RDONLY, 0);
  61.  
  62. /*  If error opening file, punt  */
  63.     if (binfd < 0)
  64.     {
  65.     fprintf(stderr, "OFFReadIndexed: cannot open data file %s\n", fname);
  66.     return(-1);
  67.     }
  68.  
  69. /*  Read first word of file to determine file type  */
  70.     read(binfd, &code, sizeof(long));
  71.  
  72.     if (code != OFF_INDEXED_MAGIC)
  73.     {
  74.     /*  Close the file  */
  75.     close(binfd);
  76.  
  77.     /*  Try to open it as an ascii data file  */
  78.     ascfd = fopen(fname, "r");
  79.  
  80.     /*  If error opening file, punt  */
  81.     if (ascfd == NULL)
  82.         {
  83.         fprintf(stderr, "OFFReadIndexed: cannot open data file %s\n",
  84.             fname);
  85.         return(-1);
  86.         }
  87.     type = OFF_ASCII;
  88.     }
  89.  
  90. /*  Read in the number of data items and indices for the object  */
  91.     if (type == OFF_ASCII)
  92.     fscanf(ascfd,"%d %d\n", &nitems, &nindices);
  93.     else
  94.     {
  95.     read(binfd, &nitems, sizeof(long));
  96.     read(binfd, &nindices, sizeof(long));
  97.     }
  98.     pProp->PropCount = nitems;
  99.  
  100. /*  Compute data size  */
  101.     for (i = 0; i < strlen(pProp->DataFormat); i++)
  102.     {
  103.     switch (pProp->DataFormat[i])
  104.         {
  105.         case 'i': size[i] = sizeof(long);
  106.               padding[i] = ((datasize % 4) == 0) ?
  107.                 0 : 4 - datasize % 4;
  108.               strcpy(format[i], "%d");
  109.               break;
  110.         case 'f': size[i] = sizeof(float);
  111.               padding[i] = ((datasize % 4) == 0) ?
  112.                 0 : 4 - datasize % 4;
  113.               strcpy(format[i], "%f");
  114.               break;
  115.         case 'd': size[i] = sizeof(double);
  116.               padding[i] = ((datasize % 4) == 0) ?
  117.                 0 : 4 - datasize % 4;
  118.               strcpy(format[i], "%F");
  119.               break;
  120.         case 'h': size[i] = sizeof(short);
  121.               padding[i] = ((datasize % 2) == 0) ? 0 : 1;
  122.               strcpy(format[i], "%hd");
  123.               break;
  124.         case 'b': size[i] = sizeof(char);
  125.               padding[i] = 0;
  126.               strcpy(format[i], "%d");
  127.               break;
  128.         case 's': size[i] = sizeof(char *);
  129.               padding[i] = ((datasize % 4) == 0) ?
  130.                 0 : 4 - datasize % 4;
  131.               strcpy(format[i], "%s");
  132.               nostrings = 0;
  133.               break;
  134.         default:  fprintf(stderr, "OFFReadIndexed: data format not ");
  135.               fprintf(stderr, "valid for indexed data type\n");
  136.               return (-1);
  137.         }
  138.     datasize += padding[i] + size[i];
  139.     }
  140.  
  141.     endpad = ((datasize % 4) == 0) ? 0 : 4 - datasize % 4;
  142.     datasize += endpad;
  143.  
  144. /*  Allocate memory for the items and indices  */
  145.     pProp->PropData = (char *) malloc(sizeof(long) * 2
  146.         + datasize * nitems
  147.         + sizeof(short) * nindices); 
  148.  
  149.     ptr = pProp->PropData;
  150.     lptr = (long *) ptr;
  151.     *lptr++ = nitems;
  152.     *lptr++ = nindices;
  153.     ptr = (char *) lptr;
  154.  
  155.     if (type == OFF_ASCII)    /* Read info from the ascii file */
  156.     {
  157.     /*  Read in all the data items  */
  158.     for(i = 0; i < nitems; i++)
  159.         {
  160.         for(j = 0; j < strlen(pProp->DataFormat); j++)
  161.         {
  162.         ptr += padding[j];
  163.         if (pProp->DataFormat[j] == 's')
  164.             {
  165.             fscanf(ascfd, format[j], bigstr);
  166.             lptr = (long *) ptr;
  167.             *lptr = (long) malloc(strlen(bigstr) + 1);
  168.             strcpy(*lptr, bigstr);
  169.             }
  170.         else if (pProp->DataFormat[j] == 'b')
  171.             { fscanf(ascfd, format[j], &ch); *ptr = ch; }
  172.         else
  173.             fscanf(ascfd, format[j], ptr);
  174.  
  175.         ptr += size[j];
  176.         }
  177.  
  178.         ptr += endpad;
  179.         }
  180.  
  181.     /*  Read in all the indices */
  182.     for(i = 0; i < nindices; i++)
  183.         {
  184.         fscanf(ascfd,"%hd", (short *) ptr);
  185.         ptr += sizeof(short);
  186.         }
  187.  
  188.     }
  189.  
  190.     else    /* Read info from the binary file */
  191.  
  192.     {
  193.     if (nostrings)
  194.         {
  195.         read(binfd, ptr, datasize * nitems); /* Read data items */
  196.         ptr += datasize * nitems;
  197.         }
  198.     else
  199.         {
  200.         for(i = 0; i < nitems; i++)
  201.         {
  202.         for(j = 0; j < strlen(pProp->DataFormat); j++)
  203.             {
  204.             ptr += padding[j];
  205.             if (padding[j] != 0) read(binfd, ptr, padding[j]);
  206.             if (strcmp(format[j], "%s") != 0)
  207.             read(binfd, ptr, size[j]);
  208.             else
  209.             {
  210.             read(binfd, &strlength, sizeof(char *));
  211.             lptr = (long *) ptr;
  212.             *lptr = (long) malloc(strlength);
  213.             read(binfd, bigstr, strlength);
  214.             strcpy(*lptr, bigstr);
  215.             if ((strlength % 4) != 0)
  216.                 read(binfd, &junk, 4 - strlength % 4);
  217.             }
  218.             ptr += size[j];
  219.             }
  220.         }
  221.         }
  222.  
  223.     if (endpad != 0)
  224.         {
  225.         read(binfd, ptr, endpad);
  226.         ptr += endpad;
  227.         }
  228.  
  229.     /*  Read indices */
  230.     read(binfd, ptr, sizeof(short) * nindices);
  231.     }
  232.  
  233. /*  Close the data file  */
  234.     if (type == OFF_ASCII)
  235.     fclose(ascfd);
  236.     else
  237.     close(binfd);
  238.  
  239.     return(0);
  240.     }
  241.  
  242.