bufr2synop 0.24.0
Macros | Functions
bufrdeco.c File Reference

This file has the code for library bufrdeco API functions. More...

#include "config.h"
#include "bufrdeco.h"
Include dependency graph for bufrdeco.c:

Go to the source code of this file.

Macros

#define CONFIG_H
 

Functions

char * bufrdeco_get_version (char *version, size_t dversion, char *build, size_t dbuild, char *builder, size_t dbuilder, int *version_major, int *version_minor, int *version_patch)
 
int bufrdeco_parse_tree (struct bufrdeco *b)
 Parse the tree of descriptors without expand the replicators. More...
 
int bufrdeco_init (struct bufrdeco *b)
 Inits and allocate memory for a struct bufrdeco. More...
 
int bufrdeco_reset (struct bufrdeco *b)
 Reset an struct bufrdeco. This is needed when changing to another bufr. More...
 
int bufrdeco_set_out_stream (FILE *out, struct bufrdeco *b)
 Set the library normal output stream. More...
 
int bufrdeco_set_err_stream (FILE *err, struct bufrdeco *b)
 Set the error stream. More...
 
int bufrdeco_close (struct bufrdeco *b)
 Free all allocated memory. Needed when no more task to do with bufrdeco library. More...
 
int bufrdeco_set_tables_dir (struct bufrdeco *b, char *tables_dir)
 Sets the directory path for BUFR tables. Needed if it is not any default directories. More...
 
int bufrdeco_get_bufr (struct bufrdeco *b, char *filename)
 Read file and try to find a bufr report inserted in. Once found do the same that bufrdeco_read_bufr() More...
 
int bufrdeco_write_subset_offset_bits (struct bufrdeco *b, char *filename)
 Write offset bit array for subsets in a non-compressed bufr. More...
 
int bufrdeco_read_subset_offset_bits (struct bufrdeco *b, char *filename)
 Write offset bit array for subsets in a non-compressed bufr. More...
 
struct bufrdeco_subset_sequence_databufrdeco_get_target_subset_sequence_data (buf_t nset, struct bufrdeco *b)
 Prepare the struct bufrdeco to get data from the solicited subset. More...
 

Detailed Description

This file has the code for library bufrdeco API functions.

Definition in file bufrdeco.c.

Macro Definition Documentation

◆ CONFIG_H

#define CONFIG_H

Definition at line 26 of file bufrdeco.c.

Function Documentation

◆ bufrdeco_close()

int bufrdeco_close ( struct bufrdeco b)

Free all allocated memory. Needed when no more task to do with bufrdeco library.

Parameters
bpointer to the target struct
Returns
If succeeded return 0, otherwise 1

This function must be called at the end when no more calls to bufrdeco library is needed

b->out and b->err must be closed by caller if are not the default stdout or stderr

Definition at line 259 of file bufrdeco.c.

260{
261 bufrdeco_assert ( b != NULL );
262
263 // first deallocate all memory
268 {
270 b->tables = 0;
271 }
272 else
273 {
274 bufrdeco_free_tables ( & ( b->tables ) );
275 }
277
278 return 0;
279}
#define bufrdeco_assert(__my_expr__)
Check a expression and exit if it fails.
Definition: bufrdeco.h:374
int bufrdeco_free_subset_sequence_data(struct bufrdeco_subset_sequence_data *ba)
Free the memory for sequence array in a struct bufrdeco_subset_sequence_data.
int bufrdeco_free_tables(struct bufr_tables **t)
Frees the allocated space for a struct bufr_tables.
int bufrdeco_free_cache_tables(struct bufr_tables_cache *c)
deallocate and clean a bufr_tables_cache
Definition: bufrdeco_wmo.c:322
int bufrdeco_free_bitmap_array(struct bufrdeco_bitmap_array *a)
Free an allocated bitmap array.
#define BUFRDECO_USE_TABLES_CACHE
Bit mask to the member mask of struct bufrdeco to mark the use of bufr_tables cache.
Definition: bufrdeco.h:268
int bufrdeco_free_expanded_tree(struct bufrdeco_expanded_tree **t)
Frees the allocated space for a struct bufrdeco_expanded_tree.
int bufrdeco_free_compressed_data_references(struct bufrdeco_compressed_data_references *rf)
Free the memory allocated for array of references in a struct bufrdeco_compressed_data_references.
struct bufrdeco_bitmap_array bitmap
Definition: bufrdeco.h:980
struct bufrdeco_subset_sequence_data seq
Definition: bufrdeco.h:979
uint32_t mask
Definition: bufrdeco.h:966
struct bufr_tables_cache cache
Definition: bufrdeco.h:974
struct bufrdeco_compressed_data_references refs
Definition: bufrdeco.h:978
struct bufr_tables * tables
Definition: bufrdeco.h:973
struct bufrdeco_expanded_tree * tree
Definition: bufrdeco.h:975

