bufr_io.c

Go to the documentation of this file.
00001 /*------------------------------------------------------------------------
00002 
00003     BUFR encoding and decoding software and library
00004     Copyright (c) 2007,  Institute of Broadband Communication, TU-Graz
00005     on behalf of EUMETNET OPERA, http://www.knmi.nl/opera
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; version 2.1 
00010     of the License.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
00020 
00021 ----------------------------------------------------------------------------
00022 
00023 FILE:          BUFR_IO.C
00024 IDENT:         $Id: bufr_io.c,v 1.2 2007/12/18 14:40:13 fuxi Exp $
00025 
00026 AUTHORS:       Juergen Fuchsberger, Helmut Paulitsch
00027                Institute of Broadband Communication
00028                Technical University Graz, Austria
00029 
00030 VERSION NUMBER:3.0
00031 
00032 DATE CREATED:  30-NOV-2007
00033 
00034 STATUS:        DEVELOPMENT FINISHED
00035 
00036 
00037 AMENDMENT RECORD:
00038 
00039 $Log: bufr_io.c,v $
00040 Revision 1.2  2007/12/18 14:40:13  fuxi
00041 added licence header
00042 
00043 Revision 1.1  2007/12/07 08:34:56  fuxi
00044 Initial revision
00045 
00046 
00047 --------------------------------------------------------------------------- */
00048 
00057 #include <stdlib.h>
00058 #include <math.h>
00059 #include <stdio.h>
00060 #include <string.h>
00061 #include <assert.h>
00062 #include <errno.h>
00063 #include "desc.h"
00064 #include "bufr.h"
00065 #include "bitio.h"
00066 #include "rlenc.h"
00067 
00068 #define BUFR_OUT_BIN 0 
00070 /* \brief Stucture that holds a decoded (source)
00071                                 bufr message */
00072 typedef struct bufrsrc_s {  
00073 
00074     sect_1_t s1;             
00075     dd* descs;               
00076     int ndesc;               
00077     int desci;               
00078     bd_t* data;              
00079     int ndat;                
00080     int datai;               
00081 } bufrsrc_t;
00082 
00083 
00084 extern int errno;
00085 
00086 static bufrsrc_t* src_ = NULL;   /* structure containing data for encoding */
00087 static int nrows_ = -1;          /* number of rows for bitmap */
00088 static int ncols_ = -1;          /* number of colums for bitmap */
00089 static FILE *fo_ = NULL;         /* File-Pointer for outputfile */
00090 static char* imgfile_ = NULL;    /* filename for uncompressed bitmap */
00091 static char* char_ = NULL;       /* character array for ascii input */
00092 static int   cc_ = 0;            /* index into char array for ascii input */
00093 
00094 static int bufr_read_src_file (FILE* fp, bufrsrc_t* data);
00095 #if BUFR_OUT_BIN
00096 static void place_bin_values (varfl val, int ind, char* buf);
00097 #endif
00098 static int bufr_input_char (varfl* val, int ind);
00099 static int desc_to_array (dd* d, bufrsrc_t* data);
00100 static int string_to_array (char* s, bufrsrc_t* bufr);
00101 static int bufr_src_in (varfl* val, int ind);
00102 static int bufr_file_out (varfl val, int ind);
00103 static int bufr_char_to_file (varfl val, int ind);
00104 static bufrsrc_t* bufr_open_src ();
00105 static void bufr_close_src ();
00106 static FILE* bufr_open_output_file (char* name);
00107 static void bufr_close_output_file ();
00108 static char *str_save(char *str);
00109 static void replace_bin_values (char *buf);
00110 
00111 #define MAX_LINE 200         /* Max. linelength in input file */
00112 #define MAX_DATA  1000000    /* Maximum number of data elements */
00113 
00114 /*===========================================================================*/
00115 
00136 int bufr_data_from_file(char* file, bufr_t* msg)
00137 {
00138     FILE* fp;
00139     bufrsrc_t* src;
00140     int ok = 0, desch = -1;
00141 
00142     /* open file */
00143 
00144     fp = fopen (file, "r");
00145     if (fp == (FILE*) NULL) {
00146         fprintf (stderr, "Could not open file %s\n", file);
00147         return 0;
00148     }
00149 
00150     /* open global src structure for holding data from file */
00151 
00152     src = bufr_open_src ();
00153     ok = (src != (bufrsrc_t*) NULL);
00154 
00155     /* read data from file to arrays */
00156 
00157     if (ok) {
00158         ok = bufr_read_src_file (fp, src);
00159         fclose (fp);
00160     }
00161 
00162     /* output descriptors to section 3 */
00163 
00164     if (ok) {
00165         /* open bitstream */
00166 
00167         desch = bufr_open_descsec_w ();        
00168         ok = (desch >= 0);
00169     }
00170 
00171     if (ok)
00172         /* write descriptors to bitstream */
00173         
00174         ok = bufr_out_descsec (src->descs, src->ndesc, desch);
00175 
00176          /* close bitstream and write data to msg */
00177     
00178     bufr_close_descsec_w (msg, desch);
00179 
00180     /* parse descriptors and encode data to section 4 */
00181 
00182     if (ok)
00183         /* open bitstream */
00184         
00185         ok = (bufr_open_datasect_w () >= 0);
00186 
00187     if (ok) 
00188         /* write data to bitstream */
00189 
00190         ok = bufr_parse_in (src->descs, 0, src->ndesc - 1, bufr_src_in, 1);
00191 
00192         /* close bitstream and write data to msg */
00193 
00194     bufr_close_datasect_w (msg);
00195 
00196     /* free src and cleanup globals */
00197 
00198     bufr_close_src ();
00199 
00200     return ok;
00201 }
00202 
00203 /*===========================================================================*/
00223 int bufr_data_to_file (char* file, char* imgfile, bufr_t* msg) {
00224 
00225     dd *dds = NULL;
00226     int ok;
00227     int ndescs, desch;
00228 
00229     /* open output-file */
00230 
00231     if (bufr_open_output_file (file) == (FILE*) NULL) {
00232         fprintf (stderr, "Unable to open outputfile '%s'\n", file);
00233         return 0;
00234     }
00235 
00236     /* set image file name */
00237 
00238     imgfile_ = imgfile;
00239 
00240     /* open bitstreams for section 3 and 4 */
00241 
00242     desch = bufr_open_descsec_r(msg);
00243 
00244     ok = (desch >= 0);
00245 
00246     if (ok)
00247         ok = (bufr_open_datasect_r(msg) >= 0);
00248 
00249     /* calculate number of data descriptors  */
00250     
00251     ndescs = bufr_get_ndescs (msg);
00252 
00253     /* allocate memory and read data descriptors from bitstream */
00254 
00255     if (ok) 
00256         ok = bufr_in_descsec (&dds, ndescs, desch);
00257 
00258 
00259     /* output data and descriptors */
00260 
00261     if (ok) 
00262         ok = bufr_parse_out (dds, 0, ndescs - 1, bufr_file_out, 1);
00263         
00264     /* close bitstreams and free descriptor array */
00265 
00266     if (dds != (dd*) NULL)
00267         free (dds);
00268     bufr_close_descsec_r (desch);
00269     bufr_close_datasect_r ();
00270     bufr_close_output_file ();
00271 
00272     return ok;
00273 }
00274 
00275 
00276 /*===========================================================================*/
00277 /* local functions */
00278 /*===========================================================================*/
00279 
00289 static int bufr_read_src_file (FILE* fp, bufrsrc_t* data) {
00290 
00291     dd d;                 /* current descriptor */
00292     char buf[MAX_LINE];   /* strung containing current line */
00293     char s[MAX_LINE];     /* string containing data element or filename */
00294     char* sbuf = NULL;  
00295     int l, n, ascii_flag = 0;
00296 
00297     if (fp == NULL || data == (bufrsrc_t*) NULL) return 0;
00298 
00299     /* read each line and process it */
00300 
00301     while (fgets (buf, MAX_LINE, fp) != NULL) {
00302 
00303         ascii_flag = 0;
00304         l = strlen (buf);
00305 
00306         /* delete terminating \n and blanks */
00307 
00308         if (buf[l-1] == '\n') buf[l-1] = 0;
00309         trim (buf);                        
00310       
00311         /* ignore comments */
00312 
00313         if (buf[0] == '#' || strlen (buf) == 0)
00314             continue;
00315 
00316 
00317         /* check for ascii and binary data */
00318 
00319         if (strstr (buf, " '") != NULL) {
00320 
00321             sbuf = strstr (buf, " '");
00322             if (sbuf == NULL) {
00323                 fprintf (stderr, "Error reading ASCII data from input file\n");
00324                 return 0;
00325             }
00326             sbuf++;
00327             ascii_flag = 1;
00328         } else {
00329             
00330             /* replace binary values by integers */
00331 
00332             replace_bin_values (buf);
00333         }
00334 
00335         /* check for data descriptor and data */
00336 
00337         n = sscanf (buf, "%d %d %d %s", &d.f, &d.x, &d.y, s);
00338 
00339 
00340         /* replication and modification descriptors don't have values */
00341 
00342         if (d.f == 1 || d.f == 2)
00343             n = sscanf (buf, "%d %d %d", &d.f, &d.x, &d.y);
00344 
00345         /* descriptor and data */
00346 
00347         if (n == 4) {
00348             if (!desc_to_array (&d, data)) return 0;
00349             if (ascii_flag) {
00350                 if (!string_to_array (sbuf, data)) return 0;
00351             } else {
00352                 if (!string_to_array (s, data)) return 0;
00353             }
00354         }
00355         /* only descriptor */
00356 
00357         else if (n == 3) {
00358             if (!desc_to_array (&d, data)) return 0;
00359         }
00360         /* only data */
00361 
00362         else {
00363             if (ascii_flag) {
00364                 if (!string_to_array (sbuf, data)) return 0;
00365             } else {
00366                 if (!sscanf (buf, "%s", s)) return 0;
00367                 if (!string_to_array (s, data)) return 0;
00368             }
00369         }
00370     }
00371     return 1;
00372 }
00373 
00374 /*===========================================================================*/
00375 /* \ingroup cbinutl
00376     \brief Opens bufrsrc structure for function \ref bufr_src_in
00377 
00378     This functions opens a structure to hold BUFR data descriptors and
00379     data elements from an ASCII file for use by \ref bufr_src_in
00380     and returns the pointer to this structure.
00381 
00382     \return Pointer to the BUFR src structure or NULL if an error occured.
00383 
00384     \see bufr_close_src, bufr_read_src, bufr_src_in
00385 */
00386 
00387     
00388    
00389 static bufrsrc_t* bufr_open_src () {
00390 
00391     if (src_ != (bufrsrc_t*) NULL) {
00392 
00393         fprintf (stderr, "Global src structure not available!\n");
00394         return (bufrsrc_t*) NULL;
00395     }
00396 
00397     src_ = malloc (sizeof (bufrsrc_t));
00398     if (src_ == (bufrsrc_t*) NULL) {
00399 
00400         fprintf (stderr, "Error allocating memory for src structure!\n");
00401         return (bufrsrc_t*) NULL;
00402     }
00403 
00404     memset (src_, 0, sizeof (bufrsrc_t));
00405 
00406     return src_;
00407 }
00408 
00409 /*===========================================================================*/
00410 /* \ingroup cbinutl
00411     \brief Closes bufrsrc structure for function \ref bufr_src_in
00412 
00413     This functions closes the structure used by \ref bufr_src_in
00414 
00415     \see bufr_open_src, bufr_src_in
00416 */
00417 
00418 static void bufr_close_src () {
00419 
00420     int i;
00421 
00422     if (src_ == (bufrsrc_t*) NULL) return;
00423 
00424     if (src_->data != (bd_t*) NULL) {
00425         for (i = 0; i < src_->ndat; i++)
00426             free (src_->data[i]);
00427         free (src_->data);
00428     }
00429 
00430     if (src_->descs != (dd*) NULL)
00431         free (src_->descs);
00432 
00433     free (src_);
00434     src_ = (bufrsrc_t*) NULL;
00435 
00436 }
00437 
00438 
00439 /*===========================================================================*/
00440 /* \ingroup cbin
00441 
00442    \brief Gets next data value from BUFR source data.
00443 
00444    This function
00445 
00446    \param[out] val The received value
00447    \param[in] ind   Index to the global array 
00448                       \ref des[] holding the description of
00449                       known data-descriptors.
00450 
00451    \return 1 on success, 0 on error
00452 */
00453 
00454 static int bufr_src_in (varfl* val, int ind) {
00455 
00456     char* line;        /* current string we have to convert */
00457     int datai;         /* index to current data element */
00458     dd* d;             /* current descriptor */
00459     int depth = 0;     /* image depth in bytes per pixel for bitmaps */
00460     int ok = 0, bitmap = 0; 
00461     bufrval_t* vals;
00462 
00463     assert (val != (varfl*) NULL);
00464     assert (src_ != (bufrsrc_t*) NULL);
00465 
00466     /* get next line frome array */
00467 
00468     datai = src_->datai;
00469     line = src_->data[datai];
00470     if (line == NULL) {
00471         fprintf (stderr, "Data element empty!\n");
00472         return 0;
00473     }
00474 
00475     /* element descriptor */
00476 
00477     if (des[ind]->id == ELDESC) {
00478 
00479         d = &(des[ind]->el->d);
00480 
00481         /* special treatment for ASCII data */
00482 
00483         if (ind == _desc_special) {
00484             char* unit;
00485 
00486             unit = des[ind]->el->unit;
00487             if (unit != NULL && strcmp (unit, "CCITT IA5") == 0) {
00488                 char_ = line;
00489                 cc_ = 0;
00490                 if (!bufr_parse_in (d, 0, 0, bufr_input_char, 0)) {
00491                     return 0;
00492                 }
00493                 /* check if we reached end of string */
00494 
00495                 if (char_[cc_+1] != '\'') {
00496                     fprintf (stderr, 
00497                              "Number of bits missmatch for ascii data!\n");
00498                     return 0;
00499                 }
00500                 cc_ = 0;
00501                 char_ = NULL;
00502                 src_->datai++;
00503                 return 1;
00504             }
00505             else {
00506                 return 1;
00507             }
00508         }
00509 
00510         /* "normal" data -> get one value */
00511 
00512         else {
00513 
00514             /* check for missing */
00515 
00516             if (strstr (line, "missing") != NULL ||
00517                 strstr (line, "MISSING") != NULL) {
00518                 *val = MISSVAL;
00519                 src_->datai++;
00520                 return 1;
00521             }
00522 
00523             /* convert to varfl */
00524 
00525             errno = 0;
00526             *val = (varfl) strtod (line, NULL);
00527             src_->datai++;
00528             if (errno) {
00529                 fprintf (stderr, "Error reading value from bufr_src\n");
00530                 return 0;
00531             }
00532             
00533             /* check for number of rows / columns or
00534                bins / rays of radar bitmap */
00535 
00536             if (bufr_check_fxy(d, 0, 30, 21) > 0 ||
00537                 bufr_check_fxy(d, 0, 30, 195) > 0)
00538                 ncols_ = (int) *val;
00539             if (bufr_check_fxy(d, 0, 30, 22) > 0 ||
00540                 bufr_check_fxy(d, 0, 30, 194) > 0)
00541                 nrows_ = (int) *val;
00542 
00543             return 1;
00544         }
00545     }
00546     /* sequence descriptor */
00547 
00548     else if (des[ind]->id == SEQDESC) {
00549 
00550         /* check if bitmap or "normal" sequence descriptor */
00551         
00552         bitmap = 0;
00553 
00554         d = &(des[ind]->seq->d);
00555         if (d->x == 21) {
00556             if (d->y >= 192 && d->y <= 197) {
00557                 bitmap = 1;
00558                 depth = 1;
00559             }
00560             else if (d->y == 200 || d->y == 202) {
00561                 bitmap = 1;
00562                 depth = 2;
00563             }
00564         }
00565 
00566         /* seqdesc is a special opera run length encoded bitmap */
00567 
00568         if (bitmap && _opera_mode) {
00569 
00570             if (nrows_ <= 0 || ncols_ <= 0) {
00571                 fprintf (stderr, "Unknown number of rows and/or columns\n");
00572                 return 0;
00573             }
00574 
00575             /* read bitmap and run length encode to memory */
00576 
00577             /* initialize array */
00578 
00579             vals = bufr_open_val_array ();
00580 
00581             if (vals == (bufrval_t*) NULL) return 0;
00582             
00583             if (!rlenc_from_file (line, nrows_, ncols_, &(vals->vals), 
00584                                   &(vals->nvals), depth)) { 
00585                 fprintf (stderr, "Error during runlength-compression.\n");
00586                 bufr_close_val_array ();
00587                 return 0;
00588             }
00589             src_->datai++;
00590 
00591             ok = bufr_parse_in (des[ind]->seq->del, 0, des[ind]->seq->nel - 1,
00592                                 bufr_val_from_global, 0);
00593 
00594             /* free array */
00595 
00596             bufr_close_val_array ();
00597             return ok;
00598         } 
00599         /* normal sequence descriptor - just call bufr_parse_in with 
00600            all descriptors in sequence */
00601         
00602         else {
00603             return bufr_parse_in (des[ind]->seq->del, 0, 
00604                                   des[ind]->seq->nel - 1, bufr_src_in, 1);
00605         }
00606 
00607     }
00608     else {
00609         fprintf (stderr, "Unknown descriptor in bufr_src_in!\n");
00610         return 0;
00611     }
00612 }
00613 
00614 
00615 
00616 /*===========================================================================*/
00630 static FILE* bufr_open_output_file (char* name) {
00631 
00632      if (fo_ != (FILE*) NULL) {
00633          fprintf (stderr, "Global output file not available!\n");
00634          return (FILE*) NULL;
00635      }
00636 
00637      fo_ = fopen (name, "w");
00638      return fo_;
00639  }
00640 
00641 /*===========================================================================*/
00650 static void bufr_close_output_file () {
00651 
00652     if (fo_ == (FILE*) NULL) return;
00653     fclose (fo_);
00654     fo_ = (FILE*) NULL;
00655 }
00656 
00657 
00658 /*===========================================================================*/
00687 static int bufr_file_out (varfl val, int ind)
00688 
00689 {
00690     int depth = 1, bitmap, nv, ok;
00691     char sval[80];
00692     char fname[512], tmp[80];
00693     char* unit;
00694     dd* d;
00695     static int nchars = 0;    /* number of characters for ccitt output */
00696     static int in_seq = 0;    /* flag to indicate sequences */
00697     static int first_in_seq;  /* flag to indicate first element in sequence */
00698     static int count = 0;     /* counter for image files */
00699     bufrval_t* vals;
00700 
00701     /* sanity checks */
00702 
00703     if (des[ind] == (desc*) NULL || fo_ == (FILE*) NULL 
00704         || imgfile_ == (char* ) NULL) {
00705         fprintf (stderr, "Data not available for bufr_file_out!\n");
00706         return 0;
00707     }
00708 
00709     /* element descriptor */
00710 
00711     if (des[ind]->id == ELDESC) {
00712 
00713         d = &(des[ind]->el->d);
00714 
00715         /* output descriptor if not inside a sequence */
00716 
00717         if (!in_seq && ind != ccitt_special && !_replicating 
00718             && ind != add_f_special)
00719             fprintf (fo_, "%2d %2d %3d ", d->f, d->x, d->y);
00720 
00721         /* descriptor without data (1.x.y, 2.x.y) or ascii) */
00722 
00723         if (ind == _desc_special) {
00724 
00725             unit = des[ind]->el->unit;
00726 
00727             /* special treatment for ASCII data */
00728 
00729             if (unit != NULL && strcmp (unit, "CCITT IA5") == 0) {
00730                 fprintf (fo_, "       '");
00731                 if (!bufr_parse_out (d, 0, 0, bufr_char_to_file, 0)) {
00732                     return 0;
00733                 }
00734                 fprintf (fo_, "'\n");
00735                 nchars = des[ind]->el->dw / 8;                
00736             }
00737 
00738             /* only descriptor -> add newline */
00739             
00740             else if (!in_seq && !_replicating) {
00741                 fprintf (fo_, "\n");
00742             }
00743         }
00744 
00745         /* "normal" data */
00746 
00747         else { 
00748 
00749             /* check for missing values and flag tables */
00750 
00751             if (val == MISSVAL) {
00752                 strcpy (sval, "      missing");
00753             }
00754 #if BUFR_OUT_BIN
00755             else if (desc_is_flagtable (ind)) {
00756                 place_bin_values (val, ind, sval);
00757             }
00758 #endif
00759             else {
00760                 sprintf (sval, "%13.5f", val);
00761             }
00762 
00763             /* do we have a descriptor before the data element? */
00764 
00765             if (!in_seq && !_replicating && ind != add_f_special) {
00766                 fprintf (fo_, "%s            %s\n", 
00767                          sval, des[ind]->el->elname);
00768             }
00769             else {
00770                 if (!first_in_seq) 
00771                     fprintf (fo_, "          ");
00772 
00773                 fprintf (fo_, "%s  %2d %2d %3d %s\n", 
00774                          sval, d->f, d->x, d->y, des[ind]->el->elname);
00775                 first_in_seq = 0;
00776             }
00777         }
00778     } /* end if ("Element descriptor") */
00779 
00780     /* sequence descriptor */
00781 
00782     else if (des[ind]->id == SEQDESC) {
00783 
00784         d = &(des[ind]->seq->d);
00785 
00786         /* output descriptor if not inside another sequence descriptor */
00787 
00788         if (!in_seq && !_replicating)
00789             fprintf (fo_, "%2d %2d %3d ", d->f, d->x, d->y);
00790 
00791         /* check if bitmap or "normal" sequence descriptor */
00792 
00793         bitmap = 0;
00794 
00795         if (d->x == 21) {
00796             if (d->y >= 192 && d->y <= 197) {
00797                 bitmap = 1;
00798                 depth = 1;
00799             }
00800             else if (d->y == 200 || d->y == 202) {
00801                 bitmap = 1;
00802                 depth = 2;
00803             }
00804         }
00805         
00806         /* seqdesc is a special opera bitmap */
00807 
00808         if (bitmap && _opera_mode) {
00809 
00810             strcpy (fname, imgfile_);
00811 
00812             /* Add the counter to the filename */
00813             
00814             if (count != 0) {
00815                 sprintf (tmp, "%d", count);
00816                 strcat (fname, tmp);
00817             }
00818             count ++;
00819 
00820             /* read bitmap and run length decode to file */
00821 
00822             vals = bufr_open_val_array ();
00823             if (vals == (bufrval_t*) NULL) return 0;
00824 
00825             if (!bufr_parse_out (des[ind]->seq->del, 0, des[ind]->seq->nel - 1,
00826                                  bufr_val_to_global, 0)) {
00827                 bufr_close_val_array ();
00828                 return 0;
00829             }
00830 
00831             /* Runlength decode */
00832             
00833             if (!rldec_to_file (fname, vals->vals, depth, &nv)) { 
00834                 bufr_close_val_array ();
00835                 fprintf (stderr, "Error during runlength-compression.\n");
00836                 return 0;
00837             }
00838 
00839             if (in_seq || _replicating) 
00840                 fprintf (fo_, "        ");
00841 
00842             fprintf (fo_, "%s\n", fname);
00843 
00844             /* free array */
00845 
00846             bufr_close_val_array ();
00847             return 1;
00848         } 
00849         /* normal sequence descriptor - just call bufr_parse_out and
00850            remember that we are in a sequence */
00851         
00852         else {
00853             if (in_seq == 0)
00854                 first_in_seq = 1;
00855             in_seq ++;
00856             ok = bufr_parse_out (des[ind]->seq->del, 0, 
00857                                  des[ind]->seq->nel - 1, bufr_file_out, 1);
00858             in_seq --;
00859             return ok;
00860         }
00861     } /* if ("seqdesc") */
00862     return 1;
00863 }
00864 
00865 
00866 /*===========================================================================*/
00882 static int bufr_char_to_file (varfl val, int ind)
00883 
00884 
00885 {
00886     assert (ind == ccitt_special);
00887 
00888     if (fo_ == (FILE*) NULL) {
00889         fprintf (stderr, "Global file pointer not available!\n");
00890         return 0;
00891     }
00892     
00893     fprintf (fo_, "%c", (int) val);
00894     return 1;
00895 }
00896 
00897 /*===========================================================================*/
00910 static int bufr_input_char (varfl* val, int ind) {
00911 
00912     assert (ind == ccitt_special);
00913 
00914     if (char_ == NULL) {
00915         fprintf (stderr, "Global char pointer not available!\n");
00916         return 0;
00917     }
00918         
00919     /* check for correct string */
00920     
00921     if (*char_ != '\'') {
00922         fprintf (stderr, 
00923                  "Possible number of bits missmatch for ASCII data 1!\n");
00924         return 0;
00925     }
00926 
00927     /* check for correct number of characters */
00928 
00929     if (char_[cc_+1] == 0 || char_[cc_+1] == '\'') {
00930         fprintf (stderr, "Number of bits missmatch for ASCII data\n");
00931         return 0;
00932     }
00933 
00934     /* copy character to float */
00935 
00936     *val = (varfl) char_[cc_+1];
00937     cc_++;
00938 
00939 
00940     return 1;
00941 
00942 }
00943 
00944 /*===========================================================================*/
00954 static int desc_to_array (dd* d, bufrsrc_t* data)
00955 
00956 {
00957     int nd = data->ndesc;       /* number of data descriptors */
00958     dd* descs = data->descs;    /* array of data descriptors */
00959 
00960     if (nd > MAX_DESCS) {
00961         fprintf (stderr, "ERROR maximum number of descriptors exceeded!\n");
00962         return 0;
00963     }
00964 
00965     /* Allocate memory if not yet done */
00966 
00967     if (descs == (dd*) NULL) {
00968         descs = (dd *) malloc (MEMBLOCK * sizeof (dd));
00969         if (descs == (dd*) NULL) {
00970             fprintf (stderr, 
00971                      "Could not allocate memory for descriptor array!\n");
00972             return 0;
00973         }
00974                 memset (descs, 0, MEMBLOCK * sizeof (dd));
00975         nd = 0;
00976     }
00977 
00978     /* Check if memory block is large enough to hold new data 
00979        and reallocate memory if not */
00980 
00981     if (nd != 0 && nd % MEMBLOCK == 0) {
00982         descs = (dd *) realloc (descs, (nd + MEMBLOCK) * sizeof (dd));
00983         if (descs == (dd*) NULL) {
00984             fprintf (stderr, 
00985                      "Could not reallocate memory for descriptor array!\n");
00986             return 0;
00987         }
00988                 memset ((dd *) (descs + nd), 0, MEMBLOCK * sizeof (dd));
00989     }
00990 
00991     /* Add descriptor to array */
00992 
00993     memcpy ((dd*) (descs + nd), d, sizeof (dd));
00994     nd ++;
00995     data->ndesc = nd;
00996     data->descs = descs;
00997     return 1;
00998 }
00999 
01000 /*===========================================================================*/
01011 static int string_to_array (char* s, bufrsrc_t* bufr)
01012 
01013 {
01014     int ns = bufr->ndat;        /* number of data elements */
01015     bd_t* data =  bufr->data;     /* array of data elements */
01016     
01017 
01018     if (ns > MAX_DATA) {
01019         fprintf (stderr, "ERROR maximum number of data elements exceeded!\n");
01020         return 0;
01021     }
01022 
01023     /* Allocate memory if not yet done */
01024 
01025     if (data == (bd_t*) NULL) {
01026         data = (bd_t*) malloc (MEMBLOCK * sizeof(bd_t));
01027         if (data == (bd_t*) NULL) {
01028             fprintf (stderr, 
01029                      "Could not allocate memory for data array!\n");
01030             return 0;
01031         }
01032                 memset (data, 0, MEMBLOCK * sizeof(bd_t));
01033         ns = 0;
01034     }
01035 
01036     /* Check if memory block is large enough to hold new data 
01037        and reallocate memory if not */
01038 
01039     if (ns != 0 && ns % MEMBLOCK == 0) {
01040         data = (bd_t*) realloc (data, (ns + MEMBLOCK) * sizeof (bd_t));
01041         if (data == (bd_t*) NULL) {
01042             fprintf (stderr, 
01043                      "Could not reallocate memory for data array!\n");
01044             return 0;
01045         }
01046                 memset ((bd_t*) (data + ns), 0, MEMBLOCK * sizeof (bd_t));
01047     }
01048 
01049     /* Add descriptor to array */
01050 
01051     data[ns] = str_save (s);
01052     ns ++;
01053     bufr->ndat = ns;
01054     bufr->data = data;
01055     return 1;
01056 }
01057 /*===========================================================================*/
01067 static char *str_save(char *str)
01068 {
01069     register char *p;
01070     int l;
01071     
01072     /* get the string size */
01073     
01074     l = strlen(str) + 1;
01075 
01076     /* allocate memory */
01077         
01078     p = malloc(l);
01079     if (p == NULL) {
01080         fprintf (stderr, 
01081                  "Could not allocate memory for string!\n");
01082         return NULL;
01083     }
01084 
01085     /* copy string into memory */
01086     
01087     memcpy(p, str, l);
01088 
01089     /* return pointer to string */
01090     
01091     return p;
01092 }
01093 
01094 /*===========================================================================*/
01101 static void replace_bin_values (char *buf)
01102 
01103 
01104 
01105 {
01106   char *p, *q, *r;
01107   int bin_val, v, i;
01108   
01109   p = buf;
01110   while ((p = strstr (p + 1, " b")) != NULL) {
01111 
01112     /* check if that is really a binary value and get the end the the beginning of that value */
01113   
01114     q = p + 2;
01115     bin_val = 1;
01116     while (*q != 0 && *q != ' ') {
01117       if (*q != '0' && *q != '1') bin_val = 0;
01118       q ++;
01119     }
01120 
01121     /* If it is a binary value convert it to an integer */
01122 
01123     if (bin_val) {
01124       r = q; r --;
01125       v = 0;
01126       for (i = 0; r >= p; i ++, r --) {
01127         if (*r == '1') v |= 1 << i;
01128       }
01129 
01130       /* Finally replace the binary data be the integer */
01131 
01132       sprintf (p + 1, "%d", v);
01133     }
01134   }
01135 }
01136 /*===========================================================================*/
01145 #if BUFR_OUT_BIN
01146 static void place_bin_values (varfl val, int ind, char* buf) {
01147 
01148     int dwi, i, bit;
01149     assert (buf != NULL);
01150     dwi = des[ind]->el->dw;
01151 
01152     strcpy (buf, "");
01153     for (i = 0; i < 13 - 1 - dwi; i ++) strcat (buf, " ");
01154     strcat (buf, "b");
01155     for (i = dwi - 1; i >= 0; i --) {
01156         if (1 << i & (long) val) {
01157             bit = 1;
01158         } else {
01159             bit = 0;
01160         }
01161         sprintf (buf + strlen (buf), "%d", bit);
01162     }
01163 }
01164 #endif
01165 
01166 /* end of file */

Generated on Tue Dec 18 16:52:44 2007 for OPERA BUFR software by  doxygen 1.5.4