bufr2synop 0.24.0
bufrdeco_tableD.c
Go to the documentation of this file.
1/***************************************************************************
2 * Copyright (C) 2013-2022 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 bufrdeco_tableD.c
22 \brief file with the code to read table D data (code and flag tables)
23 */
24#include "bufrdeco.h"
25
26/*!
27 \fn int bufr_read_tableD ( struct bufrdeco *b )
28 \brief Reads a file with table D content according with WMO csv format
29 \param b pointer to a target struct \ref bufrdeco
30 \return If succeded return 0, otherwise 1
31*/
32int bufr_read_tableD ( struct bufrdeco *b )
33{
34 char aux[32], *c;
35 char *tk[16];
36 int nt;
37 FILE *t;
38 buf_t ix = 0;
39 buf_t i = 0;
40 int j0, nj = 0;
41 char oldkey[8];
42 char caux[256];
43 char laux[CSV_MAXL];
44 struct bufr_descriptor desc;
45 struct bufr_tableD *td;
46
47 //bufrdeco_assert (b != NULL);
48
49 td = &(b->tables->d);
50 if ( td->path[0] == 0 )
51 {
52 return 1;
53 }
54
55 // Check if we've already readed this table.
56 if ( strcmp ( td->path, td->old_path ) == 0 )
57 {
58#ifdef __DEBUG
59 printf ("# Reused table %s\n", td->path);
60#endif
61 return 0; // all done
62 }
63
64 strcpy ( caux, td->path );
65 memset ( td, 0, sizeof ( struct bufr_tableD ) );
66 strcpy ( td->path,caux );
67 if ( ( t = fopen ( td->path, "r" ) ) == NULL )
68 {
69 snprintf ( b->error, sizeof (b->error),"Unable to open table D file '%s'\n", td->path );
70 return 1;
71 }
72
73 // read first line, it is ignored
74 fgets ( laux, CSV_MAXL, t );
75
76 oldkey[0] = 0;
77 j0 = 0;
78
79 while ( fgets ( laux, CSV_MAXL, t ) != NULL && i < BUFR_MAXLINES_TABLED )
80 {
81 // Parse line
82 //printf("%s\n",laux);
83 if ( parse_csv_line ( &nt, tk, laux ) < 0 || ( nt != 2 && nt != 4) )
84 {
85 snprintf ( b->error, sizeof (b->error),"Error parsing csv line from table D file '%s' found %d tokens in line %u\n", td->path, nt, i );
86 return 1;
87 }
88
89 // item fields
90 strcpy(td->item[i].key, tk[0]);
91 strcpy(td->item[i].key2, tk[1]);
92
93 if (nt == 4 && tk[2][0])
94 strcpy (td->item[i].description, tk[2]);
95 else
96 td->item[i].description[0] = 0;
97
98 if (nt == 4 && tk[3][0])
99 strcpy(td->item[i].description2, tk[3]);
100 else
101 td->item[i].description2[0] = 0;
102
103 if ( strcmp ( oldkey, tk[0] ) )
104 {
105 if ( oldkey[0] )
106 {
107 // write number of descriptors in emulated ECMWF line
108 sprintf ( aux, "%s%3d", oldkey, nj );
109 td->l[j0][1] = aux[0];
110 td->l[j0][2] = aux[1];
111 td->l[j0][3] = aux[2];
112 td->l[j0][4] = aux[3];
113 td->l[j0][5] = aux[4];
114 td->l[j0][6] = aux[5];
115 td->l[j0][7] = aux[6];
116 td->l[j0][8] = aux[7];
117 td->l[j0][9] = aux[8];
118 }
119 j0 = i;
120 nj = 1;
121 }
122 else
123 {
124 nj++;
125 }
126 strcpy ( oldkey, tk[0] );
127
128 ix = strtoul ( tk[0], &c, 10 );
129 uint32_t_to_descriptor ( &desc, ix );
130
131 if ( td->num[desc.x] == 0 )
132 {
133 td->x_start[desc.x] = i; // marc the start
134 }
135 ( td->num[desc.x] ) ++;
136
137 // Now emule ECMWF format
138 sprintf ( td->l[i], " %s", tk[1] );
139 i++;
140 }
141 fclose ( t );
142
143 // Last sequence
144 sprintf ( aux, "%s%3d", oldkey, nj );
145 td->l[j0][1] = aux[0];
146 td->l[j0][2] = aux[1];
147 td->l[j0][3] = aux[2];
148 td->l[j0][4] = aux[3];
149 td->l[j0][5] = aux[4];
150 td->l[j0][6] = aux[5];
151 td->l[j0][7] = aux[6];
152 td->l[j0][8] = aux[7];
153 td->l[j0][9] = aux[8];
154
155 td->nlines = i;
156 td->wmo_table = 1;
157 strcpy ( td->old_path, td->path ); // store latest path
158 return 0;
159}
160
161/*!
162 \fn int bufr_find_tableD_index ( size_t *index, struct bufr_tableD *td, const char *key )
163 \brief Find the index of a line in table D for a given key of a descriptor
164 \param index pointer where to set the result
165 \param td pointer to a struct \ref bufr_tableD where all table data is stored
166 \param key string in the form FXXYYY which is the key of descriptor we want to find out
167 \return If the descriptor has been found with success then returns 0, othewise returns 1
168*/
169int bufr_find_tableD_index ( buf_t *index, struct bufr_tableD *td, const char *key )
170{
171 buf_t i, i0;
172 buf_t ix = 0;
173 char *c, aux[8];
174
175 //bufrdeco_assert ( td != NULL && key != NULL && index != NULL);
176
177 aux[0] = key[1];
178 aux[1] = key[2];
179 aux[2] = '\0';
180 ix = strtoul ( aux, &c, 10 );
181 i0 = td->x_start[ix];
182 for ( i = i0 ; i < i0 + td->num[ix] ; i++ )
183 {
184 if ( td->l[i][1] != key[0] ||
185 td->l[i][2] != key[1] ||
186 td->l[i][3] != key[2] ||
187 td->l[i][4] != key[3] ||
188 td->l[i][5] != key[4] ||
189 td->l[i][6] != key[5] )
190 {
191 continue;
192 }
193 else
194 {
195 *index = i;
196 return 0;
197 }
198 }
199 return 1; // not found
200}
201
202
203/*!
204 \fn int bufrdeco_tableD_get_descriptors_array ( struct bufr_sequence *s, struct bufrdeco *b, const char *key )
205 \brief get the descriptors array for a descriptor sequence defined in table D with F = 3
206 \param s target struct \ref bufr_sequence
207 \param b pointer to the basic container struct \ref bufrdeco
208 \param key string in the form FXXYYY which is the key of descriptor we want to find out, F = 3
209 \return If the sequence has been filled with success then returns 0, otherwise returns 1
210*/
211int bufrdeco_tableD_get_descriptors_array ( struct bufr_sequence *s, struct bufrdeco *b, const char *key )
212{
213 buf_t i, j;
214 uint32_t nv, v;
215 char *c;
216 struct bufr_tableD *td;
217
218 bufrdeco_assert ( b != NULL && s != NULL && key != NULL );
219
220 td = & ( b->tables->d );
221
222 // Reject wrong arguments
223 if ( s == NULL || b == NULL || key == NULL )
224 {
225 snprintf ( b->error, sizeof (b->error),"%s(): Wrong entry arguments\n", __func__ );
226 return 1;
227 }
228
229 // here the calling b item learn where to find table C line
230
231 if ( bufr_find_tableD_index ( &i, td, key ) )
232 {
233 snprintf ( b->error, sizeof (b->error), "%s(): descriptor '%s' not found in table D\n", __func__, key );
234 return 1; // descritor not found
235 }
236
237 // Get the name of common sequence
238 if (td->item[i].description[0])
239 strcpy(s->name, td->item[i].description);
240 else
241 s->name[0] = 0;
242
243 // reads the amount of possible values
244 nv = strtoul ( &td->l[i][7], &c, 10 );
245
246 // s->level must be set by caller
247 // s->father must be set by caller
248
249 s->ndesc = 0;
250
251 // read all descriptors
252 for ( j = 0; j < nv && ( i + j ) < td->nlines ; j++ )
253 {
254 v = strtoul ( & ( td->l[i+j][11] ), &c, 10 );
255 uint32_t_to_descriptor ( & ( s->lseq[j] ), v );
256 ( s->ndesc ) ++;
257 }
258 // s->sons are not set here
259 return 0;
260}
Include header file for bufrdeco library.
uint32_t buf_t
Type to set offsets and dimension of arrays or counters used in bufrdeco.
Definition: bufrdeco.h:346
#define bufrdeco_assert(__my_expr__)
Check a expression and exit if it fails.
Definition: bufrdeco.h:374
int uint32_t_to_descriptor(struct bufr_descriptor *d, uint32_t id)
parse an integer with a descriptor fom bufr ECWMF libary
#define CSV_MAXL
Maximum length in a string to be parsed as csv.
Definition: bufrdeco.h:128
int parse_csv_line(int *nt, char *tk[], char *lin)
Parse a csv line.
Definition: bufrdeco_csv.c:258
#define BUFR_MAXLINES_TABLED
The maximum expected lines in a Table D file.
Definition: bufrdeco.h:103
int bufr_find_tableD_index(buf_t *index, struct bufr_tableD *td, const char *key)
int bufr_read_tableD(struct bufrdeco *b)
Reads a file with table D content according with WMO csv format.
int bufrdeco_tableD_get_descriptors_array(struct bufr_sequence *s, struct bufrdeco *b, const char *key)
get the descriptors array for a descriptor sequence defined in table D with F = 3
BUFR descriptor.
Definition: bufrdeco.h:409
Stores an unexpanded sequence of descriptors.
Definition: bufrdeco.h:572
struct bufr_descriptor lseq[NMAXSEQ_DESCRIPTORS]
Definition: bufrdeco.h:583
buf_t ndesc
Definition: bufrdeco.h:575
char name[BUFR_EXPLAINED_LENGTH]
Definition: bufrdeco.h:588
char description2[BUFR_EXPLAINED_LENGTH]
Definition: bufrdeco.h:912
char description[BUFR_EXPLAINED_LENGTH]
Definition: bufrdeco.h:911
Store a table D readed from a file formated and named as ECMWF bufrdc package.
Definition: bufrdeco.h:920
char l[BUFR_MAXLINES_TABLED][24]
Definition: bufrdeco.h:927
int wmo_table
Definition: bufrdeco.h:921
buf_t nlines
Definition: bufrdeco.h:924
char path[BUFRDECO_PATH_LENGTH]
Definition: bufrdeco.h:922
buf_t x_start[64]
Definition: bufrdeco.h:925
char old_path[BUFRDECO_PATH_LENGTH]
Definition: bufrdeco.h:923
struct bufr_tableD_decoded_item item[BUFR_MAXLINES_TABLED]
Definition: bufrdeco.h:928
buf_t num[64]
Definition: bufrdeco.h:926
struct bufr_tableD d
Definition: bufrdeco.h:941
This struct contains all needed data to parse and decode a BUFR file.
Definition: bufrdeco.h:965
struct bufr_tables * tables
Definition: bufrdeco.h:973
char error[1024]
Definition: bufrdeco.h:983