References bufrdeco::bitmap, bufrdeco_assert, bufrdeco_free_bitmap_array(), bufrdeco_free_cache_tables(), bufrdeco_free_compressed_data_references(), bufrdeco_free_expanded_tree(), bufrdeco_free_subset_sequence_data(), bufrdeco_free_tables(), BUFRDECO_USE_TABLES_CACHE, bufrdeco::cache, bufrdeco::mask, bufrdeco::refs, bufrdeco::seq, bufrdeco::tables, and bufrdeco::tree.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ bufrdeco_get_bufr()

int bufrdeco_get_bufr ( struct bufrdeco b,
char *  filename 
)

Read file and try to find a bufr report inserted in. Once found do the same that bufrdeco_read_bufr()

Parameters
bpointer to struct bufrdeco
filenamecomplete path of BUFR file
Returns
Returns 0 if all is OK, 1 otherwise

This function does the folowing tasks:

  • Try to find first buffer of bytes begining with 'BUFR' chars and ending with '7777'. This will be considered as a bufr file.
  • Read the file and checks the marks at the begining and end to see wheter is a BUFR file
  • Init the structs and allocate the needed memory for raw data if not done previously
  • Splits and parse the BUFR sections (without expanding descriptors nor parsing data)
  • Reads the needed Table files and store them in memory.

Definition at line 315 of file bufrdeco.c.

316{
317 bufrdeco_assert_with_return_val ( b != NULL || filename == NULL, 1 );
318
319 return bufrdeco_extract_bufr ( b, filename );
320}
#define bufrdeco_assert_with_return_val(__my_expr__, __returnval__)
Check a expression and returns a given value if it fails.
Definition: bufrdeco.h:385
int bufrdeco_extract_bufr(struct bufrdeco *b, char *filename)
Read file and try to find a bufr report inserted in. Once found do the same that bufrdeco_read_file()

References bufrdeco_assert_with_return_val, and bufrdeco_extract_bufr().

Here is the call graph for this function:

◆ bufrdeco_get_target_subset_sequence_data()

struct bufrdeco_subset_sequence_data * bufrdeco_get_target_subset_sequence_data ( buf_t  nset,
struct bufrdeco b 
)

Prepare the struct bufrdeco to get data from the solicited subset.

Parameters
nsetindex of subset we want to parse and get data. First subset in a BUFR file has index 0.
bpointer to the struct bufrdeco
Returns
If succeeded returns a pointer to the struct bufrdeco_subset_sequence_data with the results for the desired subset, otherwise returns NULL

Definition at line 396 of file bufrdeco.c.

