GRASS Programmer's Manual  6.4.2(2012)
gis/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         if (read(fd, compress, 3) != 3
00083             || compress[0] != 251 || compress[1] != 255 || compress[2] != 251)
00084             fcb->cellhd.compressed = 0;
00085     }
00086 
00087     if (!fcb->cellhd.compressed)
00088         return fd;
00089 
00090     /* allocate space to hold the row address array */
00091     fcb->row_ptr = G_calloc(fcb->cellhd.rows + 1, sizeof(off_t));
00092 
00093     /* read the row address array */
00094     return G__read_row_ptrs(fd);
00095 }
00096 
00097 int G__read_row_ptrs(int fd)
00098 {
00099     struct fileinfo *fcb = &G__.fileinfo[fd];
00100     int nrows = fcb->cellhd.rows;
00101     unsigned char nbytes;
00102     unsigned char *buf, *b;
00103     int n;
00104     int row;
00105 
00106     /*
00107      * pre3.0 row addresses were written directly from the array of off_t's
00108      * (this makes them machine dependent)
00109      */
00110 
00111     if (fcb->cellhd.compressed < 0) {
00112         n = (nrows + 1) * sizeof(off_t);
00113         if (read(fd, fcb->row_ptr, n) != n)
00114             goto badread;
00115         return 1;
00116     }
00117 
00118     /*
00119      * 3.0 row address array is in a machine independent format
00120      * (warning - the format will work even if the sizeof(off_t) is
00121      *  not the same from machine to machine, as long as the
00122      *  actual values do not exceed the capability of the off_t)
00123      */
00124 
00125     if (read(fd, &nbytes, 1) != 1)
00126         goto badread;
00127     if (nbytes == 0)
00128         goto badread;
00129 
00130     n = (nrows + 1) * nbytes;
00131     buf = G_malloc(n);
00132     if (read(fd, buf, n) != n)
00133         goto badread;
00134 
00135     for (row = 0, b = buf; row <= nrows; row++) {
00136         off_t v = 0;
00137 
00138         for (n = 0; n < (int)nbytes; n++) {
00139             unsigned char c = *b++;
00140 
00141             if (nbytes > sizeof(off_t) && n < nbytes - sizeof(off_t) &&
00142                 c != 0)
00143                 goto badread;
00144 
00145             v <<= 8;
00146             v += c;
00147         }
00148 
00149         fcb->row_ptr[row] = v;
00150     }
00151 
00152     G_free(buf);
00153 
00154     return 1;
00155 
00156   badread:
00157     G_warning(_("Fail of initial read of compressed file [%s in %s]"),
00158               fcb->name, fcb->mapset);
00159     return -1;
00160 }
00161 
00162 int G__write_row_ptrs(int fd)
00163 {
00164     struct fileinfo *fcb = &G__.fileinfo[fd];
00165     int nrows = fcb->cellhd.rows;
00166     int nbytes = sizeof(off_t);
00167     unsigned char *buf, *b;
00168     int len, row, result;
00169 
00170     lseek(fd, 0L, SEEK_SET);
00171 
00172     len = (nrows + 1) * nbytes + 1;
00173     b = buf = G_malloc(len);
00174     *b++ = nbytes;
00175 
00176     for (row = 0; row <= nrows; row++) {
00177         off_t v = fcb->row_ptr[row];
00178         int i;
00179 
00180         for (i = nbytes - 1; i >= 0; i--) {
00181             b[i] = v & 0xff;
00182             v >>= 8;
00183         }
00184 
00185         b += nbytes;
00186     }
00187 
00188     result = (write(fd, buf, len) == len);
00189     G_free(buf);
00190 
00191     return result;
00192 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines