bufr.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.C
00024 IDENT:         $Id: bufr.c,v 1.12 2007/12/18 15:50:00 fuxi Exp $
00025 
00026 AUTHOR:        Konrad Koeck
00027                Institute of Communication and Wave Propagation, 
00028                Technical University Graz, Austria
00029 
00030 VERSION NUMBER:3.0
00031 
00032 DATE CREATED:  18-DEC-2001
00033 
00034 STATUS:        DEVELOPMENT FINISHED
00035 
00036 
00037 FUNCTIONAL DESCRIPTION:
00038 -----------------------
00039 The Functions in this file can be used to encode/decode general BUFR-messages.
00040 The file bufr.h must be included to get the function-prototyping for the
00041 functions in this file. More details can be found in the descriptions of
00042 the functions.
00043 
00044 AMENDMENT RECORD:
00045 
00046 ISSUE       DATE            SCNREF      CHANGE DETAILS
00047 -----       ----            ------      --------------
00048 V2.0        18-DEC-2001     Koeck       Initial Issue
00049 
00050 $Log: bufr.c,v $
00051 Revision 1.12  2007/12/18 15:50:00  fuxi
00052 removed debugging output
00053 
00054 Revision 1.11  2007/12/18 14:40:13  fuxi
00055 added licence header
00056 
00057 Revision 1.10  2007/12/07 08:34:27  fuxi
00058 update to version 3.0
00059 
00060 Revision 1.9  2006/07/20 10:19:44  fuxi
00061 added debugging info
00062 
00063 Revision 1.8  2006/07/19 08:59:47  fuxi
00064 added debugging options
00065 
00066 Revision 1.7  2005/04/04 15:38:32  helmutp
00067 update to version 2.3
00068 no datawidth or scale change for 0 31 y descriptors
00069 subcenter and generating center
00070 
00071 Revision 1.6  2003/03/28 14:03:20  helmutp
00072 fixed missval for pixel values
00073 
00074 Revision 1.5  2003/03/27 17:17:39  helmutp
00075 update to version 2.2
00076 
00077 Revision 1.4  2003/03/13 17:10:55  helmutp
00078 use descriptor sort function instead of linear search
00079 
00080 Revision 1.3  2003/03/06 17:12:32  helmutp
00081 update to version 2.1
00082 
00083 Revision 1.2  2003/02/28 14:39:54  helmutp
00084 fixed return value in read_bufr_msg
00085 
00086 Revision 1.1  2003/02/28 13:41:12  helmutp
00087 Initial revision
00088 
00089 
00090 --------------------------------------------------------------------------- */
00091 
00099 #define BUFR_MAIN
00100 
00101 #include <stdlib.h>
00102 #include <math.h>
00103 #include <stdio.h>
00104 #include <string.h>
00105 #include <assert.h>
00106 #include <time.h>
00107 #include "desc.h"
00108 #include "bufr.h"
00109 #include "bitio.h"
00110 #include "rlenc.h"
00111 
00112 /*===========================================================================*/
00113 /* globals */
00114 /*===========================================================================*/
00115 
00116 
00117 /*===========================================================================*/
00118 /* default values */
00119 /*===========================================================================*/
00120 
00121 /* Define default values for the originating center (OPERA) 
00122    and the versions of master (WMO) and local (OPERA) table */
00123 #define SUBCENTER 255
00124 #define GENCENTER 255
00125 #define VMTAB 11
00126 #define VLTAB 4
00127 
00128 /*===========================================================================*/
00129 /* internal data                                                             */
00130 /*===========================================================================*/
00131 
00132 #define MAXREPCOUNT 300      /* Max. replication count */
00133 #define MAX_ADDFIELDS 50     /* Maximum number of nested associated fields */
00134 
00135 /* The following variables are used to hold date/time-info of the
00136    last BUFR-message created. */
00137 
00138 static long year_, mon_, day_, hour_, min_;
00139 static int af_[MAX_ADDFIELDS];  /* remember associated fields for nesting */
00140 static int naf_ = 0;            /* current number of associated field */
00141 static int datah_ = -1;          /* bitstream-handle for data-section */
00142 static bufrval_t* vals_ = NULL;  /* structure for holding data values */
00143 
00144 /*===========================================================================*/
00145 /* internal functions                                                        */
00146 /*===========================================================================*/
00147 
00148 static int bufr_val_to_datasect (varfl val, int ind);
00149 static int bufr_val_from_datasect (varfl *val, int ind);
00150 static int get_lens (char* buf, long len, int* secl);
00151 
00152 
00153 /*===========================================================================*/
00154 /* functions */
00155 /*===========================================================================*/
00156 
00163 void bufr_clean (void)
00164 
00165 
00166 {
00167   free_descs();
00168 }
00169 
00170 /*===========================================================================*/
00224 int bufr_create_msg (dd* descs, int ndescs, varfl* vals, void **datasec, 
00225                      void **ddsec, size_t *datasecl, size_t *ddescl)
00226 
00227 
00228 {
00229     bufrval_t* valarray = NULL;
00230     int ok, desch;
00231     bufr_t msg;
00232 
00233     memset (&msg, 0, sizeof (bufr_t));
00234 
00235     year_ = mon_ = day_ = hour_ = min_ = 0;
00236 
00237     /* Open two bitstreams, one for data-descriptors, one for data */
00238 
00239     desch = bufr_open_descsec_w ();
00240 
00241     ok = (desch >= 0);
00242 
00243     if (ok)
00244         ok = (bufr_open_datasect_w () >= 0);
00245 
00246     /* output data to the data descriptor bitstream */
00247 
00248     if (ok)
00249         bufr_out_descsec (descs, ndescs, desch);
00250 
00251     /* set global array */
00252 
00253     if (ok) {
00254         valarray = bufr_open_val_array ();
00255         ok = (valarray != (bufrval_t*) NULL);
00256     }
00257 
00258     if (ok) {
00259         valarray->vals = vals;
00260         valarray->vali = 0;
00261     }
00262 
00263     /* output data to the data-section */
00264 
00265     if (ok) {
00266         ok = bufr_parse_in (descs, 0, ndescs - 1, bufr_val_from_global, 0);
00267         valarray->vals = (varfl*) NULL;
00268         bufr_close_val_array ();
00269     }
00270 
00271     /* close bitstreams and write data to bufr message */
00272 
00273     bufr_close_descsec_w (&msg, desch);
00274 
00275     *ddsec = msg.sec[3];
00276     *ddescl = (size_t) msg.secl[3];
00277 
00278     bufr_close_datasect_w (&msg);
00279 
00280     *datasec = msg.sec[4];
00281     *datasecl = (size_t) msg.secl[4];
00282     
00283     return ok;
00284 }
00285 /*===========================================================================*/
00325 int bufr_encode_sections34 (dd* descs, int ndescs, varfl* vals, bufr_t* msg)
00326 
00327 
00328 {
00329     char *datasec = NULL; 
00330     char *ddsec = NULL;
00331     size_t datasecl = 0;
00332     size_t ddescl = 0;
00333     int ret;
00334 
00335     if (msg == (bufr_t*) NULL) {
00336         fprintf (stderr, "Error writing data to BUFR message\n");
00337         return 0;
00338     }
00339     
00340     ret = bufr_create_msg (descs, ndescs, vals, (void**) &datasec, 
00341                            (void**) &ddsec, &datasecl, &ddescl);
00342 
00343     msg->sec[3] = ddsec;
00344     msg->sec[4] = datasec;
00345     msg->secl[3] = ddescl;
00346     msg->secl[4] = datasecl;
00347 
00348     return ret;
00349 }
00350 
00351 /*===========================================================================*/
00369 int bufr_read_file (bufr_t* msg, char* file) {
00370 
00371     FILE* fp;           /* file pointer to bufr file */
00372     char* bm;           /* pointer to memory holding bufr file */
00373     int len;
00374 
00375     /* open file */
00376 
00377     fp = fopen (file, "rb");
00378     if (fp == NULL) {
00379         fprintf (stderr, "unable to open file '%s'\n", file);
00380         return 0;
00381     }
00382 
00383     /* get length of message */
00384 
00385     fseek (fp, 0L, SEEK_END);
00386     len = ftell (fp);
00387     fseek (fp, 0L, SEEK_SET);
00388 
00389     /* allocate memory and read message */
00390 
00391     bm = (char *) malloc ((size_t) len);
00392     if (bm == NULL) {
00393         fprintf (stderr, 
00394                  "unable to allocate %d bytes to hold BUFR-message !\n", len);
00395         fclose (fp);
00396         return 0;
00397     }
00398     if (fread (bm, 1, (size_t) len, fp) != (size_t) len) {
00399         fprintf (stderr, "Error reading BUFR message from file!\n");
00400         fclose (fp);
00401         free (bm);
00402         return 0;
00403     }
00404 
00405     fclose (fp);
00406 
00407     /* get raw bufr data */
00408 
00409     if (!bufr_get_sections (bm, len, msg)) {
00410         free (bm);
00411         return 0;
00412     }
00413 
00414     free (bm);
00415     return 1;
00416 }
00417 /*===========================================================================*/
00437 int bufr_get_sections (char* bm, int len, bufr_t* msg) 
00438 
00439 {
00440     int co, l;
00441     char* buf;          /* pointer to beginning of BUFR message */
00442     char* b7777;        /* pointer to end of BUFR message */
00443     int i;
00444 
00445     /* Search for "BUFR" */
00446 
00447     buf = NULL;
00448     for (l = 0; l < len - 4 && buf == NULL; l ++) {
00449         if (*(bm + l)     == 'B' && 
00450             *(bm + l + 1) == 'U' &&
00451             *(bm + l + 2) == 'F' &&
00452             *(bm + l + 3) == 'R') buf = bm + l;
00453     }
00454     if (buf == NULL) {
00455         fprintf (stderr, "'BUFR' not found in BUFR-message !\n");
00456         return 0;
00457     }
00458 
00459     /* Check for the ending "7777" */
00460 
00461     b7777 = NULL;
00462     for (l = 0; l < len - 3 && b7777 == NULL; l ++) {
00463         if (*(bm + l)     == '7' && 
00464             *(bm + l + 1) == '7' &&
00465             *(bm + l + 2) == '7' &&
00466             *(bm + l + 3) == '7') b7777 = bm + l;
00467     }
00468     if (b7777 == NULL) {
00469         fprintf (stderr, "'7777' not found in BUFR-message !\n");
00470         return 0;
00471     }
00472 
00473     /* Get length of all 6 sections */
00474     
00475     if (!get_lens (buf, len, msg->secl)) {
00476         fprintf (stderr, "unable to read lengths of BUFR-sections !\n");
00477         return 0;
00478     }
00479 
00480     /* allocate memory for each section */
00481 
00482     co = 0;
00483     for (i = 0; i < 6; i ++) {
00484         msg->sec[i] = (char *) malloc ((size_t) msg->secl[i] + 1);
00485         if (msg->sec[i] == NULL) {
00486             fprintf (stderr, 
00487                      "unable to allocate %d bytes for section %d !\n", 
00488                      msg->secl[i], i);
00489             return 0;
00490         }
00491         memcpy (msg->sec[i], buf + co, (size_t) msg->secl[i]);
00492         co += msg->secl[i];
00493     }
00494     return co;
00495 }
00496 
00497 /*===========================================================================*/
00514 int bufr_out_descsec (dd *descp, int ndescs, int desch)
00515 
00516 {
00517     unsigned long l;
00518     int i;
00519 
00520     /* Append data descriptor to data descriptor section */
00521 
00522     for (i = 0; i < ndescs; i ++) {
00523         l = (unsigned long) descp->f;
00524         if (!bitio_o_append (desch, l, 2)) return 0;
00525         l = (unsigned long) descp->x;
00526         if (!bitio_o_append (desch, l, 6)) return 0;
00527         l = (unsigned long) descp->y;
00528         if (!bitio_o_append (desch, l, 8)) return 0;
00529         descp ++;
00530     }
00531 
00532     return 1;
00533 }
00534 /*===========================================================================*/
00546 int bufr_open_descsec_w () {
00547 
00548     size_t n;
00549     int desch;
00550 
00551     /* open bitstream */
00552 
00553     desch = bitio_o_open ();
00554     if (desch == -1) {
00555         bitio_o_close (desch, &n);
00556         return -1;
00557     }
00558 
00559     /* output default data */
00560 
00561     bitio_o_append (desch, 0L, 24);  /* length of descriptor-section, set to 
00562                                          0. The correct length is set by 
00563                                          close_descsec_w. */
00564     bitio_o_append (desch, 0L, 8);   /* reserved octet, set to 0 */
00565     bitio_o_append (desch, 1L, 16);  /* number of data subsets */
00566     bitio_o_append (desch, 128L, 8); /* observed non-compressed data */
00567     return desch;
00568 }
00569 /*===========================================================================*/
00570 
00584 void bufr_close_descsec_w(bufr_t* bufr, int desch) {
00585 
00586     int n;
00587     size_t st;
00588 
00589     if (desch == -1 || bufr == (bufr_t*) NULL) return;
00590 
00591     /* get current length */
00592 
00593     n = (int)  bitio_o_get_size (desch);
00594 
00595     /* number of bytes must be an even number */
00596 
00597         if (n % 2 != 0) bitio_o_append (desch, 0L, 8);
00598 
00599     /* write length of section to beginning */
00600     
00601     n = (int) bitio_o_get_size (desch);
00602     bitio_o_outp (desch, (long) n, 24, 0L);
00603 
00604     /* close bitstream and return pointer */
00605 
00606     bufr->sec[3] = (char *) bitio_o_close (desch, &st);
00607     bufr->secl[3] = (int) st;
00608 }
00609 
00610 
00611 /*===========================================================================*/
00622 int setup_sec0125 (char* sec[], size_t secl[], sect_1_t s1)
00623 
00624 {
00625     bufr_t msg;
00626     int i;
00627 
00628     for (i = 0; i < 6; i++) {
00629         msg.secl[i] = (int) secl[i];
00630         msg.sec[i] = sec[i];
00631     }
00632 
00633     if (!bufr_encode_sections0125 (&s1, &msg))
00634         return 0;
00635 
00636     for (i = 0; i < 6; i++) {
00637         secl[i] = (size_t) msg.secl[i];
00638         sec[i]  = msg.sec[i];
00639     }
00640 
00641     return 1;
00642 
00643 }
00644 /*===========================================================================*/
00657 int save_sections (char** sec, size_t* secl, char* buffile)
00658 
00659 {
00660     FILE *fp;
00661     int i;
00662 
00663     /* open file */
00664 
00665     fp = fopen (buffile, "wb");
00666     if (fp == NULL) {
00667         fprintf (stderr, "Could not open file %s!\n", buffile);
00668         return 0;
00669     }
00670 
00671     /* output all sections */
00672 
00673     for (i = 0; i < 6; i ++) {
00674         if (fwrite (sec[i], 1, secl[i], fp) != secl[i]) {
00675             fclose (fp);
00676             fprintf (stderr, 
00677                      "An error occoured writing '%s'. File is invalid !\n", 
00678                      buffile);
00679             return 0;
00680         }
00681     }
00682 
00683     /* close file and return */
00684 
00685     fclose (fp);
00686     return 1;
00687 }
00688 
00689 
00690 /*===========================================================================*/
00691 
00735 int bufr_parse_new (dd *descs, int start, int end, 
00736                     int (*inputfkt) (varfl *val, int ind),
00737                     int (*outputfkt) (varfl val, int ind),
00738                     int callback_all_descs) {
00739 
00740     int i, j, nrep, nd;
00741     int ind;                    /* current descriptor index */
00742     varfl d;                    /* one float value to process */
00743     dd descr;                   /* current descriptor */
00744     static int level = 0;       /* recursion level */
00745     char* tmp;
00746     int operator_qual;          /* flag that indicates data descriptor
00747                                    operator qualifiers (0 31 y) */
00748 
00749 
00750     /* increase recursion level */
00751 
00752     level ++;
00753 
00754     /* parse all descriptors */
00755 
00756     for (ind = start; ind <= end; ind++) {
00757 
00758         /* get current descriptor */
00759 
00760         memcpy (&descr, descs + ind, sizeof (dd));
00761 
00762         if (descr.f == 0) {
00763 
00764             /* descriptor is element descriptor */
00765 
00766             if ((i = get_index (ELDESC, &descr)) < 0) {
00767 
00768                 /* invalid descriptor */
00769 
00770                 fprintf (stderr, 
00771                        "Unknown data descriptor found: F=%d, X=%d, Y=%d !\n", 
00772                          descr.f, descr.x, descr.y);
00773                 return 0;
00774             }
00775 
00776             /* Special Treatment for ASCII data */
00777 
00778             if (strcmp (des[i]->el->unit, "CCITT IA5") == 0) {
00779                 
00780                 /* call outputfkt to ouput descriptor and allow
00781                    use of proper callback for ascii */
00782                 
00783                 if (callback_all_descs) {
00784                     varfl v;
00785                     des[_desc_special]->el->d.f = descr.f;
00786                     des[_desc_special]->el->d.x = descr.x;
00787                     des[_desc_special]->el->d.y = descr.y;
00788                     des[_desc_special]->el->dw = des[i]->el->dw;
00789                     tmp = des[_desc_special]->el->unit;
00790                     des[_desc_special]->el->unit = des[i]->el->unit;
00791                     if (!(*inputfkt) (&v, _desc_special)) return 0;
00792                     if (!(*outputfkt) (0, _desc_special)) return 0;
00793                     des[_desc_special]->el->unit = tmp;
00794                     continue;
00795                 }
00796 
00797                 /*loop through all bytes of the character 
00798                   string and store them using the special descriptor 
00799                   we have created. */
00800 
00801                 for (j = 0; j < des[i]->el->dw / 8; j ++) { 
00802 
00803                     if (!(*inputfkt) (&d, ccitt_special)) return 0;
00804                     if (!(*outputfkt) (d, ccitt_special)) return 0;
00805                 }
00806                 continue;
00807             }
00808 
00809             /* Write data to output function. If an "Add associated field" 
00810                has been set we have to store additional items, 
00811                except it is a 0 31 y descritor */
00812 
00813             if (_bufr_edition < 3) {
00814                 operator_qual = (des[i]->el->d.x == 31 && 
00815                                  des[i]->el->d.y == 21);
00816             } else {
00817                 operator_qual = des[i]->el->d.x == 31;
00818             }
00819 
00820             if (addfields != 0 && !operator_qual) {
00821                     
00822                 /* set special descriptor */
00823                 
00824                 des[add_f_special]->el->scale  = 0;
00825                 des[add_f_special]->el->refval = 0;
00826                 des[add_f_special]->el->dw     = addfields;
00827 
00828                 /* process data */
00829 
00830                 if (!(*inputfkt) (&d, add_f_special)) return 0;
00831                 if (!(*outputfkt) (d, add_f_special)) return 0;
00832             }
00833 
00834             /* finally process data for the given descriptor */
00835                 
00836             if (!(*inputfkt) (&d, i)) return 0;
00837             if (!(*outputfkt) (d, i)) return 0;
00838 
00839             /* Check if this is date/time info and keep this data for 
00840                further requests in bufr_get_date_time */
00841 
00842             if (descr.x == 4) switch (descr.y)
00843                 {
00844                 case 1: 
00845                     if (_bufr_edition >= 4) {
00846                         year_ = (long) d; 
00847                     }
00848                     else {
00849                         year_ = (long) ((int) (d-1) %100 + 1);
00850                     }
00851                     break;
00852                 case 2: mon_  = (long) d; break;
00853                 case 3: day_  = (long) d; break;
00854                 case 4: hour_ = (long) d; break;
00855                 case 5: min_  = (long) d; break;
00856                 }
00857             continue;
00858         } /* end if (... ELDESC ...) */
00859 
00860         else if (descr.f == 3) {
00861 
00862             /* If data-descriptor is a sequence descriptor -> call this 
00863                function again for each entry in the sequence descriptor 
00864                or call user defined callback if parse_seqdescs is not set 
00865             */
00866 
00867             if ((i = get_index (SEQDESC, &descr)) < 0) {
00868 
00869                 /* invalid descriptor */
00870 
00871                 fprintf (stderr, 
00872                        "Unknown data descriptor found: F=%d, X=%d, Y=%d !\n", 
00873                          descr.f, descr.x, descr.y);
00874                 return 0;
00875             }
00876 
00877             if (!callback_all_descs) {
00878                 if (!bufr_parse_new (des[i]->seq->del, 0, 
00879                                      des[i]->seq->nel - 1,
00880                                      inputfkt, outputfkt, 0)) {
00881                     return 0;
00882                 }
00883             }
00884             else {
00885                 if (!inputfkt (&d, i)) return 0;
00886                 if (!outputfkt (0, i)) return 0;
00887             }
00888 
00889             continue;
00890         }
00891 
00892         else if (descr.f == 1) {
00893 
00894             /* replication descriptor */
00895 
00896             nd   = descr.x;
00897             nrep = descr.y;
00898 
00899             /* output descriptor if not in input mode */
00900             
00901             if (callback_all_descs) {
00902 
00903                 des[_desc_special]->el->d.f = descr.f;
00904                 des[_desc_special]->el->d.x = descr.x;
00905                 des[_desc_special]->el->d.y = descr.y;
00906                 if (!(*outputfkt) (0, _desc_special)) return 0;
00907             }
00908 
00909             /* if there is a delayed replication factor */
00910 
00911             if (nrep == 0) {
00912 
00913                 /* get number of replications, remember it and write it out*/
00914 
00915                 ind++;
00916                 memcpy (&descr, descs + ind, sizeof (dd));
00917                 if ((i = get_index (ELDESC, &descr)) < 0) {
00918                     fprintf (stderr, 
00919                         "Unknown data descriptor found: F=%d, X=%d, Y=%d !\n", 
00920                              descr.f, descr.x, descr.y);
00921                     return 0;
00922                 }
00923                 if (!(*inputfkt) (&d, i)) return 0;
00924                 nrep = (int) d;
00925                 if (!(*outputfkt) (nrep, i)) return 0;
00926             }
00927 
00928             
00929             /* do the replication now */
00930 
00931             for (i = 0; i < nrep; i ++) {
00932                 _replicating = i;
00933                 if (!bufr_parse_new (descs, ind + 1, ind + nd, inputfkt, 
00934                                      outputfkt, callback_all_descs))
00935                     return 0;
00936             }
00937             _replicating = 0;
00938             ind += nd;
00939             continue;
00940         }
00941 
00942         else if (descr.f == 2) {
00943 
00944             /* data modification descriptor */
00945 
00946             if (callback_all_descs) {
00947 
00948                 des[_desc_special]->el->d.f = descr.f;
00949                 des[_desc_special]->el->d.x = descr.x;
00950                 des[_desc_special]->el->d.y = descr.y;
00951                 if (!(*outputfkt) (0, _desc_special)) return 0;
00952             }
00953 
00954             switch (descr.x) {
00955 
00956                 /* change of datawidth, valid until cancelled by 2 01 000 */
00957             case 1:   
00958                 if (descr.y == 0) {
00959                     dw = 128;
00960                 } else {
00961                     dw = descr.y; 
00962                 }
00963                 continue;
00964                 
00965                 /* change of scale, valid until cancelled by 2 02 000 */
00966             case 2:
00967                 if (descr.y == 0) {
00968                     sc = 128;
00969                 } else {
00970                     sc = descr.y;
00971                 }
00972                 continue;
00973 
00974             /* case 3: */
00975                 /* modyify reference values */
00976 
00977                 /* add associated field, valid until canceled by 2 04 000 */
00978             case 4:
00979                 if (descr.y == 0) {
00980                     naf_ --;
00981                     if (naf_ < 0) {
00982                         fprintf (stderr, "Illegal call of 2 04 000!\n");
00983                         return 0;
00984                     }
00985                     addfields = af_[naf_];
00986                 }
00987                 else {
00988                     af_[naf_] = addfields;
00989                     naf_ ++;
00990                     if (naf_ > MAX_ADDFIELDS) {
00991                         fprintf (stderr, 
00992                             "Maximum number of associated fields reached!\n");
00993                         return 0;
00994                     }
00995                     addfields += descr.y;
00996                 }
00997                 continue;
00998 
00999                 /* invalid descriptor */
01000             default:
01001                 fprintf (stderr, 
01002                        "Unknown data descriptor found: F=%d, X=%d, Y=%d !\n", 
01003                          descr.f, descr.x, descr.y);
01004                 return 0;
01005             }
01006         }
01007         else {
01008             
01009             /* invalid descriptor */
01010             
01011             fprintf (stderr, 
01012                      "Unknown data descriptor found: F=%d, X=%d, Y=%d !\n", 
01013                      descr.f, descr.x, descr.y);
01014             return 0;
01015         }
01016         
01017     } /* end for loop over all descriptors */
01018 
01019     /* decrease recursing level */
01020 
01021     level --;
01022     return 1;
01023 
01024 }
01025 /*===========================================================================*/
01052 int bufr_parse (dd* descs, int start, int end, varfl *vals, unsigned *vali,
01053                 int (*userfkt) (varfl val, int ind)) {
01054     int ok;
01055     bufrval_t* bufrvals;
01056 
01057     bufrvals = bufr_open_val_array ();
01058 
01059     if (bufrvals == (bufrval_t*) NULL) {
01060         return 0;
01061     }
01062 
01063     bufrvals->vals = vals;
01064     bufrvals->vali = *vali;
01065     ok = bufr_parse_new (descs, start, end, bufr_val_from_global, userfkt, 
01066                          0);
01067     *vali = bufrvals->vali;
01068 
01069     bufrvals->vals = (varfl*) NULL;
01070     bufr_close_val_array ();
01071     return ok;
01072 }
01073 
01074 
01075 /*===========================================================================*/
01114 int bufr_parse_in  (dd *descs, int start, int end, 
01115                     int (*inputfkt) (varfl *val, int ind),
01116                     int callback_descs) {
01117 
01118   return bufr_parse_new (descs, start, end, inputfkt,  
01119                          bufr_val_to_datasect, callback_descs); 
01120 }
01121 
01122 /*===========================================================================*/
01160 int bufr_parse_out  (dd *descs, int start, int end, 
01161                      int (*outputfkt) (varfl val, int ind),
01162                      int callback_all_descs) {
01163 
01164     return bufr_parse_new (descs, start, end, bufr_val_from_datasect,  
01165                            outputfkt, callback_all_descs); 
01166 }
01167 
01168 
01169 /*===========================================================================*/
01184 void bufr_sect_1_from_file (sect_1_t* s1, char* file)
01185 {
01186   FILE *fp;
01187   char buf[200];
01188   int val, count;
01189 
01190   /* Set section 1 to default vales */
01191 
01192   s1->mtab    = 0;
01193   s1->subcent  = SUBCENTER;
01194   s1->gencent  = GENCENTER;
01195   s1->updsequ = 0;
01196   s1->opsec   = 0;
01197   s1->dcat    = 6;
01198   s1->idcatst = 0;
01199   s1->dcatst  = 0;
01200   s1->vmtab   = VMTAB;
01201   s1->vltab   = VLTAB;
01202   s1->year    = 999;
01203   s1->mon     = 999;
01204   s1->day     = 999;
01205   s1->hour    = 999;
01206   s1->min     = 999;
01207   s1->sec     = 0;
01208 
01209 /* open file and read data */
01210 
01211   fp = fopen (file, "r");
01212   if (fp == NULL) {
01213       return;
01214   }
01215 
01216   count = 0;
01217   while (fgets (buf, 200, fp) != NULL) {
01218     if (sscanf (buf, "%d", &val) == 1) {
01219         switch (count) {
01220         case 0:  s1->mtab    = val; break;
01221         case 1:  s1->subcent  = val; break;
01222         case 2:  s1->gencent  = val; break;
01223         case 3:  s1->updsequ = val; break;
01224         case 4:  s1->opsec   = val; break;
01225         case 5:  s1->dcat    = val; break;
01226         case 6:  s1->dcatst  = val; break;
01227         case 7:  s1->vmtab   = val; break;
01228         case 8:  s1->vltab   = val; break;
01229         case 9:  s1->year    = val; break;
01230         case 10:  s1->mon     = val; break;
01231         case 11: s1->day     = val; break;
01232         case 12: s1->hour    = val; break;
01233         case 13: s1->min     = val; break;
01234             /* new fields for edition 4 */
01235         case 14: s1->sec     = val; break;
01236         case 15: s1->idcatst = val; break;
01237         }
01238         count ++;
01239     }
01240   }
01241   fclose (fp);
01242 }
01243 
01244 /*===========================================================================*/
01266 int bufr_encode_sections0125 (sect_1_t* s1, bufr_t* msg)
01267 {
01268 
01269     char** sec = msg->sec;
01270     int* secl = msg->secl;
01271 
01272     size_t st;
01273     int i, hand;
01274     long len;
01275     time_t t;
01276     struct tm t1;
01277 
01278     /* encode section 1. */
01279 
01280     hand = bitio_o_open ();
01281     if (hand == -1) return 0;
01282     if (_bufr_edition >= 4) {
01283          bitio_o_append (hand, 22L, 24);         /* length of section */
01284     }
01285     else {
01286         bitio_o_append (hand, 18L, 24);         /* length of section */
01287     }
01288     bitio_o_append (hand, s1->mtab, 8);     /* master table used */
01289     if (_bufr_edition >= 4) {
01290         bitio_o_append (hand, s1->gencent, 16);  /* originating/generating 
01291                                                    center */
01292         bitio_o_append (hand, s1->subcent, 16);  /* originating/generating
01293                                                    subcenter */
01294     }
01295     else {
01296         bitio_o_append (hand, s1->subcent, 8);  /* originating subcenter */
01297         bitio_o_append (hand, s1->gencent, 8);  /* originating/generating 
01298                                                    center */
01299     }
01300     bitio_o_append (hand, s1->updsequ, 8);  /* original BUFR message */
01301     bitio_o_append (hand, s1->opsec, 8);    /* no optional section */
01302     bitio_o_append (hand, s1->dcat, 8);     /* message type */
01303     if (_bufr_edition >= 4)
01304         bitio_o_append (hand, s1->idcatst, 8);   /* international message 
01305                                                     subtype */
01306     bitio_o_append (hand, s1->dcatst, 8);   /* local message subtype */
01307     bitio_o_append (hand, s1->vmtab, 8);    /* version number of master table*/
01308     bitio_o_append (hand, s1->vltab, 8);    /* version number of local table */
01309 
01310     /* if not given in section1-file take system time */
01311 
01312     if (s1->year == 999) {   
01313         time (&t);
01314         memcpy (&t1, localtime (&t), sizeof (struct tm));
01315         if (_bufr_edition >= 4) {
01316             bitio_o_append (hand, (long) t1.tm_year + 1900, 16); /* year */
01317         }
01318         else {
01319             t1.tm_year = (t1.tm_year - 1) % 100 + 1;
01320             bitio_o_append (hand, (long) t1.tm_year, 8);      /* year */
01321         }
01322         bitio_o_append (hand, (long) t1.tm_mon + 1, 8);       /* month */
01323         bitio_o_append (hand, (long) t1.tm_mday, 8);          /* day */
01324         bitio_o_append (hand, (long) t1.tm_hour, 8);          /* hour */
01325         bitio_o_append (hand, (long) t1.tm_min, 8);           /* minute */
01326         if (_bufr_edition >= 4) 
01327             bitio_o_append (hand, (long) t1.tm_sec, 8);       /* seconds */
01328     }
01329     else {
01330         if (_bufr_edition >= 4) {
01331             bitio_o_append (hand, s1->year, 16);              /* year */
01332         }
01333         else {
01334             s1->year = (s1->year - 1) % 100 + 1;
01335             bitio_o_append (hand, s1->year, 8);                /* year */
01336         }
01337         bitio_o_append (hand, s1->mon, 8);                     /* month */
01338         bitio_o_append (hand, s1->day, 8);                     /* day */
01339         bitio_o_append (hand, s1->hour, 8);                    /* hour */
01340         bitio_o_append (hand, s1->min, 8);                     /* minute */
01341         if (_bufr_edition >= 4)
01342             bitio_o_append (hand, s1->sec, 8);                 /* second */
01343     }
01344     if (_bufr_edition < 4)
01345         bitio_o_append (hand, 0L, 8);                      /* filler (0) */
01346     sec[1] = (char *) bitio_o_close (hand, &st);
01347     secl[1] = (int) st;
01348 
01349     /* there is no section 2 */
01350 
01351     sec[2] = NULL;
01352     secl[2] = 0;
01353 
01354     /* create section 5 */
01355 
01356     hand = bitio_o_open ();
01357     for (i = 0; i < 4; i ++) bitio_o_append (hand, (long) '7', 8);
01358     sec[5] = (char *) bitio_o_close (hand, &st);
01359     secl[5] = (int) st;
01360 
01361     /* calculate total length of BUFR-message */
01362 
01363     secl[0] = 8;     /* section 0 not yet setup */
01364     len = 0L;
01365     for (i = 0; i < 6; i ++) len += (long) secl[i];
01366   
01367 
01368     /* create section 0 */
01369 
01370     hand = bitio_o_open ();
01371     if (hand == -1) return 0;
01372     bitio_o_append (hand, (unsigned long) 'B', 8);
01373     bitio_o_append (hand, (unsigned long) 'U', 8);
01374     bitio_o_append (hand, (unsigned long) 'F', 8);
01375     bitio_o_append (hand, (unsigned long) 'R', 8);
01376     bitio_o_append (hand, len, 24);          /* length of BUFR-message */
01377     bitio_o_append (hand, (long) _bufr_edition, 8);  /* BUFR edition number */
01378     sec[0] = (char *) bitio_o_close (hand, &st);
01379     secl[0] = (int) st;
01380     return 1;
01381 }
01382 /*===========================================================================*/
01396 int bufr_write_file (bufr_t* msg, char* file)
01397 {
01398 
01399     char** sec = msg->sec; 
01400     int* secl = msg->secl;
01401     FILE *fp;
01402     int i;
01403 
01404     /* open file */
01405 
01406     fp = fopen (file, "wb");
01407     if (fp == NULL) {
01408         fprintf (stderr, "Could not open file %s!\n", file);
01409         return 0;
01410     }
01411 
01412     /* output all sections */
01413 
01414     for (i = 0; i < 6; i ++) {
01415         if (fwrite (sec[i], 1, (size_t) secl[i], fp) != (size_t) secl[i]) {
01416             fclose (fp);
01417             fprintf (stderr, 
01418              "An error occoured during writing '%s'. File is invalid !\n", 
01419                      file);
01420             return 0;
01421 
01422         }
01423     }
01424 
01425     /* close file and return */
01426 
01427     fclose (fp);
01428     return 1;
01429 }
01430 
01431 /*===========================================================================*/
01432 
01445 void bufr_free_data (bufr_t* msg) {
01446 
01447     int i;
01448 
01449     if (msg == (bufr_t*) NULL) return;
01450 
01451     for (i = 0; i <= 5; i++) {
01452         if (msg->sec[i] != NULL) 
01453             free (msg->sec[i]);
01454     }
01455     memset (msg, 0, sizeof (bufr_t));
01456 }
01457 
01458 
01459 
01460 /*===========================================================================*/
01473 int bufr_check_fxy(dd *d, int ff, int xx, int yy) {
01474 
01475     if (d == (dd*) NULL) return -1;
01476     return (d->f == ff) && (d->x == xx) && (d->y == yy);
01477 }
01478 
01479 
01480 
01481 /*===========================================================================*/
01495 int bufr_decode_sections01 (sect_1_t* s1, bufr_t* msg)
01496 
01497 {
01498     int h, edition;
01499     unsigned long l;
01500 
01501     /* section 0 */
01502     h = bitio_i_open (msg->sec[0], (size_t) msg->secl[0]);
01503     if (h == -1) return 0;
01504 
01505     bitio_i_input (h, &l, 32);                  /* BUFR */
01506     bitio_i_input (h, &l, 24);                  /* length of BUFR-message */
01507     bitio_i_input (h, &l, 8); edition = l;      /* BUFR edition number */
01508     bitio_i_close (h);
01509  
01510     /* section 1 */
01511 
01512     h = bitio_i_open (msg->sec[1], (size_t) msg->secl[1]);
01513     if (h == -1) return 0;
01514   
01515     bitio_i_input (h, &l, 24);                 /* length of section */
01516 
01517     bitio_i_input (h, &l, 8);  s1->mtab = l;    /* master table used */
01518     if (edition >= 4) {
01519         bitio_i_input (h, &l, 16);  s1->gencent = l; /* generating center */
01520         bitio_i_input (h, &l, 16);  s1->subcent = l; /*originating subcenter */
01521     }
01522     else {
01523         bitio_i_input (h, &l, 8);  s1->subcent = l; /* originating subcenter */
01524         bitio_i_input (h, &l, 8);  s1->gencent = l; /* generating center */
01525     }
01526     bitio_i_input (h, &l, 8);  s1->updsequ = l; /* original BUFR message */
01527     bitio_i_input (h, &l, 8);  s1->opsec = l;   /* no optional section */
01528     bitio_i_input (h, &l, 8);  s1->dcat = l;    /* message type */
01529     if (edition >= 4)
01530         bitio_i_input (h, &l, 8);  s1->idcatst = l;  /* international message 
01531                                                         sub type */
01532     bitio_i_input (h, &l, 8);  s1->dcatst = l;  /* local message subtype */
01533     bitio_i_input (h, &l, 8);  s1->vmtab = l;   /* version number of master 
01534                                                    table used */
01535     bitio_i_input (h, &l, 8);  s1->vltab = l;   /* version number of local 
01536                                                    table used */
01537     if (edition >= 4) {
01538         bitio_i_input (h, &l, 16);  s1->year = l;    /* year */
01539     } else {
01540         bitio_i_input (h, &l, 8);  s1->year = l;    /* year */
01541     }
01542     bitio_i_input (h, &l, 8);  s1->mon = l;     /* month */
01543     bitio_i_input (h, &l, 8);  s1->day = l;     /* day */
01544     bitio_i_input (h, &l, 8);  s1->hour = l;    /* hour */
01545     bitio_i_input (h, &l, 8);  s1->min = l;     /* minute */
01546     if (edition >= 4)
01547         bitio_i_input (h, &l, 8);  s1->sec = l;    /* second */
01548     bitio_i_close (h);
01549 
01550     /* set edition */
01551 
01552     _bufr_edition = edition;
01553 
01554     return 1;
01555 }
01556 
01557 /*===========================================================================*/
01569 int bufr_sect_1_to_file (sect_1_t* s1, char* file) {
01570 
01571     FILE* fp;
01572 
01573     fp = fopen (file, "w");
01574     if (fp == NULL) {
01575         fprintf (stderr, "unable to open output file for section 1 !\n");
01576         return 0;
01577     }
01578 
01579     fprintf (fp, "%5d    master table used                  \n", s1->mtab);
01580     fprintf (fp, "%5d    originating subcenter              \n", s1->subcent);
01581     fprintf (fp, "%5d    generating center                  \n", s1->gencent);
01582     fprintf (fp, "%5d    original BUFR message              \n", s1->updsequ);
01583     fprintf (fp, "%5d    no optional section                \n", s1->opsec);
01584     fprintf (fp, "%5d    message type                       \n", s1->dcat);
01585     fprintf (fp, "%5d    local message subtype              \n", s1->dcatst);
01586     fprintf (fp, "%5d    version number of master table used\n", s1->vmtab);
01587     fprintf (fp, "%5d    version number of local table used \n", s1->vltab);
01588     fprintf (fp, "%5d    year                               \n", s1->year);
01589     fprintf (fp, "%5d    month                              \n", s1->mon);
01590     fprintf (fp, "%5d    day                                \n", s1->day);
01591     fprintf (fp, "%5d    hour                               \n", s1->hour);
01592     fprintf (fp, "%5d    minute                             \n", s1->min);
01593     /* new fields for bufr edition 4 */
01594     if (_bufr_edition >= 4) {
01595         fprintf (fp, "%5d    second                             \n", s1->sec);
01596         fprintf (fp, "%5d    international message subtype      \n", 
01597                  s1->idcatst);
01598     }
01599 
01600     fclose (fp);
01601 
01602     return 1;
01603 }
01604  
01605 /*===========================================================================*/
01645 int bufr_read_msg (void* datasec, void* ddsec, size_t datasecl, size_t ddescl,
01646                    dd** descr, int* ndescs, varfl** vals, size_t* nvals)
01647 
01648 
01649 {
01650     int ok = 0, desch;
01651     dd *d;
01652     bufr_t msg;
01653     bufrval_t* bufrvals;
01654 
01655     memset (&msg, 0, sizeof (bufr_t));
01656 
01657     msg.sec[3] = ddsec;
01658     msg.secl[3] = (int) ddescl;
01659     msg.sec[4] = datasec;
01660     msg.secl[4] = (int) datasecl;
01661 
01662     /* open bitstreams for section 3 and 4 */
01663 
01664     desch = bufr_open_descsec_r (&msg); 
01665     if (desch < 0) 
01666         return 0;
01667 
01668     if (bufr_open_datasect_r (&msg) < 0) {
01669         bufr_close_descsec_r (desch);
01670         return 0;
01671     }
01672 
01673     /* calculate number of data descriptors  */
01674     
01675     *ndescs = bufr_get_ndescs (&msg);
01676 
01677     /* allocate memory and read data descriptors from bitstream */
01678 
01679     ok = bufr_in_descsec (descr, *ndescs, desch);
01680 
01681     /* Input data from data-section according to the data-descriptors */
01682 
01683     *vals = NULL;
01684     *nvals = 0;
01685     d = *descr;
01686 
01687     bufrvals = bufr_open_val_array ();
01688 
01689     if (bufrvals == (bufrval_t*) NULL) {
01690         ok = 0;
01691     }
01692 
01693     if (ok) {
01694         ok = bufr_parse_out (d, 0, *ndescs - 1, bufr_val_to_global, 0);
01695         if (!ok)
01696             fprintf (stderr, "Error reading data from data-section !\n");
01697 
01698         *vals = bufrvals->vals;
01699         *nvals = (size_t) bufrvals->nvals;
01700         bufrvals->vals = (varfl*) NULL;
01701         bufr_close_val_array ();
01702     }
01703 
01704     /* close bitstreams */
01705 
01706     bufr_close_descsec_r (desch);
01707     bufr_close_datasect_r ();
01708 
01709     return ok;
01710 }
01711 
01712 /*===========================================================================*/
01728 int bufr_in_descsec (dd** descs, int ndescs, int desch) {
01729 
01730     int err, i;
01731     unsigned long l = 0;
01732     dd* d;
01733 
01734     if (desch < 0) {
01735         fprintf (stderr, "Descriptor handle not available! \n");
01736         return 0;
01737     }
01738 
01739 
01740     d = *descs = (dd *) malloc (ndescs * sizeof (dd));
01741     if (*descs == (dd*) NULL) {
01742         fprintf (stderr, "Unable to allocate memory for data descriptors !\n");
01743         return 0;
01744     }
01745 
01746     for (i = 0; i < ndescs; i ++) {
01747         err = 0;
01748         err = err || !bitio_i_input (desch, &l, 2);
01749         d->f = (unsigned char) l;
01750         if (!err) err = err || !bitio_i_input (desch, &l, 6);
01751         d->x = (unsigned char) l;
01752         if (!err) err = err || !bitio_i_input (desch, &l, 8);
01753         d->y = (unsigned char) l;
01754         if (err) {
01755             fprintf (stderr, 
01756                      "Number of bits for descriptor-section exceeded !\n");
01757             free (*descs);
01758             *descs = (dd*) NULL;
01759             return 0;
01760         }
01761         d ++;
01762     }
01763     return 1;
01764 }
01765 /*===========================================================================*/
01780 int bufr_open_descsec_r (bufr_t* msg) {
01781     
01782     unsigned long l;
01783     int i, desch;
01784 
01785     /* open bitstream */
01786 
01787     desch = bitio_i_open (msg->sec[3], msg->secl[3]);
01788 
01789     if (desch == -1) {
01790         bitio_i_close (desch);
01791         return -1;
01792     }
01793 
01794     /* skip trailing 7 octets (56 bits) */
01795 
01796     for (i = 0; i < 56; i ++) bitio_i_input (desch, &l, 1);
01797 
01798     return desch;
01799 }
01800 
01801 
01802 /*===========================================================================*/
01814 void bufr_close_descsec_r (int desch) {
01815 
01816     if (desch == -1) return;
01817     bitio_i_close (desch);
01818 }
01819 
01820 /*===========================================================================*/
01836 int val_to_array (varfl** vals, varfl v, size_t* nvals)
01837 
01838 {
01839   static unsigned int nv;         /* Number of values already read from bitstream */
01840   static unsigned int memsize;    /* Current size of memory-block holding data-values */
01841   varfl *d;
01842 
01843 /* Allocate memory if not yet done */
01844 
01845   if (*vals == NULL) {
01846     *vals = (varfl *) malloc (MEMBLOCK * sizeof (varfl));
01847     if (*vals == NULL) return 0;
01848                 memset (*vals, 0, MEMBLOCK * sizeof (varfl));
01849     nv = 0;
01850     memsize = MEMBLOCK;
01851   }
01852 
01853 /* Check if memory block is large anough to hold new data */
01854 
01855   if (memsize == nv) {
01856     *vals = (varfl *) realloc (*vals, (memsize + MEMBLOCK) * sizeof (varfl));
01857     if (*vals == NULL) return 0;
01858                 memset ((char *) (*vals + memsize), 0, MEMBLOCK * sizeof (varfl));
01859     memsize += MEMBLOCK;
01860     if (memsize - 1 > (~(unsigned int) 0) / sizeof (varfl)) {
01861       fprintf (stderr, "VAL_TO_ARRAY failed in file %s, line %d\n", __FILE__, __LINE__);
01862       fprintf (stderr, "Try to define varfl as float in file desc.h \n");
01863       return 0;
01864     }
01865   }
01866 
01867 /* Add value to array */
01868 
01869   d = *vals;
01870   *(d + nv) = v;
01871   nv ++;
01872   *nvals = nv;
01873   return 1;
01874 }
01875 
01876 /*===========================================================================*/
01894 int bufr_val_to_array (varfl** vals, varfl v, int* nv)
01895 {
01896     /* Allocate memory if not yet done */
01897 
01898     if (*vals == (varfl*) NULL) {
01899         *vals = (varfl *) malloc (MEMBLOCK * sizeof (varfl));
01900         if (*vals == (varfl*) NULL) {
01901             fprintf (stderr, "Could not allocate memory for value array!\n");
01902             return 0;
01903         }
01904                 memset (*vals, 0, MEMBLOCK * sizeof (varfl));
01905         *nv = 0;
01906     }
01907 
01908     /* Check if memory block is large anough to hold new data */
01909 
01910     if (*nv != 0 && *nv % MEMBLOCK == 0) {
01911         *vals = (varfl*) realloc (*vals, (*nv + MEMBLOCK) * sizeof (varfl));
01912         if (*vals == (varfl*) NULL) {
01913             fprintf (stderr, "Could not allocate memory for value array!\n");
01914             return 0;
01915         }
01916                 memset ((varfl*) (*vals + *nv), 0, MEMBLOCK * sizeof (varfl));
01917     }
01918 
01919 
01920     /* Add value to array */
01921 
01922     (*vals)[*nv] = v;
01923     (*nv)++;
01924     return 1;
01925 }
01926 
01927 /*===========================================================================*/
01943 int bufr_desc_to_array (dd* descs, dd d, int* ndescs)
01944 {
01945 
01946     if (*ndescs >= MAX_DESCS) {
01947         fprintf (stderr, "Maximum number of descriptors exceeded!\n");
01948         return 0;
01949     }
01950 
01951 
01952     /* Add descriptor to array */
01953 
01954     descs[(*ndescs)++] = d;
01955     return 1;
01956 }
01957 
01958 
01959 /*===========================================================================*/
01974 int bufr_get_ndescs (bufr_t* msg) {
01975 
01976     if (msg == (bufr_t*) NULL) {
01977         fprintf (stderr, "Error in bufr_get_ndescs!\n");
01978         return -1;
01979     }
01980     return (((msg->secl[3] - 7)* 8) / 16);  
01981 }
01982 
01983 /*===========================================================================*/
02000 void bufr_get_date_time (long *year, long *mon, long *day, long *hour,
02001                          long *min)
02002 
02003 
02004 {
02005   *year = year_;
02006   *mon  = mon_;
02007   *day  = day_;
02008   *hour = hour_;
02009   *min  = min_;
02010 }
02011 
02012 /*===========================================================================*/
02013 /* callback functions */
02014 /*===========================================================================*/
02015 
02016 
02034 static int bufr_val_to_datasect (varfl val, int ind)
02035 
02036 
02037 {
02038     unsigned long l;
02039     int ret, wi, scale, ccitt, no_change = 0;
02040 
02041     assert (datah_ >= 0);
02042 
02043     ret = 1;
02044   
02045     /* No output for special descriptors and sequence descs*/
02046 
02047     if (ind == _desc_special || des[ind]->id == SEQDESC) return 1;
02048 
02049     /* No data width or scale change for 0 31 y, code tables, flag tables
02050        and ascii data */
02051 
02052     if (_bufr_edition < 3) {
02053         
02054         no_change = (des[ind]->el->d.f == 0 && des[ind]->el->d.x == 31);
02055     }
02056     else {
02057         ccitt = (strcmp (des[ind]->el->unit, "CCITT IA5") == 0 || 
02058                  ind == ccitt_special);
02059         no_change = ((des[ind]->el->d.f == 0 && des[ind]->el->d.x == 31) ||
02060                      ccitt || desc_is_codetable(ind) || desc_is_flagtable(ind) ||
02061                      ind == add_f_special);
02062     }
02063 
02064     if (no_change) {
02065         wi = des[ind]->el->dw;
02066         scale = des[ind]->el->scale;
02067     }
02068     else {
02069         wi = des[ind]->el->dw + dw - 128;
02070         scale = des[ind]->el->scale + sc - 128;
02071     }
02072 
02073     /* If this is a missing value set all bits to 1 */
02074     
02075     if (val == MISSVAL) {
02076         l = 0xffffffff;
02077         if (bitio_o_append (datah_, l, wi) == -1) ret = 0;
02078     }
02079 
02080     /* Else it is a "normal" value */
02081 
02082     else {
02083         l = (unsigned long) (val * pow (10.0, (varfl) scale) 
02084                              - des[ind]->el->refval + 0.5);  
02085         /* + 0.5 to round to integer values */
02086 
02087         if (bitio_o_append (datah_, l, wi) == -1) ret = 0;
02088 
02089         /* check if data width was large enough to hold data to be coded */
02090 
02091         if (l >> wi != 0) {
02092             fprintf (stderr, 
02093   "WARNING: Tried to code the value %ld to %d bits (Datadesc.=%2d%3d%4d) !\n", 
02094                      l, wi, des[ind]->el->d.f, des[ind]->el->d.x, 
02095                      des[ind]->el->d.y);
02096             fprintf (stderr, "         Decoding will fail !\n");
02097         }
02098     }
02099 
02100     return ret;
02101 }
02102 
02103 /*===========================================================================*/
02116 int bufr_open_datasect_w() {
02117     size_t n;
02118 
02119     if (datah_ >= 0) {
02120         fprintf (stderr, "Global data handle not available.\n");
02121         return -1;
02122     }
02123 
02124     /* open bitstream */
02125 
02126     datah_ = bitio_o_open ();
02127     if (datah_ == -1) {
02128         bitio_o_close (datah_, &n);
02129         return -1;
02130     }
02131 
02132     /* output default data */
02133 
02134     bitio_o_append (datah_, 0L, 24);  /* Length of section (correct value 
02135                                          stored by close_datasect_w) */
02136     bitio_o_append (datah_, 0L, 8);   /* reserved octet, set to 0 */
02137     return datah_;
02138 }
02139 
02140 /*===========================================================================*/
02154 int bufr_open_datasect_r (bufr_t* msg) {
02155     
02156     unsigned long l;
02157     int i;
02158 
02159     if (datah_ >= 0) {
02160         fprintf (stderr, "Global data handle not available.\n");
02161         return -1;
02162     }
02163 
02164     /* open bitstream */
02165 
02166     datah_ = bitio_i_open (msg->sec[4], (size_t) msg->secl[4]);
02167 
02168     if (datah_ == -1) {
02169         bitio_i_close (datah_);
02170         return -1;
02171     }
02172 
02173     /* skip trailing 4 octets (32 bits) */
02174 
02175     for (i = 0; i < 32; i ++) bitio_i_input (datah_, &l, 1);
02176 
02177     return datah_;
02178 }
02179 /*===========================================================================*/
02192 /* write length of section 4 and close bitstream */
02193 
02194 void bufr_close_datasect_w(bufr_t* msg) {
02195 
02196     int n;
02197     size_t st;
02198 
02199     if (datah_ == -1 || msg == (bufr_t*) NULL) return;
02200 
02201     /* get current length */
02202 
02203     n = (int) bitio_o_get_size (datah_);
02204 
02205     /* number of bytes must be an even number */
02206 
02207         if (n % 2 != 0) bitio_o_append (datah_, 0L, 8);
02208 
02209     /* write length of section to beginning */
02210     
02211     n = (int) bitio_o_get_size (datah_);
02212     bitio_o_outp (datah_, (long) n, 24, 0L);
02213 
02214     /* close bitstream and return pointer */
02215 
02216     msg->sec[4] = (char *) bitio_o_close (datah_, &st);
02217     msg->secl[4] = (int) st;
02218     datah_ = -1;
02219 }
02220 
02221 /*===========================================================================*/
02230 void bufr_close_datasect_r () {
02231 
02232     if (datah_ == -1) return;
02233     bitio_i_close (datah_);
02234     datah_ = -1;
02235 }
02236 /*===========================================================================*/
02252 int bufr_val_from_global (varfl *val, int ind) {
02253 
02254     assert (val != (varfl*) NULL);
02255     assert (vals_ != NULL);
02256     assert (vals_->vals != NULL);
02257 
02258     /* No input for special descriptors and sequence descs*/
02259 
02260     if (ind == _desc_special || des[ind]->id == SEQDESC) return 1;
02261 
02262     *val = *(vals_->vals + vals_->vali++);
02263     return 1;
02264 
02265 }
02266 
02267 
02268 /*===========================================================================*/
02284 int bufr_val_to_global (varfl val, int ind) {
02285 
02286     assert (vals_ != (bufrval_t*) NULL);
02287 
02288     /* No output for special descriptors and sequence descs*/
02289 
02290     if (ind == _desc_special || des[ind]->id == SEQDESC) return 1;
02291 
02292     return bufr_val_to_array (&(vals_->vals), val, &(vals_->nvals));
02293 }
02294 
02295 
02296 /*===========================================================================*/
02310 bufrval_t* bufr_open_val_array () {
02311 
02312 
02313     if (vals_ != (bufrval_t*)  NULL) {
02314         fprintf (stderr, "Value array not empty!\n");
02315         return (bufrval_t*) NULL;
02316     }
02317     vals_ = malloc (sizeof (bufrval_t));
02318 
02319     if (vals_ == (bufrval_t*)  NULL) {
02320         fprintf (stderr, "Error allocating memory for Value array!\n");
02321         return (bufrval_t*) NULL;
02322     }
02323     memset (vals_, 0, sizeof (bufrval_t));
02324     return vals_;
02325 }
02326 /*===========================================================================*/
02337 void bufr_close_val_array () {
02338 
02339     if (vals_ == (bufrval_t*) NULL) return;
02340         
02341     if (vals_->vals != (varfl*) NULL) {
02342         free (vals_->vals);
02343         vals_->vals = (varfl*) NULL;
02344     }
02345     free (vals_);
02346     vals_ = (bufrval_t*) NULL;
02347 }
02348 
02349 /*===========================================================================*/
02368 static int bufr_val_from_datasect (varfl *val, int ind)
02369 
02370 
02371 {
02372     int data_width;
02373     int scale, no_change = 0, ccitt;
02374     unsigned long l, mv;
02375 
02376     assert (datah_ >= 0);
02377 
02378     /* No input for special descriptors and sequence descs*/
02379 
02380     if (ind == _desc_special || des[ind]->id == SEQDESC) return 1;
02381 
02382     /* No data width or scale change for 0 31 y, code tables, flag tables
02383        and ascii data */
02384 
02385     if (_bufr_edition < 3) {
02386         
02387         no_change = (des[ind]->el->d.f == 0 && des[ind]->el->d.x == 31);
02388     }
02389     else {
02390         ccitt = (strcmp (des[ind]->el->unit, "CCITT IA5") == 0 || 
02391                  ind == ccitt_special);
02392         no_change = ((des[ind]->el->d.f == 0 && des[ind]->el->d.x == 31) ||
02393                         ccitt || desc_is_codetable(ind) || desc_is_flagtable(ind) ||
02394                         ind == add_f_special);
02395     }
02396 
02397     if (no_change) {
02398         data_width = des[ind]->el->dw;
02399         scale = des[ind]->el->scale;
02400     }
02401     else {
02402         data_width = des[ind]->el->dw + dw - 128;
02403         scale = des[ind]->el->scale + sc - 128;
02404     }
02405     
02406     if (!bitio_i_input (datah_, &l, data_width)) {
02407       fprintf (stderr, "Error reading data from bitstrem !\n");
02408       return 0;
02409     }
02410   
02411     /* Check for a missing value. Missval for operator qualifiers is not 
02412        possible */
02413     /* no missval for pixel values in bitmaps */
02414   
02415     mv = (1 << data_width) - 1;
02416 
02417     if (l == mv && des[ind]->el->d.x != 31 && 
02418         !(des[ind]->el->d.x == 30 && des[ind]->el->d.y <= 4 && _opera_mode) &&
02419         !(des[ind]->el->d.x == 13 && des[ind]->el->d.y == 11 && _opera_mode) &&
02420         !(des[ind]->el->d.x == 21 && des[ind]->el->d.y == 14 && _opera_mode)) {
02421             *val = MISSVAL;
02422     }
02423     else {
02424         *val = ((varfl) l + des[ind]->el->refval) / 
02425             pow (10.0, (varfl) (scale));
02426     }
02427     return 1;
02428 }
02429 
02430 /*===========================================================================*/
02431 /* local functions */
02432 /*===========================================================================*/
02433 
02434 
02435 
02436 /*===========================================================================*/
02449 static int get_lens (char* buf, long len, int* secl)
02450 
02451 {
02452     int h, co, i, totlen, lens0;
02453     unsigned long l;
02454     long sum;
02455 
02456     /* The length of section 0 is constant, but get the length of the
02457        whole BUFR message */
02458 
02459     h = bitio_i_open (buf, 8);
02460     bitio_i_input (h, &l, 32);        /* skip that 'BUFR' */
02461     bitio_i_input (h, &l, 24);        /* length of whole message */
02462     bitio_i_close (h);
02463     lens0 = l;
02464 
02465     secl[0] = 8;
02466     co = 8;
02467     sum = 8;
02468 
02469     /* length of section 1 */
02470 
02471     h = bitio_i_open (buf + co, 20);
02472     if (h == -1) return 0;
02473     bitio_i_input (h, &l, 24);
02474     secl[1] = (int) l;
02475     co += secl[1];
02476     bitio_i_close (h);
02477     sum += l;
02478     if (sum > len) goto err;
02479 
02480     /* there is no section 2 */
02481 
02482     secl[2] = 0;
02483 
02484     /* length of section 3 */
02485 
02486     h = bitio_i_open (buf + co, 20);
02487     if (h == -1) return 0;
02488     bitio_i_input (h, &l, 24);
02489     secl[3] = (int) l;
02490     co += secl[3];
02491     bitio_i_close (h);
02492     sum += l;
02493     if (sum > len) goto err;
02494 
02495     /* length of section 4 */
02496 
02497     h = bitio_i_open (buf + co, 20);
02498     if (h == -1) return 0;
02499     bitio_i_input (h, &l, 24);
02500     secl[4] = (int) l;
02501     co += secl[4];
02502     bitio_i_close (h);
02503     sum += l;
02504     if (sum > len) goto err;
02505 
02506     /* length of section 5 is constant */
02507 
02508     secl[5] = 4;
02509     sum += 4;
02510     if (sum > len) goto err;
02511 
02512     /* Check the total length of the message against the sum of the lengths 
02513        of the sections. */
02514 
02515     totlen = 0;
02516     for (i = 0; i < 6; i ++) {
02517 #ifdef VERBOSE
02518         fprintf (stderr, "section %d length = %d\n", i, secl[i]);
02519 #endif
02520         totlen += secl[i];
02521     }
02522     if (totlen != lens0) {
02523         fprintf (stderr, 
02524            "WARNING: Total length of message doesn't match with the lengths\n"
02525                      "of the individual sections !\n");
02526     }
02527 
02528     return 1;
02529 
02530     /* Lengths of BUFR-sections not correct */
02531 
02532  err:
02533     fprintf (stderr, "Lengths of BUFR-sections > size of input-file !\n");
02534     return 0;
02535 }
02536 
02537 /* end of file */

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