bufr2synop 0.24.0
bufrdeco_compressed.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_compressed.c
22 \brief This file has the code to deal with compressed bufr reports
23*/
24#include "bufrdeco.h"
25
26/*!
27 \fn int bufrdeco_parse_compressed ( struct bufrdeco_compressed_data_references *r, struct bufrdeco *b )
28 \brief Preliminary parse of a compressed data bufr
29 \param r pointer to a struct \ref bufrdeco_compressed_data_references where to set the results
30 \param b basic container struct \ref bufrdeco
31 \return Returns 0 if succeeded, 1 otherwise
32
33 When a bufr report has compressed data, it is needed to do a first parse step to get references about
34 where to find the data for every descriptor in subsets. This is what this function does. If succeeded
35 the struct \a r will have all needed data to decode individual subsets.
36
37 Also be mind that the descriptors tree have to be already parsed when calling this function
38
39*/
41{
42
43 // Check about parsed tree
44 if ( b->tree == NULL || b->tree->nseq == 0 )
45 {
46 snprintf ( b->error, sizeof ( b->error ),"%s(): Try to parse compressed data without parsed tree\n", __func__ );
47 return 1; //fatal error, no parsed tree
48 }
49
50 // first we assure that needed memory is allocated and array of bufr_compressed references initizalized
52 {
53 return 1; // Something went wrong
54 }
55
56 // Then we make the parsing task in a recursive way. NULL pointer says it is the begining.
57 // The NULL argument is because we begin the compresed Preliminary parse tasks
58 if ( bufrdeco_parse_compressed_recursive ( r, NULL, b ) )
59 {
60 return 1;
61 }
62
63 // all is OK
64 return 0;
65}
66
67
68/*!
69 \fn int bufrdeco_parse_compressed_recursive ( struct bufrdeco_compressed_data_references *r, struct bufr_sequence *l, struct bufrdeco *b )
70 \brief Parse recursively the compressed data in a bufr report to get references where to get data for every descriptor in a subset
71 \param r pointer to target struct \ref bufrdeco_compressed_data_references where to set results
72 \param l pointer to a struct \ref bufr_sequence to parse in this call. If NULL then it is first root sequence
73 \param b basic container struct \ref bufrdeco
74 \return Returns 0 if succeeded, 1 otherwise
75*/
77{
78 int res;
79 buf_t i, k;
80 struct bufr_sequence *seq; // auxiliar pointer
81 struct bufrdeco_compressed_ref *rf;
82 struct bufr_replicator replicator;
83
84 // Check arguments
85 if ( b == NULL )
86 return 1;
87
88 if ( r == NULL )
89 {
90 snprintf ( b->error, sizeof ( b->error ), "%s(): Unspected NULL argument\n", __func__ );
91 return 1;
92 }
93
94 if ( l == NULL )
95 {
96 // inits the array. This is the begining of preliminary parse
97 // At the moment there are no structs bufrdeco_compressed_ref used
98 r->nd = 0;
99 // set the auxiliar pointer at the begining of array of sequences of bufrdeco_expanded_tree
100 seq = & ( b->tree->seq[0] );
101 // Cleans the state of parsing
102 memset ( & ( b->state ), 0, sizeof ( struct bufrdeco_decoding_data_state ) );
103 // and set some other initial values
104 b->state.bit_offset = 0;
105 b->state.added_bit_length = 0;
106 b->state.added_scale = 0;
107 b->state.added_reference = 0;
108 b->state.assoc_bits = 0;
109 b->state.changing_reference = 255;
110 b->state.fixed_ccitt = 0;
112 b->state.factor_reference = 1;
113 b->state.quality_active = 0;
114 b->state.subs_active = 0;
115 b->state.retained_active = 0;
116 b->state.stat1_active = 0;
117 b->state.dstat_active = 0;
118 b->state.bitmaping = 0;
119 b->state.bitmap = NULL;
120
121 }
122 else
123 {
124 // This is the case when layer of sequence is no 0, i.e. has been called recursively
125 // We just set the auxiliar index
126 seq = l;
127 }
128
129 // Mark the init of a sequence. It waste a reference to mark it
130 rf = & ( r->refs[r->nd] );
132 rf->seq = seq;
133 // Set the used elements of array in r
135 return 1;
136
137
138 // loop for a sequence
139 for ( i = 0; i < seq->ndesc ; i++ )
140 {
141 // switch according to 'f' of the descriptor of sequence
142 switch ( seq->lseq[i].f )
143 {
144 case 0:
145 // Checks if no_data_present is active for this descriptor in this sequence
146 if ( seq->no_data_present.active &&
147 i >= seq->no_data_present.first &&
148 i <= seq->no_data_present.last )
149 {
150 // If here then no_data_present has been active in this sequence
151 if ( seq->lseq[i].x > 9 &&
152 seq->lseq[i].x != 31 )
153 {
154 snprintf ( b->error, sizeof ( b->error ), "%s(): Getting data from table b with class other than 1-9,31 and no data present activated\n", __func__ );
155 return 1;
156 }
157
158 }
159
160 // Get data from table B
161 rf = & ( r->refs[r->nd] ); // pointer to the target struct bufrdeco_compressed ref. To read/write code easily
162
163 // First the the data itself
164 if ( bufrdeco_tableB_compressed ( rf, b, & ( seq->lseq[i] ), 0 ) )
165 {
166 return 1;
167 }
168
169 //case of first order statistics
170 if ( b->state.stat1_active &&
171 seq->lseq[i].x == 8 && seq->lseq[i].y == 23 )
172 {
173 k = b->bitmap.bmap[b->bitmap.nba - 1]->ns1; // index un stqts
174 b->bitmap.bmap[b->bitmap.nba - 1]->stat1_desc[k] = r->nd; // Set the value of statistical parameter
175 // update the number of quality variables for the bitmap
176 if ( k < BUFR_MAX_QUALITY_DATA )
177 ( b->bitmap.bmap[b->bitmap.nba - 1]->ns1 )++;
178 else
179 {
180 snprintf ( b->error, sizeof ( b->error ), "%s(): No more space for first order statistic vars in bitmap. Check BUFR_MAX_QUALITY_DATA\n", __func__ );
181 return 1;
182 }
183 }
184
185 //case of difference statistics
186 if ( b->state.dstat_active &&
187 seq->lseq[i].x == 8 && seq->lseq[i].y == 24 )
188 {
189 k = b->bitmap.bmap[b->bitmap.nba - 1]->nds; // index un stqts
190 b->bitmap.bmap[b->bitmap.nba - 1]->dstat_desc[k] = r->nd; // Set the value of statistical parameter
191 // update the number of quality variables for the bitmap
192 if ( k < BUFR_MAX_QUALITY_DATA )
193 ( b->bitmap.bmap[b->bitmap.nba - 1]->nds )++;
194 else
195 {
196 snprintf ( b->error, sizeof ( b->error ), "%s(): No more space for difference statistic vars in bitmap. Check BUFR_MAX_QUALITY_DATA\n", __func__ );
197 return 1;
198 }
199 }
200
202 rf->seq = seq;
204 return 1;
205
206 // Then we check for an associated field
207 rf = & ( r->refs[r->nd] );
208 // If is not an associated field returned value is -1 and no action is made
209 res = bufrdeco_tableB_compressed ( rf, b, & ( seq->lseq[i] ), 1 );
210 if ( res > 0 )
211 {
212 return 1; // case of error
213 }
214 else if ( res == 0 )
215 {
217 rf->seq = seq;
218 // associated field read with success, set again the used elements of r
220 return 1;
221
222 // Update the pointer to the target struct bufrdeco_compressed ref
223 i++; // Update main loop index, note that i is also incrmented at the end of loop.
224 }
225
226
227 break;
228
229 case 1:
230 // Case of replicator descriptor. waste a reference
231 rf = & ( r->refs[r->nd] );
233 rf->seq = seq;
234 rf->desc = & ( seq->lseq[i] );
235 // Set the used elements of array in r
237 return 1;
238
239 memset ( &replicator, 0, sizeof ( struct bufr_replicator ) ); // mr proper
240 replicator.s = seq;
241 replicator.ixrep = i; // the index of recplicator descriptor in the sequence
242 if ( seq->lseq[i].y != 0 )
243 {
244 // no delayed
245 replicator.ixdel = i; // The index of descriptor with info about actual replication factor
246 replicator.ndesc = seq->lseq[i].x;
247 replicator.nloops = seq->lseq[i].y;
248
249 // Check if this replicator is for a bit-map defining
250 if ( b->state.bitmaping )
251 {
252 b->state.bitmaping = replicator.nloops; // set it properly
253 }
254
255 // call to decode a replicated subsequence
257
258 // and then set again bitamping to 0, because it is finished
259 b->state.bitmaping = 0;
260 }
261 else
262 {
263 // case of delayed;
264 replicator.ixdel = i + 1; // the index of descriptor in sequence with information about the actual amonut of replications
265 replicator.ndesc = seq->lseq[i].x;
266 rf = & ( r->refs[r->nd] );
267
268 // The the data itself to get the loops
269 if ( bufrdeco_tableB_compressed ( rf, b, & ( seq->lseq[ replicator.ixdel ] ), 0 ) )
270 {
271 return 1;
272 }
274 rf->seq = seq;
275
276 // Set the used elements of bufrdeco_compressed_ref
278 return 1;
279
280 // Note that is supossed all subsets has the same nlopps,
281 // so the inc_bits must be 0 and nloops = ref0
282 replicator.nloops = ( size_t ) rf->ref0;
283
284 // Check if this replicator is for a bit-map defining
285 if ( b->state.bitmaping )
286 {
287 b->state.bitmaping = replicator.nloops; // set it properly
288 }
289
290 // call to decode a replicated subsequence
292
293 // and then set again bitamping to 0, because it is finished
294 b->state.bitmaping = 0;
295 }
296 i = replicator.ixdel + replicator.ndesc; // update i properly
297 break;
298
299 case 2:
300 // Case of operator descriptor
301 rf = & ( r->refs[r->nd] );
303 rf->seq = seq;
304 rf->desc = & ( seq->lseq[i] );
305 // Set the used elements of array in r
307 return 1;
308
309 if ( bufrdeco_parse_f2_compressed ( r, & ( seq->lseq[i] ), b ) )
310 {
311 return 1;
312 }
313
314 break;
315
316 case 3:
317 // Case of sequence descriptor
318 if ( bufrdeco_parse_compressed_recursive ( r, seq->sons[i], b ) )
319 {
320 return 1;
321 }
322 break;
323
324 default:
325 // this case is not possible
326 snprintf ( b->error, sizeof ( b->error ), "%s(): Found bad 'f' in descriptor '%s' \n", __func__, seq->lseq[i].c );
327 return 1;
328 break;
329 }
330 }
331
332 // Mark end of sequence. waste a reference
333 rf = & ( r->refs[r->nd] );
335 rf->seq = seq;
337 return 1;
338
339
340 return 0;
341}
342
343/*!
344 \fn int bufrdeco_decode_replicated_subsequence_compressed ( struct bufrdeco_compressed_data_references *r, struct bufr_replicator *rep, struct bufrdeco *b )
345 \brief decodes a repicated subsequence
346 \param r pointer to target struct \ref bufrdeco_compressed_data_references where to set results
347 \param rep pointer to a replicator which contains the data for replication
348 \param b basic container struct \ref bufrdeco
349
350 \return Returns 0 if succeeded, 1 otherwise
351*/
353{
354 int res;
355 buf_t i, k;
356 buf_t ixloop; // Index for loop
357 buf_t ixd; // Index for descriptor
358 struct bufrdeco_compressed_ref *rf;
359 struct bufr_replicator replicator;
360 struct bufr_sequence *l = rep->s; // sequence
361
362 // check arguments
363 if ( b == NULL )
364 return 1;
365
366 if ( r == NULL || rep == NULL )
367 {
368 snprintf ( b->error, sizeof ( b->error ), "%s(): Unspected NULL argument(s)\n", __func__ );
369 return 1;
370 }
371
372 // if no loops the we save process time and space in data
373 if ( rep->nloops == 0 )
374 return 0;
375
376
377 // The big loop
378 for ( ixloop = 0; ixloop < rep->nloops; ixloop++ )
379 {
380 for ( ixd = 0; ixd < rep->ndesc ; ixd ++ )
381 {
382 i = ixd + rep->ixdel + 1;
383 switch ( l->lseq[i].f )
384 {
385 case 0:
386 // Checks if no_data_present is active for this descriptor in this sequence
387 if ( l->no_data_present.active &&
388 i >= l->no_data_present.first &&
389 i <= l->no_data_present.last )
390 {
391 // If here then no_data_present has been active in this sequence
392 if ( l->lseq[i].x > 9 &&
393 l->lseq[i].x != 31 )
394 {
395 snprintf ( b->error, sizeof ( b->error ), "%s(): Getting data from table b with class other than 1-9,31 and no data present activated\n", __func__ );
396 return 1;
397 }
398
399 }
400 // Get data from table B
401 rf = & ( r->refs[r->nd] );
402 rf->replicated_desc = ixd + 1;
403 rf->replicated_loop = ixloop + 1;
404 rf->replicated_ndesc = rep->ndesc;
405 rf->replicated_nloop = rep->nloops;
406
407 // First then the data itself
408 if ( bufrdeco_tableB_compressed ( rf, b, & ( l->lseq[i] ), 0 ) )
409 {
410 return 1;
411 }
412
413 // Case of defining bitmap 0 31 031
414 if ( l->lseq[i].x == 31 && l->lseq[i].y == 31 && b->state.bitmaping )
415 {
416 if ( rf->ref0 == 0 ) // Assume if ref0 == 0 then all subsets are present in same bits
417 {
418 r->refs[r->nd - b->state.bitmaping].is_bitmaped_by = ( uint32_t ) r->nd ;
419 rf->bitmap_to = r->nd - b->state.bitmaping;
420 bufrdeco_add_to_bitmap ( b->bitmap.bmap[b->bitmap.nba - 1], r->nd - b->state.bitmaping, r->nd );
421 }
422 }
423
424 // Process quality data
425 if ( b->state.quality_active &&
426 l->lseq[i].x == 33 )
427 {
428 if ( ixloop == 0 )
429 {
430 k = b->bitmap.bmap[b->bitmap.nba - 1]->nq; // index un quality_given_by array to set
431 b->bitmap.bmap[b->bitmap.nba - 1]->quality[k] = r->nd; // Set the value
432 // update the number of quality variables for the bitmap
433 if ( k < BUFR_MAX_QUALITY_DATA )
434 ( b->bitmap.bmap[b->bitmap.nba - 1]->nq )++;
435 else
436 {
437 snprintf ( b->error, sizeof ( b->error ), "%s(): No more space for quality vars in bitmap. Check BUFR_MAX_QUALITY_DATA\n", __func__ );
438 return 1;
439 }
440 }
441 rf->related_to = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
442
443 }
444
445 //case of first order statistics
446 if ( b->state.stat1_active &&
447 l->lseq[i].x == 8 && l->lseq[i].y == 23 )
448 {
449 if ( ixloop == 0 )
450 {
451 k = b->bitmap.bmap[b->bitmap.nba - 1]->ns1; // index un stqts
452 b->bitmap.bmap[b->bitmap.nba - 1]->stat1_desc[k] = r->nd; // Set the value of statistical parameter
453 // update the number of quality variables for the bitmap
454 if ( k < BUFR_MAX_QUALITY_DATA )
455 ( b->bitmap.bmap[b->bitmap.nba - 1]->ns1 )++;
456 else
457 {
458 snprintf ( b->error, sizeof ( b->error ), "%s(): No more space for first order statistic vars in bitmap. Check BUFR_MAX_QUALITY_DATA\n", __func__ );
459 return 1;
460 }
461 }
462 rf->related_to = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
463 }
464
465 //case of difference statistics
466 if ( b->state.dstat_active &&
467 l->lseq[i].x == 8 && l->lseq[i].y == 24 )
468 {
469 if ( ixloop == 0 )
470 {
471 k = b->bitmap.bmap[b->bitmap.nba - 1]->nds; // index un stqts
472 b->bitmap.bmap[b->bitmap.nba - 1]->dstat_desc[k] = r->nd; // Set the value of statistical parameter
473 // update the number of quality variables for the bitmap
474 if ( k < BUFR_MAX_QUALITY_DATA )
475 ( b->bitmap.bmap[b->bitmap.nba - 1]->nds )++;
476 else
477 {
478 snprintf ( b->error, sizeof ( b->error ), "%s(): No more space for difference statistic vars in bitmap. Check BUFR_MAX_QUALITY_DATA\n", __func__ );
479 return 1;
480 }
481 }
482 rf->related_to = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
483 }
484
486 rf->seq = l;
487
488 // Set the used elements of array in r
490 return 1;
491
492 // Then associated field
493 rf = & ( r->refs[r->nd] );
494 res = bufrdeco_tableB_compressed ( rf, b, & ( l->lseq[i] ), 1 );
495 if ( res > 0 )
496 {
497 return 1; // case of error
498 }
499 else if ( res == 0 )
500 {
501 //print_bufrdeco_compressed_ref ( rf );
502 // associated field read with success
504 rf->seq = l;
505 // Set the used elements of array in r
507 return 1;
508 b->state.assoc_bits = 0; // Set again the assoc_bits to 0
509 }
510
511 break;
512
513 case 1:
514 // Case of replicator descriptor
515 rf = & ( r->refs[r->nd] );
517 rf->seq = l;
518 rf->desc = & ( l->lseq[i] );
519 rf->replicated_desc = ixd + 1;
520 rf->replicated_loop = ixloop + 1;
521 rf->replicated_ndesc = rep->ndesc;
522 rf->replicated_nloop = rep->nloops;
523
524 // Set the used elements of array in r
526 return 1;
527
528 replicator.s = l;
529 replicator.ixrep = i;
530 if ( l->lseq[i].y != 0 )
531 {
532 // no delayed
533 replicator.ixdel = i;
534 replicator.ndesc = l->lseq[i].x;
535 replicator.nloops = l->lseq[i].y;
537 ixd += replicator.ndesc; // update ixd properly
538 }
539 else
540 {
541 // case of delayed;
542 replicator.ixdel = i + 1;
543 replicator.ndesc = l->lseq[i].x;
544 rf = & ( r->refs[r->nd] );
545
546 // The data itself to get the loops
547 if ( bufrdeco_tableB_compressed ( rf, b, & ( l->lseq[replicator.ixdel] ), 0 ) )
548 {
549 return 1;
550 }
552 rf->seq = l;
553
554 // Set the used elements of bufrdeco_compressed_ref
556 return 1;
557 replicator.nloops = ( size_t ) rf->ref0;
558
560 ixd += replicator.ndesc + 1; // update ixd properly
561 }
562
563 break;
564
565 case 2:
566 rf = & ( r->refs[r->nd] );
568 rf->seq = l;
569 rf->desc = & ( l->lseq[i] );
570 rf->replicated_desc = ixd + 1;
571 rf->replicated_loop = ixloop + 1;
572 rf->replicated_ndesc = rep->ndesc;
573 rf->replicated_nloop = rep->nloops;
574
575 // Set the used elements of array in r
577 return 1;
578
579 // Case of operator descriptor
580 if ( bufrdeco_parse_f2_compressed ( r, & ( l->lseq[i] ), b ) )
581 {
582 return 1;
583 }
584
585 // Case of subsituted values
586 if ( b->state.subs_active && l->lseq[i].x == 23 && l->lseq[i].y == 255 )
587 {
588 k = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop]; // ref which is bitmaped_to
589 // Get the bitmaped descriptor k
590 rf = & ( r->refs[r->nd] );
591 if ( ixloop == 0 )
592 {
593 b->bitmap.bmap[b->bitmap.nba - 1]->subs = r->nd;
594 }
595 if ( bufrdeco_tableB_compressed ( rf, b, & ( l->lseq[k] ), 0 ) )
596 {
597 return 1;
598 }
599 rf->related_to = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
601 rf->seq = l;
602 rf->desc = & ( l->lseq[k] );
604 return 1;
605 }
606
607 // Case of repaced/retained values
608 if ( b->state.retained_active && l->lseq[i].x == 32 && l->lseq[i].y == 255 )
609 {
610 k = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
611 // Get the bitmaped descriptor k
612 rf = & ( r->refs[r->nd] );
613 if ( ixloop == 0 )
614 {
615 b->bitmap.bmap[b->bitmap.nba - 1]->retain = r->nd;
616 }
617 if ( bufrdeco_tableB_compressed ( rf, b, & ( l->lseq[k] ), 0 ) )
618 {
619 return 1;
620 }
621
622 rf->related_to = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
624 rf->seq = l;
625 rf->desc = & ( l->lseq[k] );
627 return 1;
628 }
629
630 // Case of first order statistics
631 //
632 // This operator shall signify a data item containing a
633 // first-order statistical value of the type indicated by
634 // the preceding 0 08 023 element descriptor; the
635 // element descriptor to which the first-order statistic
636 // relates is obtained by the application of the data
637 // present bit-map associated with the first-order
638 // statistical values follow operator; first-order statistical
639 // values shall be represented as defined by this element
640 // descriptor.
641 if ( b->state.stat1_active && l->lseq[i].x == 24 && l->lseq[i].y == 255 )
642 {
643 k = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
644
645 // Get the bitmaped descriptor k
646 rf = & ( r->refs[r->nd] );
647 if ( ixloop == 0 )
648 {
649 b->bitmap.bmap[b->bitmap.nba - 1]->stat1[b->bitmap.bmap[b->bitmap.nba - 1]->ns1 -1] = r->nd;
650 }
651
652 if ( bufrdeco_tableB_compressed ( rf, b, r->refs[k].desc, 0 ) )
653 {
654 return 1;
655 }
656 rf->related_to = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
658 rf->seq = l;
659 rf->desc = & ( l->lseq[k] );
661 return 1;
662 }
663
664 // Case of difference statistics
665 //
666 // This operator shall signify a data item containing a
667 // difference statistical value of the type indicated by
668 // the preceding 0 08 024 element descriptor; the
669 // element descriptor to which the difference statistical
670 // value relates is obtained by the application of the
671 // data present bit-map associated with the difference
672 // statistical values follow operator; difference statistical
673 // values shall be represented as defined by this
674 // element descriptor, but with a reference value of –2**n
675 // and a data width of (n+1), where n is the data width
676 // given by the original descriptor. This special reference
677 // value allows the statistical difference values to
678 // be centred around zero.
679 if ( b->state.dstat_active && l->lseq[i].x == 25 && l->lseq[i].y == 255 )
680 {
681 k = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
682
683 // Get the bitmaped descriptor k
684 rf = & ( r->refs[r->nd] );
685 if ( ixloop == 0 )
686 {
687 b->bitmap.bmap[b->bitmap.nba - 1]->stat1[b->bitmap.bmap[b->bitmap.nba - 1]->nds -1] = r->nd;
688 }
689
690 if ( bufrdeco_tableB_compressed ( rf, b, r->refs[k].desc, 0 ) )
691 {
692 return 1;
693 }
694
695 // here is where we change ref and bits
696 rf->ref = - ( ( int32_t ) 1 << rf->bits );
697 rf->bits++;
698 rf->related_to = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
700 rf->seq = l;
702 return 1;
703 }
704
705 if ( l->lseq[i].x == 5 ) // cases wich produces a new ref
706 {
708 rf->seq = l;
710 return 1;
711 }
712 break;
713
714 case 3:
715 // Case of sequence descriptor
716 if ( bufrdeco_parse_compressed_recursive ( r, l->sons[i], b ) )
717 return 1;
718 break;
719
720 default:
721 // this case is not possible
722 snprintf ( b->error, sizeof ( b->error ), "%s(): Found bad 'f' in descriptor\n", __func__ );
723 return 1;
724 break;
725 }
726 }
727 }
728 return 0;
729}
730
731/*!
732
733 \fn int bufrdeco_get_atom_data_from_compressed_data_ref ( struct bufr_atom_data *a, struct bufrdeco_compressed_ref *r, buf_t subset, struct bufrdeco *b )
734 \brief Get atom data from a descriptor for a given subset
735 \param a pointer to the target struct \ref bufr_atom_data where to set the results
736 \param r pointer to the struct \ref bufrdeco_compressed_ref with the info to know how and where get the data
737 \param subset index for solicited subset. First subset has index 0
738 \param b basic container struct \ref bufrdeco
739
740 \return Returns 0 if succeeded, 1 otherwise
741*/
743 buf_t subset, struct bufrdeco *b )
744{
745 buf_t i, bit_offset;
746 uint8_t has_data;
747 uint32_t ival, ival0;
748 int32_t ivals;
749 struct bufr_tableB *tb;
750
751 if ( b == NULL )
752 return 1;
753
754 if ( a == NULL || r == NULL )
755 {
756 snprintf ( b->error, sizeof ( b->error ), "%s(): Unspected NULL argument(s)\n", __func__ );
757 return 1;
758 }
759
760 if ( is_a_local_descriptor ( r->desc ) )
761 {
763 memcpy ( & ( a->desc ), r->desc, sizeof ( struct bufr_descriptor ) );
764 strcpy ( a->name, "LOCAL DESCRIPTOR" );
765 strcpy ( a->unit, "UNKNOWN" );
766 if ( r->inc_bits )
767 {
768 bit_offset = r->bit0 + r->bits + 6 + r->inc_bits * subset;
769 // extract inc_bits data
770 if ( get_bits_as_uint32_t ( &ival, &has_data, &b->sec4.raw[4], & bit_offset, r->inc_bits ) == 0 )
771 {
772 snprintf ( b->error, sizeof ( b->error ), "%s(): Cannot get associated bits from '%s'\n", __func__, r->desc->c );
773 return 1;
774 }
775 a->val = ival + r->ref0;
776 }
777 else
778 a->val = r->ref0;
779 return 0;
780 }
781
782 // some utils pointers
783 tb = & ( b->tables->b );
784 i = tb->x_start[r->desc->x] + tb->y_ref[r->desc->x][r->desc->y];
785
786 a->mask = 0;
787
788 // descriptor
789 memcpy ( & ( a->desc ), r->desc, sizeof ( struct bufr_descriptor ) );
790 // name
791 //strcpy_safe ( a->name, r->name );
792 strcpy ( a->name, r->name );
793 //unit
794 //strcpy_safe ( a->unit, r->unit );
795 strcpy ( a->unit, r->unit );
796 //scale
797 a->escale = r->escale;
798
799 // possible bitmaps
800 if ( r->is_bitmaped_by )
801 {
803 }
804
805 if ( r->bitmap_to )
806 {
807 a->bitmap_to = r->bitmap_to;
808 }
809
810 // Possible quality
811 if ( r->related_to )
812 {
813 a->related_to = r->related_to;
814 }
815
816
817 // First we check about string fields
818 if ( strstr ( a->unit, "CCITT" ) != NULL )
819 {
820 if ( r->has_data == 0 )
821 {
823 return 0;
824 }
825
826 if ( r->inc_bits == 0 )
827 {
828 // case of all data same, so copy the local ref
829 strcpy ( a->cval, r->cref0 );
831 }
832 else
833 {
834 // we have to extract chars from section data
835 // compute the bit_offset
836 bit_offset = r->bit0 + r->bits + 6 + r->inc_bits * 8 * subset;
837 if ( get_bits_as_char_array ( a->cval, &has_data, &b->sec4.raw[4], & bit_offset, r->inc_bits * 8 ) == 0 )
838 {
839 snprintf ( b->error, sizeof ( b->error ), "%s(): Cannot get uchars from '%s'\n", __func__, r->desc->c );
840 return 1;
841 }
842 if ( has_data == 0 )
843 {
845 }
846 else
847 {
849 }
850 }
851 return 0;
852 }
853
854 // now we check for associated data
855 if ( r->is_associated )
856 {
857 strcpy ( a->name, "Associated value" );
858 strcpy ( a->unit, "Associated unit" );
859 if ( r->has_data == 0 )
860 {
862 }
863 else
864 {
865 if ( r->inc_bits == 0 )
866 {
867 // case of all data same, so copy the local ref
868 a->associated = r->ref0;
869 }
870 else
871 {
872 // compute the bit_offset
873 bit_offset = r->bit0 + r->bits + 6 + r->inc_bits * subset;
874 // extract inc_bits data
875 if ( get_bits_as_uint32_t ( &ival, &has_data, &b->sec4.raw[4], & bit_offset, r->inc_bits ) == 0 )
876 {
877 snprintf ( b->error, sizeof ( b->error ), "%s(): Cannot get associated bits from '%s'\n", __func__, r->desc->c );
878 return 1;
879 }
880 // finally get the associated data
881 if ( has_data )
882 {
883 a->associated = r->ref + ( int32_t ) ( r->ref0 + ival );
884 }
885 else
886 {
888 }
889 }
890 }
891 return 0;
892 }
893
894 // numeric data
895 if ( r->has_data == 0 ||
896 r->inc_bits > r->bits ) // Here we assume no more inc_bits than bits in reference value?
897 {
898 a->val = MISSING_REAL;
900 return 0;
901 }
902
903 if ( r->inc_bits == 0 )
904 {
905 ivals = r->ref + ( int32_t ) r->ref0;
906 }
907 else
908 {
909 // read inc_bits data
910 // compute the bit_offset
911 bit_offset = r->bit0 + r->bits + 6 + r->inc_bits * subset;
912 // extract inc_bits data
913 if ( get_bits_as_uint32_t ( &ival0, &has_data, &b->sec4.raw[4], & bit_offset, r->inc_bits ) == 0 )
914 {
915 snprintf ( b->error, sizeof ( b->error ), "%s(): Cannot get %d inc_bits from '%s'\n", __func__, r->inc_bits, r->desc->c );
916 return 1;
917 }
918
919 if ( has_data )
920 {
921 ivals = r->ref + ( int32_t ) ( r->ref0 + ival0 );
922 }
923 else
924 {
925 a->val = MISSING_REAL;
927 return 0;
928 }
929 }
930
931 // Get a numeric number
932 a->val = ( double ) ( ivals ) * exp10 ( ( double ) ( - r->escale ) );
933
934 if ( strstr ( a->unit, "CODE TABLE" ) == a->unit || strstr ( a->unit, "Code table" ) == a->unit )
935 {
936 ival = ( uint32_t ) ( a->val + 0.5 );
938 if ( bufrdeco_explained_table_val ( a->ctable, 256, & ( b->tables->c ), & ( tb->item[i].tableC_ref ), & ( a->desc ), ival ) != NULL )
939 {
941 }
942 }
943 else if ( strstr ( a->unit,"FLAG" ) == a->unit || strstr ( a->unit,"Flag" ) == a->unit )
944 {
945 ival = ( uint32_t ) ( a->val + 0.5 );
947
948 if ( bufrdeco_explained_flag_val ( a->ctable, 256, & ( b->tables->c ), & ( a->desc ), ival, r->bits ) != NULL )
949 {
951 }
952 }
953
954 return 0;
955}
956
957/*!
958 \fn int bufr_decode_subset_data_compressed ( struct bufrdeco_subset_sequence_data *s, struct bufrdeco_compressed_data_references *r, struct bufrdeco *b )
959 \brief Get data for a given subset in a compressed data bufr
960 \param s pointer to a struct \ref bufrdeco_subset_sequence_data where to set the results
961 \param r pointer to the struct \ref bufrdeco_compressed_data_references with the info about how and where to get the data
962 \param b basic container struct \ref bufrdeco
963 \return Returns 0 if succeeded, 1 otherwise
964*/
966{
967 size_t i, j = 0; // references index
968 char aux[80];
969
970 if ( b == NULL )
971 return 1;
972
973 // Previous check
974 if ( r->refs == NULL || r->nd == 0 )
975 {
976 snprintf ( b->error, sizeof ( b->error ), "%s(): Try to get subset data without previous references\n", __func__ );
977 return 1;
978 }
979
980 // first some clean
981 if ( s->nd )
982 {
983 s->nd = 0;
984 }
985
986 // The subset index
987 s->ss = b->state.subset;
988
991
992 // then get sequence
993 for ( i = 0; i < r->nd; i++ )
994 {
996 (r->refs[i].replicated_desc || r->refs[i].replicated_loop) )
997 snprintf(aux, sizeof (aux), "\"Replicated\":\"Descriptor %u/%u of loop %u/%u\"", r->refs[i].replicated_desc, r->refs[i].replicated_ndesc,
999 else
1000 aux[0] = '\0';
1001
1003 {
1004 if ( bufrdeco_get_atom_data_from_compressed_data_ref ( & ( s->sequence[s->nd] ), & ( r->refs[i] ), b->state.subset, b ) )
1005 return 1;
1006
1008 {
1009 if ( j )
1011 bufrdeco_print_json_object_atom_data (b->out, & ( s->sequence[s->nd] ), aux );
1012 }
1013 if ( r->refs[i].is_associated == 0 )
1014 {
1015 if ( s->nd < ( s->dim - 1 ) )
1016 ( s->nd ) ++;
1017 else if ( bufrdeco_increase_data_array ( s ) == 0 )
1018 ( s->nd ) ++;
1019 else
1020 {
1021 snprintf ( b->error, sizeof ( b->error ), "%s(): No more bufr_atom_data available. Check BUFR_NMAXSEQ\n", __func__ );
1022 return 1;
1023 }
1024 }
1025 else
1026 {
1027 if ( s->nd < ( s->dim - 1 ) )
1028 ( s->nd ) ++;
1029 else if ( bufrdeco_increase_data_array ( s ) == 0 )
1030 ( s->nd ) ++;
1031 else
1032 {
1033 snprintf ( b->error, sizeof ( b->error ), "%s(): No more bufr_atom_data available. Check BUFR_NMAXSEQ\n", __func__ );
1034 return 1;
1035 }
1036 }
1037 j++;
1038 }
1040 {
1042 {
1043 if ( j )
1046 j = 0;
1047 }
1048 }
1050 {
1053 }
1055 {
1057 {
1058 if ( j )
1061 j++;
1062 }
1063 }
1065 {
1067 {
1068 if ( j )
1071 }
1072 j++;
1073 }
1074 }
1077
1078 return 0;
1079}
1080
1081/*!
1082 * \fn int bufrdeco_increase_compressed_data_references_count ( struct bufrdeco_compressed_data_references *r, struct bufrdeco *b )
1083 * \brief Increment the count of a struct \ref bufrdeco_compressed_data_references
1084 * \param r pointer to the target struct
1085 * \param b pointer to the current active struct \ref bufrdeco
1086 *
1087 * \return 0 if succeeded, 1 otherwise
1088 */
1090{
1091 if ( r->nd < ( BUFR_NMAXSEQ - 1 ) )
1092 {
1093 r->nd += 1;
1094 }
1095 else
1096 {
1097 snprintf ( b->error, sizeof ( b->error ), "%s(): Reached limit. Consider increas BUFR_NMAXSEQ\n", __func__ );
1098 return 1;
1099 }
1100 return 0;
1101}
Include header file for bufrdeco library.
#define BUFR_NMAXSEQ
Maximum expected descriptors in a expanded sequence for a single subset.
Definition: bufrdeco.h:116
buf_t bufrdeco_print_json_subset_data_prologue(FILE *out, struct bufrdeco *b)
Definition: bufrdeco_json.c:58
#define BUFRDECO_COMPRESSED_REF_OPERATOR_DESCRIPTOR
Bitmask for struct bufrdeco_compressed_ref which marks an operator descriptor.
Definition: bufrdeco.h:617
uint32_t buf_t
Type to set offsets and dimension of arrays or counters used in bufrdeco.
Definition: bufrdeco.h:346
buf_t bufrdeco_print_json_separator(FILE *out)
Print the comma ',' separator in an output.
int is_a_local_descriptor(struct bufr_descriptor *d)
check if a descriptor is a local descriptor
char * bufrdeco_explained_table_val(char *expl, size_t dim, struct bufr_tableC *tc, uint32_t *index, struct bufr_descriptor *d, uint32_t ival)
int bufrdeco_add_to_bitmap(struct bufrdeco_bitmap *bm, buf_t index_to, buf_t index_by)
Push a bitmap element in a bufrdeco_bitmap.
#define DESCRIPTOR_HAVE_FLAG_TABLE_STRING
Bit mask for a flag table string in a struct bufr_atom_data.
Definition: bufrdeco.h:170
buf_t bufrdeco_print_json_object_operator_descriptor(FILE *out, struct bufr_descriptor *d, char *aux)
print an operator desciptor as a json object
#define BUFR_MAX_QUALITY_DATA
Max amount of quality data which is maped by a struct bufrdeco_bitmap element.
Definition: bufrdeco.h:226
uint32_t get_bits_as_char_array(char *target, uint8_t *has_data, uint8_t *source, buf_t *bit0_offset, buf_t bit_length)
buf_t bufrdeco_print_json_sequence_descriptor_final(FILE *out)
char * bufrdeco_explained_flag_val(char *expl, size_t dim, struct bufr_tableC *tc, struct bufr_descriptor *d, uint64_t ival, uint8_t nbits)
buf_t bufrdeco_print_json_object_replicator_descriptor(FILE *out, struct bufr_descriptor *d, char *aux)
print an operator desciptor as a json object
#define BUFRDECO_COMPRESSED_REF_DATA_DESCRIPTOR_BITMASK
Bitmask for struct bufrdeco_compressed_ref which marks a data descriptor.
Definition: bufrdeco.h:611
#define BUFRDECO_OUTPUT_JSON_SUBSET_DATA
Bit mask to the member mask of struct bufrdeco to print bufr subset data in json format.
Definition: bufrdeco.h:299
#define DESCRIPTOR_HAVE_STRING_VALUE
Bit mask for a string in a struct bufr_atom_data.
Definition: bufrdeco.h:152
int bufrdeco_init_compressed_data_references(struct bufrdeco_compressed_data_references *rf)
Init a struct bufrdeco_compressed_data_references.
#define DESCRIPTOR_IS_LOCAL
Bit mask for a flag table string in a struct bufr_atom_data.
Definition: bufrdeco.h:194
#define BUFRDECO_COMPRESSED_REF_SEQUENCE_INIT_BITMASK
Bitmask for struct bufrdeco_compressed_ref which marks the init of a descriptor sequence.
Definition: bufrdeco.h:605
#define MISSING_REAL
The missing default value for real values.
Definition: bufrdeco.h:78
buf_t bufrdeco_print_json_sequence_descriptor_header(FILE *out, struct bufr_sequence *seq)
Print the header of a sequence descriptor (f == 3)
Definition: bufrdeco_json.c:94
#define MISSING_INTEGER
The missing default value for integer values.
Definition: bufrdeco.h:84
int bufrdeco_parse_f2_compressed(struct bufrdeco_compressed_data_references *r, struct bufr_descriptor *d, struct bufrdeco *b)
parse a descritor with f = 2 in case of compressed bufr
Definition: bufrdeco_f2.c:406
int bufrdeco_tableB_compressed(struct bufrdeco_compressed_ref *r, struct bufrdeco *b, struct bufr_descriptor *d, int mode)
get data from table B when parsing compressed data references
uint32_t get_bits_as_uint32_t(uint32_t *target, uint8_t *has_data, uint8_t *source, buf_t *bit0_offset, buf_t bit_length)
int bufrdeco_increase_data_array(struct bufrdeco_subset_sequence_data *s)
doubles the allocated space for a struct bufrdeco_subset_sequence_data whenever is posible
buf_t bufrdeco_print_json_subset_data_epilogue(FILE *out)
Definition: bufrdeco_json.c:77
#define DESCRIPTOR_IS_FLAG_TABLE
Bit mask for a flag table in a struct bufr_atom_data.
Definition: bufrdeco.h:176
#define DESCRIPTOR_IS_CODE_TABLE
Bit mask for a code table in a struct bufr_atom_data.
Definition: bufrdeco.h:158
#define DESCRIPTOR_VALUE_MISSING
Bit mask for a missing value in a struct bufr_atom_data.
Definition: bufrdeco.h:140
#define BUFRDECO_COMPRESSED_REF_SEQUENCE_FINAL_BITMASK
Bitmask for struct bufrdeco_compressed_ref which marks the final of a descriptor sequence.
Definition: bufrdeco.h:629
buf_t bufrdeco_print_json_object_atom_data(FILE *out, struct bufr_atom_data *a, char *aux)
Print an json object with a descriptor data.
#define BUFRDECO_COMPRESSED_REF_REPLICATOR_DESCRIPTOR
Bitmask for struct bufrdeco_compressed_ref which marks a replicator descriptor.
Definition: bufrdeco.h:623
#define DESCRIPTOR_HAVE_CODE_TABLE_STRING
Bit mask for a code table string in a struct bufr_atom_data.
Definition: bufrdeco.h:164
int bufrdeco_decode_replicated_subsequence_compressed(struct bufrdeco_compressed_data_references *r, struct bufr_replicator *rep, struct bufrdeco *b)
decodes a repicated subsequence
int bufrdeco_get_atom_data_from_compressed_data_ref(struct bufr_atom_data *a, struct bufrdeco_compressed_ref *r, buf_t subset, struct bufrdeco *b)
Get atom data from a descriptor for a given subset.
int bufrdeco_parse_compressed(struct bufrdeco_compressed_data_references *r, struct bufrdeco *b)
Preliminary parse of a compressed data bufr.
int bufrdeco_parse_compressed_recursive(struct bufrdeco_compressed_data_references *r, struct bufr_sequence *l, struct bufrdeco *b)
Parse recursively the compressed data in a bufr report to get references where to get data for every ...
int bufrdeco_increase_compressed_data_references_count(struct bufrdeco_compressed_data_references *r, struct bufrdeco *b)
Increment the count of a struct bufrdeco_compressed_data_references.
int bufr_decode_subset_data_compressed(struct bufrdeco_subset_sequence_data *s, struct bufrdeco_compressed_data_references *r, struct bufrdeco *b)
Get data for a given subset in a compressed data bufr.
Contains all the information for a single data related with a descriptor in a expanded squence.
Definition: bufrdeco.h:435
int32_t escale
Definition: bufrdeco.h:441
uint32_t mask
Definition: bufrdeco.h:437
char name[BUFR_TABLEB_NAME_LENGTH]
Definition: bufrdeco.h:438
char ctable[BUFR_EXPLAINED_LENGTH]
Definition: bufrdeco.h:444
struct bufr_descriptor desc
Definition: bufrdeco.h:436
buf_t related_to
Definition: bufrdeco.h:449
double val
Definition: bufrdeco.h:440
buf_t is_bitmaped_by
Definition: bufrdeco.h:447
uint32_t associated
Definition: bufrdeco.h:442
char unit[BUFR_TABLEB_UNIT_LENGTH]
Definition: bufrdeco.h:439
char cval[BUFR_CVAL_LENGTH]
Definition: bufrdeco.h:443
buf_t bitmap_to
Definition: bufrdeco.h:448
BUFR descriptor.
Definition: bufrdeco.h:409
char c[12]
Definition: bufrdeco.h:414
store the information when parsing related to replicators
Definition: bufrdeco.h:422
struct bufr_sequence * s
Definition: bufrdeco.h:423
uint8_t raw[BUFR_LEN]
Definition: bufrdeco.h:828
Stores an unexpanded sequence of descriptors.
Definition: bufrdeco.h:572
struct bufr_descriptor lseq[NMAXSEQ_DESCRIPTORS]
Definition: bufrdeco.h:583
struct bufr_sequence_index_range no_data_present
Definition: bufrdeco.h:578
buf_t ndesc
Definition: bufrdeco.h:575
struct bufr_sequence * sons[NMAXSEQ_DESCRIPTORS]
Definition: bufrdeco.h:584
Store a table B readed from a file formated and named as ECMWF bufrdc package.
Definition: bufrdeco.h:859
uint8_t y_ref[64][256]
Definition: bufrdeco.h:866
struct bufr_tableB_decoded_item item[BUFR_MAXLINES_TABLEB]
Definition: bufrdeco.h:867
buf_t x_start[64]
Definition: bufrdeco.h:864
struct bufr_tableB b
Definition: bufrdeco.h:939
struct bufr_tableC c
Definition: bufrdeco.h:940
struct bufrdeco_bitmap * bmap[BUFR_MAX_BITMAPS]
Definition: bufrdeco.h:493
buf_t dstat_desc[BUFR_MAX_QUALITY_DATA]
Definition: bufrdeco.h:483
buf_t stat1_desc[BUFR_MAX_QUALITY_DATA]
Definition: bufrdeco.h:480
buf_t stat1[BUFR_MAX_QUALITY_DATA]
Definition: bufrdeco.h:479
buf_t quality[BUFR_MAX_QUALITY_DATA]
Definition: bufrdeco.h:475
buf_t bitmap_to[BUFR_MAX_BITMAP_PRESENT_DATA]
Definition: bufrdeco.h:472
Manage an array of structs bufrdeco_compressed_ref.
Definition: bufrdeco.h:668
struct bufrdeco_compressed_ref * refs
Definition: bufrdeco.h:671
Struct to hold the needed reference bit offsets, descriptor tree and replications in a compressed BUF...
Definition: bufrdeco.h:639
char unit[BUFR_TABLEB_UNIT_LENGTH]
Definition: bufrdeco.h:651
char name[BUFR_TABLEB_NAME_LENGTH]
Definition: bufrdeco.h:650
struct bufr_descriptor * desc
Definition: bufrdeco.h:652
struct bufr_sequence * seq
Definition: bufrdeco.h:653
stores the state when expanding a sequence.
Definition: bufrdeco.h:524
struct bufrdeco_bitmap * bitmap
Definition: bufrdeco.h:542
struct bufr_sequence seq[BUFR_MAX_EXPANDED_SEQUENCES]
Definition: bufrdeco.h:598
Contains all the information for a subset in a expanded squence This is a version to use with bufrdec...
Definition: bufrdeco.h:458
struct bufr_atom_data * sequence
Definition: bufrdeco.h:462
This struct contains all needed data to parse and decode a BUFR file.
Definition: bufrdeco.h:965
struct bufrdeco_bitmap_array bitmap
Definition: bufrdeco.h:980
uint32_t mask
Definition: bufrdeco.h:966
struct bufr_sec4 sec4
Definition: bufrdeco.h:972
struct bufrdeco_decoding_data_state state
Definition: bufrdeco.h:976
struct bufr_tables * tables
Definition: bufrdeco.h:973
FILE * out
Definition: bufrdeco.h:984
struct bufrdeco_expanded_tree * tree
Definition: bufrdeco.h:975
char error[1024]
Definition: bufrdeco.h:983