397{
398 buf_t n = 0;
399 bufrdeco_assert ( b != NULL );
400 uint32_t mask0 = b->mask;
401
402 if ( b->sec3.subsets <= nset )
403 {
404 snprintf ( b->error, sizeof ( b->error ), "%s(): The index of target subset is over the bufr subsets (%d)\n", __func__, b->sec3.subsets );
405 return NULL;
406 }
407
408 if ( b->sec3.compressed )
409 {
410#ifdef __DEBUG
411 printf ("# Compressed\n");
412#endif
413 // case of compressed, we just need the compressed references
414 if ( b->refs.nd == 0 )
415 {
416 // case of compressed data and still not parsed the refs
417 if ( bufrdeco_parse_compressed ( & ( b->refs ), b ) )
418 {
419 return NULL;
420 }
421
422 }
423 }
424 else if ( nset > 0 )
425 {
426 // In case of not compressed bufr, to parse a subset we need to know the bit offset of the subset data in sec4
427 // There are only two ways to know that offset:
428 // 1) Parse the data of all prior subsets from n = 0 to (nset - 1).
429 // 2) Get the subset bit offset from the struct bufrdeco_subset_bit_offset already stored.
430 // This is only possible if we already parsed this subset in this session (among two bufrdeco_reset() calls)
431 // or if readed the struct from a file
432 // In any case the subset bit offset array must be poluted for all n < (nset - 1)
433
434 // clear bit BUFRDECO_OUTPUT_JSON_SUBSET_DATA if actived
435 b->mask &= ~((uint32_t) BUFRDECO_OUTPUT_JSON_SUBSET_DATA);
436
437 if ( b->offsets.nr == 0 || b->offsets.ofs[nset] == 0 )
438 {
439 for ( n = b->state.subset ; n < nset ; n++ )
440 {
441 // In every call to bufrdeco_decode_data_subset(), b->state.subset is incremented and b->offsets is updated if needed
442#ifdef __DEBUG
443 printf ("# Go to parse for subset %lu waiting %lu\n", b->state.subset, nset);
444#endif
446 }
447 }
448 }
449 // Once the previous task is made, we just adjust the subset
450 b->state.subset = nset;
451 b->mask = mask0;
452
453 // and now parse and get the desired subset data
454#ifdef __DEBUG
455 printf ("# Finally going to target parse for subset %lu\n", b->state.subset);
456#endif
458}
uint32_t buf_t
Type to set offsets and dimension of arrays or counters used in bufrdeco.
Definition: bufrdeco.h:346
struct bufrdeco_subset_sequence_data * bufrdeco_get_subset_sequence_data(struct bufrdeco *b)
Parse and get a struct bufrdeco_subset_sequence_data.
Definition: bufrdeco_data.c:39
#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
int bufrdeco_parse_compressed(struct bufrdeco_compressed_data_references *r, struct bufrdeco *b)
Preliminary parse of a compressed data bufr.
int bufrdeco_decode_data_subset(struct bufrdeco *b)
User interface to decode a BUFR subset.
Definition: bufrdeco_data.c:62
uint8_t compressed
Definition: bufrdeco.h:812
uint32_t subsets
Definition: bufrdeco.h:810
buf_t ofs[BUFR_MAX_SUBSETS]
Definition: bufrdeco.h:687
struct bufrdeco_subset_bit_offsets offsets
Definition: bufrdeco.h:977
struct bufrdeco_decoding_data_state state
Definition: bufrdeco.h:976
struct bufr_sec3 sec3
Definition: bufrdeco.h:971
char error[1024]
Definition: bufrdeco.h:983

References bufrdeco_assert, bufrdeco_decode_data_subset(), bufrdeco_get_subset_sequence_data(), BUFRDECO_OUTPUT_JSON_SUBSET_DATA, bufrdeco_parse_compressed(), bufr_sec3::compressed, bufrdeco::error, bufrdeco::mask, bufrdeco_compressed_data_references::nd, bufrdeco_subset_bit_offsets::nr, bufrdeco::offsets, bufrdeco_subset_bit_offsets::ofs, bufrdeco::refs, bufrdeco::sec3, bufrdeco::state, bufrdeco_decoding_data_state::subset, and bufr_sec3::subsets.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ bufrdeco_get_version()

char * bufrdeco_get_version ( char *  version,
size_t  dversion,
char *  build,
size_t  dbuild,
char *  builder,
size_t  dbuilder,
int *  version_major,
int *  version_minor,
int *  version_patch 
)

