bufr2synop 0.24.0
bufrdeco_tree.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_tree.c
22 \brief This file has the code which parse sequences in a bufr
23*/
24#include "bufrdeco.h"
25
26/*!
27 \fn int get_unexpanded_descriptor_array_from_sec3 ( struct bufr_sequence *s, struct bufrdeco *b )
28 \brief Set to a struct \ref bufr_sequence an unexpanded descriptor array from sec3 in a BUFR report
29 \param s Pointer to the target struct \ref bufr_sequence
30 \param b Pointer to the base struct \ref bufrdeco
31 \return If succeded return 0
32
33 Here we get a struct \ref bufr_sequence from the data about descriptors stored in sec3 of a bufr report
34*/
36{
37 buf_t i;
38
39 bufrdeco_assert (b != NULL && s != NULL);
40
41 // First we copy the array descriptors in sec3 as level0
42 for ( i = 0; i < b->sec3.ndesc ; i++ )
43 {
44 memcpy ( & ( s->lseq[i] ), & ( b->sec3.unexpanded[i] ), sizeof ( struct bufr_descriptor ) );
45 }
46 s->ndesc = b->sec3.ndesc;
47 return 0;
48}
49
50
51/*!
52 \fn int bufrdeco_parse_tree_recursive ( struct bufrdeco *b, struct bufr_sequence *father, buf_t father_idesc, const char *key )
53 \brief Parse the descriptor tree in a recursive way
54 \param key string with descriptor in form 'FXXYYY'
55 \param father pointer to the father struct \ref bufr_sequence
56 \param father_idesc index of sequence descriptor in father \ref bufr_sequence which this sequence derived
57 \param b pointer to the base struct \ref bufrdeco
58 \return 0 if success, 1 otherwise
59 */
60int bufrdeco_parse_tree_recursive ( struct bufrdeco *b, struct bufr_sequence *father, buf_t father_idesc, const char *key )
61{
62 buf_t i, j, nl;
63 struct bufr_sequence *l;
64 struct bufr_descriptor *d;
65
66 //bufrdeco_assert (b != NULL);
67
68 if ( key == NULL )
69 {
70 // case first layer
71 memset ( b->tree, 0, sizeof ( struct bufrdeco_expanded_tree ) ); //reset memory
72 b->tree->nseq = 1; // Set current number of sequences in tree, i.e. 1
73 l = & ( b->tree->seq[0] ); // This is to write easily
74 strcpy ( l->key, "000000" ); // Key '000000' is the first descriptor of first sequence of level 0
75 l->level = 0; // Level 0
76 l->father = NULL; // This layer is God, it has not father
77 l->father_idesc = father_idesc; // No meaning here
78 l->iseq = 0; // first
79 strcpy ( l->name, "Main sequence from SEC3" );
80 // here we get l->ndesc and l->lsec[] array
82 {
83 return 1;
84 }
85 }
86 else
87 {
88 // First increase nseq counter
89 if ( b->tree->nseq < NMAXSEQ_DESCRIPTORS )
90 {
91 ( b->tree->nseq ) ++;
92 }
93 else
94 {
95 // No more bufr_sequence permitted
96 snprintf ( b->error, sizeof (b->error),"%s(): Reached max number of bufr_sequence. "
97 "Use bigger NMAXSEQ_LAYER \n" , __func__);
98 return 1;
99 }
100 nl = b->tree->nseq; // To write code easily
101 l = & ( b->tree->seq[nl - 1] ); // To write code easily
102 strcpy ( l->key, key ); // Set the key of sequence in table d (f == 3)
103 l->level = father->level + 1; // level for sequence
104 l->father = father; // set the father
105 l->father_idesc = father_idesc; // Set the father idesc
106 l->iseq = nl - 1; // index of sequence in tree
107
108 // here we get ndesc and lsec array from table d
109 if ( bufrdeco_tableD_get_descriptors_array ( l, b, key ) )
110 {
111 return 1; // something went wrong
112 }
113 }
114
115 // Set init replication level values from father, copying the one in replicated[0]
116 for ( i = 1 ; i < l->ndesc ; i++)
117 {
118 l->replicated[i] = l->replicated[0];
119 }
120
121 // Checks for replication levels, no data present, event or conditioning event
122 for ( i = 0; i < l->ndesc ; i++ )
123 {
124 d = & ( l->lseq[i] ); // To write/read code easily
125
126 // Case of replication
127 if ( d->f == 1 )
128 {
129 for ( j = 0; j < d->x; j++ )
130 {
131 if ( d->y == 0 )
132 l->replicated[j + i + 2]++; // a delayed replicator follow
133 else
134 l->replicated[j + i + 1]++; // No delayed descriptor
135 }
136 }
137
138
139 if ( d->f == 2 )
140 {
141 // check for no data present descriptors
142 if ( d->x == 21 &&
143 d->y > 0 )
144 {
145 if ( ( d->y + i ) < l->ndesc )
146 {
147 l->no_data_present.active = 1;
148 l->no_data_present.first = i + 1;
149 l->no_data_present.last = i + d->y;
150
151 }
152 else
153 {
154 // range of no data present out of sequence
155 snprintf ( b->error, sizeof (b->error),"%s(): Range of 'no data present' out of sequence limits\n" , __func__);
156 return 1;
157 }
158 }
159
160 // Check for event descriptors
161 if ( d->x == 41 )
162 {
163 if ( d->y == 0 && ( i + 1 ) < l->ndesc )
164 {
165 l->event.active = 1;
166 l->event.first = i + 1;
167 l->event.last = l->ndesc - 1; // at the moment mark upto final sequence
168 }
169 else if ( ( d->y == 255 ) && l->event.active )
170 {
171 l->event.last = i;
172 }
173 else
174 {
175 snprintf ( b->error, sizeof (b->error),"%s(): unexpected or wrong event descriptor\n" , __func__);
176 return 1;
177 }
178 }
179
180 // Check for conditioning event descriptors
181 if ( d->x == 42 )
182 {
183 if ( d->y == 0 && ( i + 1 ) < l->ndesc )
184 {
185 l->cond_event.active = 1;
186 l->cond_event.first = i + 1;
187 l->cond_event.last = l->ndesc - 1; // at the moment mark upto final sequence
188 }
189 else if ( ( d->y == 255 ) && l->cond_event.active )
190 {
191 l->cond_event.last = i;
192 }
193 else
194 {
195 snprintf ( b->error, sizeof (b->error),"%s(): unexpected or wrong conditioning event event descriptor\n" , __func__);
196 return 1;
197 }
198 }
199
200 // Check for categorical forecasts descriptors
201 if ( d->x == 43 )
202 {
203 if ( d->y == 0 && ( i + 1 ) < l->ndesc )
204 {
205 l->cat_forecast.active = 1;
206 l->cat_forecast.first = i + 1;
207 l->cat_forecast.last = l->ndesc - 1; // at the moment mark upto final sequence
208 }
209 else if ( ( d->y == 255 ) && l->cat_forecast.active )
210 {
211 l->cat_forecast.last = i;
212 }
213 else
214 {
215 snprintf ( b->error, sizeof (b->error),"%s(): unexpected or wrong categorical forecasts descriptor\n" , __func__);
216 return 1;
217 }
218 }
219 }
220 }
221
222 // now we detect sons and go to parse them
223 for ( i = 0; i < l->ndesc ; i++ )
224 {
225 // we search for descriptors with f == 3
226 if ( l->lseq[i].f != 3 )
227 {
228 l->sons[i] = NULL;
229 continue;
230 }
231 l->sons[i] = & ( b->tree->seq[b->tree->nseq] );
232 l->sons[i]->replicated[0] = l->replicated[i]; // This is a trick to pass replication level to sons
233
234 // we then recursively parse the son
235 if ( bufrdeco_parse_tree_recursive ( b, l, i, l->lseq[i].c ) )
236 {
237 return 1;
238 }
239 }
240
241 // if we are here all gone well
242 return 0;
243}
244
245
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
#define NMAXSEQ_DESCRIPTORS
Maximum nuber of unexpanded descriptors in a struct bufr_sequence.
Definition: bufrdeco.h:134
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
int bufrdeco_parse_tree_recursive(struct bufrdeco *b, struct bufr_sequence *father, buf_t father_idesc, const char *key)
Parse the descriptor tree in a recursive way.
Definition: bufrdeco_tree.c:60
int get_unexpanded_descriptor_array_from_sec3(struct bufr_sequence *s, struct bufrdeco *b)
Set to a struct bufr_sequence an unexpanded descriptor array from sec3 in a BUFR report.
Definition: bufrdeco_tree.c:35
BUFR descriptor.
Definition: bufrdeco.h:409
char c[12]
Definition: bufrdeco.h:414
struct bufr_descriptor unexpanded[BUFR_LEN_UNEXPANDED_DESCRIPTOR]
Definition: bufrdeco.h:814
uint32_t ndesc
Definition: bufrdeco.h:813
Stores an unexpanded sequence of descriptors.
Definition: bufrdeco.h:572
struct bufr_sequence_index_range cond_event
Definition: bufrdeco.h:580
struct bufr_descriptor lseq[NMAXSEQ_DESCRIPTORS]
Definition: bufrdeco.h:583
struct bufr_sequence_index_range no_data_present
Definition: bufrdeco.h:578
struct bufr_sequence * father
Definition: bufrdeco.h:576
buf_t ndesc
Definition: bufrdeco.h:575
buf_t father_idesc
Definition: bufrdeco.h:577
struct bufr_sequence_index_range event
Definition: bufrdeco.h:579
char key[8]
Definition: bufrdeco.h:573
uint8_t replicated[NMAXSEQ_DESCRIPTORS]
Definition: bufrdeco.h:582
buf_t iseq
Definition: bufrdeco.h:586
buf_t level
Definition: bufrdeco.h:574
struct bufr_sequence * sons[NMAXSEQ_DESCRIPTORS]
Definition: bufrdeco.h:584
struct bufr_sequence_index_range cat_forecast
Definition: bufrdeco.h:581
char name[BUFR_EXPLAINED_LENGTH]
Definition: bufrdeco.h:588
Array of structs bufr_sequence from which bufr expanded tree is made.
Definition: bufrdeco.h:596
struct bufr_sequence seq[BUFR_MAX_EXPANDED_SEQUENCES]
Definition: bufrdeco.h:598
This struct contains all needed data to parse and decode a BUFR file.
Definition: bufrdeco.h:965
struct bufr_sec3 sec3
Definition: bufrdeco.h:971
struct bufrdeco_expanded_tree * tree
Definition: bufrdeco.h:975
char error[1024]
Definition: bufrdeco.h:983