bufr2synop 0.24.0
bufr2tac_tablec.c
Go to the documentation of this file.
1/***************************************************************************
2 * Copyright (C) 2013-2018 by Guillermo Ballester Valor *
3 * gbv@ogimet.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20/*!
21 \file bufr2tac_tablec.c
22 \brief file with the code to read table C data (code and flag tables)
23 */
24#include "bufr2tac.h"
25
26/*!
27 \fn char * get_ecmwf_tablename(char *target, char type, char *bufrtables_dir, int ksec1[40])
28 \brief Get the complete pathname of a table file needed by a bufr message
29 \param target the resulting name
30 \param type a char with type, i.e, 'B', 'C', or 'D'
31 \param bufrtables_dir string with path to bufr file tables dir
32 \param ksec1 array of integer processed prevoiously by ecmwf bufr library
33 In ECMWF library the name of a table file is Kssswwwwwxxxxxyyyzzz.TXT , where
34 - K - type of table, i.e, 'B', 'C', or 'D'
35 - sss - Master table number (zero for WMO meteorological tables)
36 - wwwww - Originating sub-centre
37 - xxxxx - Originating centre
38 - yyy - Version number of master table used
39 - zzz - Version number of local table used
40
41 If standard WMO tables are used, the Originating centre xxxxx will be set to
42*/
43char * get_ecmwf_tablename ( char *target, char type, char *bufrtables_dir, int ksec1[40] )
44{
45 if ( 0 )
46 {
47 if ( ksec1[13] != 0 ) // case of not WMO tables
48 sprintf ( target,"%s%c%03d%05d%05d%03d%03d.TXT", bufrtables_dir, type, ksec1[13], ksec1[15], ksec1[2], ksec1[14], ksec1[7] );
49 else
50 sprintf ( target,"%s%c000%05d00000%03d%03d.TXT", bufrtables_dir, type, ksec1[15], ksec1[14], ksec1[7] );
51 }
52 else
53 {
54 //FIXME Some countries uses latest C tables instead of the version they said in bufr
55 sprintf ( target,"%s%c0000000000000019000.TXT", bufrtables_dir, type );
56 }
57 return target;
58}
59
60/*!
61 \fn int read_table_c(void)
62 \brief read a Table C file with code TABLE and flag descriptors
63*/
64int read_table_c ( char tablec[MAXLINES_TABLEC][92], size_t *nlines_tablec, char *bufrtables_dir, int ksec1[40] )
65{
66 char *c, file[256];
67 FILE *t;
68 size_t i = 0;
69
70 *nlines_tablec = 0;
71
72 get_ecmwf_tablename ( &file[0], 'C', bufrtables_dir, ksec1 );
73
74 if ( ( t = fopen ( file, "r" ) ) == NULL )
75 {
76 fprintf ( stderr,"Unable to open table C file '%s'\n", file );
77 return 0;
78 }
79
80 while ( fgets ( tablec[i], 90, t ) != NULL && i < MAXLINES_TABLEC )
81 {
82 // supress the newline
83 if ( ( c = strrchr ( tablec[i],'\n' ) ) != NULL )
84 *c = '\0';
85 i++;
86 }
87 fclose ( t );
88 *nlines_tablec = i;
89 //printf("file='%s', NLINES_TABLEC=%d\n", file,NLINES_TABLEC);
90 return i;
91}
92
93/*!
94 \fn char * get_explained_table_val(char *expl, size_t dim, struct bufr_descriptor *d, int ival)
95 \brief gets a string with the meaning of a value for a code table descriptor
96 \param expl string with resulting meaning
97 \param dim max length alowed for \a expl string
98 \param d pointer to the source descriptor
99 \param ival integer value for the descriptos
100
101 If something went wrong, it returns NULL . Otherwise it returns \a expl
102*/
103char * get_explained_table_val ( char *expl, size_t dim, char tablec[MAXLINES_TABLEC][92], size_t nlines_tablec, struct bufr_descriptor *d, int ival )
104{
105 char *c;
106 long nv, v, nl;
107 size_t i, j;
108
109 // Find first line for descriptor
110 for ( i = 0; i < nlines_tablec; i++ )
111 {
112 if ( tablec[i][0] != d->c[0] ||
113 tablec[i][1] != d->c[1] ||
114 tablec[i][2] != d->c[2] ||
115 tablec[i][3] != d->c[3] ||
116 tablec[i][4] != d->c[4] ||
117 tablec[i][5] != d->c[5] )
118 continue;
119 else
120 break;
121 }
122
123 if ( i == nlines_tablec )
124 {
125 //printf("Descriptor %s No encontrado\n", d->c);
126 return NULL;
127 }
128 //printf("Descriptor %s en linea %d\n", d->c, i);
129
130 // reads the amount of possible values
131 if ( tablec[i][7] != ' ' )
132 nv = strtol ( &tablec[i][7], &c, 10 );
133 else
134 return NULL;
135
136 // read a value
137 for ( j = 0; ( long ) j < nv && i < nlines_tablec ; i++ )
138 {
139 if ( tablec[i][12] != ' ' )
140 {
141 v = strtol ( &tablec[i][12], &c, 10 );
142 j++;
143 if ( v != ival )
144 continue;
145 break;
146 }
147 }
148
149 if ( ( long ) j == nv || i == nlines_tablec )
150 return NULL; // Value not found
151
152 // read how many lines for the descriptors
153 nl = strtol ( &tablec[i][21], &c, 10 );
154
155
156 // if match then we have finished the search
157 strcpy ( expl, &tablec[i][24] );
158 if ( nl > 1 )
159 {
160 for ( nv = 1 ; nv < nl; nv++ )
161 if ( ( strlen ( expl ) + strlen ( &tablec[i + nv][22] ) ) < dim )
162 strcat ( expl, &tablec[i + nv][22] );
163 }
164
165 return expl;
166}
167
168/*!
169 \fn char * get_explained_flag_val(char *expl, size_t dim, struct bufr_descriptor *d, unsigned long ival)
170 \brief gets a strung with the meaning of a value for a flag table descriptor
171 \param expl string with resulting meaning
172 \param dim max length alowed for \a expl string
173 \param d pointer to the source descriptor
174 \param ival integer value for the descriptos
175
176 Remember that in FLAG tables for bufr, bit 1 is most significant and N the less one. Bit N only is set to
177 1 when all others are also set to one, i.e. in case of missing value.
178
179 If something went wrong, it returns NULL . Otherwise it returns \a expl
180*/
181char * get_explained_flag_val ( char *expl, size_t dim, char tablec[MAXLINES_TABLEC][92], size_t nlines_tablec, struct bufr_descriptor *d, unsigned long ival )
182{
183 char *c, *s;
184 unsigned long test, test0;
185 unsigned long nb, nx, v, nl;
186 size_t i, j;
187
188 // Find first line for descriptor
189 for ( i = 0; i < nlines_tablec; i++ )
190 {
191 if ( tablec[i][0] != d->c[0] ||
192 tablec[i][1] != d->c[1] ||
193 tablec[i][2] != d->c[2] ||
194 tablec[i][3] != d->c[3] ||
195 tablec[i][4] != d->c[4] ||
196 tablec[i][5] != d->c[5] )
197 continue;
198 else
199 break;
200 }
201
202 if ( i == nlines_tablec )
203 {
204 //printf("Descriptor %s No encontrado\n", d->c);
205 return NULL;
206 }
207 //printf("Descriptor %s en linea %d\n", d->c, i);
208
209 // reads the amount of possible bits
210 if ( tablec[i][7] != ' ' )
211 nb = strtol ( &tablec[i][7], &c, 10 );
212 else
213 return NULL;
214
215 // read a value
216 s = expl;
217 s[0] = '\0';
218
219 for ( j = 0, test0 = 2; j < nb && i < nlines_tablec ; i++ )
220 {
221 if ( tablec[i][12] != ' ' )
222 {
223 v = strtol ( &tablec[i][12], &c, 10 ); // v is the bit number
224 j++;
225
226 // case 0 with meaning
227 if ( v == 0 )
228 {
229 test0 = 1;
230 if ( ival == 0 )
231 {
232 nl = strtol ( &tablec[i][21], &c, 10 );
233 if ( strlen ( expl ) && ( strlen ( expl ) + 1 ) < dim )
234 s += sprintf ( s, "|" );
235 s += sprintf ( s,"%s", &tablec[i][24] );
236 if ( nl > 1 )
237 {
238 for ( nx = 1 ; nx < nl; nx++ )
239 if ( ( strlen ( expl ) + strlen ( &tablec[i + nx][22] ) ) < dim )
240 {
241 s += sprintf ( s, "%s", &tablec[i + nx][22] );
242 }
243 }
244 return expl;
245 }
246 }
247
248 test = test0 << ( nb - v );
249
250 if ( v && ( test & ival ) != 0 )
251 {
252 // bit match
253 // read how many lines for the descriptors
254 nl = strtol ( &tablec[i][21], &c, 10 );
255 if ( strlen ( expl ) && ( strlen ( expl ) + 1 ) < dim )
256 s += sprintf ( s, "|" );
257 s += sprintf ( s,"%s", &tablec[i][24] );
258 if ( nl > 1 )
259 {
260 for ( nx = 1 ; nx < nl; nx++ )
261 if ( ( strlen ( expl ) + strlen ( &tablec[i + nx][22] ) ) < dim )
262 {
263 s += sprintf ( s, "%s", &tablec[i + nx][22] );
264 }
265 }
266
267 }
268 else
269 continue;
270 }
271 }
272
273 // if match then we have finished the search
274
275 return expl;
276}
Include header file for binary bufr2tac.
char * get_ecmwf_tablename(char *target, char type, char *bufrtables_dir, int ksec1[40])
Get the complete pathname of a table file needed by a bufr message.
char * get_explained_flag_val(char *expl, size_t dim, char tablec[MAXLINES_TABLEC][92], size_t nlines_tablec, struct bufr_descriptor *d, unsigned long ival)
int read_table_c(char tablec[MAXLINES_TABLEC][92], size_t *nlines_tablec, char *bufrtables_dir, int ksec1[40])
char * get_explained_table_val(char *expl, size_t dim, char tablec[MAXLINES_TABLEC][92], size_t nlines_tablec, struct bufr_descriptor *d, int ival)
#define MAXLINES_TABLEC
The maximum expected lines in a Table C file, legacy def used from ECMWF.
Definition: bufrdeco.h:110
BUFR descriptor.
Definition: bufrdeco.h:409
char c[12]
Definition: bufrdeco.h:414