00001 #include "drms.h"
00002 #include "drms_priv.h"
00003 #include <zlib.h>
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #define TRY(code) if(!(code)) goto bailout;
00031
00032 int drms_binfile_read (char *filename, int nodata, DRMS_Array_t *rf) {
00033 int i;
00034 FILE *fp;
00035 char magic[9], *p, **sptr;
00036 long long bufsize;
00037
00038 if (!rf) {
00039 fprintf (stderr, "Bad pointer to array structure.\n");
00040 return 1;
00041 }
00042 memset (rf, 0, sizeof(DRMS_Array_t));
00043
00044 rf->bzero = 0.0;
00045 rf->bscale = 1.0;
00046
00047 if ((fp = fopen (filename, "r")) == NULL) {
00048 fprintf (stderr, "ERROR: Couldn\'t open file \"%s\"\n", filename);
00049 return 1;
00050 }
00051 TRY (fread (magic, 8, 1, fp));
00052 if (strncmp (magic, "DRMS RAW", 8)) {
00053 magic[8] = 0;
00054 fprintf (stderr,"Bad magic string for in file %s: \"%s\"\n", filename,
00055 magic);
00056 goto bailout;
00057 }
00058 TRY (fread (&rf->type, 4, 1, fp));
00059 TRY (fread (&rf->naxis, 4, 1, fp));
00060 #if __BYTE_ORDER == __BIG_ENDIAN
00061 byteswap (4, 1, (void *)&rf->type);
00062 byteswap (4, 1, (void *)&rf->naxis);
00063 #endif
00064 if (rf->naxis > DRMS_MAXRANK) {
00065 fprintf (stderr, "ERROR: Naxis (%d) in file exceeds DRMS_MAXRANK (%d)\n",
00066 rf->naxis, DRMS_MAXRANK);
00067 goto bailout;
00068 }
00069 for (i = 0; i < rf->naxis; i++) TRY (fread (&rf->axis[i], 4, 1, fp));
00070 if (rf->type == DRMS_TYPE_CHAR || rf->type == DRMS_TYPE_SHORT ||
00071 rf->type == DRMS_TYPE_INT || rf->type == DRMS_TYPE_LONGLONG) {
00072 TRY (fread (&rf->bscale, 8, 1, fp));
00073 TRY (fread (&rf->bzero, 8, 1, fp));
00074 }
00075 TRY (fread (&rf->buflen, 8, 1, fp));
00076 #if __BYTE_ORDER == __BIG_ENDIAN
00077 byteswap (4, rf->naxis, (void *)rf->axis);
00078 if (rf->type == DRMS_TYPE_CHAR || rf->type == DRMS_TYPE_SHORT ||
00079 rf->type == DRMS_TYPE_INT || rf->type == DRMS_TYPE_LONGLONG) {
00080 byteswap (8, 1, (void *)&rf->bscale);
00081 byteswap (8, 1, (void *)&rf->bzero);
00082 }
00083 byteswap (8, 1, (void *)&rf->buflen);
00084 #endif
00085 if (nodata) {
00086 rf->data = NULL;
00087 fclose (fp);
00088 return 0;
00089 }
00090
00091 bufsize = drms_sizeof (rf->type);
00092 for (i = 0; i < rf->naxis; i++) bufsize *= rf->axis[i];
00093 rf->data = malloc (bufsize);
00094 XASSERT (rf->data);
00095
00096 if (rf->type == DRMS_TYPE_STRING) {
00097 rf->strbuf = malloc (rf->buflen);
00098 XASSERT (rf->strbuf);
00099 if (!fread (rf->strbuf, rf->buflen, 1, fp)) {
00100 free (rf->data);
00101 free (rf->strbuf);
00102 goto bailout;
00103 }
00104 p = rf->strbuf;
00105 sptr = rf->data;
00106 *sptr++ = p;
00107 while (p < rf->strbuf + rf->buflen) {
00108 if (*p == 0) {
00109 if (sptr > (char **)(((char *)rf->data) + bufsize)) {
00110 free (rf->data);
00111 free (rf->strbuf);
00112 goto bailout;
00113 }
00114 *sptr++ = p;
00115 }
00116 p++;
00117 }
00118 } else {
00119 rf->strbuf = NULL;
00120 if (!fread (rf->data, bufsize, 1, fp)) {
00121 free (rf->data);
00122 goto bailout;
00123 }
00124 #if __BYTE_ORDER == __BIG_ENDIAN
00125 drms_byteswap (rf->type, bufsize / drms_sizeof (rf->type), rf->data);
00126 #endif
00127 }
00128 fclose (fp);
00129 return 0;
00130 bailout:
00131 fprintf (stderr, "ERROR: binfile_read failed \"%s\"\n", filename);
00132 fclose (fp);
00133 return 1;
00134 }
00135
00136 int drms_binfile_write (char *filename, DRMS_Array_t *rf) {
00137 int i;
00138 FILE *fp;
00139 char magic[9] = "DRMS RAW";
00140 size_t bufsize;
00141
00142 if (rf->type == DRMS_TYPE_STRING) {
00143 fprintf (stderr, "ERROR: data type DRMS_TYPE_STRING unsupported\n");
00144 return 1;
00145 }
00146 if ((fp = fopen (filename,"w")) == NULL) {
00147 fprintf (stderr,"ERROR: Couldn't open file \"%s\"\n", filename);
00148 return 1;
00149 }
00150 if (rf->naxis > DRMS_MAXRANK) {
00151 fprintf (stderr, "ERROR: Naxis (%d) in file exceeds DRMS_MAXRANK (%d)\n",
00152 rf->naxis, DRMS_MAXRANK);
00153 goto bailout;
00154 }
00155
00156 TRY( fwrite (magic, 8, 1, fp));
00157 #if __BYTE_ORDER == __BIG_ENDIAN
00158 byteswap (4, 1, (void *)&rf->type);
00159 byteswap (4, 1, (void *)&rf->naxis);
00160 TRY (fwrite (&rf->type, 4, 1, fp));
00161 TRY (fwrite (&rf->naxis, 4, 1, fp));
00162 byteswap (4, 1, (void *)&rf->type);
00163 byteswap (4, 1, (void *)&rf->naxis);
00164 byteswap (4, rf->naxis, (void *)rf->axis);
00165 for (i = 0; i < rf->naxis; i++) TRY (fwrite (&rf->axis[i], 4, 1, fp));
00166 byteswap (4, rf->naxis, (void *)rf->axis);
00167 if (rf->type == DRMS_TYPE_CHAR || rf->type == DRMS_TYPE_SHORT ||
00168 rf->type == DRMS_TYPE_INT || rf->type == DRMS_TYPE_LONGLONG) {
00169 byteswap (8, 1, (void *)&rf->bscale);
00170 byteswap (8, 1, (void *)&rf->bzero);
00171 TRY (fwrite (&rf->bscale, 8, 1, fp));
00172 TRY (fwrite (&rf->bzero, 8, 1, fp));
00173 byteswap (8, 1, (void *)&rf->bscale);
00174 byteswap (8, 1, (void *)&rf->bzero);
00175 }
00176 #else
00177 TRY (fwrite (&rf->type, 4, 1, fp));
00178 TRY (fwrite (&rf->naxis, 4, 1, fp));
00179 for (i = 0; i < rf->naxis; i++) TRY (fwrite (&rf->axis[i], 4, 1, fp));
00180 if (rf->type == DRMS_TYPE_CHAR || rf->type == DRMS_TYPE_SHORT ||
00181 rf->type == DRMS_TYPE_INT || rf->type == DRMS_TYPE_LONGLONG) {
00182 TRY (fwrite (&rf->bscale, 8, 1, fp));
00183 TRY (fwrite (&rf->bzero, 8, 1, fp));
00184 }
00185 #endif
00186
00187 bufsize = drms_sizeof (rf->type);
00188 for (i = 0; i < rf->naxis; i++) bufsize *= rf->axis[i];
00189 rf->buflen = bufsize;
00190 #if __BYTE_ORDER == __BIG_ENDIAN
00191 byteswap (8, 1, (void *)&rf->buflen);
00192 TRY (fwrite (&rf->buflen, 8, 1, fp));
00193 byteswap (8, 1, (void *)&rf->buflen);
00194 if (rf->type == DRMS_TYPE_CHAR || rf->type == DRMS_TYPE_SHORT ||
00195 rf->type == DRMS_TYPE_INT || rf->type == DRMS_TYPE_LONGLONG) {
00196 }
00197 drms_byteswap (rf->type, bufsize / drms_sizeof(rf->type), rf->data);
00198 fwrite (rf->data, bufsize, 1, fp);
00199 drms_byteswap (rf->type, bufsize / drms_sizeof(rf->type), rf->data);
00200 #else
00201 TRY (fwrite (&rf->buflen, 8, 1, fp));
00202 fwrite (rf->data, bufsize, 1, fp);
00203 #endif
00204 fclose(fp);
00205 return 0;
00206 bailout:
00207 fclose(fp);
00208 unlink(filename);
00209 return 1;
00210 }
00211
00212
00213
00214 int drms_zipfile_read (char *filename, int nodata, DRMS_Array_t *rf) {
00215 int i;
00216 gzFile fp;
00217 char **sptr;
00218 char *p;
00219 char magic[9];
00220 size_t bufsize;
00221
00222 if (!rf)
00223 {
00224 fprintf(stderr, "Bad pointer to array structure.\n");
00225 return 1;
00226 }
00227
00228 memset(rf, 0, sizeof(DRMS_Array_t));
00229
00230 rf->bzero = 0.0;
00231 rf->bscale = 1.0;
00232
00233 if ((fp = gzopen (filename, "r")) == NULL) {
00234 fprintf (stderr, "ERROR: Couldn't open file \"%s\"\n", filename);
00235 return 1;
00236 }
00237 TRY (gzread (fp, magic, 8));
00238 if (strncmp (magic, "DRMS RAW", 8)) {
00239 magic[8] = 0;
00240 fprintf (stderr, "Bad magic string for in file %s: \"%s\"\n", filename,
00241 magic);
00242 goto bailout;
00243 }
00244 TRY (gzread (fp, &rf->type, 4));
00245 TRY( gzread (fp, &rf->naxis, 4));
00246 #if __BYTE_ORDER == __BIG_ENDIAN
00247 byteswap (4, 1, (void *)&rf->type);
00248 byteswap (4, 1, (void *)&rf->naxis);
00249 #endif
00250 if (rf->naxis > DRMS_MAXRANK) {
00251 fprintf (stderr,"ERROR: Naxis (%d) in file exceeds DRMS_MAXRANK (%d)\n",
00252 rf->naxis, DRMS_MAXRANK);
00253 goto bailout;
00254 }
00255 for (i=0; i < rf->naxis; i++) TRY (gzread (fp, &rf->axis[i], 4));
00256 if (rf->type == DRMS_TYPE_CHAR || rf->type == DRMS_TYPE_SHORT ||
00257 rf->type == DRMS_TYPE_INT || rf->type == DRMS_TYPE_LONGLONG) {
00258 TRY (gzread (fp, &rf->bscale, 8));
00259 TRY (gzread (fp, &rf->bzero, 8));
00260 }
00261 TRY (gzread (fp, &rf->buflen, 8));
00262 #if __BYTE_ORDER == __BIG_ENDIAN
00263 byteswap (4, rf->naxis, (void *)rf->axis);
00264 if (rf->type == DRMS_TYPE_CHAR || rf->type == DRMS_TYPE_SHORT ||
00265 rf->type == DRMS_TYPE_INT || rf->type == DRMS_TYPE_LONGLONG) {
00266 byteswap (8, 1, (void *)&rf->bscale);
00267 byteswap (8, 1, (void *)&rf->bzero);
00268 }
00269 byteswap (8, 1, (void *)&rf->buflen);
00270 #endif
00271 if (nodata) {
00272 rf->data = NULL;
00273 gzclose (fp);
00274 return 0;
00275 }
00276
00277 bufsize = drms_sizeof (rf->type);
00278 for (i = 0;i < rf->naxis; i++) bufsize *= rf->axis[i];
00279 rf->data = malloc (bufsize);
00280 XASSERT (rf->data);
00281
00282 if (rf->type == DRMS_TYPE_STRING) {
00283 rf->strbuf = malloc (rf->buflen);
00284 XASSERT (rf->strbuf);
00285 if (gzread (fp, rf->strbuf, rf->buflen) < rf->buflen) {
00286 free (rf->data);
00287 free (rf->strbuf);
00288 goto bailout;
00289 }
00290 p = rf->strbuf;
00291 sptr = rf->data;
00292 *sptr++ = p;
00293 while (p < rf->strbuf + rf->buflen) {
00294 if (*p == 0) {
00295 if (sptr > (char **)(((char *)rf->data) + bufsize)) {
00296 free (rf->data);
00297 free (rf->strbuf);
00298 goto bailout;
00299 }
00300 *sptr++ = p;
00301 }
00302 p++;
00303 }
00304 } else {
00305 if (gzread (fp, rf->data, bufsize) < bufsize) {
00306 free (rf->data);
00307 goto bailout;
00308 }
00309 #if __BYTE_ORDER == __BIG_ENDIAN
00310 drms_byteswap (rf->type, bufsize / drms_sizeof (rf->type), rf->data);
00311 #endif
00312 }
00313 gzclose (fp);
00314 return 0;
00315 bailout:
00316 fprintf (stderr, "zipfile_read failed\n");
00317 gzclose (fp);
00318 return 1;
00319 }
00320
00321 int drms_zipfile_write (char *filename, DRMS_Array_t *rf) {
00322 gzFile fp;
00323 int i;
00324 char magic[] = "DRMS RAW";
00325 size_t bufsize;
00326
00327 if (rf->type == DRMS_TYPE_STRING) {
00328 fprintf (stderr, "ERROR: data type DRMS_TYPE_STRING unsupported\n");
00329 return 1;
00330 }
00331
00332
00333
00334
00335
00336
00337 fp = gzopen (filename, "wb1");
00338 if (!fp) {
00339 fprintf (stderr, "ERROR: Couldn\'t write file \"%s\"\n", filename);
00340 return 1;
00341 }
00342 if (rf->naxis>DRMS_MAXRANK) {
00343 fprintf (stderr, "ERROR: Naxis (%d) in file exceeds DRMS_MAXRANK (%d)\n",
00344 rf->naxis, DRMS_MAXRANK);
00345 goto bailout;
00346 }
00347 TRY(gzwrite (fp, magic, 8));
00348 #if __BYTE_ORDER == __BIG_ENDIAN
00349 byteswap (4, 1, (void *)&rf->type);
00350 byteswap (4, 1, (void *)&rf->naxis);
00351 #endif
00352 TRY(gzwrite (fp, &rf->type, 4));
00353 TRY(gzwrite (fp, &rf->naxis, 4));
00354 #if __BYTE_ORDER == __BIG_ENDIAN
00355 byteswap (4, 1, (void *)&rf->type);
00356 byteswap (4, 1, (void *)&rf->naxis);
00357 #endif
00358
00359 #if __BYTE_ORDER == __BIG_ENDIAN
00360 byteswap (4, rf->naxis, (void *)rf->axis);
00361 #endif
00362 for (i = 0; i < rf->naxis; i++) TRY (gzwrite (fp, &rf->axis[i], 4));
00363 #if __BYTE_ORDER == __BIG_ENDIAN
00364 byteswap (4, rf->naxis, (void *)rf->axis);
00365 #endif
00366 if (rf->type == DRMS_TYPE_CHAR || rf->type == DRMS_TYPE_SHORT ||
00367 rf->type == DRMS_TYPE_INT || rf->type == DRMS_TYPE_LONGLONG) {
00368 #if __BYTE_ORDER == __BIG_ENDIAN
00369 byteswap (8, 1, (void *)&rf->bscale);
00370 byteswap (8, 1, (void *)&rf->bzero);
00371 #endif
00372 TRY (gzwrite (fp, &rf->bscale, 8));
00373 TRY (gzwrite (fp, &rf->bzero, 8));
00374 #if __BYTE_ORDER == __BIG_ENDIAN
00375 byteswap (8, 1, (void *)&rf->bscale);
00376 byteswap (8, 1, (void *)&rf->bzero);
00377 #endif
00378 }
00379
00380 bufsize = drms_sizeof (rf->type);
00381 for (i = 0; i < rf->naxis; i++) bufsize *= rf->axis[i];
00382 rf->buflen = bufsize;
00383 #if __BYTE_ORDER == __BIG_ENDIAN
00384 byteswap (8, 1, (void *)&rf->buflen);
00385 drms_byteswap (rf->type, bufsize / drms_sizeof (rf->type), rf->data);
00386 #endif
00387 TRY (gzwrite (fp, &rf->buflen, 8));
00388 if (gzwrite(fp, rf->data, bufsize) != bufsize) goto bailout;
00389 #if __BYTE_ORDER == __BIG_ENDIAN
00390 byteswap (8, 1, (void *)&rf->buflen);
00391 drms_byteswap (rf->type, bufsize / drms_sizeof (rf->type), rf->data);
00392 #endif
00393 gzclose (fp);
00394 return 0;
00395 bailout:
00396 fprintf (stderr, "zipfile_write failed\n");
00397 gzclose (fp);
00398 unlink (filename);
00399 return 1;
00400 }