Definition at line 50 of file bufrdeco.c.

52{
53 int major = 0, minor = 0, patch = 0;
54 size_t used;
55
56 // Check argument
57 if ( version == NULL )
58 return NULL;
59
60 snprintf ( version, dversion, "%s", VERSION );
61 // default
62 sscanf ( version, "%d.%d.%d", &major, &minor, &patch );
63
64 if ( build )
65 {
66 used = 0;
67#if defined(__INTEL_COMPILER)
68 used += snprintf ( build + used, dbuild - used, "using INTEL C compiler icc %d.%d ", __INTEL_COMPILER, __INTEL_COMPILER_UPDATE );
69#elif defined(__clang_version__)
70 used += snprintf ( build + used, dbuild - used, "using clang C compiler ", __clang_version__ );
71#elif defined(__GNUC__)
72 used += snprintf ( build + used, dbuild - used, "using GNU C compiler gcc %d.%d.%d ", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__ );
73#elif defined(_MSC_VER)
74 used += snprintf ( build + used, dbuild - used, "using MICROSOFT C compiler %d ", _MSC_VER );
75#else
76 used += snprintf ( build + used, dbuild - used, "using an unknown C compiler " );
77#endif
78 snprintf ( build + used, dbuild - used,"at %s %s",__DATE__,__TIME__ );
79 }
80
81 if ( builder )
82#ifdef BUILD_USING_CMAKE
83 strncpy_safe ( builder, "cmake", dbuilder );
84#else
85 strncpy_safe ( builder, "autotools", dbuilder );
86#endif
87 if ( version_major )
88 *version_major = major;
89 if ( version_minor )
90 *version_minor = minor;
91 if ( version_patch )
92 *version_patch = patch;
93 return version;
94}
#define strncpy_safe(_target_, _src_, _dim_)
Macro to make safely a strcpy when we know in calling function the size of string target directly.
Definition: bufrdeco.h:366
#define VERSION
Definition: config.h:8

References strncpy_safe, and VERSION.

Referenced by bufrtotac_print_version().

Here is the caller graph for this function:

◆ bufrdeco_init()

int bufrdeco_init ( struct bufrdeco b)

Inits and allocate memory for a struct bufrdeco.

Parameters
bpointer to the target struct

This function only must be called once. When finished the function bufrdeco_close must be called to free all needed memory

Returns
If succeeded return 0, otherwise 1

Definition at line 138 of file bufrdeco.c.

139{
140 bufrdeco_assert ( b != NULL );
141
142 // First clear all
143 memset ( b, 0, sizeof ( struct bufrdeco ) );
144
145 // Then allocate all needed memory when starting. Further we will need to allocate some more depending on
146 // data
147
148 // allocate memory for Tables
149 if ( bufrdeco_init_tables ( &b->tables ) )
150 {
151 snprintf ( b->error, sizeof ( b->error ),"%s(): Cannot allocate space for tables\n", __func__ );
152 return 1;
153 }
154
155 // Output default streams
156 b->out = stdout;
157 b->err = stderr;
158
159 // allocate memory for expanded tree of descriptors
160 if ( bufrdeco_init_expanded_tree ( &b->tree ) )
161 {
162 snprintf ( b->error, sizeof ( b->error ),"%s(): Cannot allocate space for expanded tree of descriptors\n", __func__ );
163 return 1;
164 }
165
166
167 return 0;
168}
int bufrdeco_init_tables(struct bufr_tables **t)
Init a struct bufr_tables allocating space.
int bufrdeco_init_expanded_tree(struct bufrdeco_expanded_tree **t)
Init a struct bufrdeco_expanded_tree allocating space.
This struct contains all needed data to parse and decode a BUFR file.
Definition: bufrdeco.h:965
FILE * err
Definition: bufrdeco.h:985
FILE * out
Definition: bufrdeco.h:984

