GRASS Programmer's Manual
6.4.2(2012)
|
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 }