format.c

Go to the documentation of this file.
00001 #include <grass/gis.h>
00002 #include <grass/glocale.h>
00003 #include <unistd.h>
00004 #include <stdlib.h>
00005 
00006 #include <grass/config.h>
00007 
00008 #ifdef HAVE_UNISTD_H
00009 #include <unistd.h>
00010 #endif
00011 
00012 #include "G.h"
00013 
00053 /**********************************************************************
00054  *
00055  *   G__check_format(int fd)
00056  *
00057  *   Check to see if map with file descriptor "fd" is in compressed
00058  *   format.   If it is, the offset table at the beginning of the 
00059  *   file (which gives seek addresses into the file where code for
00060  *   each row is found) is read into the File Control Buffer (FCB).
00061  *   The compressed flag in the FCB is appropriately set.
00062  *
00063  *   returns:    1 if row pointers were read successfully, -1 otherwise
00064  **********************************************************************/
00065 
00066 int G__check_format(int fd)
00067 {
00068     struct fileinfo *fcb = &G__.fileinfo[fd];
00069     unsigned char compress[4];
00070 
00071     /*
00072      * Check to see if the file is in compress mode
00073      * 4 possibilites
00074      *   compressed flag in cellhd is negative (meaning pre 3.0 cell file)
00075      *       compression flag is first 3 bytes of cell file
00076      *   compression flag is 0 - not compressed
00077      *   compression flag is 1 - compressed using RLE (int) or zlib (FP)
00078      *   compression flag is 2 - compressed using zlib
00079      */
00080 
00081     if (fcb->cellhd.compressed < 0)
00082     {
00083         if (read(fd,compress,3) != 3
00084             || compress[0] != 251
00085             || compress[1] != 255
00086             || compress[2] != 251)
00087             fcb->cellhd.compressed = 0;
00088     }
00089 
00090     if (!fcb->cellhd.compressed)
00091         return fd;
00092 
00093     /* allocate space to hold the row address array */
00094     fcb->row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
00095 
00096     /* read the row address array */
00097     return G__read_row_ptrs(fd);
00098 }
00099 
00100 int G__read_row_ptrs(int fd)
00101 {
00102     struct fileinfo *fcb = &G__.fileinfo[fd];
00103     int nrows = fcb->cellhd.rows;
00104     unsigned char nbytes;
00105     unsigned char *buf, *b;
00106     int n;
00107     int row;
00108 
00109     /*
00110      * pre3.0 row addresses were written directly from the array of off_t's
00111      * (this makes them machine dependent)
00112      */
00113 
00114     if (fcb->cellhd.compressed < 0)
00115     {
00116         n = (nrows + 1) * sizeof(off_t);
00117         if (read(fd, fcb->row_ptr, n) != n)
00118             goto badread;
00119         return 1;
00120     }
00121 
00122     /*
00123      * 3.0 row address array is in a machine independent format
00124      * (warning - the format will work even if the sizeof(off_t) is
00125      *  not the same from machine to machine, as long as the
00126      *  actual values do not exceed the capability of the off_t)
00127      */
00128 
00129     if (read(fd, &nbytes, 1) != 1)
00130         goto badread;
00131     if (nbytes == 0)
00132         goto badread;
00133 
00134     n = (nrows + 1) * nbytes;
00135     buf = G_malloc(n);
00136     if (read (fd, buf, n) != n)
00137         goto badread;
00138 
00139     for (row = 0, b = buf; row <= nrows; row++)
00140     {
00141         off_t v = 0;
00142 
00143         for (n = 0; n < (int) nbytes; n++)
00144         {
00145             unsigned char c = *b++;
00146 
00147             if (nbytes > sizeof(off_t) && n < nbytes - sizeof(off_t) && c != 0)
00148                 goto badread;
00149 
00150             v <<= 8;
00151             v += c;
00152         }
00153 
00154         fcb->row_ptr[row] = v;
00155     }
00156 
00157     G_free (buf);
00158 
00159     return 1;
00160 
00161 badread:
00162     G_warning(_("Fail of initial read of compressed file [%s in %s]"),
00163               fcb->name, fcb->mapset);
00164     return -1;
00165 }
00166 
00167 int G__write_row_ptrs(int fd)
00168 {
00169     struct fileinfo *fcb = &G__.fileinfo[fd];
00170     int nrows = fcb->cellhd.rows;
00171     int nbytes = sizeof(off_t);
00172     unsigned char *buf, *b;
00173     int len, row, result;
00174 
00175     lseek(fd, 0L, SEEK_SET);
00176 
00177     len = (nrows + 1) * nbytes + 1;
00178     b = buf = G_malloc(len);
00179     *b++ = nbytes;
00180 
00181     for (row = 0; row <= nrows; row++)
00182     {
00183         off_t v = fcb->row_ptr[row];
00184         int i;
00185 
00186         for (i = nbytes - 1; i >= 0; i--)
00187         {
00188             b[i] = v & 0xff;
00189             v >>= 8;
00190         }
00191 
00192         b += nbytes;
00193     }
00194 
00195     result = (write(fd, buf, len) == len);
00196     G_free(buf);
00197 
00198     return result;
00199 }
00200 

Generated on Wed Dec 19 14:59:05 2007 for GRASS by  doxygen 1.5.4