References bufrdeco_assert, bufrdeco_init_expanded_tree(), bufrdeco_init_tables(), bufrdeco::err, bufrdeco::error, bufrdeco::out, bufrdeco::tables, and bufrdeco::tree.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ bufrdeco_parse_tree()

int bufrdeco_parse_tree ( struct bufrdeco b)

Parse the tree of descriptors without expand the replicators.

Parameters
bPointer to the source struct bufrdeco

This is the user function to parse the descriptor structure of a BUFR report. This is the first task we need to perform after read the bufr report with the aid of bufrdeco_read_bufr function.

At the end we will get an array of structs bufr_sequence defining the tree

A sequence layer is needed when parsing expanded descriptor sec3 and sec4

First bufr_sequence is the sequence of descriptors in sec3 after byte 8. This is a bufr_sequence in level 0.

When a sequence descriptor is found in a layer, the sequence entries found in table D form this descriptor is a son bufr_sequence. This son has then a father and also can have one or more sons. The index level is incremented by one every step it go into decendents.

And so we go in a recursive way up to the end.

Returns
If success return 0, if something went wrong return 1

Definition at line 120 of file bufrdeco.c.

121{
122 bufrdeco_assert ( b != NULL );
123
124 // here we start the parse
125 return bufrdeco_parse_tree_recursive ( b, NULL, 0, NULL );
126}
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

References bufrdeco_assert, and bufrdeco_parse_tree_recursive().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ bufrdeco_read_subset_offset_bits()

int bufrdeco_read_subset_offset_bits ( struct bufrdeco b,
char *  filename 
)

Write offset bit array for subsets in a non-compressed bufr.

Parameters
filenamecomplete path of input file to open
bpointer to the struct bufrdeco
Returns
1 if problem, 0 otherwise

Definition at line 358 of file bufrdeco.c.

359{
360 struct stat st;
361 FILE *f;
362
363 // assert nice args
364 bufrdeco_assert_with_return_val ( b != NULL || filename == NULL, 1 );
365
366 // silently return if cannot stat the file
367 if ( stat ( filename, &st ) < 0 )
368 {
369 return 1;
370 }
371
372 // open the file
373 f = fopen ( filename, "r" );
374 bufrdeco_assert_with_return_val ( f != NULL, 1 );
375
376 // Read the offsets
377 if ( bufr_read_subset_offset_bits ( f, & ( b->offsets ) ) )
378 {
379 fclose ( f );
380 return 1;
381 }
382 fclose ( f );
383 return 0;
384}
int bufr_read_subset_offset_bits(FILE *f, struct bufrdeco_subset_bit_offsets *off)
Write offset bit array for subsets in a non-compressed bufr.

References bufr_read_subset_offset_bits(), bufrdeco_assert_with_return_val, and bufrdeco::offsets.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ bufrdeco_reset()

int bufrdeco_reset ( struct bufrdeco b)

Reset an struct bufrdeco. This is needed when changing to another bufr.

Parameters
bpointer to the target struct to be resed with another bufrfile

This function must be called when parsing another BUFR report without calling bufrdeco_close and bufrdeco_init. It

Returns
If succeeded return 0, otherwise 1

Definition at line 180 of file bufrdeco.c.

181{
182 struct bufr_tables *tb;
183 struct bufr_tables_cache ch;
184 FILE *out,*err;
185 uint32_t mask;
186 bufrdeco_assert ( b != NULL );
187
188 // save the data we do not reset
189 memcpy(&ch, &b->cache, sizeof (struct bufr_tables_cache));
190 tb = b->tables;
191 mask = b->mask;
192 out = b->out;
193 err = b->err;
198
199 memset ( b, 0, sizeof ( struct bufrdeco ) );
200
201 // Restore data
202 b->out = out;
203 b->err = err;
204 b->mask = mask;
205 b->tables = tb;
206 memcpy(&b->cache, &ch, sizeof (struct bufr_tables_cache));
207
208 // allocate memory for expanded tree of descriptors
209 if ( bufrdeco_init_expanded_tree ( &b->tree ) )
210 {
211 snprintf ( b->error, sizeof ( b->error ),"%s(): Cannot allocate space for expanded tree of descriptors\n", __func__ );
212 return 1;
213 }
214
215 return 0;
216}
Struct to store the cache of structs bufr_tables.
Definition: bufrdeco.h:951
Contains all tables needed to parse a bufr file.
Definition: bufrdeco.h:938

References bufrdeco::bitmap, bufrdeco_assert, bufrdeco_free_bitmap_array(), bufrdeco_free_compressed_data_references(), bufrdeco_free_expanded_tree(), bufrdeco_free_subset_sequence_data(), bufrdeco_init_expanded_tree(), bufrdeco::cache, bufrdeco::err, bufrdeco::error, bufrdeco::mask, bufrdeco::out, bufrdeco::refs, bufrdeco::seq, bufrdeco::tables, and bufrdeco::tree.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ bufrdeco_set_err_stream()

int bufrdeco_set_err_stream ( FILE *  err,
struct bufrdeco b 
)

Set the error stream.

Parameters
errstream opened by caller
bpointer to current active struct bufrdeco
Returns
If succeeded return 0, otherwise 1

Without calling to this funcion, the default is stderr

Definition at line 242 of file bufrdeco.c.

243{
244 b->out = err;
245 return 0;
246}

References bufrdeco::out.

◆ bufrdeco_set_out_stream()

int bufrdeco_set_out_stream ( FILE *  out,
struct bufrdeco b 
)

Set the library normal output stream.

Parameters
outstream opened by caller
bpointer to current active struct bufrdeco
Returns
If succeeded return 0, otherwise 1

Without calling to this funcion, the default is stdout

Definition at line 227 of file bufrdeco.c.

228{
229 b->out = out;
230 return 0;
231}

References bufrdeco::out.

◆ bufrdeco_set_tables_dir()

int bufrdeco_set_tables_dir ( struct bufrdeco b,
char *  tables_dir 
)

Sets the directory path for BUFR tables. Needed if it is not any default directories.

Parameters
bpointer to the target struct
tables_dirSource path of tables directory
Returns
1 if problem, 0 otherwise

The default directories are '/usr/share/bufr2synop' and '/usr/local/share/bufr2synop'

Definition at line 291 of file bufrdeco.c.

292{
293 bufrdeco_assert_with_return_val ( b != NULL || tables_dir == NULL, 1 );
294
296 return 0;
297}
#define BUFRDECO_PATH_LENGTH
Length for files/directory path strings.
Definition: bufrdeco.h:335
char bufrtables_dir[BUFRDECO_PATH_LENGTH]
Definition: bufrdeco.h:982

References bufrdeco_assert_with_return_val, BUFRDECO_PATH_LENGTH, bufrdeco::bufrtables_dir, and strncpy_safe.

◆ bufrdeco_write_subset_offset_bits()

int bufrdeco_write_subset_offset_bits ( struct bufrdeco b,
char *  filename 
)

Write offset bit array for subsets in a non-compressed bufr.

Parameters
filenamecomplete path of output file to open
bpointer to the struct bufrdeco
Returns
1 if problem, 0 otherwise

Definition at line 330 of file bufrdeco.c.

331{
332 FILE *f;
333
334 // assert nice args
335 bufrdeco_assert_with_return_val ( b != NULL || filename == NULL, 1 );
336
337 // open the file
338 f = fopen ( filename, "w" );
339 bufrdeco_assert_with_return_val ( f != NULL, 1 );
340
341 // Read the offsets
342 if ( bufr_write_subset_offset_bits ( f, & ( b->offsets ) ) )
343 {
344 fclose ( f );
345 return 1;
346 }
347 fclose ( f );
348 return 0;
349}
int bufr_write_subset_offset_bits(FILE *f, struct bufrdeco_subset_bit_offsets *off)
Write offset bit array for subsets in a non-compressed bufr.

References bufr_write_subset_offset_bits(), bufrdeco_assert_with_return_val, and bufrdeco::offsets.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function: