bufr2synop 0.24.0
Data Structures | Macros | Typedefs | Functions | Variables
bufrdeco.h File Reference

Include header file for bufrdeco library. More...

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <getopt.h>
#include <time.h>
#include <math.h>
#include <sys/stat.h>
Include dependency graph for bufrdeco.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  bufr_descriptor
 BUFR descriptor. More...
 
struct  bufr_replicator
 store the information when parsing related to replicators More...
 
struct  bufr_atom_data
 Contains all the information for a single data related with a descriptor in a expanded squence. More...
 
struct  bufrdeco_subset_sequence_data
 Contains all the information for a subset in a expanded squence This is a version to use with bufrdeco parse library. More...
 
struct  bufrdeco_bitmap
 Stores all needed data for a bufr bitmap. More...
 
struct  bufrdeco_bitmap_array
 Stores all structs bufrdeco_bitmap for a bufr bitmap. More...
 
struct  bufrdeco_bitmap_related_vars
 Contains data related to a target variable with the aid of a bitmap. More...
 
struct  bufrdeco_decoding_data_state
 stores the state when expanding a sequence. More...
 
struct  bufr_sequence_index_range
 range of indexes in a struct bufr_sequence where a condition must me chequed or marked, as example no data present or event More...
 
struct  bufr_sequence
 Stores an unexpanded sequence of descriptors. More...
 
struct  bufrdeco_expanded_tree
 Array of structs bufr_sequence from which bufr expanded tree is made. More...
 
struct  bufrdeco_compressed_ref
 Struct to hold the needed reference bit offsets, descriptor tree and replications in a compressed BUFR. More...
 
struct  bufrdeco_compressed_data_references
 Manage an array of structs bufrdeco_compressed_ref. More...
 
struct  bufrdeco_subset_bit_offsets
 Array of offset in bits for every subset in a non-compressed bufr. Offset is counted in bits from the init of SEC4 data, usually bit 32. More...
 
struct  bufr_sec0
 Store de parsed section 0. More...
 
struct  gts_header
 stores WMO GTS header info More...
 
struct  bufr_sec1
 Store de parsed section 1 of a bufr file. More...
 
struct  bufr_sec2
 Store a parsed sec2 from a bufr file including rawdata. More...
 
struct  bufr_sec3
 Store a parsed sec3 from a bufr file including rawdata. More...
 
struct  bufr_sec4
 Store a parsed sec4 from a bufr file including rawdata. More...
 
struct  bufr_tableB_decoded_item
 Store parameters for a descriptor in table b, i. e. with f = 0. More...
 
struct  bufr_tableB
 Store a table B readed from a file formated and named as ECMWF bufrdc package. More...
 
struct  bufr_tableC_decoded_item
 Store parameters for a descriptor in table C, i. e. for Table code and flags Remember this is NOT the C WMO tables. More...
 
struct  bufr_tableC
 Store a table C readed from a file formated and named as ECMWF bufrdc package. More...
 
struct  bufr_tableD_decoded_item
 Store parameters for a line in table D (sequence of descritors) More...
 
struct  bufr_tableD
 Store a table D readed from a file formated and named as ECMWF bufrdc package. More...
 
struct  bufr_tables
 Contains all tables needed to parse a bufr file. More...
 
struct  bufr_tables_cache
 Struct to store the cache of structs bufr_tables. More...
 
struct  bufrdeco
 This struct contains all needed data to parse and decode a BUFR file. More...
 

Macros

#define _GNU_SOURCE
 
#define BUFRDECO   "bufrdeco"
 Name of this library. More...
 
#define BUFR_LEN   (512000)
 Max length of a BUFR file. More...
 
#define BUFR_OBS_DATA_MASK   128
 Bit mask for Observed data. More...
 
#define BUFR_COMPRESSED_DATA_MASK   64
 Bit mask for compressed data. More...
 
#define MISSING_REAL   (1.7e38)
 The missing default value for real values. More...
 
#define MISSING_INTEGER   (2147483647)
 The missing default value for integer values. More...
 
#define BUFR_MAXLINES_TABLEB   (2048)
 The maximum expected lines in a Table B file. More...
 
#define BUFR_MAXLINES_TABLEC   (8192)
 The maximum expected lines in a Table C file. More...
 
#define BUFR_MAXLINES_TABLED   (8192)
 The maximum expected lines in a Table D file. More...
 
#define MAXLINES_TABLEC   BUFR_MAXLINES_TABLEC
 The maximum expected lines in a Table C file, legacy def used from ECMWF. More...
 
#define BUFR_NMAXSEQ   (2 * 16384)
 Maximum expected descriptors in a expanded sequence for a single subset. More...
 
#define BUFR_EXPLAINED_LENGTH   (512)
 Maximum length for a explained descriptor string. More...
 
#define CSV_MAXL   (2048)
 Maximum length in a string to be parsed as csv. More...
 
#define NMAXSEQ_DESCRIPTORS   (256)
 Maximum nuber of unexpanded descriptors in a struct bufr_sequence. More...
 
#define DESCRIPTOR_VALUE_MISSING   (1)
 Bit mask for a missing value in a struct bufr_atom_data. More...
 
#define DESCRIPTOR_HAVE_REAL_VALUE   (2)
 Bit mask for a real value in a struct bufr_atom_data. More...
 
#define DESCRIPTOR_HAVE_STRING_VALUE   (4)
 Bit mask for a string in a struct bufr_atom_data. More...
 
#define DESCRIPTOR_IS_CODE_TABLE   (8)
 Bit mask for a code table in a struct bufr_atom_data. More...
 
#define DESCRIPTOR_HAVE_CODE_TABLE_STRING   (16)
 Bit mask for a code table string in a struct bufr_atom_data. More...
 
#define DESCRIPTOR_HAVE_FLAG_TABLE_STRING   (32)
 Bit mask for a flag table string in a struct bufr_atom_data. More...
 
#define DESCRIPTOR_IS_FLAG_TABLE   (64)
 Bit mask for a flag table in a struct bufr_atom_data. More...
 
#define DESCRIPTOR_IS_A_REPLICATOR   (128)
 Bit mask for a replicator descriptor in a struct bufr_atom_data. More...
 
#define DESCRIPTOR_IS_AN_OPERATOR   (256)
 Bit mask for an operator data descriptor in a struct bufr_atom_data. More...
 
#define DESCRIPTOR_IS_LOCAL   (512)
 Bit mask for a flag table string in a struct bufr_atom_data. More...
 
#define BUFR_LEN_SEC1   (8192)
 Max length in bytes for a sec1. More...
 
#define BUFR_LEN_SEC2   (8192)
 Max length in bytes for a sec2. More...
 
#define BUFR_LEN_UNEXPANDED_DESCRIPTOR   (512)
 Max amount of unexpanded descriptors in a SEC3. More...
 
#define BUFR_MAX_EXPANDED_SEQUENCES   (128)
 Max amount of unexpanded sequences in a struct bufrdeco_expanded_tree. More...
 
#define BUFR_MAX_QUALITY_DATA   (8)
 Max amount of quality data which is maped by a struct bufrdeco_bitmap element. More...
 
#define BUFR_MAX_BITMAP_PRESENT_DATA   (4096)
 Max number of data present in a bitmap definition. More...
 
#define BUFR_MAX_BITMAPS   (8)
 Max number of structs bufrdeco_bitmap that can be allocated in a struct bufrdeco_bitmap_array. More...
 
#define BUFR_MAX_SUBSETS   (2048)
 Max number of subsets in the array off bitoffset subset marks the bufrdeco library can manage. More...
 
#define BUFR_LEN_SEC3   (8 + 2 * BUFR_LEN_UNEXPANDED_DESCRIPTOR)
 Max length in bytes for a sec3. More...
 
#define BUFRDECO_OUTPUT_HTML   (1)
 Bit mask to the member mask for struct bufrdeco to format output as html for SECs 0 to 3. More...
 
#define BUFRDECO_OUTPUT_XML   (2)
 Bit mask to the member mask for struct bufrdeco to format output as xml for SECs 0 to 3. More...
 
#define BUFRDECO_USE_TABLES_CACHE   (4)
 Bit mask to the member mask of struct bufrdeco to mark the use of bufr_tables cache. More...
 
#define BUFRDECO_OUTPUT_JSON_SEC0   (8)
 Bit mask to the member mask of struct bufrdeco to print info for SEC 0 in json format. More...
 
#define BUFRDECO_OUTPUT_JSON_SEC1   (16)
 Bit mask to the member mask of struct bufrdeco to print info for SEC 1 in json format. More...
 
#define BUFRDECO_OUTPUT_JSON_SEC2   (32)
 Bit mask to the member mask of struct bufrdeco to print bufr info for SEC 2 in json format. More...
 
#define BUFRDECO_OUTPUT_JSON_SEC3   (64)
 Bit mask to the member mask of struct bufrdeco to print bufr info for SEC 3 in json format. More...
 
#define BUFRDECO_OUTPUT_JSON_SUBSET_DATA   (128)
 Bit mask to the member mask of struct bufrdeco to print bufr subset data in json format. More...
 
#define BUFRDECO_OUTPUT_JSON_EXPANDED_TREE   (256)
 Bit mask to the member mask of struct bufrdeco to print bufr expanded tree of descriptors. More...
 
#define BUFRDECO_OUTPUT_JSON   (BUFRDECO_OUTPUT_JSON_SEC0 | BUFRDECO_OUTPUT_JSON_SEC1 | BUFRDECO_OUTPUT_JSON_SEC2 | BUFRDECO_OUTPUT_JSON_SEC3 )
 Bit mask to the member mask for struct bufrdeco to format output as json for SECs 0 to 3. More...
 
#define BUFR_TABLEB_NAME_LENGTH   (128)
 Max length (in chars) reserved for a name of variable in table B. More...
 
#define BUFR_TABLEB_UNIT_LENGTH   (64)
 
#define BUFR_CVAL_LENGTH   (128)
 Max length (in chars) of a cval in a bufr_atom_data. More...
 
#define BUFRDECO_PATH_LENGTH   (256)
 Length for files/directory path strings. More...
 
#define BUFRDECO_TABLES_CACHE_SIZE   (16)
 Max number of structs bufr_tables in a bufr_tables_cache. More...
 
#define strcpy_safe(_target_, _src_)
 Macro to make safely a strcpy when we know in calling function the size of string target with sizeof() More...
 
#define strncpy_safe(_target_, _src_, _dim_)
 Macro to make safely a strcpy when we know in calling function the size of string target directly. More...
 
#define bufrdeco_assert(__my_expr__)
 Check a expression and exit if it fails. More...
 
#define bufrdeco_assert_with_return_val(__my_expr__, __returnval__)
 Check a expression and returns a given value if it fails. More...
 
#define BUFRDECO_COMPRESSED_REF_SEQUENCE_INIT_BITMASK   (1)
 Bitmask for struct bufrdeco_compressed_ref which marks the init of a descriptor sequence. More...
 
#define BUFRDECO_COMPRESSED_REF_DATA_DESCRIPTOR_BITMASK   (2)
 Bitmask for struct bufrdeco_compressed_ref which marks a data descriptor. More...
 
#define BUFRDECO_COMPRESSED_REF_OPERATOR_DESCRIPTOR   (4)
 Bitmask for struct bufrdeco_compressed_ref which marks an operator descriptor. More...
 
#define BUFRDECO_COMPRESSED_REF_REPLICATOR_DESCRIPTOR   (8)
 Bitmask for struct bufrdeco_compressed_ref which marks a replicator descriptor. More...
 
#define BUFRDECO_COMPRESSED_REF_SEQUENCE_FINAL_BITMASK   (16)
 Bitmask for struct bufrdeco_compressed_ref which marks the final of a descriptor sequence. More...
 

Typedefs

typedef uint32_t buf_t
 Type to set offsets and dimension of arrays or counters used in bufrdeco. More...
 
typedef int32_t ibuf_t
 Type to set offsets and dimension of arrays or counters used in bufrdeco. More...
 

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_close (struct bufrdeco *b)
 Free all allocated memory. Needed when no more task to do with bufrdeco library. More...
 
int bufrdeco_reset (struct bufrdeco *b)
 Reset an struct bufrdeco. This is needed when changing to another bufr. 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_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_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...
 
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...
 
int bufrdeco_read_subset_offset_bits (struct bufrdeco *b, char *filename)
 Write offset bit array for subsets in a non-compressed 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_init_expanded_tree (struct bufrdeco_expanded_tree **t)
 Init a struct bufrdeco_expanded_tree allocating space. More...
 
int bufrdeco_free_expanded_tree (struct bufrdeco_expanded_tree **t)
 Frees the allocated space for a struct bufrdeco_expanded_tree. More...
 
int bufrdeco_init_tables (struct bufr_tables **t)
 Init a struct bufr_tables allocating space. More...
 
int bufrdeco_free_tables (struct bufr_tables **t)
 Frees the allocated space for a struct bufr_tables. More...
 
int bufrdeco_substitute_tables (struct bufr_tables **replaced, struct bufr_tables *source, struct bufrdeco *b)
 substitute an struct bufr_tables into a struct bufrdeco More...
 
int bufrdeco_init_subset_sequence_data (struct bufrdeco_subset_sequence_data *ba)
 Init a struct bufrdeco_subset_sequence_data. More...
 
int bufrdeco_clean_subset_sequence_data (struct bufrdeco_subset_sequence_data *ba)
 Cleans a struct bufrdeco_subset_sequence_data. More...
 
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. More...
 
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. More...
 
int bufrdeco_init_compressed_data_references (struct bufrdeco_compressed_data_references *rf)
 Init a struct bufrdeco_compressed_data_references. More...
 
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 More...
 
int bufrdeco_store_tables (struct bufr_tables **t, struct bufr_tables_cache *c, uint8_t ver)
 Init an element of array c->tab[] if still not allocated. If allocated clean it and set *t pointing to this element. More...
 
int bufrdeco_cache_tables_search (struct bufr_tables_cache *c, uint8_t ver)
 Search a struct bufr_tables in bufr_tables_cache. More...
 
int bufrdeco_free_cache_tables (struct bufr_tables_cache *c)
 deallocate and clean a bufr_tables_cache More...
 
int bufrdeco_read_bufr (struct bufrdeco *b, char *filename)
 Read bufr file and does preliminary and first decode pass. More...
 
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() More...
 
int bufrdeco_read_buffer (struct bufrdeco *b, uint8_t *bufrx, buf_t size)
 
int get_wmo_tablenames (struct bufrdeco *b)
 Get the complete pathnames for WMO csv table files needed by a bufr message. More...
 
int bufr_read_tableB (struct bufrdeco *b)
 
int bufr_read_tableC (struct bufrdeco *b)
 Reads a file with table C content (Code table and bit flags) according with csv WMO format. More...
 
int bufr_read_tableD (struct bufrdeco *b)
 Reads a file with table D content according with WMO csv format. More...
 
int bufr_read_tables (struct bufrdeco *b)
 Read the tables according with bufr file data from a bufr table directory. More...
 
char * csv_quoted_string (char *out, char *in)
 Transform a string to a quoted string to be inserted in a csv file. More...
 
int parse_csv_line (int *nt, char *tk[], char *lin)
 Parse a csv line. More...
 
int print_bufrdeco_compressed_ref (struct bufrdeco_compressed_ref *r)
 prints a struct bufrdeco_compressed_ref More...
 
int fprint_bufrdeco_compressed_ref (FILE *f, struct bufrdeco_compressed_ref *r)
 prints a struct bufrdeco_compressed_ref More...
 
int print_bufrdeco_compressed_data_references (struct bufrdeco_compressed_data_references *r)
 prints a struct bufrdeco_compressed_references More...
 
int fprint_bufrdeco_compressed_data_references (FILE *f, struct bufrdeco_compressed_data_references *r)
 
int print_sec0_info (struct bufrdeco *b)
 Prints info from sec0. More...
 
int print_sec1_info (struct bufrdeco *b)
 Prints info from sec1. More...
 
int print_sec3_info (struct bufrdeco *b)
 Prints info from sec3. More...
 
int print_sec4_info (struct bufrdeco *b)
 Prints info from sec3. More...
 
int sprint_sec0_info (char *target, size_t lmax, struct bufrdeco *b)
 Prints info from sec0. More...
 
int sprint_sec1_info (char *target, size_t lmax, struct bufrdeco *b)
 Prints info from sec1. More...
 
int sprint_sec3_info (char *target, size_t lmax, struct bufrdeco *b)
 Prints info from sec3. More...
 
int sprint_sec4_info (char *target, size_t lmax, struct bufrdeco *b)
 Prints info from sec4. More...
 
int sprint_sec0_info_html (char *target, size_t lmax, struct bufrdeco *b)
 Prints info from sec0 in html format. More...
 
int sprint_sec1_info_html (char *target, size_t lmax, struct bufrdeco *b)
 Prints info from sec1. More...
 
int sprint_sec3_info_html (char *target, size_t lmax, struct bufrdeco *b)
 Prints info from sec3 formatted as html. More...
 
int sprint_sec4_info_html (char *target, size_t lmax, struct bufrdeco *b)
 Prints info from sec4. More...
 
int bufrdeco_print_tree (struct bufrdeco *b)
 Print a tree of descriptors. More...
 
int bufrdeco_fprint_tree (FILE *f, struct bufrdeco *b)
 Print a tree of descriptors. More...
 
int bufrdeco_print_atom_data_stdout (struct bufr_atom_data *a)
 print the data in a struct bufr_atom_data to stdout More...
 
int bufrdeco_print_atom_data_file (FILE *f, struct bufr_atom_data *a)
 print the data in a struct bufr_atom_data to a file already open by caller More...
 
int bufrdeco_print_subset_sequence_data (struct bufrdeco_subset_sequence_data *s)
 Prints a struct bufrdeco_subset_sequence_data. More...
 
int bufrdeco_print_subset_sequence_data_html (struct bufrdeco_subset_sequence_data *s)
 
int bufrdeco_print_subset_sequence_data_tagged_html (struct bufrdeco_subset_sequence_data *s, char *id)
 
int bufrdeco_fprint_subset_sequence_data_html (FILE *f, struct bufrdeco_subset_sequence_data *s)
 
int bufrdeco_fprint_subset_sequence_data_tagged_html (FILE *f, struct bufrdeco_subset_sequence_data *s, char *id)
 
int bufrdeco_fprint_subset_sequence_data (FILE *f, struct bufrdeco_subset_sequence_data *s)
 
char * bufrdeco_print_atom_data (char *target, size_t lmax, struct bufr_atom_data *a)
 print the data in a struct bufr_atom_data to a string More...
 
char * bufrdeco_print_atom_data_html (char *target, size_t lmax, struct bufr_atom_data *a, uint32_t ss)
 print the data in a struct bufr_atom_data to a string as cells of table rows More...
 
char * get_formatted_value_from_escale (char *fmt, size_t dim, int32_t escale, double val)
 gets a string with formatted value depending of scale More...
 
char * get_formatted_value_from_escale2 (char *fmt, size_t dim, int32_t escale, double val)
 gets a string with formatted value depending of scale More...
 
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. More...
 
int bufrdeco_decode_data_subset (struct bufrdeco *b)
 User interface to decode a BUFR subset. More...
 
int bufrdeco_decode_subset_data_recursive (struct bufrdeco_subset_sequence_data *d, struct bufr_sequence *l, struct bufrdeco *b)
 decode the data from a subset in a recursive way More...
 
int bufrdeco_decode_replicated_subsequence (struct bufrdeco_subset_sequence_data *d, struct bufr_replicator *r, struct bufrdeco *b)
 Decodes a replicated sequence. More...
 
int bufrdeco_parse_f2_descriptor (struct bufrdeco_subset_sequence_data *s, struct bufr_descriptor *d, struct bufrdeco *b)
 parse a descritor with f = 2 More...
 
int bufrdeco_parse_compressed (struct bufrdeco_compressed_data_references *r, struct bufrdeco *b)
 Preliminary parse of a compressed data bufr. More...
 
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 descriptor in a subset. More...
 
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. More...
 
int bufrdeco_decode_replicated_subsequence_compressed (struct bufrdeco_compressed_data_references *r, struct bufr_replicator *rep, struct bufrdeco *b)
 decodes a repicated subsequence More...
 
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 More...
 
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 More...
 
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. More...
 
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. More...
 
struct bufrdeco_subset_sequence_databufrdeco_get_subset_sequence_data (struct bufrdeco *b)
 Parse and get a struct bufrdeco_subset_sequence_data. More...
 
buf_t bufrdeco_print_json_sec0 (FILE *out, struct bufrdeco *b)
 
buf_t bufrdeco_print_json_sec1 (FILE *out, struct bufrdeco *b)
 Print info form sec 1 in json format. More...
 
buf_t bufrdeco_print_json_sec2 (FILE *out, struct bufrdeco *b)
 Print info form optional sec 2 in json format. More...
 
buf_t bufrdeco_print_json_sec3 (FILE *out, struct bufrdeco *b)
 Print info form sec 3 in json format. More...
 
buf_t bufrdeco_print_json_tree (struct bufrdeco *b)
 
buf_t bufrdeco_print_json_tree_recursive (FILE *out, struct bufrdeco *b, struct bufr_sequence *seq)
 Print a tree of descriptors to a file in a recursive way in json format. More...
 
buf_t bufrdeco_print_json_subset_data_prologue (FILE *out, struct bufrdeco *b)
 
buf_t bufrdeco_print_json_subset_data_epilogue (FILE *out)
 
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. More...
 
buf_t bufrdeco_print_json_object_operator_descriptor (FILE *out, struct bufr_descriptor *d, char *aux)
 print an operator desciptor as a json object More...
 
buf_t bufrdeco_print_json_object_replicator_descriptor (FILE *out, struct bufr_descriptor *d, char *aux)
 print an operator desciptor as a json object More...
 
buf_t bufrdeco_print_json_sequence_descriptor_header (FILE *out, struct bufr_sequence *seq)
 Print the header of a sequence descriptor (f == 3) More...
 
buf_t bufrdeco_print_json_sequence_descriptor_final (FILE *out)
 
buf_t bufrdeco_print_json_separator (FILE *out)
 Print the comma ',' separator in an output. More...
 
buf_t bufrdeco_print_json_scape_string_cvals (FILE *out, char *source)
 prints a descriptor string value scaping the '"' for a json format More...
 
uint32_t two_bytes_to_uint32 (const uint8_t *source)
 returns the uint32_t value from an array of two bytes, most significant first More...
 
uint32_t three_bytes_to_uint32 (const uint8_t *source)
 returns the uint32_t value from an array of three bytes, most significant first More...
 
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)
 
uint32_t get_bits_as_char_array (char *target, uint8_t *has_data, uint8_t *source, buf_t *bit0_offset, buf_t bit_length)
 
char * bufrdeco_explained_table_val (char *expl, size_t dim, struct bufr_tableC *tc, uint32_t *index, struct bufr_descriptor *d, uint32_t ival)
 
char * bufrdeco_explained_flag_val (char *expl, size_t dim, struct bufr_tableC *tc, struct bufr_descriptor *d, uint64_t ival, uint8_t nbits)
 
char * bufrdeco_explained_table_csv_val (char *expl, size_t dim, struct bufr_tableC *tc, uint32_t *index, struct bufr_descriptor *d, uint32_t ival)
 
char * bufrdeco_explained_flag_csv_val (char *expl, size_t dim, struct bufr_tableC *tc, struct bufr_descriptor *d, uint64_t ival, uint8_t nbits)
 
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 More...
 
int bufrdeco_tableB_val (struct bufr_atom_data *a, struct bufrdeco *b, struct bufr_descriptor *d)
 Get data from a table B descriptor. More...
 
int bufr_find_tableB_index (buf_t *index, struct bufr_tableB *tb, const char *key)
 found a descriptor index in a struct bufr_tableB More...
 
int get_table_b_reference_from_uint32_t (int32_t *target, uint8_t bits, uint32_t source)
 Get an int32_t from bits according with bufr criteria to change the reference of a descritor. Most significant bit in source is sign. More...
 
int bufr_find_tableC_csv_index (buf_t *index, struct bufr_tableC *tc, const char *key, uint32_t code)
 
char * bufrdeco_get_f2_descriptor_explanation (char *e, size_t dim, struct bufr_descriptor *d)
 
int bufrdeco_allocate_bitmap (struct bufrdeco *b)
 allocate bitmap More...
 
int bufrdeco_clean_bitmaps (struct bufrdeco *b)
 Clean all allocated bitmaps, but still is in memory. More...
 
int bufrdeco_free_bitmap_array (struct bufrdeco_bitmap_array *a)
 Free an allocated bitmap array. More...
 
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. More...
 
int two_bytes_to_descriptor (struct bufr_descriptor *d, const uint8_t *source)
 set a struct bufr_descriptor from two consecutive bytes in bufr file More...
 
int uint32_t_to_descriptor (struct bufr_descriptor *d, uint32_t id)
 parse an integer with a descriptor fom bufr ECWMF libary More...
 
int is_a_delayed_descriptor (struct bufr_descriptor *d)
 check if a descriptor is a delayed descriptor More...
 
int is_a_local_descriptor (struct bufr_descriptor *d)
 check if a descriptor is a local descriptor More...
 
int is_a_short_delayed_descriptor (struct bufr_descriptor *d)
 check if a descriptor is a short delayed descriptor More...
 
char * bufr_adjust_string (char *s)
 Supress trailing blanks of a string. More...
 
char * bufr_charray_to_string (char *s, char *buf, size_t size)
 get a null termitated c-string from an array of unsigned chars More...
 
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. More...
 
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. More...
 

Variables

const char DEFAULT_BUFRTABLES_ECMWF_DIR1 []
 
const char DEFAULT_BUFRTABLES_ECMWF_DIR2 []
 
const char DEFAULT_BUFRTABLES_WMO_CSV_DIR1 []
 
const char DEFAULT_BUFRTABLES_WMO_CSV_DIR2 []
 
const double pow10pos [8]
 
const double pow10neg [8]
 
const int32_t pow10pos_int [10]
 

Detailed Description

Include header file for bufrdeco library.

Definition in file bufrdeco.h.

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 28 of file bufrdeco.h.

◆ BUFR_COMPRESSED_DATA_MASK

#define BUFR_COMPRESSED_DATA_MASK   64

Bit mask for compressed data.

Definition at line 72 of file bufrdeco.h.

◆ BUFR_CVAL_LENGTH

#define BUFR_CVAL_LENGTH   (128)

Max length (in chars) of a cval in a bufr_atom_data.

Definition at line 329 of file bufrdeco.h.

◆ BUFR_EXPLAINED_LENGTH

#define BUFR_EXPLAINED_LENGTH   (512)

Maximum length for a explained descriptor string.

Definition at line 122 of file bufrdeco.h.

◆ BUFR_LEN

#define BUFR_LEN   (512000)

Max length of a BUFR file.

Definition at line 60 of file bufrdeco.h.

◆ BUFR_LEN_SEC1

#define BUFR_LEN_SEC1   (8192)

Max length in bytes for a sec1.

Definition at line 200 of file bufrdeco.h.

◆ BUFR_LEN_SEC2

#define BUFR_LEN_SEC2   (8192)

Max length in bytes for a sec2.

Definition at line 206 of file bufrdeco.h.

◆ BUFR_LEN_SEC3

#define BUFR_LEN_SEC3   (8 + 2 * BUFR_LEN_UNEXPANDED_DESCRIPTOR)

Max length in bytes for a sec3.

Definition at line 250 of file bufrdeco.h.

◆ BUFR_LEN_UNEXPANDED_DESCRIPTOR

#define BUFR_LEN_UNEXPANDED_DESCRIPTOR   (512)

Max amount of unexpanded descriptors in a SEC3.

Definition at line 213 of file bufrdeco.h.

◆ BUFR_MAX_BITMAP_PRESENT_DATA

#define BUFR_MAX_BITMAP_PRESENT_DATA   (4096)

Max number of data present in a bitmap definition.

Definition at line 232 of file bufrdeco.h.

◆ BUFR_MAX_BITMAPS

#define BUFR_MAX_BITMAPS   (8)

Max number of structs bufrdeco_bitmap that can be allocated in a struct bufrdeco_bitmap_array.

Definition at line 238 of file bufrdeco.h.

◆ BUFR_MAX_EXPANDED_SEQUENCES

#define BUFR_MAX_EXPANDED_SEQUENCES   (128)

Max amount of unexpanded sequences in a struct bufrdeco_expanded_tree.

Definition at line 220 of file bufrdeco.h.

◆ BUFR_MAX_QUALITY_DATA

#define BUFR_MAX_QUALITY_DATA   (8)

Max amount of quality data which is maped by a struct bufrdeco_bitmap element.

Definition at line 226 of file bufrdeco.h.

◆ BUFR_MAX_SUBSETS

#define BUFR_MAX_SUBSETS   (2048)

Max number of subsets in the array off bitoffset subset marks the bufrdeco library can manage.

Definition at line 244 of file bufrdeco.h.

◆ BUFR_MAXLINES_TABLEB

#define BUFR_MAXLINES_TABLEB   (2048)

The maximum expected lines in a Table B file.

Definition at line 90 of file bufrdeco.h.

◆ BUFR_MAXLINES_TABLEC

#define BUFR_MAXLINES_TABLEC   (8192)

The maximum expected lines in a Table C file.

Definition at line 96 of file bufrdeco.h.

◆ BUFR_MAXLINES_TABLED

#define BUFR_MAXLINES_TABLED   (8192)

The maximum expected lines in a Table D file.

Definition at line 103 of file bufrdeco.h.

◆ BUFR_NMAXSEQ

#define BUFR_NMAXSEQ   (2 * 16384)

Maximum expected descriptors in a expanded sequence for a single subset.

Definition at line 116 of file bufrdeco.h.

◆ BUFR_OBS_DATA_MASK

#define BUFR_OBS_DATA_MASK   128

Bit mask for Observed data.

Definition at line 66 of file bufrdeco.h.

◆ BUFR_TABLEB_NAME_LENGTH

#define BUFR_TABLEB_NAME_LENGTH   (128)

Max length (in chars) reserved for a name of variable in table B.

Max length (in chars) reserved for the unit string in table B.

◆ BUFR_TABLEB_UNIT_LENGTH

#define BUFR_TABLEB_UNIT_LENGTH   (64)

Definition at line 323 of file bufrdeco.h.

◆ BUFRDECO

#define BUFRDECO   "bufrdeco"

Name of this library.

Definition at line 54 of file bufrdeco.h.

◆ bufrdeco_assert

#define bufrdeco_assert (   __my_expr__)
Value:
if ( !(__my_expr__)) {\
fprintf(stderr, "%s: %s():%d -> ***The expression (%s) is false***\n", \
basename(__FILE__), __func__, __LINE__, #__my_expr__) ; \
exit (EXIT_FAILURE);\
}

Check a expression and exit if it fails.

Definition at line 374 of file bufrdeco.h.

◆ bufrdeco_assert_with_return_val

#define bufrdeco_assert_with_return_val (   __my_expr__,
  __returnval__ 
)
Value:
if ( !(__my_expr__)) {\
fprintf(stderr, "%s: %s():%d -> ***The expression (%s) is false***\n", \
basename(__FILE__), __func__, __LINE__, #__my_expr__) ; \
return (__returnval__);\
}

Check a expression and returns a given value if it fails.

Definition at line 385 of file bufrdeco.h.

◆ BUFRDECO_COMPRESSED_REF_DATA_DESCRIPTOR_BITMASK

#define BUFRDECO_COMPRESSED_REF_DATA_DESCRIPTOR_BITMASK   (2)

Bitmask for struct bufrdeco_compressed_ref which marks a data descriptor.

Definition at line 611 of file bufrdeco.h.

◆ BUFRDECO_COMPRESSED_REF_OPERATOR_DESCRIPTOR

#define BUFRDECO_COMPRESSED_REF_OPERATOR_DESCRIPTOR   (4)

Bitmask for struct bufrdeco_compressed_ref which marks an operator descriptor.

Definition at line 617 of file bufrdeco.h.

◆ BUFRDECO_COMPRESSED_REF_REPLICATOR_DESCRIPTOR

#define BUFRDECO_COMPRESSED_REF_REPLICATOR_DESCRIPTOR   (8)

Bitmask for struct bufrdeco_compressed_ref which marks a replicator descriptor.

Definition at line 623 of file bufrdeco.h.

◆ BUFRDECO_COMPRESSED_REF_SEQUENCE_FINAL_BITMASK

#define BUFRDECO_COMPRESSED_REF_SEQUENCE_FINAL_BITMASK   (16)

Bitmask for struct bufrdeco_compressed_ref which marks the final of a descriptor sequence.

Definition at line 629 of file bufrdeco.h.

◆ BUFRDECO_COMPRESSED_REF_SEQUENCE_INIT_BITMASK

#define BUFRDECO_COMPRESSED_REF_SEQUENCE_INIT_BITMASK   (1)

Bitmask for struct bufrdeco_compressed_ref which marks the init of a descriptor sequence.

Definition at line 605 of file bufrdeco.h.

◆ BUFRDECO_OUTPUT_HTML

#define BUFRDECO_OUTPUT_HTML   (1)

Bit mask to the member mask for struct bufrdeco to format output as html for SECs 0 to 3.

Definition at line 256 of file bufrdeco.h.

◆ BUFRDECO_OUTPUT_JSON

Bit mask to the member mask for struct bufrdeco to format output as json for SECs 0 to 3.

Definition at line 311 of file bufrdeco.h.

◆ BUFRDECO_OUTPUT_JSON_EXPANDED_TREE

#define BUFRDECO_OUTPUT_JSON_EXPANDED_TREE   (256)

Bit mask to the member mask of struct bufrdeco to print bufr expanded tree of descriptors.

Definition at line 305 of file bufrdeco.h.

◆ BUFRDECO_OUTPUT_JSON_SEC0

#define BUFRDECO_OUTPUT_JSON_SEC0   (8)

Bit mask to the member mask of struct bufrdeco to print info for SEC 0 in json format.

Definition at line 275 of file bufrdeco.h.

◆ BUFRDECO_OUTPUT_JSON_SEC1

#define BUFRDECO_OUTPUT_JSON_SEC1   (16)

Bit mask to the member mask of struct bufrdeco to print info for SEC 1 in json format.

Definition at line 281 of file bufrdeco.h.

◆ BUFRDECO_OUTPUT_JSON_SEC2

#define BUFRDECO_OUTPUT_JSON_SEC2   (32)

Bit mask to the member mask of struct bufrdeco to print bufr info for SEC 2 in json format.

Definition at line 287 of file bufrdeco.h.

◆ BUFRDECO_OUTPUT_JSON_SEC3

#define BUFRDECO_OUTPUT_JSON_SEC3   (64)

Bit mask to the member mask of struct bufrdeco to print bufr info for SEC 3 in json format.

Definition at line 293 of file bufrdeco.h.

◆ BUFRDECO_OUTPUT_JSON_SUBSET_DATA

#define BUFRDECO_OUTPUT_JSON_SUBSET_DATA   (128)

Bit mask to the member mask of struct bufrdeco to print bufr subset data in json format.

Definition at line 299 of file bufrdeco.h.

◆ BUFRDECO_OUTPUT_XML

#define BUFRDECO_OUTPUT_XML   (2)

Bit mask to the member mask for struct bufrdeco to format output as xml for SECs 0 to 3.

Definition at line 262 of file bufrdeco.h.

◆ BUFRDECO_PATH_LENGTH

#define BUFRDECO_PATH_LENGTH   (256)

Length for files/directory path strings.

Definition at line 335 of file bufrdeco.h.

◆ BUFRDECO_TABLES_CACHE_SIZE

#define BUFRDECO_TABLES_CACHE_SIZE   (16)

Max number of structs bufr_tables in a bufr_tables_cache.

Definition at line 341 of file bufrdeco.h.

◆ BUFRDECO_USE_TABLES_CACHE

#define BUFRDECO_USE_TABLES_CACHE   (4)

Bit mask to the member mask of struct bufrdeco to mark the use of bufr_tables cache.

Definition at line 268 of file bufrdeco.h.

◆ CSV_MAXL

#define CSV_MAXL   (2048)

Maximum length in a string to be parsed as csv.

Definition at line 128 of file bufrdeco.h.

◆ DESCRIPTOR_HAVE_CODE_TABLE_STRING

#define DESCRIPTOR_HAVE_CODE_TABLE_STRING   (16)

Bit mask for a code table string in a struct bufr_atom_data.

Definition at line 164 of file bufrdeco.h.

◆ DESCRIPTOR_HAVE_FLAG_TABLE_STRING

#define DESCRIPTOR_HAVE_FLAG_TABLE_STRING   (32)

Bit mask for a flag table string in a struct bufr_atom_data.

Definition at line 170 of file bufrdeco.h.

◆ DESCRIPTOR_HAVE_REAL_VALUE

#define DESCRIPTOR_HAVE_REAL_VALUE   (2)

Bit mask for a real value in a struct bufr_atom_data.

Definition at line 146 of file bufrdeco.h.

◆ DESCRIPTOR_HAVE_STRING_VALUE

#define DESCRIPTOR_HAVE_STRING_VALUE   (4)

Bit mask for a string in a struct bufr_atom_data.

Definition at line 152 of file bufrdeco.h.

◆ DESCRIPTOR_IS_A_REPLICATOR

#define DESCRIPTOR_IS_A_REPLICATOR   (128)

Bit mask for a replicator descriptor in a struct bufr_atom_data.

Definition at line 182 of file bufrdeco.h.

◆ DESCRIPTOR_IS_AN_OPERATOR

#define DESCRIPTOR_IS_AN_OPERATOR   (256)

Bit mask for an operator data descriptor in a struct bufr_atom_data.

Definition at line 188 of file bufrdeco.h.

◆ DESCRIPTOR_IS_CODE_TABLE

#define DESCRIPTOR_IS_CODE_TABLE   (8)

Bit mask for a code table in a struct bufr_atom_data.

Definition at line 158 of file bufrdeco.h.

◆ DESCRIPTOR_IS_FLAG_TABLE

#define DESCRIPTOR_IS_FLAG_TABLE   (64)

Bit mask for a flag table in a struct bufr_atom_data.

Definition at line 176 of file bufrdeco.h.

◆ DESCRIPTOR_IS_LOCAL

#define DESCRIPTOR_IS_LOCAL   (512)

Bit mask for a flag table string in a struct bufr_atom_data.

Definition at line 194 of file bufrdeco.h.

◆ DESCRIPTOR_VALUE_MISSING

#define DESCRIPTOR_VALUE_MISSING   (1)

Bit mask for a missing value in a struct bufr_atom_data.

Definition at line 140 of file bufrdeco.h.

◆ MAXLINES_TABLEC

#define MAXLINES_TABLEC   BUFR_MAXLINES_TABLEC

The maximum expected lines in a Table C file, legacy def used from ECMWF.

Definition at line 110 of file bufrdeco.h.

◆ MISSING_INTEGER

#define MISSING_INTEGER   (2147483647)

The missing default value for integer values.

Definition at line 84 of file bufrdeco.h.

◆ MISSING_REAL

#define MISSING_REAL   (1.7e38)

The missing default value for real values.

Definition at line 78 of file bufrdeco.h.

◆ NMAXSEQ_DESCRIPTORS

#define NMAXSEQ_DESCRIPTORS   (256)

Maximum nuber of unexpanded descriptors in a struct bufr_sequence.

Definition at line 134 of file bufrdeco.h.

◆ strcpy_safe

#define strcpy_safe (   _target_,
  _src_ 
)
Value:
{\
strncpy(_target_,_src_,(sizeof(_target_) - 1)); \
_target_[sizeof(_target_) - 1] = '\0';}

Macro to make safely a strcpy when we know in calling function the size of string target with sizeof()

Definition at line 358 of file bufrdeco.h.

◆ strncpy_safe

#define strncpy_safe (   _target_,
  _src_,
  _dim_ 
)
Value:
{\
strncpy(_target_, _src_, _dim_ - 1); \
_target_[_dim_ - 1] = '\0';}

Macro to make safely a strcpy when we know in calling function the size of string target directly.

Definition at line 366 of file bufrdeco.h.

Typedef Documentation

◆ buf_t

Type to set offsets and dimension of arrays or counters used in bufrdeco.

Definition at line 346 of file bufrdeco.h.

◆ ibuf_t

Type to set offsets and dimension of arrays or counters used in bufrdeco.

Definition at line 351 of file bufrdeco.h.

Function Documentation

◆ bufr_adjust_string()

char * bufr_adjust_string ( char *  s)

Supress trailing blanks of a string.

Parameters
sstring to process
Returns
the resulting s string

Definition at line 333 of file bufrdeco_utils.c.

334{
335 size_t l;
336
337 //bufrdeco_assert (s != NULL);
338
339 l = strlen ( s );
340 while ( l && s[--l] == ' ' )
341 s[l] = '\0';
342 return s;
343}

Referenced by bufrdeco_print_json_object_atom_data(), bufrdeco_print_json_tree_recursive(), and main().

Here is the caller graph for this function:

◆ bufr_charray_to_string()

char * bufr_charray_to_string ( char *  s,
char *  buf,
size_t  size 
)

get a null termitated c-string from an array of unsigned chars

Parameters
sresulting string
bufpointer to first element in array
sizenumber of chars in array
Returns
the resulting s string

Definition at line 316 of file bufrdeco_utils.c.

317{
318 //bufrdeco_assert (s != NULL && buf != NULL);
319
320 // copy
321 memcpy ( s , buf, size );
322 // add final string mark
323 s[size] = '\0';
324 return s;
325}

Referenced by main().

Here is the caller graph for this function:

◆ bufr_decode_subset_data_compressed()

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.

Parameters
spointer to a struct bufrdeco_subset_sequence_data where to set the results
rpointer to the struct bufrdeco_compressed_data_references with the info about how and where to get the data
bbasic container struct bufrdeco
Returns
Returns 0 if succeeded, 1 otherwise

Definition at line 965 of file bufrdeco_compressed.c.

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}
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
buf_t bufrdeco_print_json_separator(FILE *out)
Print the comma ',' separator in an output.
buf_t bufrdeco_print_json_object_operator_descriptor(FILE *out, struct bufr_descriptor *d, char *aux)
print an operator desciptor as a json object
buf_t bufrdeco_print_json_sequence_descriptor_final(FILE *out)
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 BUFRDECO_COMPRESSED_REF_SEQUENCE_INIT_BITMASK
Bitmask for struct bufrdeco_compressed_ref which marks the init of a descriptor sequence.
Definition: bufrdeco.h:605
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
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 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
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.
struct bufrdeco_compressed_ref * refs
Definition: bufrdeco.h:671
struct bufr_descriptor * desc
Definition: bufrdeco.h:652
struct bufr_sequence * seq
Definition: bufrdeco.h:653
struct bufr_atom_data * sequence
Definition: bufrdeco.h:462
uint32_t mask
Definition: bufrdeco.h:966
struct bufrdeco_decoding_data_state state
Definition: bufrdeco.h:976
FILE * out
Definition: bufrdeco.h:984
char error[1024]
Definition: bufrdeco.h:983

References BUFRDECO_COMPRESSED_REF_DATA_DESCRIPTOR_BITMASK, BUFRDECO_COMPRESSED_REF_OPERATOR_DESCRIPTOR, BUFRDECO_COMPRESSED_REF_REPLICATOR_DESCRIPTOR, BUFRDECO_COMPRESSED_REF_SEQUENCE_FINAL_BITMASK, BUFRDECO_COMPRESSED_REF_SEQUENCE_INIT_BITMASK, bufrdeco_get_atom_data_from_compressed_data_ref(), bufrdeco_increase_data_array(), BUFRDECO_OUTPUT_JSON_SUBSET_DATA, bufrdeco_print_json_object_atom_data(), bufrdeco_print_json_object_operator_descriptor(), bufrdeco_print_json_object_replicator_descriptor(), bufrdeco_print_json_separator(), bufrdeco_print_json_sequence_descriptor_final(), bufrdeco_print_json_sequence_descriptor_header(), bufrdeco_print_json_subset_data_epilogue(), bufrdeco_print_json_subset_data_prologue(), bufrdeco_compressed_ref::desc, bufrdeco_subset_sequence_data::dim, bufrdeco::error, bufrdeco_compressed_ref::is_associated, bufrdeco_compressed_ref::mask, bufrdeco::mask, bufrdeco_subset_sequence_data::nd, bufrdeco_compressed_data_references::nd, bufrdeco::out, bufrdeco_compressed_data_references::refs, bufrdeco_compressed_ref::replicated_desc, bufrdeco_compressed_ref::replicated_loop, bufrdeco_compressed_ref::replicated_ndesc, bufrdeco_compressed_ref::replicated_nloop, bufrdeco_compressed_ref::seq, bufrdeco_subset_sequence_data::sequence, bufrdeco_subset_sequence_data::ss, bufrdeco::state, and bufrdeco_decoding_data_state::subset.

Referenced by bufrdeco_decode_data_subset().

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

◆ bufr_find_tableB_index()

int bufr_find_tableB_index ( buf_t index,
struct bufr_tableB tb,
const char *  key 
)

found a descriptor index in a struct bufr_tableB

Parameters
indexpointer to a size_t where to set the result if success
tbpointer to struct bufr_tableB where are stored all table B data
keydescriptor string in format FXXYYY
Returns
0 if success, 1 otherwise

Definition at line 205 of file bufrdeco_tableB.c.

206{
207 uint32_t ix;
208 buf_t i, i0;
209 char *c;
210 struct bufr_descriptor desc;
211
212 //bufrdeco_assert ( tb != NULL);
213
214 ix = strtoul ( key, &c, 10 );
215 uint32_t_to_descriptor ( &desc, ix );
216
217 // first chance
218 i0 = tb->x_start[desc.x] + tb->y_ref[desc.x][desc.y];
219 if ( tb->item[i0].x == desc.x && tb->item[i0].y == desc.y )
220 {
221 *index = i0;
222 return 0;
223 }
224 // Second chance
225 i0 = tb->x_start[desc.x];
226 for ( i = i0 ; i < i0 + tb->num[desc.x] ; i++ )
227 {
228 if ( tb->item[i].x != desc.x )
229 {
230 return 1; // descriptor not found
231 }
232 if ( tb->item[i].y == desc.y )
233 {
234 *index = i;
235 return 0; // found
236 }
237 }
238 return 1; // not found
239}
uint32_t buf_t
Type to set offsets and dimension of arrays or counters used in bufrdeco.
Definition: bufrdeco.h:346
int uint32_t_to_descriptor(struct bufr_descriptor *d, uint32_t id)
parse an integer with a descriptor fom bufr ECWMF libary
BUFR descriptor.
Definition: bufrdeco.h:409
char c[12]
Definition: bufrdeco.h:414
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 num[64]
Definition: bufrdeco.h:865
buf_t x_start[64]
Definition: bufrdeco.h:864

References bufr_descriptor::c, bufr_tableB::item, bufr_tableB::num, uint32_t_to_descriptor(), bufr_descriptor::x, bufr_tableB_decoded_item::x, bufr_tableB::x_start, bufr_descriptor::y, bufr_tableB_decoded_item::y, and bufr_tableB::y_ref.

Referenced by bufr_restore_original_tableB_item(), bufrdeco_fprint_tree_recursive(), and bufrdeco_print_json_tree_recursive().

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

◆ bufr_find_tableC_csv_index()

int bufr_find_tableC_csv_index ( buf_t index,
struct bufr_tableC tc,
const char *  key,
uint32_t  code 
)

Definition at line 134 of file bufrdeco_tableC.c.

135{
136 uint32_t ix;
137 buf_t i, i0;
138 char *c;
139 struct bufr_descriptor desc;
140
141 bufrdeco_assert ( tc != NULL && index != NULL );
142
143 ix = strtoul ( key, &c, 10 );
144 uint32_t_to_descriptor ( &desc, ix );
145 i0 = tc->x_start[desc.x];
146 for ( i = i0 ; i < i0 + tc->num[desc.x] ; i++ )
147 {
148 if ( tc->item[i].y == desc.y && tc->item[i].ival == code )
149 {
150 *index = i;
151 return 0; // found
152 }
153 }
154 return 1; // not found
155}
#define bufrdeco_assert(__my_expr__)
Check a expression and exit if it fails.
Definition: bufrdeco.h:374
buf_t num[64]
Definition: bufrdeco.h:897
struct bufr_tableC_decoded_item item[BUFR_MAXLINES_TABLEC]
Definition: bufrdeco.h:899
buf_t x_start[64]
Definition: bufrdeco.h:896

References bufrdeco_assert, bufr_descriptor::c, bufr_tableC::item, bufr_tableC_decoded_item::ival, bufr_tableC::num, uint32_t_to_descriptor(), bufr_descriptor::x, bufr_tableC::x_start, bufr_descriptor::y, and bufr_tableC_decoded_item::y.

Referenced by bufrdeco_explained_table_val().

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

◆ bufr_read_subset_offset_bits()

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.

Parameters
ffile pointer opened by caller
offpointer to the struct bufrdeco_subset_bit_offsets with the data to write into file
Returns
if success return 0, otherwise 1

Definition at line 577 of file bufrdeco_utils.c.

578{
579 size_t readed;
580
581 //bufrdeco_assert (off != NULL && f != NULL );
582
583 readed = fread( &(off->nr), sizeof (buf_t ), 1, f);
584 bufrdeco_assert_with_return_val (readed == 1, 1);
585
586 readed = fread( &(off->ofs[0]), sizeof (buf_t ), off->nr, f);
587 bufrdeco_assert_with_return_val (readed == off->nr, 1);
588
589 return 0;
590}
#define bufrdeco_assert_with_return_val(__my_expr__, __returnval__)
Check a expression and returns a given value if it fails.
Definition: bufrdeco.h:385
buf_t ofs[BUFR_MAX_SUBSETS]
Definition: bufrdeco.h:687

References bufrdeco_assert_with_return_val, bufrdeco_subset_bit_offsets::nr, and bufrdeco_subset_bit_offsets::ofs.

Referenced by bufrdeco_read_subset_offset_bits().

Here is the caller graph for this function:

◆ bufr_read_tableB()

int bufr_read_tableB ( struct bufrdeco b)

Definition at line 42 of file bufrdeco_tableB.c.

43{
44 char *c;
45 FILE *t;
46 buf_t i = 0;
47 int nt;
48 uint32_t ix;
49 char l[CSV_MAXL];
50 char caux[512];
51 char *tk[16];
52 struct bufr_tableB *tb;
53 struct bufr_descriptor desc;
54
55 //bufrdeco_assert ( b != NULL );
56
57 tb = &(b->tables->b);
58 if ( tb->path[0] == 0 )
59 {
60 return 1;
61 }
62
63 // If we've already readed this table. We just regenerate the table with original values
64 if ( strcmp ( tb->path, tb->old_path ) == 0 )
65 {
66#ifdef __DEBUG
67 printf ("# Reused table %s\n", tb->path);
68#endif
69 for ( i = 0; i < tb->nlines ; i++ )
70 {
71 tb->item[i].scale = tb->item[i].scale_ori;
72 tb->item[i].reference = tb->item[i].reference_ori;
73 tb->item[i].nbits = tb->item[i].nbits_ori;
74 tb->item[i].changed = 0;
75 }
76 return 0; // all done
77 }
78
79 strcpy ( caux, tb->path );
80 memset ( tb, 0, sizeof ( struct bufr_tableB ) );
81 strcpy ( tb->path, caux );
82 if ( ( t = fopen ( tb->path, "r" ) ) == NULL )
83 {
84 snprintf ( b->error, sizeof (b->error),"Unable to open table B file '%s'\n", tb->path );
85 return 1;
86 }
87
88 // read first line, it is ignored
89 fgets ( l, CSV_MAXL, t );
90
91 while ( fgets ( l, CSV_MAXL, t ) != NULL && i < BUFR_MAXLINES_TABLEB )
92 {
93 // Parse line
94 if ( parse_csv_line ( &nt, tk, l ) < 0 || nt != 7 )
95 {
96 snprintf ( b->error, sizeof (b->error),"Error parsing csv line from table B file '%s'\n", tb->path );
97 return 1;
98 }
99
100 // First we build the descriptor
101 ix = strtoul ( tk[0], &c, 10 );
102 uint32_t_to_descriptor ( &desc, ix );
103 tb->item[i].changed = 0; // Original from table B
104 tb->item[i].x = desc.x; // x
105 tb->item[i].y = desc.y; // y
106 strcpy ( tb->item[i].key, desc.c ); // key
107 if ( tb->num[desc.x] == 0 )
108 {
109 tb->x_start[desc.x] = i; // marc the start
110 }
111 tb->y_ref[desc.x][desc.y] = i - tb->x_start[desc.x]; // marc the position from start of first x
112 ( tb->num[desc.x] )++;
113
114 // detailed name
115 if ( tk[2][0] )
116 {
117 sprintf ( caux,"%s %s", tk[1], tk[2] );
118 }
119 else
120 {
121 strcpy ( caux, tk[1] );
122 }
123
124 // and finally copy
125 strcpy ( tb->item[i].name, caux );
126
127 // unit
128 strcpy ( caux, tk[3] );
129 strcpy ( tb->item[i].unit, caux );
130
131 // escale
132 tb->item[i].scale_ori = strtol ( tk[4], &c, 10 );
133 tb->item[i].scale = tb->item[i].scale_ori;
134
135 // reference
136 tb->item[i].reference_ori = strtol ( tk[5], &c, 10 );
137 tb->item[i].reference = tb->item[i].reference_ori;
138
139 // bits
140 tb->item[i].nbits_ori = strtol ( tk[6], &c, 10 );
141 tb->item[i].nbits = tb->item[i].nbits_ori;
142
143 i++;
144 }
145 tb->x_start[0] = 0; // fix the start for x = 0
146 fclose ( t );
147 tb->nlines = i;
148 tb->wmo_table = 1;
149 strcpy ( tb->old_path, tb->path ); // store latest path
150 return 0;
151}
#define BUFR_MAXLINES_TABLEB
The maximum expected lines in a Table B file.
Definition: bufrdeco.h:90
#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
char unit[BUFR_TABLEB_UNIT_LENGTH]
Definition: bufrdeco.h:843
char name[BUFR_TABLEB_NAME_LENGTH]
Definition: bufrdeco.h:842
Store a table B readed from a file formated and named as ECMWF bufrdc package.
Definition: bufrdeco.h:859
buf_t nlines
Definition: bufrdeco.h:863
char old_path[BUFRDECO_PATH_LENGTH]
Definition: bufrdeco.h:862
int wmo_table
Definition: bufrdeco.h:860
char path[BUFRDECO_PATH_LENGTH]
Definition: bufrdeco.h:861
struct bufr_tableB b
Definition: bufrdeco.h:939
struct bufr_tables * tables
Definition: bufrdeco.h:973

References bufr_tables::b, BUFR_MAXLINES_TABLEB, bufr_descriptor::c, bufr_tableB_decoded_item::changed, CSV_MAXL, bufrdeco::error, bufr_tableB::item, bufr_tableB_decoded_item::key, bufr_tableB_decoded_item::name, bufr_tableB_decoded_item::nbits, bufr_tableB_decoded_item::nbits_ori, bufr_tableB::nlines, bufr_tableB::num, bufr_tableB::old_path, parse_csv_line(), bufr_tableB::path, bufr_tableB_decoded_item::reference, bufr_tableB_decoded_item::reference_ori, bufr_tableB_decoded_item::scale, bufr_tableB_decoded_item::scale_ori, bufrdeco::tables, uint32_t_to_descriptor(), bufr_tableB_decoded_item::unit, bufr_tableB::wmo_table, bufr_descriptor::x, bufr_tableB_decoded_item::x, bufr_tableB::x_start, bufr_descriptor::y, bufr_tableB_decoded_item::y, and bufr_tableB::y_ref.

Referenced by bufr_read_tables().

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

◆ bufr_read_tableC()

int bufr_read_tableC ( struct bufrdeco b)

Reads a file with table C content (Code table and bit flags) according with csv WMO format.

Parameters
bpointer to a target struct bufrdeco
Returns
0 if success, 1 otherwise

Definition at line 33 of file bufrdeco_tableC.c.

34{
35 char *c;
36 //size_t used = 0;
37 FILE *t;
38 int nt;
39 uint32_t ix;
40 buf_t i = 0;
41 struct bufr_descriptor desc;
42 struct bufr_tableC *tc;
43 char *tk[16];
44 char caux[256], l[CSV_MAXL];
45
46 //bufrdeco_assert ( b != NULL );
47
48 tc = & ( b->tables->c );
49
50 if ( tc->path[0] == 0 )
51 {
52 return 1;
53 }
54
55 // If we've already readed this table.
56 if ( strcmp ( tc->path, tc->old_path ) == 0 )
57 {
58#ifdef __DEBUG
59 printf ("# Reused table %s\n", tc->path);
60#endif
61 return 0; // all done
62 }
63
64 strcpy ( caux, tc->path );
65 memset ( tc, 0, sizeof ( struct bufr_tableC ) );
66 strcpy ( tc->path, caux );
67 if ( ( t = fopen ( tc->path, "r" ) ) == NULL )
68 {
69 snprintf ( b->error, sizeof ( b->error ),"Unable to open table C file '%s'\n", tc->path );
70 return 1;
71 }
72
73 // read first line, it is ignored
74 fgets ( l, CSV_MAXL, t );
75
76 while ( fgets ( l, CSV_MAXL, t ) != NULL && i < BUFR_MAXLINES_TABLEC )
77 {
78
79 // Parse line
80 if ( parse_csv_line ( &nt, tk, l ) < 0 || nt != 6 )
81 {
82 snprintf ( b->error, sizeof ( b->error ),"Error parsing csv line from table C file '%s'. Found %d fields in line %u \n", tc->path, nt, i );
83 return 1;
84 }
85
86 // Check if code contains other than non-numeric i.e. 'All' or '-'
87 // In this case, the line is ignored
88 if ( tk[1][0] == 0 || strchr ( tk[1], '-' ) != NULL || strstr ( tk[1], "All" ) != NULL )
89 continue;
90
91 // Key
92 // First we build the descriptor
93 ix = strtoul ( tk[0], &c, 10 );
94 uint32_t_to_descriptor ( &desc, ix );
95 strcpy ( tc->item[i].key, tk[0] );
96 tc->item[i].x = desc.x;
97 tc->item[i].y = desc.y;
98
99 // Integer value
100 tc->item[i].ival = strtoul ( tk[1], &c, 10 );
101
102 // Description
103 c = & tc->item[i].description[0];
104 snprintf ( c, BUFR_EXPLAINED_LENGTH, "%s %s %s %s", tk[2], tk[3], tk[4], tk[5] );
105
106 if ( tc->num[desc.x] == 0 )
107 {
108 tc->x_start[desc.x] = i; // marc the start
109 }
110 if ( tc->y_ref[desc.x][desc.y] == 0 )
111 {
112 tc->y_ref[desc.x][desc.y] = i - tc->x_start[desc.x]; // marc the position from start of first x
113 }
114 ( tc->num[desc.x] ) ++;
115 i++;
116 }
117 fclose ( t );
118 tc->nlines = i;
119 tc->wmo_table = 1;
120 strcpy ( tc->old_path, tc->path ); // store latest path
121 return 0;
122}
#define BUFR_EXPLAINED_LENGTH
Maximum length for a explained descriptor string.
Definition: bufrdeco.h:122
#define BUFR_MAXLINES_TABLEC
The maximum expected lines in a Table C file.
Definition: bufrdeco.h:96
char description[BUFR_EXPLAINED_LENGTH]
Definition: bufrdeco.h:882
Store a table C readed from a file formated and named as ECMWF bufrdc package.
Definition: bufrdeco.h:891
int wmo_table
Definition: bufrdeco.h:892
char path[BUFRDECO_PATH_LENGTH]
Definition: bufrdeco.h:893
buf_t nlines
Definition: bufrdeco.h:895
char old_path[BUFRDECO_PATH_LENGTH]
Definition: bufrdeco.h:894
buf_t y_ref[64][256]
Definition: bufrdeco.h:898
struct bufr_tableC c
Definition: bufrdeco.h:940

References BUFR_EXPLAINED_LENGTH, BUFR_MAXLINES_TABLEC, bufr_tables::c, CSV_MAXL, bufr_tableC_decoded_item::description, bufrdeco::error, bufr_tableC::item, bufr_tableC_decoded_item::ival, bufr_tableC_decoded_item::key, bufr_tableC::nlines, bufr_tableC::num, bufr_tableC::old_path, parse_csv_line(), bufr_tableC::path, bufrdeco::tables, uint32_t_to_descriptor(), bufr_tableC::wmo_table, bufr_descriptor::x, bufr_tableC_decoded_item::x, bufr_tableC::x_start, bufr_descriptor::y, bufr_tableC_decoded_item::y, and bufr_tableC::y_ref.

Referenced by bufr_read_tables().

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

◆ bufr_read_tableD()

int bufr_read_tableD ( struct bufrdeco b)

Reads a file with table D content according with WMO csv format.

Parameters
bpointer to a target struct bufrdeco
Returns
If succeded return 0, otherwise 1

Definition at line 32 of file bufrdeco_tableD.c.

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}
#define BUFR_MAXLINES_TABLED
The maximum expected lines in a Table D file.
Definition: bufrdeco.h:103
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

References BUFR_MAXLINES_TABLED, CSV_MAXL, bufr_tables::d, bufr_tableD_decoded_item::description, bufr_tableD_decoded_item::description2, bufrdeco::error, bufr_tableD::item, bufr_tableD_decoded_item::key, bufr_tableD_decoded_item::key2, bufr_tableD::l, bufr_tableD::nlines, bufr_tableD::num, bufr_tableD::old_path, parse_csv_line(), bufr_tableD::path, bufrdeco::tables, uint32_t_to_descriptor(), bufr_tableD::wmo_table, bufr_descriptor::x, and bufr_tableD::x_start.

Referenced by bufr_read_tables().

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

◆ bufr_read_tables()

int bufr_read_tables ( struct bufrdeco b)

Read the tables according with bufr file data from a bufr table directory.

Parameters
bbasic struct with needed data
Returns
if success return 0, otherwise 1

The default directories where to search bufr tables are stored in DEFAULT_BUFRTABLES_WMO_CSV_DIR1 and DEFAULT_BUFRTABLES_WMO_CSV_DIR2

Definition at line 162 of file bufrdeco_wmo.c.

163{
164 int index;
165 buf_t i;
166 bufrdeco_assert ( b != NULL );
167 struct bufr_tableB *tb;
168
170 {
171 // When using cache, member b->tables is actually a pointer in array b->cache.tab[]
172
173 if ( ( index = bufrdeco_cache_tables_search ( & ( b->cache ), b->sec1.master_version ) ) >= 0 )
174 {
175#ifdef __DEBUG
176 printf ( "# Found tables in cache for version %u index %d\n", b->sec1.master_version, index );
177#endif
178 // hit cache, then the only task is to change member b->tables, and restore original values from item im tableB
179 b->tables = b->cache.tab[index];
180 tb = & ( b->tables->b );
181
182 for ( i = 0; i < tb->nlines ; i++ )
183 {
184 tb->item[i].scale = tb->item[i].scale_ori;
185 tb->item[i].reference = tb->item[i].reference_ori;
186 tb->item[i].nbits = tb->item[i].nbits_ori;
187 tb->item[i].changed = 0;
188 }
189
190 // all done
191 return 0;
192 }
193 else
194 {
195#ifdef __DEBUG
196 printf ( "# Tables for version %u not found in cache. Stored in index %d\n", b->sec1.master_version, b->cache.next );
197#endif
198 // If not in cache, the new master version tables has to be stored. This implies that
199 bufrdeco_store_tables ( & ( b->tables ), & ( b->cache ), b->sec1.master_version );
200
201 // get tablenames
202 if ( get_wmo_tablenames ( b ) )
203 {
204 snprintf ( b->error, sizeof ( b->error ),"%s(): Cannot find bufr tables\n", __func__ );
205 return 1;
206 }
207
208 // Missed cache
209 if ( bufr_read_tableB ( b ) )
210 {
211 return 1;
212 }
213
214 if ( bufr_read_tableC ( b ) )
215 {
216 return 1;
217 }
218
219 if ( bufr_read_tableD ( b ) )
220 {
221 return 1;
222 }
223
224 }
225 }
226 else
227 {
228 // If tables still not initialized then do it
229 if ( b->tables == NULL && bufrdeco_init_tables ( & ( b->tables ) ) )
230 {
231 snprintf ( b->error, sizeof ( b->error ), "%s(): Cannot allocate memory for tables\n", __func__ );
232 return 1;
233 }
234 // get tablenames
235 if ( get_wmo_tablenames ( b ) )
236 {
237 snprintf ( b->error, sizeof ( b->error ),"%s(): Cannot find bufr tables\n", __func__ );
238 return 1;
239 }
240
241 // And now read tables
242 if ( bufr_read_tableB ( b ) )
243 {
244 return 1;
245 }
246
247 if ( bufr_read_tableC ( b ) )
248 {
249 return 1;
250 }
251
252 if ( bufr_read_tableD ( b ) )
253 {
254 return 1;
255 }
256 }
257 return 0;
258}
int bufrdeco_init_tables(struct bufr_tables **t)
Init a struct bufr_tables allocating space.
int bufr_read_tableC(struct bufrdeco *b)
Reads a file with table C content (Code table and bit flags) according with csv WMO format.
int bufr_read_tableD(struct bufrdeco *b)
Reads a file with table D content according with WMO csv format.
#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 bufr_read_tableB(struct bufrdeco *b)
int get_wmo_tablenames(struct bufrdeco *b)
Get the complete pathnames for WMO csv table files needed by a bufr message.
Definition: bufrdeco_wmo.c:47
int bufrdeco_store_tables(struct bufr_tables **t, struct bufr_tables_cache *c, uint8_t ver)
Init an element of array c->tab[] if still not allocated. If allocated clean it and set *t pointing t...
Definition: bufrdeco_wmo.c:269
int bufrdeco_cache_tables_search(struct bufr_tables_cache *c, uint8_t ver)
Search a struct bufr_tables in bufr_tables_cache.
Definition: bufrdeco_wmo.c:304
uint8_t master_version
Definition: bufrdeco.h:782
struct bufr_tables * tab[BUFRDECO_TABLES_CACHE_SIZE]
Definition: bufrdeco.h:955
struct bufr_tables_cache cache
Definition: bufrdeco.h:974
struct bufr_sec1 sec1
Definition: bufrdeco.h:969

References bufr_tables::b, bufr_read_tableB(), bufr_read_tableC(), bufr_read_tableD(), bufrdeco_assert, bufrdeco_cache_tables_search(), bufrdeco_init_tables(), bufrdeco_store_tables(), BUFRDECO_USE_TABLES_CACHE, bufrdeco::cache, bufr_tableB_decoded_item::changed, bufrdeco::error, get_wmo_tablenames(), bufr_tableB::item, bufrdeco::mask, bufr_sec1::master_version, bufr_tableB_decoded_item::nbits, bufr_tableB_decoded_item::nbits_ori, bufr_tables_cache::next, bufr_tableB::nlines, bufr_tableB_decoded_item::reference, bufr_tableB_decoded_item::reference_ori, bufr_tableB_decoded_item::scale, bufr_tableB_decoded_item::scale_ori, bufrdeco::sec1, bufr_tables_cache::tab, and bufrdeco::tables.

Referenced by bufrdeco_read_buffer().

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

◆ bufr_write_subset_offset_bits()

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.

Parameters
ffile pointer opened by caller
offpointer to the struct bufrdeco_subset_bit_offsets with the data to write into file
Returns
if success return 0, otherwise 1

Definition at line 555 of file bufrdeco_utils.c.

556{
557 size_t wrote;
558
559 //bufrdeco_assert (off != NULL && f != NULL );
560
561 wrote = fwrite( &(off->nr), sizeof (buf_t ), 1, f);
562 bufrdeco_assert_with_return_val (wrote == 1, 1);
563
564 wrote = fwrite( &(off->ofs[0]), sizeof (buf_t ), off->nr, f);
565 bufrdeco_assert_with_return_val (wrote == off->nr, 1);
566
567 return 0;
568}

References bufrdeco_assert_with_return_val, bufrdeco_subset_bit_offsets::nr, and bufrdeco_subset_bit_offsets::ofs.

Referenced by bufrdeco_write_subset_offset_bits().

Here is the caller graph for this function:

◆ bufrdeco_add_to_bitmap()

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.

Parameters
bmtarget struct bufrdeco_bitmap where to push
index_toindex of the bufrdeco_bitmap which this is bitmapping to
index_byindex of the bufrdeco_bitmap which this is bitmapped by
Returns
If no space to push returns 1, otherwise 0

Definition at line 461 of file bufrdeco_utils.c.

462{
463 //bufrdeco_assert (bm != NULL);
464
466 {
467 bm->bitmap_to[bm->nb] = index_to;
468 bm->bitmaped_by[bm->nb] = index_by;
469 ( bm->nb )++;
470 return 0;
471 }
472 return 1;
473}
#define BUFR_MAX_BITMAP_PRESENT_DATA
Max number of data present in a bitmap definition.
Definition: bufrdeco.h:232
buf_t bitmaped_by[BUFR_MAX_BITMAP_PRESENT_DATA]
Definition: bufrdeco.h:473
buf_t bitmap_to[BUFR_MAX_BITMAP_PRESENT_DATA]
Definition: bufrdeco.h:472

References bufrdeco_bitmap::bitmap_to, bufrdeco_bitmap::bitmaped_by, BUFR_MAX_BITMAP_PRESENT_DATA, and bufrdeco_bitmap::nb.

Referenced by bufrdeco_decode_replicated_subsequence(), and bufrdeco_decode_replicated_subsequence_compressed().

Here is the caller graph for this function:

◆ bufrdeco_allocate_bitmap()

int bufrdeco_allocate_bitmap ( struct bufrdeco b)

allocate bitmap

Parameters
bthe active struct bufrdeco
Returns
If succeeded return 0, otherwise 1

Definition at line 269 of file bufrdeco_memory.c.

270{
271 buf_t nba;
272
273 bufrdeco_assert ( b != NULL );
274
275 nba = b->bitmap.nba;
276
277 if ( nba < BUFR_MAX_BITMAPS )
278 {
279 if ( b->bitmap.bmap[nba] != NULL )
280 {
281 // the bitmap already is allocated
282 return 0;
283 }
284 // let's try to allocate it!
285 if ( ( b->bitmap.bmap[nba] = ( struct bufrdeco_bitmap * ) calloc ( 1, sizeof ( struct bufrdeco_bitmap ) ) ) == NULL )
286 {
287 snprintf ( b->error, sizeof ( b->error ),"%s(): Cannot allocate space for struct bufrdeco_bitmap\n", __func__ );
288 return 1;
289 }
290 // Update de counter
291 ( b->bitmap.nba )++;
292 return 0;
293 }
294 else
295 {
296 snprintf ( b->error, sizeof ( b->error ),"%s(): Too much bitmaps to allocate. The limit is %d\n", __func__, BUFR_MAX_BITMAPS );
297 return 1;
298 }
299}
#define BUFR_MAX_BITMAPS
Max number of structs bufrdeco_bitmap that can be allocated in a struct bufrdeco_bitmap_array.
Definition: bufrdeco.h:238
struct bufrdeco_bitmap * bmap[BUFR_MAX_BITMAPS]
Definition: bufrdeco.h:493
Stores all needed data for a bufr bitmap.
Definition: bufrdeco.h:470
struct bufrdeco_bitmap_array bitmap
Definition: bufrdeco.h:980

References bufrdeco::bitmap, bufrdeco_bitmap_array::bmap, BUFR_MAX_BITMAPS, bufrdeco_assert, bufrdeco::error, and bufrdeco_bitmap_array::nba.

Referenced by bufrdeco_parse_f2_compressed(), and bufrdeco_parse_f2_descriptor().

Here is the caller graph for this function:

◆ bufrdeco_cache_tables_search()

int bufrdeco_cache_tables_search ( struct bufr_tables_cache c,
uint8_t  ver 
)

Search a struct bufr_tables in bufr_tables_cache.

Parameters
cpointer to the struct bufr_tables_cache where to search
versmall int with the master version acting as a key in the seardch
Returns
The index of found struct. If no struct found returns -1

Definition at line 304 of file bufrdeco_wmo.c.

305{
306 buf_t i = 0;
307
308 for ( i = 0; i < BUFRDECO_TABLES_CACHE_SIZE ; i++ )
309 {
310 if ( c->ver[i] == ver )
311 return i; // found
312 }
313 return -1; // Not found
314}
#define BUFRDECO_TABLES_CACHE_SIZE
Max number of structs bufr_tables in a bufr_tables_cache.
Definition: bufrdeco.h:341
int8_t ver[BUFRDECO_TABLES_CACHE_SIZE]
Definition: bufrdeco.h:954

References BUFRDECO_TABLES_CACHE_SIZE, and bufr_tables_cache::ver.

Referenced by bufr_read_tables().

Here is the caller graph for this function:

◆ bufrdeco_clean_bitmaps()

int bufrdeco_clean_bitmaps ( struct bufrdeco b)

Clean all allocated bitmaps, but still is in memory.

Parameters
bthe active struct bufrdeco
Returns
If succeeded return 0, otherwise 1

Definition at line 308 of file bufrdeco_memory.c.

309{
310 buf_t i;
311
312 bufrdeco_assert ( b != NULL );
313
314 for ( i = 0; i < b->bitmap.nba ; i++ )
315 {
316 if ( b->bitmap.bmap[i] == NULL )
317 continue;
318 memset ( b->bitmap.bmap[i], 0, sizeof ( struct bufrdeco_bitmap ) );
319 }
320 b->bitmap.nba = 0;
321 return 0;
322}

References bufrdeco::bitmap, bufrdeco_bitmap_array::bmap, bufrdeco_assert, and bufrdeco_bitmap_array::nba.

Referenced by bufrdeco_decode_data_subset().

Here is the caller graph for this function:

◆ bufrdeco_clean_subset_sequence_data()

int bufrdeco_clean_subset_sequence_data ( struct bufrdeco_subset_sequence_data ba)

Cleans a struct bufrdeco_subset_sequence_data.

Parameters
baPointer to struct bufrdeco_subset_sequence_data to clean
Returns
0 if succeeded, 1 otherwise

For eficience, if sequence in the struct bufrdeco_subset_sequence_data is allocated, just set the used elements to zero. If is still no allocated memory for sequence inits the struct

Definition at line 164 of file bufrdeco_memory.c.

165{
166 bufrdeco_assert ( ba != NULL );
167
168 if ( ba->sequence != NULL )
169 {
170 ba->nd = 0;
171 return 0;
172 }
173 else
175}
int bufrdeco_init_subset_sequence_data(struct bufrdeco_subset_sequence_data *ba)
Init a struct bufrdeco_subset_sequence_data.

References bufrdeco_assert, bufrdeco_init_subset_sequence_data(), bufrdeco_subset_sequence_data::nd, and bufrdeco_subset_sequence_data::sequence.

Referenced by bufrdeco_decode_data_subset().

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

◆ 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}
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.
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_subset_sequence_data seq
Definition: bufrdeco.h:979
struct bufrdeco_compressed_data_references refs
Definition: bufrdeco.h:978
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_decode_data_subset()

int bufrdeco_decode_data_subset ( struct bufrdeco b)

User interface to decode a BUFR subset.

Parameters
bpointer to the base struct bufrdeco
Returns
Return 0 in case of success, 1 otherwise

Note that if succeeded the counter to current subset index is increased. Remember that in case of non compressed data we must to decode all previous subsets to get the desired one. In case of compressed we can access directly to a the desired subset

Definition at line 62 of file bufrdeco_data.c.

63{
66
67 // check arguments
68 bufrdeco_assert ( b != NULL );
69
70 s = & ( b->seq );
71 r = & ( b->refs );
72
73 if ( s == NULL || r == NULL )
74 {
75 snprintf ( b->error, sizeof ( b->error ), "%s(): Unspected NULL argument(s)\n", __func__ );
76 return 1;
77 }
78
79 // Check about parsed tree
80 if ( b->tree == NULL || b->tree->nseq == 0 )
81 {
82 snprintf ( b->error, sizeof ( b->error ), "%s(): Try to parse compressed data without parsed tree\n", __func__ );
83 return 1;
84 }
85
86 // First we init the subset sequence data
88 {
89 return 1;
90 }
91
92 // also we clean the possible defined bitmaps in prior subsets
93 if ( bufrdeco_clean_bitmaps ( b ) )
94 {
95 return 1;
96 }
97
98 // Then we get the data from an already parsed descriptor tree
99 if ( b->sec3.compressed )
100 {
101 if ( r->nd == 0 )
102 {
103 // case of compressed data and still not parsed
104 if ( bufrdeco_parse_compressed ( r, b ) )
105 {
106 return 1;
107 }
108 }
109 if ( bufr_decode_subset_data_compressed ( s, r, b ) )
110 {
111 return 1;
112 }
113 }
114 else
115 {
116 if ( bufrdeco_decode_subset_data_recursive ( s, NULL, b ) )
117 {
118 return 1;
119 }
120 }
121
122 // Finally we update the subset counter
123 ( b->state.subset ) ++;
124 return 0;
125}
int bufrdeco_clean_bitmaps(struct bufrdeco *b)
Clean all allocated bitmaps, but still is in memory.
int bufrdeco_parse_compressed(struct bufrdeco_compressed_data_references *r, struct bufrdeco *b)
Preliminary parse of a compressed data bufr.
int bufrdeco_clean_subset_sequence_data(struct bufrdeco_subset_sequence_data *ba)
Cleans a struct bufrdeco_subset_sequence_data.
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.
int bufrdeco_decode_subset_data_recursive(struct bufrdeco_subset_sequence_data *d, struct bufr_sequence *l, struct bufrdeco *b)
decode the data from a subset in a recursive way
uint8_t compressed
Definition: bufrdeco.h:812
Manage an array of structs bufrdeco_compressed_ref.
Definition: bufrdeco.h:668
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_sec3 sec3
Definition: bufrdeco.h:971

References bufr_decode_subset_data_compressed(), bufrdeco_assert, bufrdeco_clean_bitmaps(), bufrdeco_clean_subset_sequence_data(), bufrdeco_decode_subset_data_recursive(), bufrdeco_parse_compressed(), bufr_sec3::compressed, bufrdeco::error, bufrdeco_compressed_data_references::nd, bufrdeco_expanded_tree::nseq, bufrdeco::refs, bufrdeco::sec3, bufrdeco::seq, bufrdeco::state, bufrdeco_decoding_data_state::subset, and bufrdeco::tree.

Referenced by bufrdeco_get_subset_sequence_data(), and bufrdeco_get_target_subset_sequence_data().

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

◆ bufrdeco_decode_replicated_subsequence()

int bufrdeco_decode_replicated_subsequence ( struct bufrdeco_subset_sequence_data d,
struct bufr_replicator r,
struct bufrdeco b 
)

Decodes a replicated sequence.

Parameters
dtarget struct bufrdeco_subset_sequence_data
rpointer to a struct bufr_replicator which manage the replication task
bpointer to the base struct bufrdeco
Returns
If succeeded return 0, 1 otherwise

Definition at line 509 of file bufrdeco_data.c.

510{
511 buf_t i, k;
512 buf_t ixloop; // Index for loop
513 buf_t ixd; // Index for descriptor
514 struct bufr_sequence *l = r->s; // sequence
515 struct bufr_replicator replicator;
516 char aux[80];
517
518 bufrdeco_assert ( b != NULL );
519
520 if ( d == NULL || r == NULL )
521 {
522 {
523 snprintf ( b->error, sizeof ( b->error ), "%s(): Unspected NULL argument(s)\n", __func__ );
524 return 1;
525 }
526 }
527
528 for ( ixloop = 0; ixloop < r->nloops; ixloop++ )
529 {
530 for ( ixd = 0; ixd < r->ndesc ; ixd ++ )
531 {
533 snprintf(aux, sizeof (aux), "\"Replicated\":\"Descriptor %u/%u of loop %u/%u\"", ixd + 1, ixloop + 1, r->ndesc, r->nloops);
534
535 i = ixd + r->ixdel + 1;
536 switch ( l->lseq[i].f )
537 {
538 case 0:
539 // Checks if no_data_present is active for this descriptor in this sequence
540 if ( l->no_data_present.active &&
541 i >= l->no_data_present.first &&
542 i <= l->no_data_present.last )
543 {
544 // If here then no_data_present has been active in this sequence
545 if ( l->lseq[i].x > 9 &&
546 l->lseq[i].x != 31 )
547 {
548 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__ );
549 return 1;
550 }
551 }
552
553 // Repeat the extraction of data if b->state.data_repetition_factor != 0
554 // It get data al least a time
555 do
556 {
557 // decrement counter if not zero
560
561 // Get data from table B
562 if ( bufrdeco_tableB_val ( & ( d->sequence[d->nd] ), b, & ( l->lseq[i] ) ) )
563 {
564 return 1;
565 }
567 {
569 bufrdeco_print_json_object_atom_data ( b->out, & ( d->sequence[d->nd] ), aux );
570 }
571 }
572 while ( b->state.data_repetition_factor != 0 );
573
574 // case of delayed replicator description and data
575 if ( l->lseq[i].x == 31 && ( l->lseq[i].y == 11 || l->lseq[i].y == 12 ) )
577
578
579 // Case of defining bitmap 0 31 031
580 if ( l->lseq[i].x == 31 && l->lseq[i].y == 31 && b->state.bitmaping )
581 {
582 if ( d->sequence[d->nd].val == 0.0 ) // Check if it is meaning present data
583 {
584 d->sequence[d->nd - b->state.bitmaping].is_bitmaped_by = d->nd;
585 d->sequence[d->nd].bitmap_to = d->nd - b->state.bitmaping;
586 // Add reference to bitmap
587 bufrdeco_add_to_bitmap ( b->bitmap.bmap[b->bitmap.nba - 1], d->nd - b->state.bitmaping, d->nd );
588 }
589 }
590
591 // Process quality data
592 if ( b->state.quality_active &&
593 l->lseq[i].x == 33 )
594 {
595 if ( ixloop == 0 )
596 {
597 k = b->bitmap.bmap[b->bitmap.nba - 1]->nq;
598 b->bitmap.bmap[b->bitmap.nba - 1]->quality[k] = d->nd;
599 if ( k < BUFR_MAX_QUALITY_DATA )
600 ( b->bitmap.bmap[b->bitmap.nba - 1]->nq )++;
601 else
602 {
603 snprintf ( b->error, sizeof ( b->error ), "%s(): No more space for quality vars in bitmap. Check BUFR_MAX_QUALITY_DATA\n", __func__ );
604 return 1;
605 }
606 }
607 d->sequence[d->nd].related_to = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
608 }
609
610 //case of first order statistics
611 if ( b->state.stat1_active &&
612 l->lseq[i].x == 8 && l->lseq[i].y == 23 )
613 {
614 if ( ixloop == 0 )
615 {
616 k = b->bitmap.bmap[b->bitmap.nba - 1]->ns1; // index un stqts
617 b->bitmap.bmap[b->bitmap.nba - 1]->stat1_desc[k] = d->nd; // Set the value of statistical parameter
618 // update the number of quality variables for the bitmap
619 if ( k < BUFR_MAX_QUALITY_DATA )
620 ( b->bitmap.bmap[b->bitmap.nba - 1]->ns1 )++;
621 else
622 {
623 snprintf ( b->error, sizeof ( b->error ), "%s(): No more space for first order statistic vars in bitmap. Check BUFR_MAX_QUALITY_DATA\n", __func__ );
624 return 1;
625 }
626 }
627 d->sequence[d->nd].related_to = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
628 }
629
630 //case of difference statistics
631 if ( b->state.dstat_active &&
632 l->lseq[i].x == 8 && l->lseq[i].y == 24 )
633 {
634 if ( ixloop == 0 )
635 {
636 k = b->bitmap.bmap[b->bitmap.nba - 1]->nds; // index in stats
637 b->bitmap.bmap[b->bitmap.nba - 1]->dstat_desc[k] = d->nd; // Set the value of statistical parameter
638 // update the number of quality variables for the bitmap
639 if ( k < BUFR_MAX_QUALITY_DATA )
640 ( b->bitmap.bmap[b->bitmap.nba - 1]->nds )++;
641 else
642 {
643 snprintf ( b->error, sizeof ( b->error ), "%s(): No more space for difference statistic vars in bitmap. Check BUFR_MAX_QUALITY_DATA\n", __func__ );
644 return 1;
645 }
646 }
647 d->sequence[d->nd].related_to = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
648 }
649
650 if ( d->nd < ( d->dim - 1 ) )
651 {
652 ( d->nd ) ++;
653 }
654 else if ( bufrdeco_increase_data_array ( d ) == 0 )
655 {
656 ( d->nd ) ++;
657 }
658 else
659 {
660 snprintf ( b->error, sizeof ( b->error ), "%s(): No more bufr_atom_data available. Check BUFR_NMAXSEQ\n", __func__ );
661 return 1;
662 }
663 break;
664
665 case 1:
666 // Case of replicator descriptor
667 replicator.s = l;
668 replicator.ixrep = i;
670 {
673 }
674
675 if ( l->lseq[i].y != 0 )
676 {
677 // no delayed
678 replicator.ixdel = i;
679 replicator.ndesc = l->lseq[i].x;
680 replicator.nloops = l->lseq[i].y;
681 bufrdeco_decode_replicated_subsequence ( d, &replicator, b );
682 ixd += replicator.ndesc; // update ixd properly
683 }
684 else
685 {
686 // case of delayed;
687 replicator.ixdel = i + 1;
688 replicator.ndesc = l->lseq[i].x;
689 // here we read ndesc from delayed replicator descriptor
690 if ( bufrdeco_tableB_val ( & ( d->sequence[d->nd] ), b, & ( l->lseq[i + 1] ) ) )
691 {
692 return 1;
693 }
695 {
697 bufrdeco_print_json_object_atom_data ( b->out, & ( d->sequence[d->nd] ), aux );
698 }
699 replicator.nloops = ( size_t ) d->sequence[d->nd].val;
700 if ( d->nd < ( d->dim - 1 ) )
701 {
702 ( d->nd ) ++;
703 }
704 else if ( bufrdeco_increase_data_array ( d ) == 0 )
705 {
706 ( d->nd ) ++;
707 }
708 else
709 {
710 snprintf ( b->error, sizeof ( b->error ), "%s(): No more bufr_atom_data available. Check BUFR_NMAXSEQ\n", __func__ );
711 return 1;
712 }
713 bufrdeco_decode_replicated_subsequence ( d, &replicator, b );
714 ixd += replicator.ndesc + 1; // update ixd properly
715 }
716 //i = r->ixdel + r->ndesc; // update i properly
717 break;
718
719 case 2:
720 // Case of operator descriptor
721 if ( bufrdeco_parse_f2_descriptor ( d, & ( l->lseq[i] ), b ) )
722 {
723 return 1;
724 }
725
727 {
730 }
731 // Case of subsituted values
732 if ( b->state.subs_active && l->lseq[i].x == 23 && l->lseq[i].y == 255 )
733 {
734 k = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop]; // ref which is bitmaped_to
735 // Get the bitmaped descriptor k
736 if ( ixloop == 0 )
737 {
738 b->bitmap.bmap[b->bitmap.nba - 1]->subs = d->nd;
739 }
740 if ( bufrdeco_tableB_val ( & ( d->sequence[d->nd] ), b, & ( l->lseq[k] ) ) )
741 {
742 return 1;
743 }
744 d->sequence[d->nd].related_to = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
745
746 if ( d->nd < ( d->dim - 1 ) )
747 {
748 d->nd += 1;
749 }
750 else
751 {
752 snprintf ( b->error, sizeof ( b->error ), "%s(): Reached limit. Consider increas BUFR_NMAXSEQ\n", __func__ );
753 return 1;
754 }
755 }
756
757 // Case of replaced/retained values
758 if ( b->state.retained_active && l->lseq[i].x == 32 && l->lseq[i].y == 255 )
759 {
760 k = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
761 // Get the bitmaped descriptor k
762 if ( ixloop == 0 )
763 {
764 b->bitmap.bmap[b->bitmap.nba - 1]->retain = d->nd;
765 }
766 if ( bufrdeco_tableB_val ( & ( d->sequence[d->nd] ), b, & ( l->lseq[k] ) ) )
767 {
768 return 1;
769 }
770
771 d->sequence[d->nd].related_to = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
772 if ( d->nd < ( d->dim - 1 ) )
773 {
774 d->nd += 1;
775 }
776 else
777 {
778 snprintf ( b->error, sizeof ( b->error ), "%s(): Reached limit. Consider increas BUFR_NMAXSEQ\n", __func__ );
779 return 1;
780 }
781 }
782
783 // Case of first order statistics
784 //
785 // This operator shall signify a data item containing a
786 // first-order statistical value of the type indicated by
787 // the preceding 0 08 023 element descriptor; the
788 // element descriptor to which the first-order statistic
789 // relates is obtained by the application of the data
790 // present bit-map associated with the first-order
791 // statistical values follow operator; first-order statistical
792 // values shall be represented as defined by this element
793 // descriptor.
794 if ( b->state.stat1_active && l->lseq[i].x == 24 && l->lseq[i].y == 255 )
795 {
796 k = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
797
798 // Get the bitmaped descriptor k
799 if ( ixloop == 0 )
800 {
801 b->bitmap.bmap[b->bitmap.nba - 1]->stat1[b->bitmap.bmap[b->bitmap.nba - 1]->ns1 -1] = d->nd;
802 }
803
804 if ( bufrdeco_tableB_val ( & ( d->sequence[d->nd] ), b, & ( l->lseq[k] ) ) )
805 {
806 return 1;
807 }
808
809 d->sequence[d->nd].related_to = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
810 if ( d->nd < ( d->dim - 1 ) )
811 {
812 d->nd += 1;
813 }
814 else
815 {
816 snprintf ( b->error, sizeof ( b->error ), "%s(): Reached limit. Consider increas BUFR_NMAXSEQ\n", __func__ );
817 return 1;
818 }
819 }
820
821 // Case of difference statistics
822 //
823 // This operator shall signify a data item containing a
824 // difference statistical value of the type indicated by
825 // the preceding 0 08 024 element descriptor; the
826 // element descriptor to which the difference statistical
827 // value relates is obtained by the application of the
828 // data present bit-map associated with the difference
829 // statistical values follow operator; difference statistical
830 // values shall be represented as defined by this
831 // element descriptor, but with a reference value of –2**n
832 // and a data width of (n+1), where n is the data width
833 // given by the original descriptor. This special reference
834 // value allows the statistical difference values to
835 // be centred around zero.
836 if ( b->state.dstat_active && l->lseq[i].x == 25 && l->lseq[i].y == 255 )
837 {
838 k = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
839
840 // Get the bitmaped descriptor k
841 if ( ixloop == 0 )
842 {
843 b->bitmap.bmap[b->bitmap.nba - 1]->stat1[b->bitmap.bmap[b->bitmap.nba - 1]->nds -1] = d->nd;
844 }
845
846 // in bufrdeco_tableB_val() is taken into acount when is difference statistics active
847 if ( bufrdeco_tableB_val ( & ( d->sequence[d->nd] ), b, & ( l->lseq[k] ) ) )
848 {
849 return 1;
850 }
851
852 /*d->sequence[d->nd].ref = - ( ( int32_t ) 1 << d->sequence[d->nd].bits );
853 d->sequence[d->nd].bits++;*/
854 d->sequence[d->nd].related_to = b->bitmap.bmap[b->bitmap.nba - 1]->bitmap_to[ixloop];
855 if ( d->nd < ( d->dim - 1 ) )
856 {
857 d->nd += 1;
858 }
859 else
860 {
861 snprintf ( b->error, sizeof ( b->error ), "%s(): Reached limit. Consider increas BUFR_NMAXSEQ\n", __func__ );
862 return 1;
863 }
864 }
865
866 break;
867
868 case 3:
871 if ( bufrdeco_decode_subset_data_recursive ( d, l->sons[i], b ) )
872 {
873 return 1;
874 }
875 break;
876
877 default:
878 // this case is not possible
879 snprintf ( b->error, sizeof ( b->error ), "%s(): Found bad 'f' in descriptor\n", __func__ );
880 return 1;
881 break;
882 }
883 }
884 }
885 return 0;
886}
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.
int bufrdeco_parse_f2_descriptor(struct bufrdeco_subset_sequence_data *s, struct bufr_descriptor *d, struct bufrdeco *b)
parse a descritor with f = 2
Definition: bufrdeco_f2.c:39
#define BUFR_MAX_QUALITY_DATA
Max amount of quality data which is maped by a struct bufrdeco_bitmap element.
Definition: bufrdeco.h:226
int bufrdeco_tableB_val(struct bufr_atom_data *a, struct bufrdeco *b, struct bufr_descriptor *d)
Get data from a table B descriptor.
int bufrdeco_increase_data_array(struct bufrdeco_subset_sequence_data *d)
doubles the allocated space for a struct bufrdeco_subset_sequence_data whenever is posible
int bufrdeco_decode_replicated_subsequence(struct bufrdeco_subset_sequence_data *d, struct bufr_replicator *r, struct bufrdeco *b)
Decodes a replicated sequence.
buf_t related_to
Definition: bufrdeco.h:449
double val
Definition: bufrdeco.h:440
buf_t is_bitmaped_by
Definition: bufrdeco.h:447
buf_t bitmap_to
Definition: bufrdeco.h:448
store the information when parsing related to replicators
Definition: bufrdeco.h:422
struct bufr_sequence * s
Definition: bufrdeco.h:423
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
struct bufr_sequence * sons[NMAXSEQ_DESCRIPTORS]
Definition: bufrdeco.h:584
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

References bufr_sequence_index_range::active, bufrdeco::bitmap, bufr_atom_data::bitmap_to, bufrdeco_bitmap::bitmap_to, bufrdeco_decoding_data_state::bitmaping, bufrdeco_bitmap_array::bmap, BUFR_MAX_QUALITY_DATA, bufrdeco_add_to_bitmap(), bufrdeco_assert, bufrdeco_decode_replicated_subsequence(), bufrdeco_decode_subset_data_recursive(), bufrdeco_increase_data_array(), BUFRDECO_OUTPUT_JSON_SUBSET_DATA, bufrdeco_parse_f2_descriptor(), bufrdeco_print_json_object_atom_data(), bufrdeco_print_json_object_operator_descriptor(), bufrdeco_print_json_object_replicator_descriptor(), bufrdeco_print_json_separator(), bufrdeco_tableB_val(), bufrdeco_decoding_data_state::data_repetition_factor, bufrdeco_subset_sequence_data::dim, bufrdeco_decoding_data_state::dstat_active, bufrdeco_bitmap::dstat_desc, bufrdeco::error, bufr_descriptor::f, bufr_sequence_index_range::first, bufr_atom_data::is_bitmaped_by, bufr_replicator::ixdel, bufr_replicator::ixrep, bufr_sequence::lseq, bufrdeco::mask, bufrdeco_bitmap_array::nba, bufrdeco_subset_sequence_data::nd, bufr_replicator::ndesc, bufrdeco_bitmap::nds, bufr_replicator::nloops, bufr_sequence::no_data_present, bufrdeco_bitmap::nq, bufrdeco_bitmap::ns1, bufrdeco::out, bufrdeco_bitmap::quality, bufrdeco_decoding_data_state::quality_active, bufr_atom_data::related_to, bufrdeco_bitmap::retain, bufrdeco_decoding_data_state::retained_active, bufr_replicator::s, bufrdeco_subset_sequence_data::sequence, bufr_sequence::sons, bufrdeco_bitmap::stat1, bufrdeco_decoding_data_state::stat1_active, bufrdeco_bitmap::stat1_desc, bufrdeco::state, bufrdeco_bitmap::subs, bufrdeco_decoding_data_state::subs_active, bufr_atom_data::val, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_decode_replicated_subsequence(), and bufrdeco_decode_subset_data_recursive().

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

◆ bufrdeco_decode_replicated_subsequence_compressed()

int bufrdeco_decode_replicated_subsequence_compressed ( struct bufrdeco_compressed_data_references r,
struct bufr_replicator rep,
struct bufrdeco b 
)

decodes a repicated subsequence

Parameters
rpointer to target struct bufrdeco_compressed_data_references where to set results
reppointer to a replicator which contains the data for replication
bbasic container struct bufrdeco
Returns
Returns 0 if succeeded, 1 otherwise

Definition at line 352 of file bufrdeco_compressed.c.

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}
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
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_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.
buf_t ndesc
Definition: bufrdeco.h:575
Struct to hold the needed reference bit offsets, descriptor tree and replications in a compressed BUF...
Definition: bufrdeco.h:639

References bufr_sequence_index_range::active, bufrdeco_decoding_data_state::assoc_bits, bufrdeco::bitmap, bufrdeco_bitmap::bitmap_to, bufrdeco_compressed_ref::bitmap_to, bufrdeco_decoding_data_state::bitmaping, bufrdeco_compressed_ref::bits, bufrdeco_bitmap_array::bmap, BUFR_MAX_QUALITY_DATA, bufrdeco_add_to_bitmap(), BUFRDECO_COMPRESSED_REF_DATA_DESCRIPTOR_BITMASK, BUFRDECO_COMPRESSED_REF_OPERATOR_DESCRIPTOR, BUFRDECO_COMPRESSED_REF_REPLICATOR_DESCRIPTOR, bufrdeco_decode_replicated_subsequence_compressed(), bufrdeco_increase_compressed_data_references_count(), bufrdeco_parse_compressed_recursive(), bufrdeco_parse_f2_compressed(), bufrdeco_tableB_compressed(), bufrdeco_compressed_ref::desc, bufrdeco_decoding_data_state::dstat_active, bufrdeco_bitmap::dstat_desc, bufrdeco::error, bufr_descriptor::f, bufr_sequence_index_range::first, bufrdeco_compressed_ref::is_bitmaped_by, bufr_replicator::ixdel, bufr_replicator::ixrep, bufr_sequence_index_range::last, bufr_sequence::lseq, bufrdeco_compressed_ref::mask, bufrdeco_bitmap_array::nba, bufrdeco_compressed_data_references::nd, bufr_replicator::ndesc, bufrdeco_bitmap::nds, bufr_replicator::nloops, bufr_sequence::no_data_present, bufrdeco_bitmap::nq, bufrdeco_bitmap::ns1, bufrdeco_bitmap::quality, bufrdeco_decoding_data_state::quality_active, bufrdeco_compressed_ref::ref, bufrdeco_compressed_ref::ref0, bufrdeco_compressed_data_references::refs, bufrdeco_compressed_ref::related_to, bufrdeco_compressed_ref::replicated_desc, bufrdeco_compressed_ref::replicated_loop, bufrdeco_compressed_ref::replicated_ndesc, bufrdeco_compressed_ref::replicated_nloop, bufrdeco_bitmap::retain, bufrdeco_decoding_data_state::retained_active, bufr_replicator::s, bufrdeco_compressed_ref::seq, bufr_sequence::sons, bufrdeco_bitmap::stat1, bufrdeco_decoding_data_state::stat1_active, bufrdeco_bitmap::stat1_desc, bufrdeco::state, bufrdeco_bitmap::subs, bufrdeco_decoding_data_state::subs_active, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_decode_replicated_subsequence_compressed(), and bufrdeco_parse_compressed_recursive().

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

◆ bufrdeco_decode_subset_data_recursive()

int bufrdeco_decode_subset_data_recursive ( struct bufrdeco_subset_sequence_data d,
struct bufr_sequence l,
struct bufrdeco b 
)

decode the data from a subset in a recursive way

Parameters
dpointer to the target struct bufrdeco_subset_sequence_data
lpointer to the source struct bufr_sequence
bpointer to the base struct bufrdeco
Returns
0 in case of success, 1 otherwise

Definition at line 171 of file bufrdeco_data.c.

172{
173 size_t i, j, k;
174 struct bufr_sequence *seq;
175 struct bufr_replicator replicator;
176
177 bufrdeco_assert ( b != NULL );
178
179 if ( d == NULL )
180 {
181 snprintf ( b->error, sizeof ( b->error ), "%s(): Unspected NULL argument(s)\n", __func__ );
182 return 1;
183 }
184
185
186 // clean subset data, if l == NULL we are at the begining of a subset, level 0
187 if ( l == NULL )
188 {
189
190 //memset ( s, 0, sizeof ( struct bufr_subset_sequence_data ) );
191 d->nd = 0;
192 d->ss = b->state.subset;
193 seq = & ( b->tree->seq[0] );
194 if ( b->state.subset == 0 )
195 {
196 b->state.bit_offset = 0;
197 }
198
199 // Manage bit offset of the subset
200 if ( b->state.subset < BUFR_MAX_SUBSETS )
201 {
202 // No bit offset still set for this subset
203 if ( b->offsets.ofs[b->state.subset] == 0 )
204 {
205 if ( b->offsets.nr <= b->state.subset )
206 b->offsets.nr = b->state.subset + 1;
208 }
209 else
210 {
211 // offset is already set, so we can go directly to the data
213 }
214 }
215 else
216 {
217 snprintf ( b->error, sizeof ( b->error ), "%s(): Cannot manage subset bit offset for subset %u. Consider increase BUFR_MAX_SUBSETS\n",
218 __func__, b->state.subset );
219 return 1;
220 }
221
222 // also reset reference and bits inc
223 b->state.added_bit_length = 0;
224 b->state.added_scale = 0;
225 b->state.added_reference = 0;
226 b->state.assoc_bits = 0;
227 b->state.changing_reference = 255;
228 b->state.fixed_ccitt = 0;
230 b->state.factor_reference = 1;
231 b->state.quality_active = 0;
232 b->state.subs_active = 0;
233 b->state.retained_active = 0;
234 b->state.stat1_active = 0;
235 b->state.dstat_active = 0;
236 b->state.bitmaping = 0;
238 b->state.bitmap = NULL;
239
240 // print prologue if needed
243
244 }
245 else
246 {
247 seq = l;
248 }
249
250 // loop for a sequence
252 {
253 //if (seq->iseq)
254 // bufrdeco_print_json_separator ( b->out ); // print json array element separator
256 }
257
258 for ( i = 0, j = 0 ; i < seq->ndesc ; i++ )
259 {
260 switch ( seq->lseq[i].f )
261 {
262 case 0:
263
264 // Checks if no_data_present is active for this descriptor in this sequence
265 if ( seq->no_data_present.active &&
266 i >= seq->no_data_present.first &&
267 i <= seq->no_data_present.last )
268 {
269 // If here then no_data_present has been active in this sequence
270 if ( seq->lseq[i].x > 9 &&
271 seq->lseq[i].x != 31 )
272 {
273 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",
274 __func__ );
275 return 1;
276 }
277
278 }
279
280
281 // Repeat the extraction of data if b->state.data_repetition_factor != 0
282 // It get data al least a time
283 // It is supossed that prior parsed descriptor was 0 31 011 or 0 31 012 which set de value of repetition data
284 do
285 {
286 // decrement counter if not zero
289
290 // Get data from table B
291 if ( bufrdeco_tableB_val ( & ( d->sequence[d->nd] ), b, & ( seq->lseq[i] ) ) )
292 {
293 return 1;
294 }
296 {
297 if (j)
299 bufrdeco_print_json_object_atom_data ( b->out, & ( d->sequence[d->nd] ), NULL );
300 j++;
301 }
302 }
303 while ( b->state.data_repetition_factor != 0 );
304
305 // case of delayed replicator description and data
306 if ( seq->lseq[i].x == 31 && ( seq->lseq[i].y == 11 || seq->lseq[i].y == 12 ) )
307 {
309 }
310
311 //case of first order statistics
312 if ( b->state.stat1_active &&
313 seq->lseq[i].x == 8 && seq->lseq[i].y == 23 )
314 {
315 k = b->bitmap.bmap[b->bitmap.nba - 1]->ns1; // index un stqts
316 b->bitmap.bmap[b->bitmap.nba - 1]->stat1_desc[k] = d->nd; // Set the value of statistical parameter
317 // update the number of quality variables for the bitmap
318 if ( k < BUFR_MAX_QUALITY_DATA )
319 ( b->bitmap.bmap[b->bitmap.nba - 1]->ns1 )++;
320 else
321 {
322 snprintf ( b->error, sizeof ( b->error ), "%s(): No more space for first order statistic vars in bitmap. Check BUFR_MAX_QUALITY_DATA\n",
323 __func__ );
324 return 1;
325 }
326 }
327
328 //case of difference statistics
329 if ( b->state.dstat_active &&
330 seq->lseq[i].x == 8 && seq->lseq[i].y == 24 )
331 {
332 k = b->bitmap.bmap[b->bitmap.nba - 1]->nds; // index in stats
333 b->bitmap.bmap[b->bitmap.nba - 1]->dstat_desc[k] = d->nd; // Set the value of statistical parameter
334 // update the number of quality variables for the bitmap
335 if ( k < BUFR_MAX_QUALITY_DATA )
336 ( b->bitmap.bmap[b->bitmap.nba - 1]->nds )++;
337 else
338 {
339 snprintf ( b->error, sizeof ( b->error ), "%s(): No more space for difference statistic vars in bitmap. Check BUFR_MAX_QUALITY_DATA\n",
340 __func__ );
341 return 1;
342 }
343 }
344
345
346
347 // Add info about common sequence to which bufr_atom_data belongs
348 d->sequence[d->nd].seq = seq;
349 d->sequence[d->nd].ns = i;
350
351 //bufr_print_atom_data_stdout(& ( d->sequence[d->nd] ));
352 if ( d->nd < ( d->dim - 1 ) )
353 {
354 ( d->nd ) ++;
355 }
356 else if ( bufrdeco_increase_data_array ( d ) == 0 )
357 {
358 ( d->nd ) ++;
359 }
360 else
361 {
362 snprintf ( b->error, sizeof ( b->error ), "%s(): No more bufr_atom_data available. Check BUFR_NMAXSEQ\n", __func__ );
363 return 1;
364 }
365 break;
366
367 case 1:
368 // Case of replicator descriptor
369 replicator.s = seq;
370 replicator.ixrep = i;
372 {
373 if (j)
376 j++;
377 }
378
379 if ( seq->lseq[i].y != 0 )
380 {
381 // no delayed
382 replicator.ixdel = i;
383 replicator.ndesc = seq->lseq[i].x;
384 replicator.nloops = seq->lseq[i].y;
385
386 // Check if this replicator is for a bit-map defining
387 if ( b->state.bitmaping )
388 {
389 b->state.bitmaping = replicator.nloops; // set it properly
390 }
391
392 bufrdeco_decode_replicated_subsequence ( d, &replicator, b );
393
394 // and then set again bitamping to 0, because it is finished
395 b->state.bitmaping = 0;
396
397 i += replicator.ndesc;
398 }
399 else
400 {
401 // case of delayed;
402 replicator.ixdel = i + 1;
403 replicator.ndesc = seq->lseq[i].x;
404 // here we read ndesc from delayed replicator descriptor
405 if ( bufrdeco_tableB_val ( & ( d->sequence[d->nd] ), b, & ( seq->lseq[i + 1] ) ) )
406 {
407 return 1;
408 }
410 {
411 if (j)
413 bufrdeco_print_json_object_atom_data ( b->out, & ( d->sequence[d->nd] ), NULL );
414 j++;
415 }
416 // Add info about common sequence to which bufr_atom_data belongs
417 d->sequence[d->nd].seq = seq;
418 d->sequence[d->nd].ns = i + 1;
419
420 replicator.nloops = ( size_t ) ( d->sequence[d->nd].val );
421
422 // Check if this replicator is for a bit-map defining
423 if ( b->state.bitmaping )
424 {
425 b->state.bitmaping = replicator.nloops; // set it properly
426 }
427
428 if ( d->nd < ( d->dim - 1 ) )
429 {
430 ( d->nd ) ++;
431 }
432 else if ( bufrdeco_increase_data_array ( d ) == 0 )
433 {
434 ( d->nd ) ++;
435 }
436 else
437 {
438
439 snprintf ( b->error, sizeof ( b->error ), "%s(): No more bufr_atom_data available. Check BUFR_NMAXSEQ\n", __func__ );
440 return 1;
441 }
442 bufrdeco_decode_replicated_subsequence ( d, &replicator, b );
443
444 // and then set again bitamping to 0, because it is finished
445 b->state.bitmaping = 0;
446
447 i += replicator.ndesc + 1;
448 }
449 //i = replicator.ixdel + replicator.ndesc; // update i properly
450 break;
451
452 case 2:
453 // Case of operator descriptor
454 if ( bufrdeco_parse_f2_descriptor ( d, & ( seq->lseq[i] ), b ) )
455 {
456 return 1;
457 }
459 {
460 if (j)
462 bufrdeco_print_json_object_operator_descriptor ( b->out, & ( seq->lseq[i] ), NULL );
463 j++;
464 }
465 break;
466
467 case 3:
469 {
470 if (j)
471 bufrdeco_print_json_separator ( b->out ); // print json array element separator
472 j++;
473 }
474 // Case of sequence descriptor
475 if ( bufrdeco_decode_subset_data_recursive ( d, seq->sons[i], b ) )
476 {
477 return 1;
478 }
479 break;
480
481 default:
482 // this case is not possible
483 snprintf ( b->error, sizeof ( b->error ), "%s(): Found bad 'f' in descriptor '%s' \n", seq->lseq[i].c, __func__ );
484 return 1;
485 break;
486 }
487 }
488
489 // End of sequence
492
493 // End of data subset
494 if ( l == NULL && ( b->mask & BUFRDECO_OUTPUT_JSON_SUBSET_DATA ) )
496
497 return 0;
498
499};
#define BUFR_MAX_SUBSETS
Max number of subsets in the array off bitoffset subset marks the bufrdeco library can manage.
Definition: bufrdeco.h:244
struct bufr_sequence * seq
Definition: bufrdeco.h:445
struct bufrdeco_bitmap * bitmap
Definition: bufrdeco.h:542
struct bufr_sequence seq[BUFR_MAX_EXPANDED_SEQUENCES]
Definition: bufrdeco.h:598
struct bufrdeco_subset_bit_offsets offsets
Definition: bufrdeco.h:977

References bufr_sequence_index_range::active, bufrdeco_decoding_data_state::added_bit_length, bufrdeco_decoding_data_state::added_reference, bufrdeco_decoding_data_state::added_scale, bufrdeco_decoding_data_state::assoc_bits, bufrdeco_decoding_data_state::bit_offset, bufrdeco_decoding_data_state::bitmap, bufrdeco::bitmap, bufrdeco_decoding_data_state::bitmaping, bufrdeco_bitmap_array::bmap, BUFR_MAX_QUALITY_DATA, BUFR_MAX_SUBSETS, bufrdeco_assert, bufrdeco_decode_replicated_subsequence(), bufrdeco_decode_subset_data_recursive(), bufrdeco_increase_data_array(), BUFRDECO_OUTPUT_JSON_SUBSET_DATA, bufrdeco_parse_f2_descriptor(), bufrdeco_print_json_object_atom_data(), bufrdeco_print_json_object_operator_descriptor(), bufrdeco_print_json_object_replicator_descriptor(), bufrdeco_print_json_separator(), bufrdeco_print_json_sequence_descriptor_final(), bufrdeco_print_json_sequence_descriptor_header(), bufrdeco_print_json_subset_data_epilogue(), bufrdeco_print_json_subset_data_prologue(), bufrdeco_tableB_val(), bufr_descriptor::c, bufrdeco_decoding_data_state::changing_reference, bufrdeco_decoding_data_state::data_repetition_factor, bufrdeco_subset_sequence_data::dim, bufrdeco_decoding_data_state::dstat_active, bufrdeco_bitmap::dstat_desc, bufrdeco::error, bufr_descriptor::f, bufrdeco_decoding_data_state::factor_reference, bufr_sequence_index_range::first, bufrdeco_decoding_data_state::fixed_ccitt, bufr_replicator::ixdel, bufr_replicator::ixrep, bufrdeco_decoding_data_state::local_bit_reserved, bufr_sequence::lseq, bufrdeco::mask, bufrdeco_bitmap_array::nba, bufrdeco_subset_sequence_data::nd, bufr_replicator::ndesc, bufr_sequence::ndesc, bufrdeco_bitmap::nds, bufr_replicator::nloops, bufr_sequence::no_data_present, bufrdeco_subset_bit_offsets::nr, bufr_atom_data::ns, bufrdeco_bitmap::ns1, bufrdeco::offsets, bufrdeco_subset_bit_offsets::ofs, bufrdeco::out, bufrdeco_decoding_data_state::quality_active, bufrdeco_decoding_data_state::retained_active, bufr_replicator::s, bufr_atom_data::seq, bufrdeco_expanded_tree::seq, bufrdeco_subset_sequence_data::sequence, bufr_sequence::sons, bufrdeco_subset_sequence_data::ss, bufrdeco_decoding_data_state::stat1_active, bufrdeco_bitmap::stat1_desc, bufrdeco::state, bufrdeco_decoding_data_state::subs_active, bufrdeco_decoding_data_state::subset, bufrdeco::tree, bufr_atom_data::val, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_decode_data_subset(), bufrdeco_decode_replicated_subsequence(), and bufrdeco_decode_subset_data_recursive().

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

◆ bufrdeco_explained_flag_csv_val()

char * bufrdeco_explained_flag_csv_val ( char *  expl,
size_t  dim,
struct bufr_tableC tc,
struct bufr_descriptor d,
uint64_t  ival,
uint8_t  nbits 
)

◆ bufrdeco_explained_flag_val()

char * bufrdeco_explained_flag_val ( char *  expl,
size_t  dim,
struct bufr_tableC tc,
struct bufr_descriptor d,
uint64_t  ival,
uint8_t  nbits 
)

Definition at line 200 of file bufrdeco_tableC.c.

202{
203 size_t used = 0;
204 uint64_t test, test0;
205 uint64_t v;
206 size_t i, j;
207
208 bufrdeco_assert ( tc != NULL && expl != NULL && d != NULL);
209
210 if ( tc->num[d->x] == 0 )
211 {
212 //printf("Descriptor %s No encontrado\n", d->c);
213 return NULL;
214 }
215
216 // First line for descriptor
217 i = tc->x_start[d->x] + tc->y_ref[d->x][d->y];
218
219 // init description
220 expl[0] = '\0';
221
222 for ( j = 0, test0 = 1 ; j < nbits && ( tc->item[i].x == d->x ) && ( tc->item[i].y == d->y ) ; i++ )
223 {
224 v = tc->item[i].ival; // v is the bit number
225 j++;
226
227 // case 0 with meaning
228 if ( v == 0 )
229 {
230 test0 = 1;
231 if ( ival == 0 )
232 {
233 used += snprintf ( expl + used, dim - used, "|" );
234 used += snprintf ( expl + used, dim - used, "%s", tc->item[i].description );
235 return expl;
236 }
237 }
238
239 test = test0 << ( nbits - v );
240
241 if ( v && ( test & ival ) != 0 )
242 {
243 used += snprintf ( expl + used, dim - used, "|" );
244 used += snprintf ( expl + used, dim - used, "%s", tc->item[i].description );
245 }
246 else
247 {
248 continue;
249 }
250 //printf ( "%s\n", expl );
251 }
252 // if match then we have finished the search
253 return expl;
254}

References bufrdeco_assert, bufr_tableC_decoded_item::description, bufr_tableC::item, bufr_tableC_decoded_item::ival, bufr_tableC::num, bufr_descriptor::x, bufr_tableC_decoded_item::x, bufr_tableC::x_start, bufr_descriptor::y, bufr_tableC_decoded_item::y, and bufr_tableC::y_ref.

Referenced by bufrdeco_get_atom_data_from_compressed_data_ref(), and bufrdeco_tableB_val().

Here is the caller graph for this function:

◆ bufrdeco_explained_table_csv_val()

char * bufrdeco_explained_table_csv_val ( char *  expl,
size_t  dim,
struct bufr_tableC tc,
uint32_t *  index,
struct bufr_descriptor d,
uint32_t  ival 
)

◆ bufrdeco_explained_table_val()

char * bufrdeco_explained_table_val ( char *  expl,
size_t  dim,
struct bufr_tableC tc,
uint32_t *  index,
struct bufr_descriptor d,
uint32_t  ival 
)

Definition at line 168 of file bufrdeco_tableC.c.

169{
170 buf_t i;
171
172 bufrdeco_assert ( tc != NULL && expl != NULL && index != NULL && d != NULL);
173
174 if ( bufr_find_tableC_csv_index ( &i, tc, d->c, ival ) )
175 {
176 return NULL; // descritor not found
177 }
178
179 // here the calling b item learn where to find first table C struct for a given x and y.
180 *index = tc->x_start[d->x] + tc->y_ref[d->x][d->y];
181
182 strncpy_safe ( expl, tc->item[i].description, dim );
183 return expl;
184}
#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
int bufr_find_tableC_csv_index(buf_t *index, struct bufr_tableC *tc, const char *key, uint32_t code)

References bufr_find_tableC_csv_index(), bufrdeco_assert, bufr_descriptor::c, bufr_tableC_decoded_item::description, bufr_tableC::item, strncpy_safe, bufr_descriptor::x, bufr_tableC::x_start, bufr_descriptor::y, and bufr_tableC::y_ref.

Referenced by bufrdeco_get_atom_data_from_compressed_data_ref(), and bufrdeco_tableB_val().

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

◆ bufrdeco_extract_bufr()

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()

Parameters
bpointer to struct bufrdeco
filenamecomplete path of BUFR file
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 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.

< pointer to a memory buffer where we write raw bufr file

Definition at line 120 of file bufrdeco_read.c.

121{
122 int aux, res;
123 uint8_t *bufrx = NULL, *pbeg = NULL; /*!< pointer to a memory buffer where we write raw bufr file */
124 buf_t n = 0, beg, end, size = 0;
125 FILE *fp;
126 struct stat st;
127
128 bufrdeco_assert ( b != NULL );
129
130 /* Stat input file */
131 if ( stat ( filename, &st ) < 0 )
132 {
133 snprintf ( b->error, sizeof ( b->error ), "%s(): cannot stat file '%s'\n", __func__, filename );
134 return 1;
135 }
136
137 /* Alloc nedeed memory for bufr */
138 if ( S_ISREG ( st.st_mode ) || S_ISLNK ( st.st_mode ) )
139 {
140 if ( ( bufrx = ( uint8_t * ) calloc ( 1, st.st_size + 4 ) ) == NULL )
141 {
142 snprintf ( b->error, sizeof ( b->error ), "%s(): cannot alloc memory for file '%s'\n", __func__, filename );
143 return 1;
144 }
145 }
146 else
147 {
148 snprintf ( b->error, sizeof ( b->error ), "%s(): '%s' is not a regular file nor symbolic link\n", __func__, filename );
149 return 1;
150 }
151
152 /* Inits bufr struct */
153 if ( ( st.st_size + 4 ) >= BUFR_LEN )
154 {
155 snprintf ( b->error, sizeof ( b->error ), "%s(): File '%s' too large. Consider increase BUFR_LEN\n", __func__, filename );
156 free ( ( void * ) bufrx );
157 return 1;
158 }
159
160 // Open and read the file
161 if ( ( fp = fopen ( filename, "r" ) ) == NULL )
162 {
163 snprintf ( b->error, sizeof ( b->error ), "%s(): cannot open file '%s'\n", __func__, filename );
164 free ( ( void * ) bufrx );
165 return 1;
166 }
167
168 beg = end = st.st_size;
169 while ( ( aux = fgetc ( fp ) ) != EOF && ( int ) n < st.st_size )
170 {
171 bufrx[n++] = ( uint8_t ) aux;
172
173 // check if first 'BUFR' item has been found
174 if ( n >= 4 &&
175 bufrx[n - 4] == 'B' &&
176 bufrx[n - 3] == 'U' &&
177 bufrx[n - 2] == 'F' &&
178 bufrx[n - 1] == 'R' )
179 {
180 beg = n - 4;
181 pbeg = &bufrx[ n - 4];
182 }
183
184 // check if first '7777' has been found after first 'BUFR'
185 if ( n > 4 &&
186 beg < ( ( size_t ) st.st_size - 4 ) &&
187 bufrx[n - 4] == '7' &&
188 bufrx[n - 3] == '7' &&
189 bufrx[n - 2] == '7' &&
190 bufrx[n - 1] == '7' )
191 {
192 end = n - 1;
193 size = end - beg + 1;
194 }
195 }
196
197
198 // close the file
199 fclose ( fp );
200
201 if ( size < 8 )
202 {
203 snprintf ( b->error, sizeof ( b->error ), "%s(): not found a '7777' item after 'BUFR'\n", __func__ );
204 return 1;
205 }
206 res = bufrdeco_read_buffer ( b, pbeg, size );
207 free ( bufrx );
208 return res;
209}
#define BUFR_LEN
Max length of a BUFR file.
Definition: bufrdeco.h:60
int bufrdeco_read_buffer(struct bufrdeco *b, uint8_t *bufrx, buf_t size)

References BUFR_LEN, bufrdeco_assert, bufrdeco_read_buffer(), and bufrdeco::error.

Referenced by bufrdeco_get_bufr(), and main().

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

◆ bufrdeco_fprint_subset_sequence_data()

int bufrdeco_fprint_subset_sequence_data ( FILE *  f,
struct bufrdeco_subset_sequence_data s 
)

Definition at line 520 of file bufrdeco_print.c.

521{
522 size_t i;
523 char aux[1024];
524
525 bufrdeco_assert ( f != NULL && s != NULL);
526
527 for ( i = 0; i < s->nd ; i++ )
528 {
529 if ( i && s->sequence[i].seq != s->sequence[i - 1].seq )
530 fprintf ( f, "\n" );
531
532 fprintf ( f, "%5lu: %s\n", i, bufrdeco_print_atom_data ( aux, sizeof ( aux ), &s->sequence[i] ) );
533 }
534 return 0;
535
536}
char * bufrdeco_print_atom_data(char *target, size_t lmax, struct bufr_atom_data *a)
print the data in a struct bufr_atom_data to a string

References bufrdeco_assert, bufrdeco_print_atom_data(), bufrdeco_subset_sequence_data::nd, bufr_atom_data::seq, and bufrdeco_subset_sequence_data::sequence.

Referenced by bufrdeco_print_subset_sequence_data().

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

◆ bufrdeco_fprint_subset_sequence_data_html()

int bufrdeco_fprint_subset_sequence_data_html ( FILE *  f,
struct bufrdeco_subset_sequence_data s 
)

Definition at line 241 of file bufrdeco_print_html.c.

242{
243 size_t i;
244 char aux[1024];
245
246 bufrdeco_assert ( f != NULL && s != NULL );
247
248 fprintf ( f, "<div class='bufr_subset'>\n" );
249 fprintf ( f, "<table>\n" );
250 for ( i = 0; i < s->nd ; i++ )
251 {
252 fprintf ( f, "<tr><td>%5lu:</td>%s</tr>\n", i, bufrdeco_print_atom_data_html ( aux, sizeof (aux), &s->sequence[i], s->ss ) );
253 }
254 fprintf ( f, "</table>\n" );
255 fprintf ( f, "</div>\n" );
256 return 0;
257}
char * bufrdeco_print_atom_data_html(char *target, size_t lmax, struct bufr_atom_data *a, uint32_t ss)
print the data in a struct bufr_atom_data to a string as cells of table rows

References bufrdeco_assert, bufrdeco_print_atom_data_html(), bufrdeco_subset_sequence_data::nd, bufrdeco_subset_sequence_data::sequence, and bufrdeco_subset_sequence_data::ss.

Referenced by bufrdeco_print_subset_sequence_data_html().

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

◆ bufrdeco_fprint_subset_sequence_data_tagged_html()

int bufrdeco_fprint_subset_sequence_data_tagged_html ( FILE *  f,
struct bufrdeco_subset_sequence_data s,
char *  id 
)

Definition at line 279 of file bufrdeco_print_html.c.

280{
281 size_t i;
282 char aux[1024];
283
284 bufrdeco_assert ( f != NULL && s != NULL && id != NULL );
285
286 fprintf ( f, "\n<div class='bufr_subset' id='%s'>\n", id );
287 fprintf ( f, "<table>\n" );
288 fprintf ( f, "<caption>%s</caption>\n", id );
289 fprintf ( f, "<tr><th></th><th>Descriptor</th><th>Name</th><th>Unit</th><th>Value</th><th>Description</th></tr>\n" );
290 for ( i = 0; i < s->nd ; i++ )
291 {
292 fprintf ( f, "<tr><td class='ndesc' id='d_%u_%lu' >#%lu</td>%s</tr>\n", s->ss, i, i, bufrdeco_print_atom_data_html ( aux, sizeof (aux), &s->sequence[i], s->ss ) );
293 }
294 fprintf ( f, "</table>\n" );
295 fprintf ( f, "</div>\n" );
296 return 0;
297}

References bufrdeco_assert, bufrdeco_print_atom_data_html(), bufrdeco_subset_sequence_data::nd, bufrdeco_subset_sequence_data::sequence, and bufrdeco_subset_sequence_data::ss.

Referenced by bufrdeco_print_subset_sequence_data_tagged_html().

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

◆ bufrdeco_fprint_tree()

int bufrdeco_fprint_tree ( FILE *  f,
struct bufrdeco b 
)

Print a tree of descriptors.

Parameters
fPointer to file opened by caller
bpointer to a basic container struct bufrdeco
Returns
If succeeded return 0

Definition at line 360 of file bufrdeco_print.c.

361{
362 bufrdeco_assert ( f != NULL && b != NULL );
363
364 if ( b->mask & BUFRDECO_OUTPUT_HTML )
365 fprintf ( f, "<pre>\n" );
366 bufrdeco_fprint_tree_recursive ( f, b, NULL );
367 if ( b->mask & BUFRDECO_OUTPUT_HTML )
368 fprintf ( f, "</pre>\n" );
369 else
370 fprintf ( f, "\n" );
371 return 0;
372};
#define BUFRDECO_OUTPUT_HTML
Bit mask to the member mask for struct bufrdeco to format output as html for SECs 0 to 3.
Definition: bufrdeco.h:256
int bufrdeco_fprint_tree_recursive(FILE *f, struct bufrdeco *b, struct bufr_sequence *seq)
Print a tree of descriptors to a file in a recursive way.

References bufrdeco_assert, bufrdeco_fprint_tree_recursive(), BUFRDECO_OUTPUT_HTML, and bufrdeco::mask.

Here is the call graph for this function:

◆ bufrdeco_free_bitmap_array()

int bufrdeco_free_bitmap_array ( struct bufrdeco_bitmap_array a)

Free an allocated bitmap array.

Parameters
apointer to target struct bufrdeco_bitmap_array to free
Returns
If succeeded return 0, otherwise 1

Definition at line 331 of file bufrdeco_memory.c.

332{
333 buf_t i;
334
335 bufrdeco_assert ( a != NULL );
336
337 for ( i = 0; i < a->nba ; i++ )
338 {
339 if ( a->bmap[i] == NULL )
340 continue;
341
342 free ( ( void* ) a->bmap[i] );
343 a->bmap[i] = NULL;
344 }
345 a->nba = 0;
346 return 0;
347}

References bufrdeco_bitmap_array::bmap, bufrdeco_assert, and bufrdeco_bitmap_array::nba.

Referenced by bufrdeco_close(), and bufrdeco_reset().

Here is the caller graph for this function:

◆ bufrdeco_free_cache_tables()

int bufrdeco_free_cache_tables ( struct bufr_tables_cache c)

deallocate and clean a bufr_tables_cache

Parameters
cpointer to the struct to clean
Returns
0 if success

Definition at line 322 of file bufrdeco_wmo.c.

323{
324 buf_t i;
325
326 for ( i = 0; i < BUFRDECO_TABLES_CACHE_SIZE; i++ )
327 {
328 if ( c->tab[i] )
329 {
330 free ( ( void * ) c->tab[i] );
331 }
332 }
333 // then clean
334 memset ( c, 0, sizeof ( struct bufr_tables_cache ) );
335 return 0;
336}
Struct to store the cache of structs bufr_tables.
Definition: bufrdeco.h:951

References BUFRDECO_TABLES_CACHE_SIZE, and bufr_tables_cache::tab.

Referenced by bufrdeco_close().

Here is the caller graph for this function:

◆ bufrdeco_free_compressed_data_references()

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.

Parameters
rfpointer to the target struct bufrdeco_compressed_data_references to free
Returns
If succeeded return 0, otherwise 1

Definition at line 250 of file bufrdeco_memory.c.

251{
252 bufrdeco_assert ( rf != NULL );
253
254 if ( rf->refs != NULL )
255 {
256 free ( ( void * ) rf->refs );
257 rf->refs = NULL;
258 }
259 return 0;
260}

References bufrdeco_assert, and bufrdeco_compressed_data_references::refs.

Referenced by bufrdeco_close(), and bufrdeco_reset().

Here is the caller graph for this function:

◆ bufrdeco_free_expanded_tree()

int bufrdeco_free_expanded_tree ( struct bufrdeco_expanded_tree **  t)

Frees the allocated space for a struct bufrdeco_expanded_tree.

Parameters
tpointer to the target pointer to struct bufrdeco_expanded_tree
Returns
0 and *t is set to NULL

Definition at line 89 of file bufrdeco_memory.c.

90{
91 bufrdeco_assert ( t != NULL );
92
93 if ( *t != NULL )
94 {
95 free ( ( void * ) *t );
96 *t = NULL;
97 }
98 return 0;
99}

References bufrdeco_assert.

Referenced by bufrdeco_close(), and bufrdeco_reset().

Here is the caller graph for this function:

◆ bufrdeco_free_subset_sequence_data()

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.

Parameters
bapointer to the target struct to free
Returns
0 if succeeded

Definition at line 183 of file bufrdeco_memory.c.

184{
185 bufrdeco_assert ( ba != NULL );
186
187 if ( ba->sequence != NULL )
188 {
189 free ( ( void * ) ba->sequence );
190 ba->sequence = NULL;
191 }
192 return 0;
193}

References bufrdeco_assert, and bufrdeco_subset_sequence_data::sequence.

Referenced by bufrdeco_close(), and bufrdeco_reset().

Here is the caller graph for this function:

◆ bufrdeco_free_tables()

int bufrdeco_free_tables ( struct bufr_tables **  t)

Frees the allocated space for a struct bufr_tables.

Parameters
tpointer to the target pointer to struct bufr_tables
Returns
0 and *t is set to NULL

Definition at line 51 of file bufrdeco_memory.c.

52{
53 bufrdeco_assert ( t != NULL );
54
55 if ( *t != NULL )
56 {
57 free ( ( void * ) *t );
58 *t = NULL;
59 }
60 return 0;
61}

References bufrdeco_assert.

Referenced by bufrdeco_close().

Here is the caller graph for this function:

◆ bufrdeco_get_atom_data_from_compressed_data_ref()

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.

Parameters
apointer to the target struct bufr_atom_data where to set the results
rpointer to the struct bufrdeco_compressed_ref with the info to know how and where get the data
subsetindex for solicited subset. First subset has index 0
bbasic container struct bufrdeco
Returns
Returns 0 if succeeded, 1 otherwise

Definition at line 742 of file bufrdeco_compressed.c.

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}
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)
#define DESCRIPTOR_HAVE_FLAG_TABLE_STRING
Bit mask for a flag table string in a struct bufr_atom_data.
Definition: bufrdeco.h:170
uint32_t get_bits_as_char_array(char *target, uint8_t *has_data, uint8_t *source, buf_t *bit0_offset, buf_t bit_length)
char * bufrdeco_explained_flag_val(char *expl, size_t dim, struct bufr_tableC *tc, struct bufr_descriptor *d, uint64_t ival, uint8_t nbits)
#define DESCRIPTOR_HAVE_STRING_VALUE
Bit mask for a string in a struct bufr_atom_data.
Definition: bufrdeco.h:152
#define DESCRIPTOR_IS_LOCAL
Bit mask for a flag table string in a struct bufr_atom_data.
Definition: bufrdeco.h:194
#define MISSING_REAL
The missing default value for real values.
Definition: bufrdeco.h:78
#define MISSING_INTEGER
The missing default value for integer values.
Definition: bufrdeco.h:84
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)
#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 DESCRIPTOR_HAVE_CODE_TABLE_STRING
Bit mask for a code table string in a struct bufr_atom_data.
Definition: bufrdeco.h:164
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
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
uint8_t raw[BUFR_LEN]
Definition: bufrdeco.h:828
char unit[BUFR_TABLEB_UNIT_LENGTH]
Definition: bufrdeco.h:651
char name[BUFR_TABLEB_NAME_LENGTH]
Definition: bufrdeco.h:650
struct bufr_sec4 sec4
Definition: bufrdeco.h:972

References bufr_atom_data::associated, bufr_tables::b, bufrdeco_compressed_ref::bit0, bufr_atom_data::bitmap_to, bufrdeco_compressed_ref::bitmap_to, bufrdeco_compressed_ref::bits, bufrdeco_explained_flag_val(), bufrdeco_explained_table_val(), bufr_descriptor::c, bufr_tables::c, bufrdeco_compressed_ref::cref0, bufr_atom_data::ctable, bufr_atom_data::cval, bufr_atom_data::desc, bufrdeco_compressed_ref::desc, DESCRIPTOR_HAVE_CODE_TABLE_STRING, DESCRIPTOR_HAVE_FLAG_TABLE_STRING, DESCRIPTOR_HAVE_STRING_VALUE, DESCRIPTOR_IS_CODE_TABLE, DESCRIPTOR_IS_FLAG_TABLE, DESCRIPTOR_IS_LOCAL, DESCRIPTOR_VALUE_MISSING, bufrdeco::error, bufr_atom_data::escale, bufrdeco_compressed_ref::escale, get_bits_as_char_array(), get_bits_as_uint32_t(), bufrdeco_compressed_ref::has_data, bufrdeco_compressed_ref::inc_bits, is_a_local_descriptor(), bufrdeco_compressed_ref::is_associated, bufr_atom_data::is_bitmaped_by, bufrdeco_compressed_ref::is_bitmaped_by, bufr_tableB::item, bufr_atom_data::mask, MISSING_INTEGER, MISSING_REAL, bufr_atom_data::name, bufrdeco_compressed_ref::name, bufr_sec4::raw, bufrdeco_compressed_ref::ref, bufrdeco_compressed_ref::ref0, bufr_atom_data::related_to, bufrdeco_compressed_ref::related_to, bufrdeco::sec4, bufr_tableB_decoded_item::tableC_ref, bufrdeco::tables, bufr_atom_data::unit, bufrdeco_compressed_ref::unit, bufr_atom_data::val, bufr_descriptor::x, bufr_tableB::x_start, bufr_descriptor::y, and bufr_tableB::y_ref.

Referenced by bufr_decode_subset_data_compressed().

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}
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_f2_descriptor_explanation()

char * bufrdeco_get_f2_descriptor_explanation ( char *  e,
size_t  dim,
struct bufr_descriptor d 
)

Definition at line 773 of file bufrdeco_f2.c.

774{
775 // check the input
776 bufrdeco_assert ( e != NULL && d != NULL && d->f == 2 )
777
778 switch ( d->x )
779 {
780 case 1:
781 if (d->y)
782 snprintf ( e, dim, "Change data width %d bits.", d->y - 128 );
783 else
784 snprintf ( e, dim, "Change data width 0 bits.");
785 break;
786
787 case 2:
788 if (d->y)
789 snprintf ( e, dim, "Change scale %d units.", d->y - 128 );
790 else
791 snprintf ( e, dim, "Change scale 0 units.");
792 break;
793
794 case 3:
795 if ( d->y != 255 )
796 snprintf ( e, dim, "Change reference values. Each new reference value has %d bits width.", d->y );
797 else
798 snprintf ( e, dim, "Change reference values concluded." );
799 break;
800
801 case 4:
802 snprintf ( e, dim,"Add associated field. Precede each data element with %d bits of information.", d->y );
803 break;
804
805 case 5:
806 snprintf ( e, dim, "Signify character. %d characters CCITT IA5 are inserted as a data field of %d x 8 bits in length.", d->y, d->y );
807 break;
808
809 case 6:
810 snprintf ( e, dim, "Signify data width. %d bits of data are described by immediately following descsriptor", d->y );
811 break;
812
813 case 7:
814 snprintf ( e, dim, "Increase scale, reference value and data width." );
815 break;
816
817 case 8:
818 snprintf ( e, dim, "Change width of CCITT IA5 field to %d characters instead of the indicated in table B", d->y );
819 break;
820
821 case 21:
822 snprintf ( e, dim, "**** Next %d descriptor(s) on this sequence level do not have data present ****", d->y );
823 break;
824
825 case 22:
826 snprintf ( e, dim, "Quality information follows. The values of Class 33 elements which follow relate to the data defined by the data present bit-map." );
827 break;
828
829 case 23:
830 if ( d->y == 0 )
831 snprintf ( e, dim, "Substituted values operator. The substituted values which follow relate to the data defined by the data present bit-map." );
832 else if ( d->y == 255 )
833 snprintf ( e, dim, "Substituted values marker operator. This operator shall signify a data item containing a substituted value." );
834 break;
835
836 case 24:
837 if ( d->y == 0 )
838 snprintf ( e, dim, "First-order statistical values follow." );
839 else if ( d->y == 255 )
840 snprintf ( e, dim, "First-order statistical values marker operator" );
841 break;
842
843 case 25:
844 if ( d->y == 0 )
845 snprintf ( e, dim,"Replaced/retained values follow." );
846 else if ( d->y == 255 )
847 snprintf ( e, dim, "Replaced/retained value marker operator" );
848 break;
849
850 case 32:
851 if ( d->y == 0 )
852 snprintf ( e, dim, "Difference statistical values follow." );
853 else if ( d->y == 255 )
854 snprintf ( e, dim, "Difference statistical values marker operator" );
855 break;
856
857 case 35:
858 snprintf ( e, dim, "Cancel backward data reference" );
859 break;
860
861 case 36:
862 snprintf ( e, dim, "Define data present bit-map" );
863 break;
864
865 case 37:
866 snprintf ( e, dim, " Use defined data present bit-map" );
867 break;
868
869 case 41:
870 if ( d->y == 0 )
871 snprintf ( e, dim, "@@@@ Event definition begins in next descriptor of this sequence level @@@@" );
872 else
873 snprintf ( e, dim, "@@@@ Event definition ends here @@@@" );
874 break;
875
876 case 42:
877 if ( d->y == 0 )
878 snprintf ( e, dim, "!!!! Conditioning event definition begins in next descriptor of this sequence level !!!!" );
879 else
880 snprintf ( e, dim, "!!!! Conditioning event definition ends here !!!!" );
881 break;
882
883 case 43:
884 if ( d->y == 0 )
885 snprintf ( e, dim, "&&&& Categorical forecast follow in next descriptor of this sequence level &&&&" );
886 else
887 snprintf ( e, dim, "&&&& Categorical forecast ends here &&&&" );
888 break;
889
890 default:
891 e[0] = 0; // void string
892 break;
893 }
894
895 return e;
896}

References bufrdeco_assert, bufr_descriptor::f, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_fprint_tree_recursive(), bufrdeco_print_json_object_operator_descriptor(), and bufrdeco_print_json_tree_recursive().

Here is the caller graph for this function:

◆ bufrdeco_get_subset_sequence_data()

struct bufrdeco_subset_sequence_data * bufrdeco_get_subset_sequence_data ( struct bufrdeco b)

Parse and get a struct bufrdeco_subset_sequence_data.

Parameters
bbasic container struct bufrdeco
Returns
If succeeded returns a pointer to the struct bufrdeco_subset_sequence_data with the results for a subset, otherwise returns NULL

Note that if succeeded the counter to current subset index is increased. Remember that in case of non compressed data we must to decode all previous subsets to get the desired one. In case of compressed we can access directly to a the desired subset

Definition at line 39 of file bufrdeco_data.c.

40{
41 bufrdeco_assert ( b != NULL );
42
44 {
45 return NULL;
46 }
47 return & ( b->seq );
48}
int bufrdeco_decode_data_subset(struct bufrdeco *b)
User interface to decode a BUFR subset.
Definition: bufrdeco_data.c:62

References bufrdeco_assert, bufrdeco_decode_data_subset(), and bufrdeco::seq.

Referenced by bufrdeco_get_target_subset_sequence_data().

Here is the call graph for this function:
Here is the caller 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}
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
int bufrdeco_decode_data_subset(struct bufrdeco *b)
User interface to decode a BUFR subset.
Definition: bufrdeco_data.c:62
uint32_t subsets
Definition: bufrdeco.h:810

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 VERSION
Definition: config.h:8

References strncpy_safe, and VERSION.

Referenced by bufrtotac_print_version().

Here is the caller graph for this function:

◆ bufrdeco_increase_compressed_data_references_count()

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.

Parameters
rpointer to the target struct
bpointer to the current active struct bufrdeco
Returns
0 if succeeded, 1 otherwise

Definition at line 1089 of file bufrdeco_compressed.c.

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}
#define BUFR_NMAXSEQ
Maximum expected descriptors in a expanded sequence for a single subset.
Definition: bufrdeco.h:116

References BUFR_NMAXSEQ, bufrdeco::error, and bufrdeco_compressed_data_references::nd.

Referenced by bufrdeco_decode_replicated_subsequence_compressed(), and bufrdeco_parse_compressed_recursive().

Here is the caller graph for this function:

◆ bufrdeco_increase_data_array()

int bufrdeco_increase_data_array ( struct bufrdeco_subset_sequence_data d)

doubles the allocated space for a struct bufrdeco_subset_sequence_data whenever is posible

Parameters
dpointer to source struct bufrdeco_subset_sequence_data
Returns
0 when success, otherwise return 1 and the struct is unmodified

The amount of data in a bufr must be huge. In a first moment, the dimension of a sequence of structs bufr_atom_data is BUFR_NMAXSEQ but may be increased. This function task is try to double the allocated dimension and reallocate it.

Definition at line 139 of file bufrdeco_data.c.

140{
141 bufrdeco_assert ( d != NULL );
142
143 if ( d->dim < ( BUFR_NMAXSEQ * 8 ) ) // check if reached the limit
144 {
145 if ( ( d->sequence = ( struct bufr_atom_data * ) realloc ( ( void * ) d->sequence,
146 d->dim * 2 * sizeof ( struct bufr_atom_data ) ) ) == NULL )
147 {
148 return 1;
149 }
150 else
151 {
152 d->dim *= 2;
153 return 0;
154 }
155 }
156 else
157 {
158 return 1;
159 }
160}
Contains all the information for a single data related with a descriptor in a expanded squence.
Definition: bufrdeco.h:435

References BUFR_NMAXSEQ, bufrdeco_assert, bufrdeco_subset_sequence_data::dim, and bufrdeco_subset_sequence_data::sequence.

Referenced by bufr_decode_subset_data_compressed(), bufrdeco_decode_replicated_subsequence(), bufrdeco_decode_subset_data_recursive(), and bufrdeco_parse_f2_descriptor().

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_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

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_init_compressed_data_references()

int bufrdeco_init_compressed_data_references ( struct bufrdeco_compressed_data_references rf)

Init a struct bufrdeco_compressed_data_references.

Parameters
rfpointer ti the target struct
Returns
0 if succeded, otherwise 1

If already memory is allocated for array of references then just adjust the used index to zero. Otherwise it allocate the needed memory and init the struct

Definition at line 205 of file bufrdeco_memory.c.

206{
207 bufrdeco_assert ( rf != NULL );
208
209 if ( rf->refs != NULL && rf->dim != 0 )
210 {
211 rf->nd = 0; // Here we set the used elements to 0 of dim
212 }
213 else if ( rf->refs == NULL )
214 {
215 // Here memory is still not allocated. Proceed to allocate with BUFR_NMAXSEQ
216 if ( ( rf->refs = ( struct bufrdeco_compressed_ref * ) calloc ( 1, BUFR_NMAXSEQ * sizeof ( struct bufrdeco_compressed_ref ) ) ) == NULL )
217 {
218 fprintf ( stderr,"%s(): Cannot allocate memory for bufrdeco_compressed_ref array\n", __func__ );
219 return 1;
220 }
221 rf->nd = 0; // Set de used elements (bufrdeco_compressed_ref)
222 rf->dim = BUFR_NMAXSEQ; // Set de allocated bufr_compressed_rer elements
223 }
224 return 0;
225}

References BUFR_NMAXSEQ, bufrdeco_assert, bufrdeco_compressed_data_references::dim, bufrdeco_compressed_data_references::nd, and bufrdeco_compressed_data_references::refs.

Referenced by bufrdeco_clean_compressed_data_references(), and bufrdeco_parse_compressed().

Here is the caller graph for this function:

◆ bufrdeco_init_expanded_tree()

int bufrdeco_init_expanded_tree ( struct bufrdeco_expanded_tree **  t)

Init a struct bufrdeco_expanded_tree allocating space.

Parameters
tpointer to the target pointer to struct bufrdeco_expanded_tree
Returns
0 if succeeded, 1 otherwise

Definition at line 70 of file bufrdeco_memory.c.

71{
72 bufrdeco_assert ( t != NULL );
73
74 if ( *t != NULL )
75 free ( ( void * ) *t );
76
77 if ( ( *t = ( struct bufrdeco_expanded_tree * ) calloc ( 1, sizeof ( struct bufrdeco_expanded_tree ) ) ) == NULL )
78 return 1;
79 return 0;
80}
Array of structs bufr_sequence from which bufr expanded tree is made.
Definition: bufrdeco.h:596

References bufrdeco_assert.

Referenced by bufrdeco_init(), and bufrdeco_reset().

Here is the caller graph for this function:

◆ bufrdeco_init_subset_sequence_data()

int bufrdeco_init_subset_sequence_data ( struct bufrdeco_subset_sequence_data ba)

Init a struct bufrdeco_subset_sequence_data.

Parameters
bapointer to the target struct
Returns
0 if succeeded, 1 otherwise

It is supossed that no memory is allocated for sequence. If we are not sure better use function bufrdeco_clean_subset_sequence_data

Definition at line 140 of file bufrdeco_memory.c.

141{
142 bufrdeco_assert ( ba != NULL );
143
144 memset ( ba, 0, sizeof ( struct bufrdeco_subset_sequence_data ) );
145 if ( ( ba->sequence = ( struct bufr_atom_data * ) calloc ( 1, BUFR_NMAXSEQ * sizeof ( struct bufr_atom_data ) ) ) == NULL )
146 {
147 fprintf ( stderr,"%s():Cannot allocate memory for atom data array\n", __func__ );
148 return 1;
149 }
150 ba->dim = BUFR_NMAXSEQ;
151 return 0;
152}

References BUFR_NMAXSEQ, bufrdeco_assert, bufrdeco_subset_sequence_data::dim, and bufrdeco_subset_sequence_data::sequence.

Referenced by bufrdeco_clean_subset_sequence_data().

Here is the caller graph for this function:

◆ bufrdeco_init_tables()

int bufrdeco_init_tables ( struct bufr_tables **  t)

Init a struct bufr_tables allocating space.

Parameters
tpointer to the target pointer to struct bufr_tables
Returns
0 if succeeded, 1 otherwise

Definition at line 32 of file bufrdeco_memory.c.

33{
34 bufrdeco_assert ( t != NULL );
35
36 if ( *t != NULL )
37 free ( ( void * ) *t );
38
39 if ( ( *t = ( struct bufr_tables * ) calloc ( 1, sizeof ( struct bufr_tables ) ) ) == NULL )
40 return 1;
41 return 0;
42}
Contains all tables needed to parse a bufr file.
Definition: bufrdeco.h:938

References bufrdeco_assert.

Referenced by bufr_read_tables(), bufrdeco_init(), bufrdeco_store_tables(), and bufrdeco_substitute_tables().

Here is the caller graph for this function:

◆ bufrdeco_parse_compressed()

int bufrdeco_parse_compressed ( struct bufrdeco_compressed_data_references r,
struct bufrdeco b 
)

Preliminary parse of a compressed data bufr.

Parameters
rpointer to a struct bufrdeco_compressed_data_references where to set the results
bbasic container struct bufrdeco
Returns
Returns 0 if succeeded, 1 otherwise

When a bufr report has compressed data, it is needed to do a first parse step to get references about where to find the data for every descriptor in subsets. This is what this function does. If succeeded the struct r will have all needed data to decode individual subsets.

Also be mind that the descriptors tree have to be already parsed when calling this function

Definition at line 40 of file bufrdeco_compressed.c.

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}
int bufrdeco_init_compressed_data_references(struct bufrdeco_compressed_data_references *rf)
Init a struct bufrdeco_compressed_data_references.

References bufrdeco_init_compressed_data_references(), bufrdeco_parse_compressed_recursive(), bufrdeco::error, bufrdeco_expanded_tree::nseq, and bufrdeco::tree.

Referenced by bufrdeco_decode_data_subset(), and bufrdeco_get_target_subset_sequence_data().

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

◆ bufrdeco_parse_compressed_recursive()

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 descriptor in a subset.

Parameters
rpointer to target struct bufrdeco_compressed_data_references where to set results
lpointer to a struct bufr_sequence to parse in this call. If NULL then it is first root sequence
bbasic container struct bufrdeco
Returns
Returns 0 if succeeded, 1 otherwise

Definition at line 76 of file bufrdeco_compressed.c.

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}
stores the state when expanding a sequence.
Definition: bufrdeco.h:524

References bufr_sequence_index_range::active, bufrdeco_decoding_data_state::added_bit_length, bufrdeco_decoding_data_state::added_reference, bufrdeco_decoding_data_state::added_scale, bufrdeco_decoding_data_state::assoc_bits, bufrdeco_decoding_data_state::bit_offset, bufrdeco_decoding_data_state::bitmap, bufrdeco::bitmap, bufrdeco_decoding_data_state::bitmaping, bufrdeco_bitmap_array::bmap, BUFR_MAX_QUALITY_DATA, BUFRDECO_COMPRESSED_REF_DATA_DESCRIPTOR_BITMASK, BUFRDECO_COMPRESSED_REF_OPERATOR_DESCRIPTOR, BUFRDECO_COMPRESSED_REF_REPLICATOR_DESCRIPTOR, BUFRDECO_COMPRESSED_REF_SEQUENCE_FINAL_BITMASK, BUFRDECO_COMPRESSED_REF_SEQUENCE_INIT_BITMASK, bufrdeco_decode_replicated_subsequence_compressed(), bufrdeco_increase_compressed_data_references_count(), bufrdeco_parse_compressed_recursive(), bufrdeco_parse_f2_compressed(), bufrdeco_tableB_compressed(), bufr_descriptor::c, bufrdeco_decoding_data_state::changing_reference, bufrdeco_compressed_ref::desc, bufrdeco_decoding_data_state::dstat_active, bufrdeco_bitmap::dstat_desc, bufrdeco::error, bufr_descriptor::f, bufrdeco_decoding_data_state::factor_reference, bufr_sequence_index_range::first, bufrdeco_decoding_data_state::fixed_ccitt, bufr_replicator::ixdel, bufr_replicator::ixrep, bufrdeco_decoding_data_state::local_bit_reserved, bufr_sequence::lseq, bufrdeco_compressed_ref::mask, bufrdeco_bitmap_array::nba, bufrdeco_compressed_data_references::nd, bufr_replicator::ndesc, bufr_sequence::ndesc, bufrdeco_bitmap::nds, bufr_replicator::nloops, bufr_sequence::no_data_present, bufrdeco_bitmap::ns1, bufrdeco_decoding_data_state::quality_active, bufrdeco_compressed_ref::ref0, bufrdeco_compressed_data_references::refs, bufrdeco_decoding_data_state::retained_active, bufr_replicator::s, bufrdeco_expanded_tree::seq, bufrdeco_compressed_ref::seq, bufr_sequence::sons, bufrdeco_decoding_data_state::stat1_active, bufrdeco_bitmap::stat1_desc, bufrdeco::state, bufrdeco_decoding_data_state::subs_active, bufrdeco::tree, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_decode_replicated_subsequence_compressed(), bufrdeco_parse_compressed(), and bufrdeco_parse_compressed_recursive().

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

◆ bufrdeco_parse_f2_compressed()

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

Parameters
rpointer to a struct bufrdeco_compressed_data_references where to set data references if any
dpointer to the source descriptor
bpointer to the base struct bufrdeco
Returns
If succeded return 0, otherwise 1

Definition at line 406 of file bufrdeco_f2.c.

407{
408 buf_t nbits;
409 uint32_t ival;
410 struct bufrdeco_compressed_ref *rf;
411 uint8_t has_data;
412
413 // Check args
414 bufrdeco_assert ( b != NULL );
415
416 if ( d == NULL || r == NULL )
417 {
418 snprintf ( b->error, sizeof ( b->error ), "%s(): Unspected NULL argument(s)\n", __func__ );
419 }
420
421 if ( d->f != 2 )
422 {
423 return 0; // nothing to do here
424 }
425
426 switch ( d->x )
427 {
428 case 1:
429 // Add (YYY–128) bits to the data width given for each
430 // data element in Table B, other than CCITT IA5
431 // (character) data, code or flag tables.
432 if ( d->y )
433 {
434 b->state.added_bit_length = d->y - 128;
435 }
436 else
437 {
438 b->state.added_bit_length = 0;
439 }
440 break;
441
442 case 2:
443 // Add YYY–128 to the scale for each data element in
444 // Table B, other than CCITT IA5 (character) data, code
445 // or flag tables.
446 if ( d->y )
447 {
448 b->state.added_scale = d->y - 128;
449 }
450 else
451 {
452 b->state.added_scale = 0;
453 }
454 break;
455
456 case 3:
457 // Subsequent element descriptors define new reference
458 // values for corresponding Table B entries. Each new
459 // reference value is represented by YYY bits in the Data
460 // section. Definition of new reference values is concluded
461 // by coding this operator with YYY = 255. Negative
462 // reference values shall be represented by a positive
463 // integer with the left-most bit (bit 1) set to 1.
464 b->state.changing_reference = d->y;
465 break;
466
467 case 4:
468 // Precede each data element with YYY bits of
469 // information. This operation associates a data field
470 // (e.g. quality control information) of YYY bits with each
471 // data element.
472 b->state.assoc_bits = d->y;
473 break;
474
475 case 5:
476 // YYY characters (CCITT International Alphabet No. 5) are
477 // inserted as a data field of YYY x 8 bits in length.
478 nbits = 8 * d->y;
479 rf = & ( r->refs[r->nd] );
481 rf->desc = d;
482 if ( get_bits_as_char_array ( rf->cref0, &rf->has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), nbits ) == 0 )
483 {
484 snprintf ( b->error, sizeof ( b->error ), "%s(): Cannot get %u uchars from '%s'\n", __func__, d->y, d->c );
485 return 1;
486 }
487 //strcpy_safe ( rf->name, "SIGNIFY CHARACTER" );
488 //strcpy_safe ( rf->unit, "CCITTIA5" ); // unit
489 strcpy ( rf->name, "SIGNIFY CHARACTER" );
490 strcpy ( rf->unit, "CCITTIA5" ); // unit
491
492 // Is suppossed all data will have same length in all subsets
493 // extracting inc_bits from next 6 bits
494 if ( get_bits_as_uint32_t ( &ival, &has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), 6 ) == 0 )
495 {
496 snprintf ( b->error, sizeof ( b->error ), "%s(): Cannot get 6 bits for inc_bits from '%s'\n", __func__, d->c );
497 return 1;
498 }
499 if ( ival != d->y )
500 {
501 snprintf ( b->error, sizeof ( b->error ), "%s(): Bad length in inc_bits for a 2 05 YYY descriptor from '%s'\n", __func__, d->c );
502 return 1;
503 }
504 rf->inc_bits = ival;
505 b->state.bit_offset += rf->inc_bits * 8 * b->sec3.subsets;
506 if ( r->nd < ( BUFR_NMAXSEQ - 1 ) )
507 {
508 r->nd += 1;
509 }
510 else
511 {
512 snprintf ( b->error, sizeof ( b->error ), "%s(): Reached limit. Consider increas BUFR_NMAXSEQ\n", __func__ );
513 return 1;
514 }
515 break;
516
517 case 6:
518 // YYY bits of data are described by the immediately
519 // following local descriptor.
520 b->state.local_bit_reserved = d->y;
521 break;
522
523 case 7:
524 // For Table B elements, which are not CCITT IA5
525 // (character data), code tables, or flag tables:
526 // 1. Add YYY to the existing scale factor
527 // YYY
528 // 2. Multiply the existing reference value by 10
529 // 3. Calculate ((10 x YYY) + 2) ÷ 3, disregard any
530 // fractional remainder and add the result to the
531 // existing bit width.
532 if ( d->y )
533 {
534 b->state.added_scale = d->y;
535 if ( d->y < 10 )
537 else
538 {
539 snprintf ( b->error, sizeof ( b->error ), "%s(): Too much %u increase bits for operator '%s'", __func__, d->y,
540 d->c );
541 return 1;
542 }
543 b->state.added_bit_length = ( int8_t ) ( ( 10.0 * d->y + 2.0 ) / 3.0 );
544 }
545 else
546 {
547 b->state.added_scale = 0;
548 b->state.factor_reference = 1;
549 b->state.added_bit_length = 0;
550 }
551 break;
552
553 case 8:
554 // YYY characters from CCITT International Alphabet
555 // No. 5 (representing YYY x 8 bits in length) replace the
556 // specified data width given for each CCITT IA5
557 // element in Table B.
558 b->state.fixed_ccitt = d->y;
559 break;
560
561 case 21:
562 // Data not present
563 //
564 // Data values present in Section 4 (Data section)
565 // corresponding to the following YYY descriptors shall
566 // be limited to data from Classes 01–09, and Class 31.
567 //
568 // It is nor processed here, it is already processed when parsing tree of expanded descriptors
569 // adjusting the proper struct \ref bufr_sequence_index_range no_data_present
570 break;
571
572 case 22:
573 // Quality information follows
574 // The values of Class 33 elements which follow relate to
575 // the data defined by the data present bit-map.
576 //
577 // Here we jsut activate the quality_active flag
578 b->state.quality_active = 1;
579 b->state.subs_active = 0;
580 b->state.retained_active = 0;
581 b->state.stat1_active = 0;
582 b->state.dstat_active = 0;
583 break;
584
585 case 23:
586 if ( d->y == 0 )
587 {
588 // Substituted operator values
589 //
590 // The substituted values which follow relate to the data
591 // defined by the data present bit-map.
592 b->state.quality_active = 0;
593 b->state.subs_active = 1;
594 b->state.retained_active = 0;
595 b->state.stat1_active = 0;
596 b->state.dstat_active = 0;
597 }
598 break;
599
600 case 24:
601 if ( d->y == 0 )
602 {
603 // First-order statistical values follow
604 //
605 // The statistical values which follow relate to the data
606 // defined by the data present bit-map.
607 b->state.quality_active = 0;
608 b->state.subs_active = 0;
609 b->state.retained_active = 0;
610 b->state.stat1_active = 1;
611 b->state.dstat_active = 0;
612 }
613 break;
614
615 case 25:
616 if ( d->y == 0 )
617 {
618 // Difference statistical values follow
619 //
620 // The statistical values which follow relate to the data
621 // defined by the data present bit-map.
622 b->state.quality_active = 0;
623 b->state.subs_active = 0;
624 b->state.retained_active = 0;
625 b->state.stat1_active = 0;
626 b->state.dstat_active = 1;
627 }
628 break;
629
630 case 32:
631 if ( d->y == 0 )
632 {
633 // Replaced/retained values follow
634 //
635 // The replaced/retained values which follow relate to the
636 // data defined by the data present bit-map.
637 b->state.quality_active = 0;
638 b->state.subs_active = 0;
639 b->state.retained_active = 1;
640 b->state.stat1_active = 0;
641 b->state.dstat_active = 0;
642 }
643 break;
644
645
646 case 35:
647 // Cancel backward data reference
648 //
649 // This operator terminates all previously defined backward
650 // reference and cancels any previously defined
651 // data present bit-map; it causes the next data present
652 // bit-map to refer to the data descriptors which
653 // immediately precede the operator to which it relates.
654
655 // Set the bitmap pointer to NULL.
656 b->state.bitmap = NULL;
657 break;
658
659 case 36:
660 // Define data present bit-map
661 //
662 // This operator defines the data present bit-map which
663 // follows for possible re-use; only one data present
664 // bit-map may be defined between this operator and the
665 // cancel use defined data present bit-map operator.
666
667 // Here we just add a bufrdeco_bitmap struct set the current bitmap
668 if ( bufrdeco_allocate_bitmap ( b ) )
669 {
670 // Cannot allocate another bitmap
671 return 1;
672 }
673 // Set the new current bitmap
674 b->state.bitmap = b->bitmap.bmap[b->bitmap.nba - 1];
675
676 // Now set the bitmaping backward count to 1 to flag that next replicator descriptor must be set it properly
677 b->state.bitmaping = 1;
678
679 break;
680
681 case 37:
682 // if y = 0000 use defined data present bit-map
683 // This operator causes the defined data present bit-map to be used again.
684 //
685 // if y = 255 Cancel use defined data present bit-map
686 // This operator cancels the re-use of the defined data present bit-map.
687 if ( d->y == 0 )
688 {
689 if ( b->bitmap.nba && b->state.bitmap == NULL )
690 b->state.bitmap = b->bitmap.bmap[b->bitmap.nba - 1];
691 }
692 else if ( d->y == 255 )
693 {
694 b->state.bitmap = NULL;
695 }
696 break;
697
698 case 41:
699 // This operator denotes the beginning of the definition of an event.
700 //
701 // An event, as defined for use with operators 2 41 000 and 2 42 000,
702 // is a set of one or more circumstances described using appropriate
703 // Table B descriptors along with their corresponding data values. The
704 // grouping of such descriptors together as a single “event” allows
705 // them to be collectively assigned as the target of a separate descriptor
706 // such as 0 33 045 or 0 33 046. When defining a circumstance within an
707 // event, descriptor 0 33 042 may be employed preceding the appropriate
708 // Table B descriptor in order to indicate that the corresponding value
709 // is actually a bound for a range of values.
710 //
711 // If y = 255 then it denotes the conclusion of the
712 // event definition that was begun via the previous 2 41 000
713 // operator.
714 //
715 // It is nor processed here, it is already processed when parsing tree of expanded descriptors
716 // adjusting the proper struct \ref bufr_sequence_index_range event
717 break;
718
719 case 42:
720 // This operator denotes the beginning of the definition of a conditioning event.
721 //
722 // An event, as defined for use with operators 2 41 000 and 2 42 000,
723 // is a set of one or more circumstances described using appropriate
724 // Table B descriptors along with their corresponding data values. The
725 // grouping of such descriptors together as a single “event” allows
726 // them to be collectively assigned as the target of a separate descriptor
727 // such as 0 33 045 or 0 33 046. When defining a circumstance within an
728 // event, descriptor 0 33 042 may be employed preceding the appropriate
729 // Table B descriptor in order to indicate that the corresponding value
730 // is actually a bound for a range of values.
731 //
732 // If y = 255 then it denotes the conclusion of the conditioning
733 // event definition that was begun via the previous 2 42 000
734 // operator.
735 //
736 // It is nor processed here, it is already processed when parsing tree of expanded descriptors
737 // adjusting the proper struct \ref bufr_sequence_index_range cond_event
738 break;
739
740 case 43:
741 // The values which follow are categorical forecast values
742 //
743 // A categorical forecast value represents a “best guess” from among a set of related,
744 // and often mutually exclusive, data values or categories. Operator 2 43 000 may be
745 // used to designate one or more values as categorical forecast values, and descriptor
746 // 0 33 042 may be employed preceding any such value in order to indicate that that value
747 // is actually a bound for a range of value
748 //
749 // If y == 255 then it denotes the conclusion of the definition of categorical forecast
750 // values that was begun via theprevious 2 43 000 operator.
751 //
752 // It is nor processed here, it is already processed when parsing tree of expanded descriptors
753 // adjusting the proper struct \ref bufr_sequence_index_range cat_forecast
754 break;
755
756 default:
757 // Still not processed: 21
758 snprintf ( b->error, sizeof ( b->error ), "%s(): Still no proccessed descriptor '%s' in "
759 "current library version %s \n", __func__, d->c, VERSION );
760 return 1;
761 }
762 return 0;
763}
int bufrdeco_allocate_bitmap(struct bufrdeco *b)
allocate bitmap
const int32_t pow10pos_int[10]

References bufrdeco_decoding_data_state::added_bit_length, bufrdeco_decoding_data_state::added_scale, bufrdeco_decoding_data_state::assoc_bits, bufrdeco_decoding_data_state::bit_offset, bufrdeco_decoding_data_state::bitmap, bufrdeco::bitmap, bufrdeco_decoding_data_state::bitmaping, bufrdeco_bitmap_array::bmap, BUFR_NMAXSEQ, bufrdeco_allocate_bitmap(), bufrdeco_assert, BUFRDECO_COMPRESSED_REF_DATA_DESCRIPTOR_BITMASK, bufr_descriptor::c, bufrdeco_decoding_data_state::changing_reference, bufrdeco_compressed_ref::cref0, bufrdeco_compressed_ref::desc, bufrdeco_decoding_data_state::dstat_active, bufrdeco::error, bufr_descriptor::f, bufrdeco_decoding_data_state::factor_reference, bufrdeco_decoding_data_state::fixed_ccitt, get_bits_as_char_array(), get_bits_as_uint32_t(), bufrdeco_compressed_ref::has_data, bufrdeco_compressed_ref::inc_bits, bufrdeco_decoding_data_state::local_bit_reserved, bufrdeco_compressed_ref::mask, bufrdeco_compressed_ref::name, bufrdeco_bitmap_array::nba, bufrdeco_compressed_data_references::nd, pow10pos_int, bufrdeco_decoding_data_state::quality_active, bufr_sec4::raw, bufrdeco_compressed_data_references::refs, bufrdeco_decoding_data_state::retained_active, bufrdeco::sec3, bufrdeco::sec4, bufrdeco_decoding_data_state::stat1_active, bufrdeco::state, bufrdeco_decoding_data_state::subs_active, bufr_sec3::subsets, bufrdeco_compressed_ref::unit, VERSION, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_decode_replicated_subsequence_compressed(), and bufrdeco_parse_compressed_recursive().

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

◆ bufrdeco_parse_f2_descriptor()

int bufrdeco_parse_f2_descriptor ( struct bufrdeco_subset_sequence_data s,
struct bufr_descriptor d,
struct bufrdeco b 
)

parse a descritor with f = 2

Parameters
spointer to a struct bufrdeco_subset_sequence_data where to set data if any
dpointer to the source descriptor
bpointer to the base struct bufrdeco
Returns
If succeded return 0, otherwise 1

Definition at line 39 of file bufrdeco_f2.c.

40{
41 buf_t nbits;
42 struct bufr_atom_data *a;
43 uint8_t has_data;
44
45 // Check args
46 bufrdeco_assert ( b != NULL );
47
48 if ( d == NULL || s == NULL )
49 {
50 snprintf ( b->error, sizeof ( b->error ), "%s(): Unspected NULL argument(s)\n", __func__ );
51 }
52
53 if ( d->f != 2 )
54 {
55 return 0; // nothing to do here
56 }
57
58 switch ( d->x )
59 {
60 case 1:
61 // Add (YYY–128) bits to the data width given for each
62 // data element in Table B, other than CCITT IA5
63 // (character) data, code or flag tables.
64 if ( d->y )
65 {
66 b->state.added_bit_length = d->y - 128;
67 }
68 else
69 {
71 }
72 break;
73
74 case 2:
75 // Add YYY–128 to the scale for each data element in
76 // Table B, other than CCITT IA5 (character) data, code
77 // or flag tables.
78 if ( d->y )
79 {
80 b->state.added_scale = d->y - 128;
81 }
82 else
83 {
84 b->state.added_scale = 0;
85 }
86 break;
87
88 case 3:
89 // Subsequent element descriptors define new reference
90 // values for corresponding Table B entries. Each new
91 // reference value is represented by YYY bits in the Data
92 // section. Definition of new reference values is concluded
93 // by coding this operator with YYY = 255. Negative
94 // reference values shall be represented by a positive
95 // integer with the left-most bit (bit 1) set to 1.
97 break;
98
99 case 4:
100 // Precede each data element with YYY bits of
101 // information. This operation associates a data field
102 // (e.g. quality control information) of YYY bits with each
103 // data element.
104 b->state.assoc_bits = d->y;
105 break;
106
107 case 5:
108 // YYY characters (CCITT International Alphabet No. 5) are
109 // inserted as a data field of YYY x 8 bits in length.
110 nbits = 8 * d->y;
111 a = & ( s->sequence[s->nd] );
112 memcpy ( &a->desc, d, sizeof ( struct bufr_descriptor ) );
113 if ( get_bits_as_char_array ( a->cval, &has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), nbits ) == 0 )
114 {
115 snprintf ( b->error, sizeof ( b->error ), "%s(): Cannot get %u uchars from '%s'\n", __func__, d->y, d->c );
116 return 1;
117 }
118 if ( has_data == 0 )
119 {
121 }
122 else
123 {
125 }
126 //strcpy_safe ( a->name, "SIGNIFY CHARACTER" );
127 //strcpy_safe ( a->unit, "CCITTIA5" ); // unit
128 strcpy ( a->name, "SIGNIFY CHARACTER" );
129 strcpy ( a->unit, "CCITTIA5" ); // unit
131 {
134 }
135
136 if ( s->nd < ( s->dim - 1 ) )
137 {
138 ( s->nd ) ++;
139 }
140 else if ( bufrdeco_increase_data_array ( s ) == 0 )
141 {
142 ( s->nd ) ++;
143 }
144 else
145 {
146 snprintf ( b->error, sizeof ( b->error ), "%s(): No more bufr_atom_data available. Check BUFR_NMAXSEQ\n", __func__ );
147 return 1;
148 }
149 break;
150
151 case 6:
152 // YYY bits of data are described by the immediately
153 // following local descriptor.
154 b->state.local_bit_reserved = d->y;
155 break;
156
157 case 7:
158 // For Table B elements, which are not CCITT IA5
159 // (character data), code tables, or flag tables:
160 // 1. Add YYY to the existing scale factor
161 // YYY
162 // 2. Multiply the existing reference value by 10
163 // 3. Calculate ((10 x YYY) + 2) ÷ 3, disregard any
164 // fractional remainder and add the result to the
165 // existing bit width.
166 if ( d->y )
167 {
168 b->state.added_scale = d->y;
169 if ( d->y < 10 )
171 else
172 {
173 snprintf ( b->error, sizeof ( b->error ), "%s(): Too much %u increase bits for operator '%s'", __func__, d->y,
174 d->c );
175 return 1;
176 }
177 b->state.added_bit_length = ( int8_t ) ( ( 10.0 * d->y + 2.0 ) / 3.0 );
178 }
179 else
180 {
181 b->state.added_scale = 0;
182 b->state.factor_reference = 1;
183 b->state.added_bit_length = 0;
184 }
185 break;
186
187 case 8:
188 // YYY characters from CCITT International Alphabet
189 // No. 5 (representing YYY x 8 bits in length) replace the
190 // specified data width given for each CCITT IA5
191 // element in Table B.
192 b->state.fixed_ccitt = d->y;
193 break;
194
195 case 21:
196 // Data not present
197 //
198 // Data values present in Section 4 (Data section)
199 // corresponding to the following YYY descriptors shall
200 // be limited to data from Classes 01–09, and Class 31.
201
202 // It is nor processed here, it is already processed when parsing tree of expanded descriptors
203 // adjusting the proper struct \ref bufr_sequence_index_range no_data_present
204 break;
205
206 case 22:
207 // Quality information follows
208 // The values of Class 33 elements which follow relate to
209 // the data defined by the data present bit-map.
210 //
211 // Here we jsut activate the quality_active flag
212 b->state.quality_active = 1;
213 b->state.subs_active = 0;
214 b->state.retained_active = 0;
215 b->state.stat1_active = 0;
216 b->state.dstat_active = 0;
217 break;
218
219 case 23:
220 if ( d->y == 0 )
221 {
222 // Substituted operator values
223 //
224 // The substituted values which follow relate to the data
225 // defined by the data present bit-map.
226 b->state.quality_active = 0;
227 b->state.subs_active = 1;
228 b->state.retained_active = 0;
229 b->state.stat1_active = 0;
230 b->state.dstat_active = 0;
231 }
232 break;
233
234 case 24:
235 if ( d->y == 0 )
236 {
237 // First-order statistical values follow
238 //
239 // The statistical values which follow relate to the data
240 // defined by the data present bit-map.
241 b->state.quality_active = 0;
242 b->state.subs_active = 0;
243 b->state.retained_active = 0;
244 b->state.stat1_active = 1;
245 b->state.dstat_active = 0;
246 }
247 break;
248
249 case 25:
250 if ( d->y == 0 )
251 {
252 // Difference statistical values follow
253 //
254 // The statistical values which follow relate to the data
255 // defined by the data present bit-map.
256 b->state.quality_active = 0;
257 b->state.subs_active = 0;
258 b->state.retained_active = 0;
259 b->state.stat1_active = 0;
260 b->state.dstat_active = 1;
261 }
262 break;
263
264 case 32:
265 if ( d->y == 0 )
266 {
267 // Replaced/retained values follow
268 //
269 // The replaced/retained values which follow relate to the
270 // data defined by the data present bit-map.
271 b->state.quality_active = 0;
272 b->state.subs_active = 0;
273 b->state.retained_active = 1;
274 b->state.stat1_active = 0;
275 b->state.dstat_active = 0;
276 }
277 break;
278
279 case 35:
280 // Cancel backward data reference
281 //
282 // This operator terminates all previously defined backward
283 // reference and cancels any previously defined
284 // data present bit-map; it causes the next data present
285 // bit-map to refer to the data descriptors which
286 // immediately precede the operator to which it relates.
287
288 // Set the bitmap pointer to NULL.
289 b->state.bitmap = NULL;
290 break;
291
292 case 36:
293 // Define data present bit-map
294 //
295 // This operator defines the data present bit-map which
296 // follows for possible re-use; only one data present
297 // bit-map may be defined between this operator and the
298 // cancel use defined data present bit-map operator.
299
300 // Here we just add a bufrdeco_bitmap struct set the current bitmap
301 if ( bufrdeco_allocate_bitmap ( b ) )
302 {
303 // Cannot allocate another bitmap
304 return 1;
305 }
306 // Set the new current bitmap
307 b->state.bitmap = b->bitmap.bmap[b->bitmap.nba - 1];
308
309 // Now set the bitmaping backward count to 1 to flag that next replicator descriptor must be set it properly
310 b->state.bitmaping = 1;
311
312 break;
313
314 case 37:
315 // if y = 0000 use defined data present bit-map
316 // This operator causes the defined data present bit-map to be used again.
317 //
318 // if y = 255 Cancel use defined data present bit-map
319 // This operator cancels the re-use of the defined data present bit-map.
320 if ( d->y == 0 )
321 {
322 if ( b->bitmap.nba && b->state.bitmap == NULL )
323 b->state.bitmap = b->bitmap.bmap[b->bitmap.nba - 1];
324 }
325 else if ( d->y == 255 )
326 {
327 b->state.bitmap = NULL;
328 }
329 break;
330
331 case 41:
332 // This operator denotes the beginning of the definition of an event.
333 //
334 // An event, as defined for use with operators 2 41 000 and 2 42 000,
335 // is a set of one or more circumstances described using appropriate
336 // Table B descriptors along with their corresponding data values. The
337 // grouping of such descriptors together as a single “event” allows
338 // them to be collectively assigned as the target of a separate descriptor
339 // such as 0 33 045 or 0 33 046. When defining a circumstance within an
340 // event, descriptor 0 33 042 may be employed preceding the appropriate
341 // Table B descriptor in order to indicate that the corresponding value
342 // is actually a bound for a range of values.
343 //
344 // If y = 255 then it denotes the conclusion of the
345 // event definition that was begun via the previous 2 41 000
346 // operator.
347 //
348 // It is nor processed here, it is already processed when parsing tree of expanded descriptors
349 // adjusting the proper struct \ref bufr_sequence_index_range event
350 break;
351
352 case 42:
353 // This operator denotes the beginning of the definition of a conditioning event.
354 //
355 // An event, as defined for use with operators 2 41 000 and 2 42 000,
356 // is a set of one or more circumstances described using appropriate
357 // Table B descriptors along with their corresponding data values. The
358 // grouping of such descriptors together as a single “event” allows
359 // them to be collectively assigned as the target of a separate descriptor
360 // such as 0 33 045 or 0 33 046. When defining a circumstance within an
361 // event, descriptor 0 33 042 may be employed preceding the appropriate
362 // Table B descriptor in order to indicate that the corresponding value
363 // is actually a bound for a range of values.
364 //
365 // If y = 255 then it denotes the conclusion of the conditioning
366 // event definition that was begun via the previous 2 42 000
367 // operator.
368 //
369 // It is nor processed here, it is already processed when parsing tree of expanded descriptors
370 // adjusting the proper struct \ref bufr_sequence_index_range cond_event
371 break;
372
373 case 43:
374 // The values which follow are categorical forecast values
375 //
376 // A categorical forecast value represents a “best guess” from among a set of related,
377 // and often mutually exclusive, data values or categories. Operator 2 43 000 may be
378 // used to designate one or more values as categorical forecast values, and descriptor
379 // 0 33 042 may be employed preceding any such value in order to indicate that that value
380 // is actually a bound for a range of value
381 //
382 // If y == 255 then it denotes the conclusion of the definition of categorical forecast
383 // values that was begun via theprevious 2 43 000 operator.
384 //
385 // It is nor processed here, it is already processed when parsing tree of expanded descriptors
386 // adjusting the proper struct \ref bufr_sequence_index_range cat_forecast
387 break;
388
389 default:
390 snprintf ( b->error, sizeof ( b->error ), "%s(): Still no proccessed descriptor '%s' in "
391 "current library version %s\n", __func__, d->c, VERSION );
392 return 1;
393 }
394 return 0;
395}

References bufrdeco_decoding_data_state::added_bit_length, bufrdeco_decoding_data_state::added_scale, bufrdeco_decoding_data_state::assoc_bits, bufrdeco_decoding_data_state::bit_offset, bufrdeco_decoding_data_state::bitmap, bufrdeco::bitmap, bufrdeco_decoding_data_state::bitmaping, bufrdeco_bitmap_array::bmap, bufrdeco_allocate_bitmap(), bufrdeco_assert, bufrdeco_increase_data_array(), BUFRDECO_OUTPUT_JSON_SUBSET_DATA, bufrdeco_print_json_object_atom_data(), bufrdeco_print_json_separator(), bufr_descriptor::c, bufrdeco_decoding_data_state::changing_reference, bufr_atom_data::cval, bufr_atom_data::desc, DESCRIPTOR_HAVE_STRING_VALUE, DESCRIPTOR_VALUE_MISSING, bufrdeco_subset_sequence_data::dim, bufrdeco_decoding_data_state::dstat_active, bufrdeco::error, bufr_descriptor::f, bufrdeco_decoding_data_state::factor_reference, bufrdeco_decoding_data_state::fixed_ccitt, get_bits_as_char_array(), bufrdeco_decoding_data_state::local_bit_reserved, bufr_atom_data::mask, bufrdeco::mask, bufr_atom_data::name, bufrdeco_bitmap_array::nba, bufrdeco_subset_sequence_data::nd, bufrdeco::out, pow10pos_int, bufrdeco_decoding_data_state::quality_active, bufr_sec4::raw, bufrdeco_decoding_data_state::retained_active, bufrdeco::sec4, bufrdeco_subset_sequence_data::sequence, bufrdeco_decoding_data_state::stat1_active, bufrdeco::state, bufrdeco_decoding_data_state::subs_active, bufr_atom_data::unit, VERSION, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_decode_replicated_subsequence(), and bufrdeco_decode_subset_data_recursive().

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_parse_tree_recursive()

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.

Parameters
keystring with descriptor in form 'FXXYYY'
fatherpointer to the father struct bufr_sequence
father_idescindex of sequence descriptor in father bufr_sequence which this sequence derived
bpointer to the base struct bufrdeco
Returns
0 if success, 1 otherwise

Definition at line 60 of file bufrdeco_tree.c.

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}
#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
struct bufr_sequence_index_range cond_event
Definition: bufrdeco.h:580
struct bufr_sequence * father
Definition: bufrdeco.h:576
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_index_range cat_forecast
Definition: bufrdeco.h:581
char name[BUFR_EXPLAINED_LENGTH]
Definition: bufrdeco.h:588

References bufr_sequence_index_range::active, bufrdeco_parse_tree_recursive(), bufrdeco_tableD_get_descriptors_array(), bufr_descriptor::c, bufr_sequence::cat_forecast, bufr_sequence::cond_event, bufrdeco::error, bufr_sequence::event, bufr_descriptor::f, bufr_sequence::father, bufr_sequence::father_idesc, bufr_sequence_index_range::first, get_unexpanded_descriptor_array_from_sec3(), bufr_sequence::iseq, bufr_sequence::key, bufr_sequence_index_range::last, bufr_sequence::level, bufr_sequence::lseq, bufr_sequence::name, bufr_sequence::ndesc, NMAXSEQ_DESCRIPTORS, bufr_sequence::no_data_present, bufrdeco_expanded_tree::nseq, bufr_sequence::replicated, bufrdeco_expanded_tree::seq, bufr_sequence::sons, bufrdeco::tree, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_parse_tree(), and bufrdeco_parse_tree_recursive().

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

◆ bufrdeco_print_atom_data()

char * bufrdeco_print_atom_data ( char *  target,
size_t  lmax,
struct bufr_atom_data a 
)

print the data in a struct bufr_atom_data to a string

Parameters
targetstring where to print the result
lmaxsize of allocated string target
apointer to struct ref bufr_atom_data with data to print
Returns
a pointer to result string

Definition at line 433 of file bufrdeco_print.c.

434{
435 char aux[256];
436 size_t used = 0;
437 size_t nlimit, climit;
438
439 bufrdeco_assert ( a != NULL && target != NULL );
440
441 used += snprintf ( target + used, lmax - used, "%u %02u %03u ", a->desc.f, a->desc.x, a->desc.y );
442 strcpy_safe ( aux, a->name );
443 aux[64] = '\0';
444 used += snprintf ( target + used, lmax - used, "%-64s ", aux );
445 strcpy_safe ( aux, a->unit );
446 aux[20] = '\0';
447 used += snprintf ( target + used, lmax - used, "%-20s", aux );
449 {
450 used += snprintf ( target + used, lmax - used, "%17s", "MISSING" );
451 }
452 else
453 {
455 {
456 strcpy_safe ( aux, a->cval );
457 aux[64] = '\0';
458 used += snprintf ( target + used, lmax - used, " " );
459 used += snprintf ( target + used, lmax - used, "%s", aux );
460 }
462 || strstr ( a->unit, "CODE TABLE" ) == a->unit
463 || strstr ( a->unit, "Code table" ) == a->unit )
464 {
465 strcpy_safe ( aux, a->ctable );
466 aux[64] = '\0';
467 used += snprintf ( target + used, lmax - used, "%17u ", ( uint32_t ) a->val );
468 used += snprintf ( target + used, lmax - used, "%s", aux );
469 }
471 {
472 strcpy_safe ( aux, a->ctable );
473 aux[64] = '\0';
474 used += snprintf ( target + used, lmax - used, " 0x%08X ", ( uint32_t ) a->val );
475 used += snprintf ( target + used, lmax - used, "%s", aux );
476 }
477 else
478 {
479 used += snprintf ( target + used, lmax - used, "%s ", get_formatted_value_from_escale ( aux, sizeof ( aux ), a->escale, a->val ) );
480 }
481
482 }
483
484 // Now print remaining chars in a->name or a->ctable
485 nlimit = 64;
486 climit = 64;
487 while ( ( strlen ( a->name ) > nlimit && nlimit < BUFR_TABLEB_NAME_LENGTH ) ||
488 ( strlen ( a->ctable ) > climit && climit < BUFR_EXPLAINED_LENGTH ) )
489 {
490 aux[0] = 0;
491 if ( strlen ( a->name ) > nlimit && nlimit < BUFR_TABLEB_NAME_LENGTH )
492 strncpy ( aux, a->name + nlimit, 64 );
493 used += snprintf ( target + used, lmax - used, "\n %-64s", aux );
494 aux[0] = 0;
495 if ( strlen ( a->ctable ) > climit && climit < BUFR_EXPLAINED_LENGTH )
496 strncpy ( aux, a->ctable + climit, 64 );
497 used += snprintf ( target + used, lmax - used, " %s", aux );
498 nlimit += 64;
499 climit += 64;
500 }
501
502 if ( a->is_bitmaped_by != 0 )
503 used += snprintf ( target + used, lmax - used, " *IS BITMAPED BY #%u*", a->is_bitmaped_by );
504
505 if ( a->bitmap_to != 0 )
506 used += snprintf ( target + used, lmax - used, " *BITMAP TO #%u*", a->bitmap_to );
507
508 if ( a->related_to != 0 )
509 used += snprintf ( target + used, lmax - used, " *RELATED TO #%u*", a->related_to );
510
511 return target;
512}
#define strcpy_safe(_target_, _src_)
Macro to make safely a strcpy when we know in calling function the size of string target with sizeof(...
Definition: bufrdeco.h:358
char * get_formatted_value_from_escale(char *fmt, size_t dim, int32_t escale, double val)
gets a string with formatted value depending of scale
#define BUFR_TABLEB_NAME_LENGTH
Max length (in chars) reserved for a name of variable in table B.

References bufr_atom_data::bitmap_to, BUFR_EXPLAINED_LENGTH, BUFR_TABLEB_NAME_LENGTH, bufrdeco_assert, bufr_atom_data::ctable, bufr_atom_data::cval, bufr_atom_data::desc, DESCRIPTOR_HAVE_CODE_TABLE_STRING, DESCRIPTOR_HAVE_FLAG_TABLE_STRING, DESCRIPTOR_HAVE_STRING_VALUE, DESCRIPTOR_VALUE_MISSING, bufr_atom_data::escale, bufr_descriptor::f, get_formatted_value_from_escale(), bufr_atom_data::is_bitmaped_by, bufr_atom_data::mask, bufr_atom_data::name, bufr_atom_data::related_to, strcpy_safe, bufr_atom_data::unit, bufr_atom_data::val, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_fprint_subset_sequence_data(), and bufrdeco_print_atom_data_file().

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

◆ bufrdeco_print_atom_data_file()

int bufrdeco_print_atom_data_file ( FILE *  f,
struct bufr_atom_data a 
)

print the data in a struct bufr_atom_data to a file already open by caller

Parameters
fPointer to file opened by caller
apointer to struct ref bufr_atom_data with data to print
Returns
If succeeded return 0

Definition at line 403 of file bufrdeco_print.c.

404{
405 char aux[1024];
406 bufrdeco_assert ( f != NULL && a != NULL );
407
408 bufrdeco_print_atom_data ( aux, sizeof ( aux ), a );
409 fprintf ( f, "%s\n",aux );
410 return 0;
411}

References bufrdeco_assert, and bufrdeco_print_atom_data().

Referenced by bufrdeco_print_atom_data_stdout().

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

◆ bufrdeco_print_atom_data_html()

char * bufrdeco_print_atom_data_html ( char *  target,
size_t  lmax,
struct bufr_atom_data a,
uint32_t  ss 
)

print the data in a struct bufr_atom_data to a string as cells of table rows

Parameters
targetstring where to print the result
lmaxdimension of target
apointer to struct ref bufr_atom_data with data to print
ssindex of subset in bufr
Returns
a pointer to result string

Definition at line 160 of file bufrdeco_print_html.c.

161{
162 char aux[256];
163 size_t used = 0;
164
165 bufrdeco_assert ( a != NULL && lmax != 0 && target != NULL );
166
167 used += snprintf ( target + used , lmax - used,"<td class='desc'>%u %02u %03u</td>", a->desc.f, a->desc.x, a->desc.y );
168 used += snprintf ( target + used , lmax - used,"<td class='name'>%s</td>", a->name );
169 used += snprintf ( target + used , lmax - used,"<td class='unit'>%s</td>", a->unit );
171 {
172 if ( a->is_bitmaped_by != 0 )
173 used += snprintf ( target + used , lmax - used,"<td class='missing'>MISSING</td><td>NOTE: Bitmaped by <a href='#d%u_%u'>#%u</a></td>", ss, a->is_bitmaped_by, a->is_bitmaped_by );
174 else if ( a->bitmap_to != 0 )
175 used += snprintf ( target + used , lmax - used,"<td class='missing'>MISSING</td><td>NOTE: Bitmap to <a href='#d%u_%u'>#%u</a></td>", ss, a->bitmap_to, a->bitmap_to );
176 else if ( a->related_to != 0 )
177 used += snprintf ( target + used , lmax - used,"<td class='missing'>MISSING</td><td>NOTE: Related to <a href='#d%u_%u'>#%u</a></td>", ss, a->related_to, a->related_to );
178 else
179 used += snprintf ( target + used , lmax - used,"<td class='missing'>MISSING</td><td></td>" );
180 }
181 else
182 {
184 {
185 if ( a->is_bitmaped_by != 0 )
186 used += snprintf ( target + used , lmax - used,"<td></td><td class='cval'>%s<br>NOTE: Bitmaped by <a href='#d%u_%u'>#%u</a></td>\n", a->cval, ss, a->is_bitmaped_by, a->is_bitmaped_by );
187 else if ( a->bitmap_to != 0 )
188 used += snprintf ( target + used , lmax - used,"<td></td><td class='cval'>%s<br>NOTE: Bitmap to <a href='#d%u_%u'>#%u</a></td>\n", a->cval, ss, a->bitmap_to, a->bitmap_to );
189 else if ( a->related_to != 0 )
190 used += snprintf ( target + used , lmax - used,"<td></td><td class='cval'>%s<br>NOTE: Related to <a href='#d%u_%u'>#%u</a></td>\n", a->cval, ss, a->related_to, a->related_to );
191 else
192 used += snprintf ( target + used , lmax - used,"<td></td><td class='cval'>%s</td>\n", a->cval );
193 }
195 || strstr ( a->unit, "CODE TABLE" ) == a->unit
196 || strstr ( a->unit, "Code table" ) == a->unit )
197 {
198 used += snprintf ( target + used , lmax - used,"<td class='ival'>%17u</td>", ( uint32_t ) a->val );
199 if ( a->is_bitmaped_by != 0 )
200 used += snprintf ( target + used , lmax - used,"<td class='ctable'>%s<br>NOTE: Bitmaped by <a href='#d%u_%u'>#%u</a></td>\n", a->ctable, ss, a->is_bitmaped_by, a->is_bitmaped_by );
201 else if ( a->bitmap_to != 0 )
202 used += snprintf ( target + used , lmax - used,"<td class='ctable'>%s<br>NOTE: Bitmap to <a href='#d%u_%u'>#%u</a></td>\n", a->ctable, ss, a->bitmap_to, a->bitmap_to );
203 else if ( a->related_to != 0 )
204 used += snprintf ( target + used , lmax - used,"<td class='ctable'>%s<br>NOTE: Related to <a href='#d%u_%u'>#%u</a></td>\n", a->ctable, ss, a->related_to, a->related_to );
205 else
206 used += snprintf ( target + used , lmax - used,"<td class='ctable'>%s</td>\n", a->ctable );
207 }
209 {
210 used += snprintf ( target + used , lmax - used,"<td class='hval'>0x%08X</td>", ( uint32_t ) a->val );
211 if ( a->is_bitmaped_by != 0 )
212 used += snprintf ( target + used , lmax - used,"<td class='ctable'>%s<br>NOTE: Bitmaped by <a href='#%du_%u'>#%u</a></td>\n", a->ctable, ss, a->is_bitmaped_by, a->is_bitmaped_by );
213 else if ( a->bitmap_to != 0 )
214 used += snprintf ( target + used , lmax - used,"<td class='ctable'>%s<br>NOTE: Bitmap to <a href='#d%u_%u'>#%u</a></td>\n", a->ctable, ss, a->bitmap_to, a->bitmap_to );
215 else if ( a->related_to != 0 )
216 used += snprintf ( target + used , lmax - used,"<td class='ctable'>%s<br>NOTE: Related to <a href='#d%u_%u'>#%u</a></td>\n", a->ctable, ss, a->related_to, a->related_to );
217 else
218 used += snprintf ( target + used , lmax - used,"<td class='ctable'>%s</td>\n", a->ctable );
219 }
220 else
221 {
222 if ( a->is_bitmaped_by != 0 )
223 used += snprintf ( target + used , lmax - used,"<td class='rval'>%s</td><td>NOTE: Bitmaped by <a href='#d%u_%u'>#%u</a></td>" , get_formatted_value_from_escale ( aux, sizeof (aux), a->escale, a->val ), ss, a->is_bitmaped_by, a->is_bitmaped_by );
224 else if ( a->bitmap_to != 0 )
225 used += snprintf ( target + used , lmax - used,"<td class='rval'>%s</td><td>NOTE: Bitmap to <a href='#d%u_%u'>#%u</a></td>" , get_formatted_value_from_escale ( aux, sizeof (aux), a->escale, a->val ) , ss, a->bitmap_to, a->bitmap_to );
226 else if ( a->related_to != 0 )
227 used += snprintf ( target + used , lmax - used,"<td class='rval'>%s</td><td>NOTE: Related to <a href='#d%u_%u'>#%u</a></td>" , get_formatted_value_from_escale ( aux, sizeof (aux), a->escale, a->val ), ss, a->related_to, a->related_to );
228 else
229 used += snprintf ( target + used , lmax - used,"<td class='rval'>%s</td><td></td>" , get_formatted_value_from_escale ( aux, sizeof (aux), a->escale, a->val ) );
230 }
231 }
232 return target;
233}

References bufr_atom_data::bitmap_to, bufrdeco_assert, bufr_atom_data::ctable, bufr_atom_data::cval, bufr_atom_data::desc, DESCRIPTOR_HAVE_CODE_TABLE_STRING, DESCRIPTOR_HAVE_FLAG_TABLE_STRING, DESCRIPTOR_HAVE_STRING_VALUE, DESCRIPTOR_VALUE_MISSING, bufr_atom_data::escale, bufr_descriptor::f, get_formatted_value_from_escale(), bufr_atom_data::is_bitmaped_by, bufr_atom_data::mask, bufr_atom_data::name, bufr_atom_data::related_to, bufr_atom_data::unit, bufr_atom_data::val, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_fprint_subset_sequence_data_html(), and bufrdeco_fprint_subset_sequence_data_tagged_html().

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

◆ bufrdeco_print_atom_data_stdout()

int bufrdeco_print_atom_data_stdout ( struct bufr_atom_data a)

print the data in a struct bufr_atom_data to stdout

Parameters
apointer to struct ref bufr_atom_data with data to print
Returns
If succeeded return 0

Definition at line 419 of file bufrdeco_print.c.

420{
421 return bufrdeco_print_atom_data_file ( stdout, a );
422}
int bufrdeco_print_atom_data_file(FILE *f, struct bufr_atom_data *a)
print the data in a struct bufr_atom_data to a file already open by caller

References bufrdeco_print_atom_data_file().

Here is the call graph for this function:

◆ bufrdeco_print_json_object_atom_data()

buf_t bufrdeco_print_json_object_atom_data ( FILE *  out,
struct bufr_atom_data a,
char *  add 
)

Print an json object with a descriptor data.

Parameters
outoutput stream opened by caller
apointer to target struct bufr_atom_data
addadtional optional info
Returns
The amount of bytes sent to out

There are four cases of objects, depending of data type { "descriptor":"f xx yyy", "name":"name_of_descriptor" , "unit":"name_of_unit", "value":"string_value"} { "descriptor":"f xx yyy", "name":"name_of_descriptor" , "unit":"Code table", "value":"numeric_value", "meaning":"explanation_string} { "descriptor":"f xx yyy", "name":"name_of_descriptor" , "unit":"Flag value", "value":"numeric_value", "meaning":"explanation_string} { "descriptor":"f xx yyy", "name":"name_of_descriptor" , "unit":"name_of_unit", "value":"numeric_value"}

Definition at line 134 of file bufrdeco_json.c.

135{
136 char aux[256];
137 buf_t used = 0;
138
139 used += fprintf ( out, "{\"Descriptor\":\"%u %02u %03u\",\"Name\":\"%s\",", a->desc.f, a->desc.x, a->desc.y, bufr_adjust_string ( a->name ) );
140
141 // add aditional info keys
142 if ( add != NULL && add[0] )
143 used += fprintf ( out, "%s,", add );
144
146 {
147 // string data case
149 used += fprintf ( out, "\"Unit\":\"CCITT5\",\"Value\":\"MISSING\"}" ) ;
150 else
151 {
152 used += fprintf ( out, "\"Unit\":\"CCITT5\",\"Value\":\"" ) ;
154 used += fprintf ( out, "\"}" );
155 }
156 }
157 else if ( a->mask & DESCRIPTOR_IS_CODE_TABLE )
158 {
159 // code table case
161 used += fprintf ( out, "\"Unit\":\"Code table\",\"Value\":\"MISSING\"}" ) ;
162 else
163 {
164 used += fprintf ( out, "\"Unit\":\"Code table\",\"Value\":%u,", ( uint32_t ) ( a->val + 0.5 ) ) ;
165 used += fprintf ( out, "\"Meaning\":\"%s\"}", bufr_adjust_string ( a->ctable ) );
166 }
167 }
168 else if ( a->mask & DESCRIPTOR_IS_FLAG_TABLE )
169 {
170 // flag table case
172 used += fprintf ( out, "\"Unit\":\"Flag table\",\"Value\":\"MISSING\"}" ) ;
173 else
174 {
175 used += fprintf ( out, "\"Unit\":\"Flag table\",\"Value\":\"0x%08X\",", ( uint32_t ) ( a->val ) ) ;
176 used += fprintf ( out, "\"Meaning\":\"%s\"}", bufr_adjust_string ( a->ctable ) );
177 }
178 }
179 else
180 {
181 // numeric data case
183 used += fprintf ( out, "\"Unit\":\"%s\",\"Value\":\"MISSING\"}", a->unit ) ;
184 else
185 {
186 used += fprintf ( out, "\"Unit\":\"%s\",\"Value\":%s}", a->unit,
187 get_formatted_value_from_escale2 ( aux, sizeof ( aux ), a->escale, a->val ) );
188
189 }
190 }
191 return used;
192}
buf_t bufrdeco_print_json_scape_string_cvals(FILE *out, char *source)
prints a descriptor string value scaping the '"' for a json format
Definition: bufrdeco_json.c:33
char * get_formatted_value_from_escale2(char *fmt, size_t dim, int32_t escale, double val)
gets a string with formatted value depending of scale
char * bufr_adjust_string(char *s)
Supress trailing blanks of a string.

References bufr_adjust_string(), bufrdeco_print_json_scape_string_cvals(), bufr_atom_data::ctable, bufr_atom_data::cval, bufr_atom_data::desc, DESCRIPTOR_HAVE_STRING_VALUE, DESCRIPTOR_IS_CODE_TABLE, DESCRIPTOR_IS_FLAG_TABLE, DESCRIPTOR_VALUE_MISSING, bufr_atom_data::escale, bufr_descriptor::f, get_formatted_value_from_escale2(), bufr_atom_data::mask, bufr_atom_data::name, bufr_atom_data::unit, bufr_atom_data::val, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufr_decode_subset_data_compressed(), bufrdeco_decode_replicated_subsequence(), bufrdeco_decode_subset_data_recursive(), and bufrdeco_parse_f2_descriptor().

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

◆ bufrdeco_print_json_object_operator_descriptor()

buf_t bufrdeco_print_json_object_operator_descriptor ( FILE *  out,
struct bufr_descriptor d,
char *  add 
)

print an operator desciptor as a json object

Parameters
outoutput stream opened by caller
dpointer to operator descriptor
addadtional optional info
Returns
The amount of bytes sent to out

Definition at line 203 of file bufrdeco_json.c.

204{
205 buf_t used = 0;
206 char explanation[256];
207
208 if ( d->f == 2 )
209 {
210 // only prints if f == 2
211 used += fprintf ( out, "{\"Descriptor\":\"%u %02u %03u\",", d->f, d->x, d->y );
212 // add aditional info keys
213 if ( add != NULL && add[0] )
214 used += fprintf ( out, "%s,", add );
215
216 used += fprintf ( out, "\"Operator\": \"%s\"}", bufrdeco_get_f2_descriptor_explanation ( explanation, sizeof ( explanation ), d ) );
217 }
218 return used;
219}
char * bufrdeco_get_f2_descriptor_explanation(char *e, size_t dim, struct bufr_descriptor *d)
Definition: bufrdeco_f2.c:773

References bufrdeco_get_f2_descriptor_explanation(), bufr_descriptor::f, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufr_decode_subset_data_compressed(), bufrdeco_decode_replicated_subsequence(), and bufrdeco_decode_subset_data_recursive().

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

◆ bufrdeco_print_json_object_replicator_descriptor()

buf_t bufrdeco_print_json_object_replicator_descriptor ( FILE *  out,
struct bufr_descriptor d,
char *  add 
)

print an operator desciptor as a json object

Parameters
outstring where to print
dpointer to operator descriptor
addadditional info
Returns
The amount of bytes sent to out

Definition at line 230 of file bufrdeco_json.c.

231{
232 buf_t used = 0;
233
234 if ( d->f == 1 )
235 {
236 used += fprintf ( out, "{\"Descriptor\":\"%u %02u %03u\",", d->f, d->x, d->y );
237 // add aditional info keys
238 if ( add != NULL && add[0] )
239 used += fprintf ( out, "%s,", add );
240
241 if ( d->y == 0 )
242 {
243 if ( d->x == 1 )
244 used += fprintf ( out, "\"Replicator\":\"Replicator for %d descriptor after next delayed descriptor which set the number of replications.\"}", d->x );
245 else
246 used += fprintf ( out, "\"Replicator\":\"Replicator for %d descriptors after next delayed descriptor which set the number of replications.\"}", d->x );
247 }
248 else
249 {
250 if ( d->x == 1 )
251 used += fprintf ( out, "\"Replicator\":\"Replicator for next descriptor %d times.\"}", d->y );
252 else
253 used += fprintf ( out, "\"Replicator\":\"Replicator for next %d descriptors %d times\"}", d->x, d->y );
254 }
255
256 }
257 return used;
258}

References bufr_descriptor::f, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufr_decode_subset_data_compressed(), bufrdeco_decode_replicated_subsequence(), and bufrdeco_decode_subset_data_recursive().

Here is the caller graph for this function:

◆ bufrdeco_print_json_scape_string_cvals()

buf_t bufrdeco_print_json_scape_string_cvals ( FILE *  out,
char *  source 
)

prints a descriptor string value scaping the '"' for a json format

Parameters
outoutput stream
sourcesource string
Returns
The amount of bytes sent to out

Definition at line 33 of file bufrdeco_json.c.

34{
35 buf_t i = 0, used = 0;
36 while ( source[i] )
37 {
38 switch ( source[i] )
39 {
40 case '"':
41 used += fprintf ( out, "%c%c", '\\', source[i++] );
42 break;
43 default:
44 used += fprintf ( out, "%c", source[i++] );
45 break;
46 }
47 }
48 return used;
49}

Referenced by bufrdeco_print_json_object_atom_data().

Here is the caller graph for this function:

◆ bufrdeco_print_json_sec0()

buf_t bufrdeco_print_json_sec0 ( FILE *  out,
struct bufrdeco b 
)

Definition at line 280 of file bufrdeco_json.c.

281{
282 size_t used = 0;
283
284 bufrdeco_assert ( b != NULL );
285 used += fprintf ( out, "{\"Sec 0\":{" );
286 used += fprintf ( out, "\"Bufr length\":%u,", b->sec0.bufr_length );
287 used += fprintf ( out, "\"Bufr edition\":%u}}", b->sec0.edition );
288 return used;
289}
uint8_t edition
Definition: bufrdeco.h:698
uint32_t bufr_length
Definition: bufrdeco.h:697
struct bufr_sec0 sec0
Definition: bufrdeco.h:968

References bufr_sec0::bufr_length, bufrdeco_assert, bufr_sec0::edition, and bufrdeco::sec0.

Referenced by bufrdeco_read_buffer().

Here is the caller graph for this function:

◆ bufrdeco_print_json_sec1()

bufrdeco_print_json_sec1 ( FILE *  out,
struct bufrdeco b 
)

Print info form sec 1 in json format.

Parameters
outstring where to print
bactuve struct bufrdeco
Returns
The amount of bytes sent to out

Definition at line 300 of file bufrdeco_json.c.

301{
302 size_t used = 0;
303
304 bufrdeco_assert ( b != NULL );
305 used += fprintf ( out, "{\"Sec 1\":{" );
306 used += fprintf ( out, "\"Length\":%u", b->sec1.length );
307 used += fprintf ( out, ",\"Bufr master table\":%u", b->sec1.master );
308 used += fprintf ( out, ",\"Centre\":%u", b->sec1.centre );
309 used += fprintf ( out, ",\"Sub-Centre\":%u", b->sec1.subcentre );
310 used += fprintf ( out, ",\"Update sequence\":%u", b->sec1.update );
311 used += fprintf ( out, ",\"Options\":\"0x%x\"", b->sec1.options );
312 used += fprintf ( out, ",\"Category\":%u", b->sec1.category );
313 used += fprintf ( out, ",\"Subcategory\":%u", b->sec1.subcategory );
314 used += fprintf ( out, ",\"Sub-category local\":%u", b->sec1.subcategory_local );
315 used += fprintf ( out, ",\"Master table version\":%u", b->sec1.master_version );
316 used += fprintf ( out, ",\"Master table local\":%u", b->sec1.master_local );
317 used += fprintf ( out, ",\"Year\":%u", b->sec1.year );
318 used += fprintf ( out, ",\"Month\":%u", b->sec1.month );
319 used += fprintf ( out, ",\"Day\":%u", b->sec1.day );
320 used += fprintf ( out, ",\"Hour\":%u", b->sec1.hour );
321 used += fprintf ( out, ",\"Minute\":%u", b->sec1.minute );
322 used += fprintf ( out, ",\"Second\":%u", b->sec1.second );
323 if ( b->sec0.edition == 3 )
324 used += fprintf ( out, ",\"Aditional space\":%u", b->sec1.length - 17 );
325 else
326 used += fprintf ( out, ",\"Aditional space\":%u", b->sec1.length - 22 );
327 used += fprintf ( out, "}" );
328
329 if ( b->tables->b.path[0] )
330 {
331 used += fprintf ( out, ",{\"Used tables\":{" );
332 used += fprintf ( out, ",\"TableB file\":\"%s\"", b->tables->b.path );
333 used += fprintf ( out, ",\"tableC file\":\"%s\"", b->tables->c.path );
334 used += fprintf ( out, ",\"tableD file\":\"%s\"", b->tables->d.path );
335 used += fprintf ( out, "}" );
336 }
337 used += fprintf ( out, "}" );
338
339 return used;
340}
uint8_t month
Definition: bufrdeco.h:785
uint32_t year
Definition: bufrdeco.h:784
uint8_t master_local
Definition: bufrdeco.h:783
uint32_t subcentre
Definition: bufrdeco.h:776
uint32_t centre
Definition: bufrdeco.h:775
uint8_t category
Definition: bufrdeco.h:779
uint8_t options
Definition: bufrdeco.h:778
uint8_t minute
Definition: bufrdeco.h:788
uint8_t subcategory
Definition: bufrdeco.h:780
uint8_t second
Definition: bufrdeco.h:789
uint8_t day
Definition: bufrdeco.h:786
uint32_t length
Definition: bufrdeco.h:773
uint8_t subcategory_local
Definition: bufrdeco.h:781
uint8_t hour
Definition: bufrdeco.h:787
uint8_t update
Definition: bufrdeco.h:777
uint8_t master
Definition: bufrdeco.h:774

References bufr_tables::b, bufrdeco_assert, bufr_tables::c, bufr_sec1::category, bufr_sec1::centre, bufr_tables::d, bufr_sec1::day, bufr_sec0::edition, bufr_sec1::hour, bufr_sec1::length, bufr_sec1::master, bufr_sec1::master_local, bufr_sec1::master_version, bufr_sec1::minute, bufr_sec1::month, bufr_sec1::options, bufr_tableB::path, bufr_tableC::path, bufr_tableD::path, bufrdeco::sec0, bufrdeco::sec1, bufr_sec1::second, bufr_sec1::subcategory, bufr_sec1::subcategory_local, bufr_sec1::subcentre, bufrdeco::tables, bufr_sec1::update, and bufr_sec1::year.

Referenced by bufrdeco_read_buffer().

Here is the caller graph for this function:

◆ bufrdeco_print_json_sec2()

buf_t bufrdeco_print_json_sec2 ( FILE *  out,
struct bufrdeco b 
)

Print info form optional sec 2 in json format.

Parameters
outstring where to print
bactuve struct bufrdeco
Returns
The amount of bytes sent to out

Definition at line 350 of file bufrdeco_json.c.

351{
352 size_t used = 0;
353
354 bufrdeco_assert ( b != NULL );
355 used += fprintf ( out, "{\"Sec 2\":{" );
356 if ( b->sec1.options & 0x80 )
357 used += fprintf ( out, "\"Length\":%u}}", b->sec2.length );
358 else
359 used += fprintf ( out, "\"Length\":0}}" );
360
361 return used;
362}
uint32_t length
Definition: bufrdeco.h:799
struct bufr_sec2 sec2
Definition: bufrdeco.h:970

References bufrdeco_assert, bufr_sec2::length, bufr_sec1::options, bufrdeco::sec1, and bufrdeco::sec2.

Referenced by bufrdeco_read_buffer().

Here is the caller graph for this function:

◆ bufrdeco_print_json_sec3()

bufrdeco_print_json_sec3 ( FILE *  out,
struct bufrdeco b 
)

Print info form sec 3 in json format.

Parameters
outstring where to print
bactuve struct bufrdeco
Returns
The amount of bytes sent to out

Definition at line 372 of file bufrdeco_json.c.

373{
374 buf_t used = 0, i;
375
376 bufrdeco_assert ( b != NULL );
377 used += fprintf ( out, "{\"Sec 3\":{" );
378 used += fprintf ( out, "\"Sec3 length\":%u", b->sec3.length );
379 used += fprintf ( out, ",\"Subsets\":%u", b->sec3.subsets );
380 used += fprintf ( out, ",\"Observed\":%u", b->sec3.observed );
381 used += fprintf ( out, ",\"Compressed\":%u", b->sec3.compressed );
382 used += fprintf ( out, ",\"Unexpanded descriptors\":%u", b->sec3.ndesc );
383 used += fprintf ( out, ",\"Unexpanded array\":" );
384
385 used += fprintf ( out,"[" );
386 for ( i = 0; i < b->sec3.ndesc; i++ )
387 {
388 if ( i )
389 used += fprintf ( out,"," );
390 used += fprintf ( out, "{\"%u\":\"%u %02u %03u\"}", i, b->sec3.unexpanded[i].f, b->sec3.unexpanded[i].x, b->sec3.unexpanded[i].y );
391 }
392 used += fprintf ( out,"]}}" );
393
394 return used;
395}
uint8_t observed
Definition: bufrdeco.h:811
struct bufr_descriptor unexpanded[BUFR_LEN_UNEXPANDED_DESCRIPTOR]
Definition: bufrdeco.h:814
uint32_t ndesc
Definition: bufrdeco.h:813
uint32_t length
Definition: bufrdeco.h:809

References bufrdeco_assert, bufr_sec3::compressed, bufr_descriptor::f, bufr_sec3::length, bufr_sec3::ndesc, bufr_sec3::observed, bufrdeco::sec3, bufr_sec3::subsets, bufr_sec3::unexpanded, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_read_buffer().

Here is the caller graph for this function:

◆ bufrdeco_print_json_separator()

buf_t bufrdeco_print_json_separator ( FILE *  out)

Print the comma ',' separator in an output.

Parameters
outstring where to print
Returns
The amount of bytes sent to out

Definition at line 267 of file bufrdeco_json.c.

268{
269 return fprintf ( out, "," );
270}

Referenced by bufr_decode_subset_data_compressed(), bufrdeco_decode_replicated_subsequence(), bufrdeco_decode_subset_data_recursive(), and bufrdeco_parse_f2_descriptor().

Here is the caller graph for this function:

◆ bufrdeco_print_json_sequence_descriptor_final()

buf_t bufrdeco_print_json_sequence_descriptor_final ( FILE *  out)

Definition at line 110 of file bufrdeco_json.c.

111{
112 buf_t used = 0;
113 // print final
114 used += fprintf ( out, "]}" );
115 return used;
116}

Referenced by bufr_decode_subset_data_compressed(), and bufrdeco_decode_subset_data_recursive().

Here is the caller graph for this function:

◆ bufrdeco_print_json_sequence_descriptor_header()

buf_t bufrdeco_print_json_sequence_descriptor_header ( FILE *  out,
struct bufr_sequence seq 
)

Print the header of a sequence descriptor (f == 3)

Parameters
outoutput stream opened by caller
seqpointer to a bufr_sequence bufr_sequence
Returns
The amount of bytes sent to out

Definition at line 94 of file bufrdeco_json.c.

95{
96 buf_t used = 0;
97
98 used += fprintf ( out, "{\"Descriptor\":\"%c %c%c %c%c%c\",", seq->key[0], seq->key[1], seq->key[2], seq->key[3], seq->key[4], seq->key[5] );
99 used += fprintf ( out, "\"Sequence description\":\"%s\",\"Expanded sequence\":[", seq->name );
100 return used;
101}

References bufr_sequence::key, and bufr_sequence::name.

Referenced by bufr_decode_subset_data_compressed(), and bufrdeco_decode_subset_data_recursive().

Here is the caller graph for this function:

◆ bufrdeco_print_json_subset_data_epilogue()

buf_t bufrdeco_print_json_subset_data_epilogue ( FILE *  out)

Definition at line 77 of file bufrdeco_json.c.

78{
79 buf_t used = 0;
80
81 // print prologue
82 used += fprintf ( out, "}\n" );
83 return used;
84}

Referenced by bufr_decode_subset_data_compressed(), and bufrdeco_decode_subset_data_recursive().

Here is the caller graph for this function:

◆ bufrdeco_print_json_subset_data_prologue()

buf_t bufrdeco_print_json_subset_data_prologue ( FILE *  out,
struct bufrdeco b 
)

Definition at line 58 of file bufrdeco_json.c.

59{
60 buf_t used = 0;
61
62 bufrdeco_assert ( b != NULL );
63
64 // print prologue
65 used += fprintf ( out, "{\"BUFR File\":\"%s\",\"Subset\":%u,\"Decoded data\":",b->header.filename, b->seq.ss );
66
67 return used;
68}
struct gts_header header
Definition: bufrdeco.h:967
char filename[BUFRDECO_PATH_LENGTH]
Definition: bufrdeco.h:712

References bufrdeco_assert, gts_header::filename, bufrdeco::header, bufrdeco::seq, and bufrdeco_subset_sequence_data::ss.

Referenced by bufr_decode_subset_data_compressed(), and bufrdeco_decode_subset_data_recursive().

Here is the caller graph for this function:

◆ bufrdeco_print_json_tree()

buf_t bufrdeco_print_json_tree ( struct bufrdeco b)

Definition at line 508 of file bufrdeco_json.c.

509{
510 buf_t used = 0;
511 bufrdeco_assert ( b != NULL );
512
514 used += bufrdeco_print_json_tree_recursive ( b->out, b, NULL );
515 return used;
516};
buf_t bufrdeco_print_json_tree_recursive(FILE *out, struct bufrdeco *b, struct bufr_sequence *seq)
Print a tree of descriptors to a file in a recursive way in json format.
#define BUFRDECO_OUTPUT_JSON_EXPANDED_TREE
Bit mask to the member mask of struct bufrdeco to print bufr expanded tree of descriptors.
Definition: bufrdeco.h:305

References bufrdeco_assert, BUFRDECO_OUTPUT_JSON_EXPANDED_TREE, bufrdeco_print_json_tree_recursive(), bufrdeco::mask, and bufrdeco::out.

Referenced by main().

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

◆ bufrdeco_print_json_tree_recursive()

int bufrdeco_print_json_tree_recursive ( FILE *  out,
struct bufrdeco b,
struct bufr_sequence seq 
)

Print a tree of descriptors to a file in a recursive way in json format.

Parameters
outstream opened by caller
bpointer to the basic container struct bufrdeco
seqpointer to the struct bufr_sequence to print
Returns
The amount of bytes sent to out

Definition at line 405 of file bufrdeco_json.c.

406{
407 buf_t i, k, used = 0;
408 struct bufr_sequence *l;
409 char explanation[256];
410
411 bufrdeco_assert ( out != NULL && b != NULL );
412
413 if ( seq == NULL )
414 {
415 l = & ( b->tree->seq[0] );
416 }
417 else
418 {
419 l = seq;
420 }
421
422 // begins the array
423 for ( i = 0; i < l->ndesc; i++ )
424 {
425 if ( i )
426 used += fprintf ( out, "," );
427 fprintf ( out, "{\"%u %02u %03u\"", l->lseq[i].f, l->lseq[i].x,l->lseq[i].y );
428
429 if ( l->lseq[i].f != 3 )
430 {
431 if ( l->lseq[i].f == 0 )
432 {
433 if ( bufr_find_tableB_index ( &k, & ( b->tables->b ), l->lseq[i].c ) )
434 used += fprintf ( out, "\"Not found in tables\"}" );
435 else
436 {
437 used += fprintf ( out, ":\"" );
438 if ( l->replicated[i] )
439 {
440 if ( l->replicated[i] )
441 {
442 if ( l->replicated[i] == 1 )
443 used += fprintf ( out, "Replicated | " );
444 else
445 used += fprintf ( out, "Replicated depth %u | ", l->replicated[i] );
446 }
447 }
448 if ( is_a_delayed_descriptor ( & l->lseq[i] ) ||
450 used += fprintf ( out, "* %s\"}", b->tables->b.item[k].name );
451 else
452 used += fprintf ( out, "%s\"}", b->tables->b.item[k].name );
453 }
454 }
455 else if ( l->lseq[i].f == 2 )
456 {
457 used += fprintf ( out, ":\"%s\"}", bufrdeco_get_f2_descriptor_explanation ( explanation, sizeof ( explanation ), & ( l->lseq[i] ) ) );
458 }
459 else if ( l->lseq[i].f == 1 )
460 {
461 if ( l->lseq[i].y == 0 )
462 {
463 if ( l->lseq[i].x == 1 )
464 used += fprintf ( out, ":\"* Replicator for %d descriptor after next delayed descriptor which set the number of replications.\"}", l->lseq[i].x );
465 else
466 used += fprintf ( out, ":\"* Replicator for %d descriptors after next delayed descriptor which set the number of replications.\"}", l->lseq[i].x );
467 }
468 else
469 {
470 if ( l->lseq[i].x == 1 )
471 used += fprintf ( out, ":\"* Replicator for next descriptor %d times\"}", l->lseq[i].y );
472 else
473 used += fprintf ( out, ":\"* Replicator for next %d descriptors %d times\"}", l->lseq[i].x, l->lseq[i].y );
474 }
475 }
476 else
477 used += fprintf ( out, "\n" );
478 continue;
479 }
480 else
481 {
482 // f == 3
483 used += fprintf ( out, ":\"" );
484 if ( l->replicated[i] )
485 {
486 if ( l->replicated[i] == 1 )
487 used += fprintf ( out, "Replicated | " );
488 else
489 used += fprintf ( out, "Replicated depth %u | ", l->replicated[i] );
490 }
491 used += fprintf ( out, "%s\"", bufr_adjust_string ( l->name ) );
492 used += fprintf ( out, ",\"Expanded\":[" );
493 // parse de son
494 used += bufrdeco_print_json_tree_recursive ( out, b, l->sons[i] );
495 used += fprintf ( out, "]}" );
496 // we then recursively parse the son
497 }
498 }
499 return used;
500}
int bufr_find_tableB_index(buf_t *index, struct bufr_tableB *tb, const char *key)
found a descriptor index in a struct bufr_tableB
int is_a_delayed_descriptor(struct bufr_descriptor *d)
check if a descriptor is a delayed descriptor
int is_a_short_delayed_descriptor(struct bufr_descriptor *d)
check if a descriptor is a short delayed descriptor

References bufr_tables::b, bufr_adjust_string(), bufr_find_tableB_index(), bufrdeco_assert, bufrdeco_get_f2_descriptor_explanation(), bufrdeco_print_json_tree_recursive(), bufr_descriptor::c, bufr_descriptor::f, is_a_delayed_descriptor(), is_a_short_delayed_descriptor(), bufr_tableB::item, bufr_sequence::lseq, bufr_sequence::name, bufr_tableB_decoded_item::name, bufr_sequence::ndesc, bufr_sequence::replicated, bufrdeco_expanded_tree::seq, bufr_sequence::sons, bufrdeco::tables, bufrdeco::tree, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_print_json_tree(), and bufrdeco_print_json_tree_recursive().

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

◆ bufrdeco_print_subset_sequence_data()

int bufrdeco_print_subset_sequence_data ( struct bufrdeco_subset_sequence_data s)

Prints a struct bufrdeco_subset_sequence_data.

Parameters
spointer to the struct to print
Returns
If succeeded return 0

Definition at line 545 of file bufrdeco_print.c.

546{
547 bufrdeco_assert ( s != NULL );
548 return bufrdeco_fprint_subset_sequence_data ( stdout, s );
549}
int bufrdeco_fprint_subset_sequence_data(FILE *f, struct bufrdeco_subset_sequence_data *s)

References bufrdeco_assert, and bufrdeco_fprint_subset_sequence_data().

Referenced by main().

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

◆ bufrdeco_print_subset_sequence_data_html()

int bufrdeco_print_subset_sequence_data_html ( struct bufrdeco_subset_sequence_data s)

Definition at line 265 of file bufrdeco_print_html.c.

266{
267 bufrdeco_assert ( s != NULL );
268
270}
int bufrdeco_fprint_subset_sequence_data_html(FILE *f, struct bufrdeco_subset_sequence_data *s)

References bufrdeco_assert, and bufrdeco_fprint_subset_sequence_data_html().

Here is the call graph for this function:

◆ bufrdeco_print_subset_sequence_data_tagged_html()

int bufrdeco_print_subset_sequence_data_tagged_html ( struct bufrdeco_subset_sequence_data s,
char *  id 
)

Definition at line 306 of file bufrdeco_print_html.c.

307{
308 bufrdeco_assert ( s != NULL );
309
311}
int bufrdeco_fprint_subset_sequence_data_tagged_html(FILE *f, struct bufrdeco_subset_sequence_data *s, char *id)

References bufrdeco_assert, and bufrdeco_fprint_subset_sequence_data_tagged_html().

Referenced by main().

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

◆ bufrdeco_print_tree()

int bufrdeco_print_tree ( struct bufrdeco b)

Print a tree of descriptors.

Parameters
bpointer to a basic container struct bufrdeco
Returns
The amount of bytes sent to out
Parameters
bpointer to a basic container struct bufrdeco
Returns
If succeeded return 0

Definition at line 381 of file bufrdeco_print.c.

382{
383 bufrdeco_assert ( b != NULL );
384
385 if ( b->mask & BUFRDECO_OUTPUT_HTML )
386 printf ( "<pre>\n" );
387 bufrdeco_fprint_tree_recursive ( stdout, b, NULL );
388 if ( b->mask & BUFRDECO_OUTPUT_HTML )
389 printf ( "</pre>\n" );
390 else
391 printf ( "\n" );
392 return 0;
393};

References bufrdeco_assert, bufrdeco_fprint_tree_recursive(), BUFRDECO_OUTPUT_HTML, and bufrdeco::mask.

Referenced by main().

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

◆ bufrdeco_read_buffer()

int bufrdeco_read_buffer ( struct bufrdeco b,
uint8_t *  bufrx,
buf_t  size 
)

Definition at line 225 of file bufrdeco_read.c.

226{
227 uint8_t *c;
228 buf_t ix, ud;
229
230 bufrdeco_assert ( b != NULL );
231
232 // Some fast checks
233 if ( ( size + 4 ) >= BUFR_LEN )
234 {
235 snprintf ( b->error, sizeof ( b->error ), "%s(): Buffer provided too large. Consider increase BUFR_LEN\n", __func__ );
236 return 1;
237 }
238
239 if ( size < 8 )
240 {
241 snprintf ( b->error, sizeof ( b->error ), "%s(): Too few bytes for a bufr\n", __func__ );
242 return 1;
243 }
244
245 // check if begins with BUFR
246 if ( bufrx[0] != 'B' || bufrx[1] != 'U' || bufrx[2] != 'F' || bufrx[3] != 'R' )
247 {
248 snprintf ( b->error, sizeof ( b->error ), "%s(): bufr file does not begin with 'BUFR' chars\n", __func__ );
249 return 1;
250 }
251
252 // check if end with '7777'
253 if ( bufrx[size - 4] != '7' || bufrx[size - 3] != '7' || bufrx[size - 2] != '7' || bufrx[size - 1] != '7' )
254 {
255 snprintf ( b->error, sizeof ( b->error ), "%s(): bufe file does not end with '7777' chars\n", __func__ );
256 return 1;
257 }
258
259 /******************* section 0 *****************************/
260
261 // we have already checked about begin and end
262
263 // length of whole message
264 b->sec0.bufr_length = three_bytes_to_uint32 ( &bufrx[4] );
265 // check if length is correct
266 if ( b->sec0.bufr_length != ( uint32_t ) size )
267 {
268 snprintf ( b->error, sizeof ( b->error ), "%s(): bufr file have %u bytes and it says %u\n", __func__,
269 ( uint32_t ) size, b->sec0.bufr_length );
270 return 1;
271 }
272
273 // set bufr edition number
274 b->sec0.edition = bufrx[7];
275
276 if ( b->sec0.edition < 3 )
277 {
278 snprintf ( b->error, sizeof ( b->error ), "%s(): Bufr edition must be 3 or superior and this file is coded with version %u\n", __func__, b->sec0.edition );
279 return 1;
280 }
281
282 // raw
283 memcpy ( &b->sec0.raw[0], &bufrx[0], 8 );
284
287
288 /******************* section 1 *****************************/
289 c = &bufrx[8]; // pointer to begin of sec1
290 switch ( b->sec0.edition )
291 {
292 case 3:
294 b->sec1.master = c[3];
295 b->sec1.subcentre = c[4];
296 b->sec1.centre = c[5];
297 b->sec1.update = c[6];
298 b->sec1.options = c[7];
299 b->sec1.category = c[8];
300 b->sec1.subcategory = c[9];
301 b->sec1.subcategory_local = 0; // not in version 3
302 b->sec1.master_version = c[10];
303 b->sec1.master_local = c[11];
304 if ( c[12] > 80 )
305 b->sec1.year = 1900 + c[12];
306 else
307 b->sec1.year = 2000 + c[12];
308 b->sec1.month = c[13];
309 b->sec1.day = c[14];
310 b->sec1.hour = c[15];
311 b->sec1.minute = c[16];
312 b->sec1.second = 0; // not in version 3
313 break;
314 case 4:
316 b->sec1.master = c[3];
317 b->sec1.centre = two_bytes_to_uint32 ( &c[4] );
318 b->sec1.subcentre = two_bytes_to_uint32 ( &c[6] );
319 b->sec1.update = c[8];
320 b->sec1.options = c[9];
321 b->sec1.category = c[10];
322 b->sec1.subcategory = c[11];
323 b->sec1.subcategory_local = c[12];
324 b->sec1.master_version = c[13];
325 b->sec1.master_local = c[14];
326 b->sec1.year = two_bytes_to_uint32 ( &c[15] );
327 b->sec1.month = c[17];
328 b->sec1.day = c[18];
329 b->sec1.hour = c[19];
330 b->sec1.minute = c[20];
331 b->sec1.second = c[21];
332 break;
333 default:
334 snprintf ( b->error, sizeof ( b->error ), "%s(): This file is coded with version %u and is not supported\n", __func__, b->sec0.edition );
335 free ( ( void * ) bufrx );
336 return 1;
337 }
338 memcpy ( b->sec1.raw, c, b->sec1.length ); // raw data
339 c += b->sec1.length;
340
343
344 /******************* section 2 (Optional) ******************/
345 if ( b->sec1.options & 0x80 )
346 {
348 memcpy ( b->sec2.raw, c, b->sec2.length );
349 c += b->sec2.length;
350 }
353
354 /******************* section 3 *****************************/
356 b->sec3.subsets = two_bytes_to_uint32 ( &c[4] );
357 if ( c[6] & 0x80 )
358 b->sec3.observed = 1;
359 else
360 b->sec3.observed = 0;
361 if ( c[6] & 0x40 )
362 b->sec3.compressed = 1;
363 else
364 b->sec3.compressed = 0;
365
366 // loop of unexpanded descriptors
367 for ( ix = 7, ud = 0; ( ix + 1 ) < b->sec3.length && ud < BUFR_LEN_UNEXPANDED_DESCRIPTOR; ix += 2 )
368 {
369 two_bytes_to_descriptor ( &b->sec3.unexpanded[ud], &c[ix] );
370 if ( b->sec3.unexpanded[ud].f || b->sec3.unexpanded[ud].x || b->sec3.unexpanded[ud].y )
371 ud++;
372 }
373 b->sec3.ndesc = ud;
374 memcpy ( b->sec3.raw, c, b->sec3.length );
375 c += b->sec3.length;
376
379
380 /******************* section 4 *****************************/
382 // we copy 4 byte more without danger because of latest '7777' and to use fastest exctracting bits algorithm
383 memcpy ( b->sec4.raw, c, b->sec4.length + 4 );
384
385 b->sec4.bit_offset = 32; // the first bit in byte 4
386
387#ifdef DEBUG_TIME
388 bufrdeco_clock_start = clock();
389#endif
390
391 if ( bufr_read_tables ( b ) )
392 {
393 return 1;
394 }
395#ifdef DEBUG_TIME
396 bufrdeco_clock_end = clock();
397 print_timing ( bufrdeco_clock_start, bufrdeco_clock_end,bufr_read_tables_wmo() );
398#endif
399
400 return 0;
401}
buf_t bufrdeco_print_json_sec2(FILE *out, struct bufrdeco *b)
Print info form optional sec 2 in json format.
uint32_t two_bytes_to_uint32(const uint8_t *source)
returns the uint32_t value from an array of two bytes, most significant first
uint32_t three_bytes_to_uint32(const uint8_t *source)
returns the uint32_t value from an array of three bytes, most significant first
buf_t bufrdeco_print_json_sec0(FILE *out, struct bufrdeco *b)
#define BUFRDECO_OUTPUT_JSON_SEC2
Bit mask to the member mask of struct bufrdeco to print bufr info for SEC 2 in json format.
Definition: bufrdeco.h:287
int bufr_read_tables(struct bufrdeco *b)
Read the tables according with bufr file data from a bufr table directory.
Definition: bufrdeco_wmo.c:162
#define BUFRDECO_OUTPUT_JSON_SEC3
Bit mask to the member mask of struct bufrdeco to print bufr info for SEC 3 in json format.
Definition: bufrdeco.h:293
#define BUFRDECO_OUTPUT_JSON_SEC0
Bit mask to the member mask of struct bufrdeco to print info for SEC 0 in json format.
Definition: bufrdeco.h:275
#define BUFRDECO_OUTPUT_JSON_SEC1
Bit mask to the member mask of struct bufrdeco to print info for SEC 1 in json format.
Definition: bufrdeco.h:281
#define BUFR_LEN_UNEXPANDED_DESCRIPTOR
Max amount of unexpanded descriptors in a SEC3.
Definition: bufrdeco.h:213
buf_t bufrdeco_print_json_sec3(FILE *out, struct bufrdeco *b)
Print info form sec 3 in json format.
buf_t bufrdeco_print_json_sec1(FILE *out, struct bufrdeco *b)
Print info form sec 1 in json format.
int two_bytes_to_descriptor(struct bufr_descriptor *d, const uint8_t *source)
set a struct bufr_descriptor from two consecutive bytes in bufr file
uint8_t raw[8]
Definition: bufrdeco.h:699
uint8_t raw[BUFR_LEN_SEC1]
Definition: bufrdeco.h:790
uint8_t raw[BUFR_LEN_SEC2]
Definition: bufrdeco.h:800
uint8_t raw[BUFR_LEN_SEC3]
Definition: bufrdeco.h:815
uint32_t length
Definition: bufrdeco.h:826
size_t bit_offset
Definition: bufrdeco.h:827

References bufr_sec4::bit_offset, BUFR_LEN, BUFR_LEN_UNEXPANDED_DESCRIPTOR, bufr_sec0::bufr_length, bufr_read_tables(), bufrdeco_assert, BUFRDECO_OUTPUT_JSON_SEC0, BUFRDECO_OUTPUT_JSON_SEC1, BUFRDECO_OUTPUT_JSON_SEC2, BUFRDECO_OUTPUT_JSON_SEC3, bufrdeco_print_json_sec0(), bufrdeco_print_json_sec1(), bufrdeco_print_json_sec2(), bufrdeco_print_json_sec3(), bufr_sec1::category, bufr_sec1::centre, bufr_sec3::compressed, bufr_sec1::day, bufr_sec0::edition, bufrdeco::error, bufr_descriptor::f, bufr_sec1::hour, bufr_sec1::length, bufr_sec2::length, bufr_sec3::length, bufr_sec4::length, bufrdeco::mask, bufr_sec1::master, bufr_sec1::master_local, bufr_sec1::master_version, bufr_sec1::minute, bufr_sec1::month, bufr_sec3::ndesc, bufr_sec3::observed, bufr_sec1::options, bufrdeco::out, bufr_sec0::raw, bufr_sec4::raw, bufr_sec1::raw, bufr_sec2::raw, bufr_sec3::raw, bufrdeco::sec0, bufrdeco::sec1, bufrdeco::sec2, bufrdeco::sec3, bufrdeco::sec4, bufr_sec1::second, bufr_sec1::subcategory, bufr_sec1::subcategory_local, bufr_sec1::subcentre, bufr_sec3::subsets, three_bytes_to_uint32(), two_bytes_to_descriptor(), two_bytes_to_uint32(), bufr_sec3::unexpanded, bufr_sec1::update, bufr_descriptor::x, bufr_descriptor::y, and bufr_sec1::year.

Referenced by bufrdeco_extract_bufr(), and bufrdeco_read_bufr().

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

◆ bufrdeco_read_bufr()

int bufrdeco_read_bufr ( struct bufrdeco b,
char *  filename 
)

Read bufr file and does preliminary and first decode pass.

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

This function does the folowing tasks:

  • 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 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.

< pointer to a memory buffer where we write raw bufr file

Definition at line 41 of file bufrdeco_read.c.

42{
43 int aux, res;
44 uint8_t *bufrx = NULL; /*!< pointer to a memory buffer where we write raw bufr file */
45 buf_t n = 0;
46 FILE *fp;
47 struct stat st;
48
49 bufrdeco_assert ( b != NULL );
50
51 /* Stat input file */
52 if ( stat ( filename, &st ) < 0 )
53 {
54 snprintf ( b->error, sizeof ( b->error ), "%s(): cannot stat file '%s'\n", __func__, filename );
55 return 1;
56 }
57
58 /* Alloc nedeed memory for bufr */
59 if ( S_ISREG ( st.st_mode ) || S_ISLNK ( st.st_mode ) )
60 {
61 if ( ( bufrx = ( uint8_t * ) calloc ( 1, st.st_size + 4 ) ) == NULL )
62 {
63 snprintf ( b->error, sizeof ( b->error ), "%s(): cannot alloc memory for file '%s'\n", __func__, filename );
64 return 1;
65 }
66 }
67 else
68 {
69 snprintf ( b->error, sizeof ( b->error ), "%s(): '%s' is not a regular file nor symbolic link\n", __func__, filename );
70 return 1;
71 }
72
73 /* Inits bufr struct */
74 if ( ( st.st_size + 4 ) >= BUFR_LEN )
75 {
76 snprintf ( b->error, sizeof ( b->error ), "%s(): File '%s' too large. Consider increase BUFR_LEN\n", __func__, filename );
77 free ( ( void * ) bufrx );
78 return 1;
79 }
80
81 // Open and read the file
82 if ( ( fp = fopen ( filename, "r" ) ) == NULL )
83 {
84 snprintf ( b->error, sizeof ( b->error ), "%s(): cannot open file '%s'\n", __func__, filename );
85 free ( ( void * ) bufrx );
86 return 1;
87 }
88
89 while ( ( aux = fgetc ( fp ) ) != EOF && ( int ) n < st.st_size )
90 bufrx[n++] = ( uint8_t ) aux;
91
92 //n = fread(&bufrx[0], 1, st.st_size, fp);
93 //bufrdeco_assert(n == (size_t)st.st_size);
94
95 // close the file
96
97 fclose ( fp );
98
99 res = bufrdeco_read_buffer ( b, bufrx, n );
100 free ( bufrx );
101 return res;
102}

References BUFR_LEN, bufrdeco_assert, bufrdeco_read_buffer(), and bufrdeco::error.

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}

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_store_tables()

int bufrdeco_store_tables ( struct bufr_tables **  t,
struct bufr_tables_cache c,
uint8_t  ver 
)

Init an element of array c->tab[] if still not allocated. If allocated clean it and set *t pointing to this element.

Parameters
tpointer to array of struct bufr_tables
cpointer ti struct bufr_tables_cache
verversion of tables acting as key
Returns
if success return 0

Definition at line 269 of file bufrdeco_wmo.c.

270{
271 if ( c->tab[c->next] == NULL )
272 {
273 // Init the array element
274 bufrdeco_init_tables ( & ( c->tab[c->next] ) );
275
276 // increase the counter of allocated elements
277 ( c->nt )++;
278 }
279 else
280 {
281 // Clean the element in array with zeroes
282 memset ( c->tab[c->next], 0, sizeof ( struct bufr_tables ) );
283
284 // sets the proper version as a key of element
285 c->ver[c->next] = ver;
286 }
287
288 // t will point to array element
289 *t = c->tab[c->next];
290
291 // Set the member 'next'. It marks the next element in array it will be modified when failing a search in future
292 c->next = ( c->next + 1 ) % BUFRDECO_TABLES_CACHE_SIZE;
293 return 0;
294}

References bufrdeco_init_tables(), BUFRDECO_TABLES_CACHE_SIZE, bufr_tables_cache::next, bufr_tables_cache::nt, bufr_tables_cache::tab, and bufr_tables_cache::ver.

Referenced by bufr_read_tables().

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

◆ bufrdeco_substitute_tables()

int bufrdeco_substitute_tables ( struct bufr_tables **  replaced,
struct bufr_tables source,
struct bufrdeco b 
)

substitute an struct bufr_tables into a struct bufrdeco

Parameters
replacedPointer where to set the replaced pointer
sourcePointer to a struct bufr_tables
bpointer to the container basic struct bufrdeco
Returns
0 if succeeded, 1 otherwise

Remember that the struct bufr_tables used in bufrdeco library is the one which pointer is in struct bufrdeco . To avoid problems the struct must be initialized before substituted in this fucntion. Both source and replaced structs are not modified.

This is useful if we do not want to read and parse tables again if the caller has a pool of already readed tables.

Definition at line 116 of file bufrdeco_memory.c.

117{
118 bufrdeco_assert ( b != NULL );
119
120 *replaced = b->tables;
121 if ( source == NULL )
122 {
123 // allocate memory for table
124 return bufrdeco_init_tables ( & ( b->tables ) );
125 }
126 else
127 b->tables = source;
128 return 0;
129}
int bufrdeco_init_tables(struct bufr_tables **t)
Init a struct bufr_tables allocating space.

References bufrdeco_assert, bufrdeco_init_tables(), and bufrdeco::tables.

Here is the call graph for this function:

◆ bufrdeco_tableB_compressed()

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

Parameters
rpointer to a struct bufrdeco_compressed_ref where to set results
bbasic container struct bufrdeco
dpointer to the reference struct bufr_descriptor
modeIf 0 then we are getting the data itself for a descriptor. If mode = 1 then we are dealing with associated bits
Returns
If succeeded returns 0. If problem returns 1. If mode = 1 and no associated bits returns -1

Definition at line 250 of file bufrdeco_tableB.c.

251{
252 buf_t i;
253 uint32_t ival;
254 uint8_t has_data;
255 struct bufr_tableB *tb;
256
257 bufrdeco_assert ( b != NULL && r != NULL && d != NULL );
258
259 tb = & ( b->tables->b );
260
261 // if mode 1 then we search for associated_bits
262 if ( mode && b->state.assoc_bits == 0 )
263 {
264 // This is not an associated field, return -1
265 return -1;
266 }
267
268 if ( mode )
269 {
270 r->is_associated = 1; // Mark this reference as asociated
271 }
272
273 if ( is_a_local_descriptor ( d ) )
274 {
275 // if is a local descriptor we just skip the needed bits signified by operator 2 06 YYY
276 // we assign ref = 0 and ref0 as readed reserved bits. We also will assume escale = 0
277 r->desc = d;
279 r->bit0 = b->state.bit_offset; // OFFSET
280 strcpy_safe ( r->name, "LOCAL DESCRIPTOR" );
281 strcpy_safe ( r->unit, "UNKNOWN" );
282
283 // get bits for ref0
284 if ( get_bits_as_uint32_t ( &r->ref0, &r->has_data, &b->sec4.raw[4], & ( b->state.bit_offset ),
285 b->state.local_bit_reserved ) == 0 )
286 {
287 snprintf (b->error, sizeof (b->error), "%s(): Cannot get bits from '%s'\n", __func__, d->c );
288 return 1;
289 }
290
291 // and get 6 bits for inc_bits
292 if ( get_bits_as_uint32_t ( &ival, &has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), 6 ) == 0 )
293 {
294 snprintf (b->error, sizeof (b->error), "%s(): Cannot get 6 bits for inc_bits from '%s'\n", __func__, d->c );
295 return 1;
296 }
297
298 r->escale = 0;
299 r->inc_bits = ( uint8_t ) ival; // set the inc_bits
300 // Update the bit offset
301 b->state.bit_offset += r->inc_bits * b->sec3.subsets;
302 b->state.local_bit_reserved = 0; // Clean the reserved bits
303
304 // All is done for this local descriptor
305 return 0;
306 }
307
308 // build the index for tableB
309 i = tb->x_start[d->x] + tb->y_ref[d->x][d->y];
310
311 // copy the descriptor to reference member desc
312 r->desc = d;
313 r->ref = tb->item[i].reference_ori; // copy the reference value from tableB, first from original
314 r->bits = tb->item[i].nbits + b->state.added_bit_length; // copy the bits from tableB
315 r->escale = tb->item[i].scale; // copy the scale from Tableb
316 strcpy_safe ( r->name, tb->item[i].name ); // copy the name
317 strcpy_safe ( r->unit, tb->item[i].unit ); // copy the unit name
318
319 // Add the added_scaled if not flag or code table
320 if ( strstr ( r->unit, "CODE TABLE" ) != r->unit && strstr ( r->unit,"FLAG" ) != r->unit &&
321 strstr ( r->unit, "Code table" ) != r->unit && strstr ( r->unit,"Flag" ) != r->unit )
322 {
323 r->escale += b->state.added_scale;
324 }
325 r->bit0 = b->state.bit_offset; // Sets the reference offset to current state offset
326 r->cref0[0] = '\0'; // default
327 r->ref0 = 0 ; // default
328
329 // check if is changing reference then we change reference value
330 if ( b->state.changing_reference != 255 )
331 {
332 // The descriptor operator 2 03 YYY is on action
333 // get the bits
334 if ( get_bits_as_uint32_t ( &ival, &r->has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), b->state.changing_reference ) == 0 )
335 {
336 snprintf (b->error, sizeof (b->error), "%s(): Cannot get bits from '%s'\n", __func__, d->c );
337 return 1;
338 }
339
340 // Change the new reference value in tableB with value previously readed because of rules for negative numbers
341 // (we still have the original value in reference_ori)
343 {
344 snprintf (b->error, sizeof (b->error), "%s(): Cannot change reference in 2 03 YYY operator for '%s'\n", __func__, d->c );
345 return 1;
346 }
347
348 strcpy_safe ( r->unit, "NEW REFERENCE" );
349 r->ref = tb->item[i].reference;
350
351 // extracting inc_bits from next 6 bits
352 if ( get_bits_as_uint32_t ( &ival, &has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), 6 ) == 0 )
353 {
354 snprintf (b->error, sizeof (b->error), "%s(): Cannot get 6 bits for inc_bits from '%s'\n", __func__, d->c );
355 return 1;
356 }
357 // Here is supossed that all subsets will have the same reference change,
358 // so inc_bits must be 0 and no inc data should be present
359 if ( ival )
360 {
361 snprintf (b->error, sizeof (b->error), "%s(): Bad format for compressed data when changing reference from '%s'\n", __func__, d->c );
362 return 1;
363 }
364 r->ref0 = 0; // here we also assume that ref0 = 0
365 r->inc_bits = 0;
366 return 0;
367 }
368
369 if ( strstr ( r->unit, "CCITT" ) != NULL )
370 {
371 // Case of CCITT string as unit
372
373 if ( b->state.fixed_ccitt != 0 ) // can be changed by 2 08 YYY operator
374 r->bits = 8 * b->state.fixed_ccitt;
375
376 if ( get_bits_as_char_array ( r->cref0, &r->has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), r->bits ) == 0 )
377 {
378 snprintf (b->error, sizeof (b->error), "%s(): Cannot get uchars from '%s'\n", __func__, d->c );
379 return 1;
380 }
381 // extracting inc_bits from next 6 bits
382 if ( get_bits_as_uint32_t ( &ival, &has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), 6 ) == 0 )
383 {
384 snprintf (b->error, sizeof (b->error), "%s(): Cannot get 6 bits for inc_bits from '%s'\n", __func__, d->c );
385 return 1;
386 }
387 r->inc_bits = ival;
388 r->ref0 = 0;
389
390 // Set the bit_offset after all bits needed by this element in all subsets
391 b->state.bit_offset += r->inc_bits * 8 * b->sec3.subsets;
392
393 // all is done here !!
394 return 0;
395 }
396
397 // is a numeric field, i.e, a data value, a flag code or a code
398 // get reference value
399 if ( mode ) // case of associated field
400 {
401 if ( get_bits_as_uint32_t ( &r->ref0, &r->has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), b->state.assoc_bits ) == 0 )
402 {
403 snprintf (b->error, sizeof (b->error), "%s(): Cannot get associated bits from '%s'\n", __func__, d->c );
404 return 1;
405 }
406 // patch for delayed descriptor: it allways have data
408 r->has_data = 1;
409 }
410 else // case of data
411 {
412 if ( get_bits_as_uint32_t ( &r->ref0, &r->has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), r->bits ) == 0 )
413 {
414 snprintf (b->error, sizeof (b->error), "%s(): Cannot get the data bits from '%s'\n", __func__, d->c );
415 return 1;
416 }
417 // patch for delayed descriptor: it allways have data
419 r->has_data = 1;
420 }
421
422 // extracting inc_bits from next 6 bits for inc_bits
423 if ( get_bits_as_uint32_t ( &ival, &has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), 6 ) == 0 )
424 {
425 snprintf (b->error, sizeof (b->error), "%s(): Cannot get 6 bits for inc_bits from '%s'\n", __func__, d->c );
426 return 1;
427 }
428 r->inc_bits = ival;
429
430 // if is a delayed descriptor then inc_bits MUST be 0.
432 {
433 snprintf (b->error, sizeof (b->error), "%s(): Found a delayed descriptor with inc_bits != 0\n", __func__ );
434 return 1;
435 }
436
437 // Set the bit_offset after all bits needed by this element in all subsets
438 b->state.bit_offset += r->inc_bits * b->sec3.subsets;
439
440 return 0;
441}
int get_table_b_reference_from_uint32_t(int32_t *target, uint8_t bits, uint32_t source)
Get an int32_t from bits according with bufr criteria to change the reference of a descritor....

References bufrdeco_decoding_data_state::added_bit_length, bufrdeco_decoding_data_state::added_scale, bufrdeco_decoding_data_state::assoc_bits, bufr_tables::b, bufrdeco_compressed_ref::bit0, bufrdeco_decoding_data_state::bit_offset, bufrdeco_compressed_ref::bits, bufrdeco_assert, bufr_descriptor::c, bufrdeco_decoding_data_state::changing_reference, bufrdeco_compressed_ref::cref0, bufrdeco_compressed_ref::desc, bufrdeco::error, bufrdeco_compressed_ref::escale, bufrdeco_decoding_data_state::fixed_ccitt, get_bits_as_char_array(), get_bits_as_uint32_t(), get_table_b_reference_from_uint32_t(), bufrdeco_compressed_ref::has_data, bufrdeco_compressed_ref::inc_bits, is_a_delayed_descriptor(), is_a_local_descriptor(), is_a_short_delayed_descriptor(), bufrdeco_compressed_ref::is_associated, bufr_tableB::item, bufrdeco_decoding_data_state::local_bit_reserved, bufrdeco_compressed_ref::name, bufr_tableB_decoded_item::name, bufr_tableB_decoded_item::nbits, bufr_sec4::raw, bufrdeco_compressed_ref::ref, bufrdeco_compressed_ref::ref0, bufr_tableB_decoded_item::reference, bufr_tableB_decoded_item::reference_ori, bufr_tableB_decoded_item::scale, bufrdeco::sec3, bufrdeco::sec4, bufrdeco::state, strcpy_safe, bufr_sec3::subsets, bufrdeco::tables, bufrdeco_compressed_ref::unit, bufr_tableB_decoded_item::unit, bufr_descriptor::x, bufr_tableB::x_start, bufr_descriptor::y, and bufr_tableB::y_ref.

Referenced by bufrdeco_decode_replicated_subsequence_compressed(), and bufrdeco_parse_compressed_recursive().

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

◆ bufrdeco_tableB_val()

int bufrdeco_tableB_val ( struct bufr_atom_data a,
struct bufrdeco b,
struct bufr_descriptor d 
)

Get data from a table B descriptor.

Parameters
apointer to a struct bufr_atom_data where to set the results
bpointer to the basic struct bufrdeco
dpointer to the target descriptor
Returns
0 if success, 1 otherwise

Definition at line 451 of file bufrdeco_tableB.c.

452{
453 buf_t i, nbits = 0;
454 uint32_t ival;
455 uint8_t has_data;
456 int32_t /*escale = 0,*/ reference = 0;
457 struct bufr_tableB *tb;
458
459 //bufrdeco_assert ( a != NULL && b != NULL && d != NULL );
460
461 tb = & ( b->tables->b );
462
463 if ( is_a_local_descriptor ( d ) )
464 {
465 // if is a local descriptor we just skip the bits signified by operator 2 06 YYY
467 strcpy_safe ( a->name, "LOCAL DESCRIPTOR" );
468 strcpy_safe ( a->unit, "UNKNOWN" );
469 if ( get_bits_as_uint32_t ( &ival, &has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), b->state.local_bit_reserved ) == 0 )
470 {
471 snprintf (b->error, sizeof (b->error), "%s(): Cannot get bits from '%s'\n", __func__, d->c );
472 return 1;
473 }
474 a->val = ival; // we assume escale = 0 and ref = 0
475 b->state.local_bit_reserved = 0; // Clean the reserved bits
476 return 0;
477 }
478
479 i = tb->x_start[d->x] + tb->y_ref[d->x][d->y];
480
481 memcpy ( & ( a->desc ), d, sizeof ( struct bufr_descriptor ) );
482 a->mask = 0;
483 strcpy_safe ( a->name, tb->item[i].name );
484 strcpy_safe ( a->unit, tb->item[i].unit );
485 a->escale = tb->item[i].scale;
486
487 // Case of difference statistics active
488 if ( b->state.dstat_active )
489 nbits = tb->item[i].nbits + 1;
490 else
491 nbits = tb->item[i].nbits;
492
493 if ( b->state.changing_reference != 255 )
494 {
495 // The descriptor operator 2 03 YYY is on action
496 // Get preliminar value
497 if ( get_bits_as_uint32_t ( &ival, &has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), b->state.changing_reference ) == 0 )
498 {
499 snprintf (b->error, sizeof (b->error), "%s(): Cannot get bits from '%s'\n", __func__, d->c );
500 return 1;
501 }
502
503 // Then change the preliminar reference value because of rules for negative numbers
505 {
506 snprintf (b->error, sizeof (b->error), "%s(): Cannot change reference in 2 03 YYY operator for '%s'\n", __func__, d->c );
507 return 1;
508 }
509 strcpy_safe ( a->unit, "NEW REFERENCE" );
510 a->val = ( double ) tb->item[i].reference;
511 return 0;
512 }
513
514 // case of difference statistics active
515 if ( b->state.dstat_active )
516 reference = - ( ( int32_t ) 1 << ( tb->item[i].nbits ) );
517 else
518 reference = tb->item[i].reference;
519
520 //printf(" escale = %d reference = %d nbits = %lu\n", escale, reference, nbits);
521 if ( strstr ( a->unit, "CCITT" ) != NULL )
522 {
523 if ( b->state.fixed_ccitt != 0 ) // can be changed by 2 08 YYY operator
524 nbits = 8 * b->state.fixed_ccitt;
525
526 if ( get_bits_as_char_array ( a->cval, &has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), nbits ) == 0 )
527 {
528 snprintf (b->error, sizeof (b->error), "%s(): Cannot get uchars from '%s'\n", __func__, d->c );
529 return 1;
530 }
531 if ( has_data == 0 )
532 {
534 }
535 else
536 {
538 }
539 return 0;
540 }
541
542 // is a numeric field, i.e, a data value, a flag code or a code
543 // Set associated bits
544 if ( b->state.assoc_bits &&
545 a->desc.x != 31 && // Data description qualifier has not associated bits itself
546 get_bits_as_uint32_t ( &a->associated, &has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), b->state.assoc_bits ) == 0 )
547 {
548 snprintf (b->error, sizeof (b->error), "%s(): Cannot get associated bits from '%s'\n", __func__, d->c );
549 return 1;
550 }
551 else
552 {
554 }
555
556 if ( strstr ( a->unit, "CODE TABLE" ) != a->unit && strstr ( a->unit,"FLAG" ) != a->unit &&
557 strstr ( a->unit, "Code table" ) != a->unit && strstr ( a->unit,"Flag" ) != a->unit )
558 {
559 // case of numeric, no string nor code nor flag
560 nbits += b->state.added_bit_length;
561 }
562
563 if ( get_bits_as_uint32_t ( &ival, &has_data, &b->sec4.raw[4], & ( b->state.bit_offset ), nbits ) == 0 )
564 {
565 snprintf (b->error, sizeof (b->error), "%s(): Cannot get bits from '%s'\n", __func__, d->c );
566 return 1;
567 }
568
569 // patch for delayed descriptor: it allways have data
570 if ( a->desc.x == 31 )
571 has_data = 1;
572
573 if ( has_data )
574 {
575 if ( strstr ( a->unit, "CODE TABLE" ) != a->unit && strstr ( a->unit,"FLAG" ) != a->unit &&
576 strstr ( a->unit, "Code table" ) != a->unit && strstr ( a->unit,"Flag" ) != a->unit )
577 {
578 a->escale += b->state.added_scale;
579 reference += b->state.added_reference;
580 if ( b->state.factor_reference > 1 )
581 reference *= b->state.factor_reference;
582 }
583 // Get a numeric number
584 if ( a->escale >= 0 && a->escale < 8 )
585 {
586 a->val = ( double ) ( ( int32_t ) ival + reference ) * pow10neg[ ( size_t ) a->escale];
587 }
588 else if ( a->escale < 0 && a->escale > -8 )
589 {
590 a->val = ( double ) ( ( int32_t ) ival + reference ) * pow10pos[ ( size_t ) ( -a->escale )];
591 }
592 else
593 {
594 a->val = ( double ) ( ( int32_t ) ival + reference ) * exp10 ( ( double ) ( -a->escale ) );
595 }
596
597 if ( strstr ( a->unit, "CODE TABLE" ) == a->unit || strstr ( a->unit, "Code table" ) == a->unit )
598 {
599 ival = ( uint32_t ) ( a->val + 0.5 );
601 if ( bufrdeco_explained_table_val ( a->ctable, 256, & ( b->tables->c ), & ( tb->item[i].tableC_ref ), & ( a->desc ), ival ) != NULL )
602 {
604 }
605 }
606 else if ( strstr ( a->unit,"FLAG" ) == a->unit || strstr ( a->unit,"Flag" ) == a->unit )
607 {
608 ival = ( uint32_t ) ( a->val + 0.5 );
610
611 if ( bufrdeco_explained_flag_val ( a->ctable, 256, & ( b->tables->c ), & ( a->desc ), ival, nbits ) != NULL )
612 {
614 }
615 }
616 }
617 else
618 {
619 a->val = MISSING_REAL;
621 }
622
623 return 0;
624}
const double pow10pos[8]
const double pow10neg[8]

References bufrdeco_decoding_data_state::added_bit_length, bufrdeco_decoding_data_state::added_reference, bufrdeco_decoding_data_state::added_scale, bufrdeco_decoding_data_state::assoc_bits, bufr_atom_data::associated, bufr_tables::b, bufrdeco_decoding_data_state::bit_offset, bufrdeco_explained_flag_val(), bufrdeco_explained_table_val(), bufr_descriptor::c, bufr_tables::c, bufrdeco_decoding_data_state::changing_reference, bufr_atom_data::ctable, bufr_atom_data::cval, bufr_atom_data::desc, DESCRIPTOR_HAVE_CODE_TABLE_STRING, DESCRIPTOR_HAVE_FLAG_TABLE_STRING, DESCRIPTOR_HAVE_STRING_VALUE, DESCRIPTOR_IS_CODE_TABLE, DESCRIPTOR_IS_FLAG_TABLE, DESCRIPTOR_IS_LOCAL, DESCRIPTOR_VALUE_MISSING, bufrdeco_decoding_data_state::dstat_active, bufrdeco::error, bufr_atom_data::escale, bufrdeco_decoding_data_state::factor_reference, bufrdeco_decoding_data_state::fixed_ccitt, get_bits_as_char_array(), get_bits_as_uint32_t(), get_table_b_reference_from_uint32_t(), is_a_local_descriptor(), bufr_tableB::item, bufrdeco_decoding_data_state::local_bit_reserved, bufr_atom_data::mask, MISSING_INTEGER, MISSING_REAL, bufr_atom_data::name, bufr_tableB_decoded_item::name, bufr_tableB_decoded_item::nbits, pow10neg, pow10pos, bufr_sec4::raw, bufr_tableB_decoded_item::reference, bufr_tableB_decoded_item::scale, bufrdeco::sec4, bufrdeco::state, strcpy_safe, bufr_tableB_decoded_item::tableC_ref, bufrdeco::tables, bufr_atom_data::unit, bufr_tableB_decoded_item::unit, bufr_atom_data::val, bufr_descriptor::x, bufr_tableB::x_start, bufr_descriptor::y, and bufr_tableB::y_ref.

Referenced by bufrdeco_decode_replicated_subsequence(), and bufrdeco_decode_subset_data_recursive().

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

◆ bufrdeco_tableD_get_descriptors_array()

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

Parameters
starget struct bufr_sequence
bpointer to the basic container struct bufrdeco
keystring in the form FXXYYY which is the key of descriptor we want to find out, F = 3
Returns
If the sequence has been filled with success then returns 0, otherwise returns 1

Definition at line 211 of file bufrdeco_tableD.c.

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}
int bufr_find_tableD_index(buf_t *index, struct bufr_tableD *td, const char *key)

References bufr_find_tableD_index(), bufrdeco_assert, bufr_tables::d, bufr_tableD_decoded_item::description, bufrdeco::error, bufr_tableD::item, bufr_tableD::l, bufr_sequence::lseq, bufr_sequence::name, bufr_sequence::ndesc, bufr_tableD::nlines, bufrdeco::tables, and uint32_t_to_descriptor().

Referenced by bufrdeco_parse_tree_recursive().

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

◆ 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:

◆ csv_quoted_string()

char * csv_quoted_string ( char *  out,
char *  in 
)

Transform a string to a quoted string to be inserted in a csv file.

Parameters
outresulting string
ininput string
Returns
If problem returns NULL, otherwise out

Definition at line 48 of file bufrdeco_csv.c.

49{
50 size_t i = 0, j = 0;
51
52 if ( in == NULL || out == NULL)
53 return NULL;
54
55 if ( in[0] == 0 )
56 return in;
57
58 out[j++] = '\"';
59 while ( in[i] && j < ( CSV_MAXL - 1 ) && i < CSV_MAXL )
60 {
61 if ( in[i] == '\"' )
62 {
63 out[j++] = '\"';
64 out[j++] = '\"';
65 i++;
66 }
67 else
68 out[j++] = in[i++];
69 }
70 out[j++] = '\"';
71 out[j] = 0; // end of string
72 return out;
73}

References CSV_MAXL.

Referenced by main().

Here is the caller graph for this function:

◆ fprint_bufrdeco_compressed_data_references()

int fprint_bufrdeco_compressed_data_references ( FILE *  f,
struct bufrdeco_compressed_data_references r 
)

Definition at line 619 of file bufrdeco_print.c.

620{
621 size_t i;
622
623 bufrdeco_assert ( f != NULL && r != NULL);
624
625 for ( i = 0; i < r->nd; i++ )
627
628 return 0;
629}
int fprint_bufrdeco_compressed_ref(FILE *f, struct bufrdeco_compressed_ref *r)
prints a struct bufrdeco_compressed_ref

References bufrdeco_assert, fprint_bufrdeco_compressed_ref(), bufrdeco_compressed_data_references::nd, and bufrdeco_compressed_data_references::refs.

Here is the call graph for this function:

◆ fprint_bufrdeco_compressed_ref()

int fprint_bufrdeco_compressed_ref ( FILE *  f,
struct bufrdeco_compressed_ref r 
)

prints a struct bufrdeco_compressed_ref

Parameters
fpointer to a file opened by caller
rpointer to the struct to print
Returns
If succeeded return 0

Definition at line 558 of file bufrdeco_print.c.

559{
560 bufrdeco_assert ( f != NULL && r != NULL );
561
563 return 0;
564
565 fprintf ( f, "%s -> A=%u, D=%u, ",r->desc->c,r->is_associated,r->has_data );
566 if ( r->cref0[0] == '\0' )
567 {
568 fprintf ( f, "bits=%2u, ref=%10d, escale=%3d,", r->bits, r->ref, r->escale );
569 fprintf ( f, " bit0=%10u, ref0=%10u, inc_bits=%2u ", r->bit0, r->ref0, r->inc_bits );
570 fprintf ( f, "%s %s\n",r->name, r->unit );
571 }
572 else
573 {
574 fprintf ( f, "'%s', chars=%3u\n", r->cref0, r->inc_bits );
575 }
576 return 0;
577}

References bufrdeco_compressed_ref::bit0, bufrdeco_compressed_ref::bits, bufrdeco_assert, BUFRDECO_COMPRESSED_REF_DATA_DESCRIPTOR_BITMASK, bufr_descriptor::c, bufrdeco_compressed_ref::cref0, bufrdeco_compressed_ref::desc, bufrdeco_compressed_ref::escale, bufrdeco_compressed_ref::has_data, bufrdeco_compressed_ref::inc_bits, bufrdeco_compressed_ref::is_associated, bufrdeco_compressed_ref::mask, bufrdeco_compressed_ref::name, bufrdeco_compressed_ref::ref, bufrdeco_compressed_ref::ref0, and bufrdeco_compressed_ref::unit.

Referenced by fprint_bufrdeco_compressed_data_references(), and print_bufrdeco_compressed_ref().

Here is the caller graph for this function:

◆ get_bits_as_char_array()

uint32_t get_bits_as_char_array ( char *  target,
uint8_t *  has_data,
uint8_t *  source,
buf_t bit0_offset,
buf_t  bit_length 
)

Definition at line 86 of file bufrdeco_utils.c.

87{
88 buf_t i, j, k;
89 buf_t nc;
90 uint8_t *c;
91
92 //bufrdeco_assert (has_data != NULL && source != NULL && target != NULL && bit0_offset != NULL);
93
94 if ( bit_length % 8 )
95 return 0; // bit_length needs to be divisible by 8
96
97 //printf("bit_length=%lu\n", bit_length);
98
99 nc = bit_length / 8;
100 i = ( *bit0_offset ) % 8;
101 k = 8 - i;
102 *has_data = 0; // marc if no missing data is present
103 for ( j = 0; j < nc ; j++ )
104 {
105 c = source + ( *bit0_offset ) / 8;
106 * ( target + j ) = ( *c & biti[i] );
107 if ( i )
108 {
109 * ( target + j ) <<= i;
110 * ( target + j ) |= ( ( * ( c + 1 ) & bitk[i - 1] ) >> k );
111 }
112 if ( * ( target + j ) != -1 )
113 *has_data = 1;
114 //printf("%c", * ( target + j ) );
115 *bit0_offset += 8; // update bit0_offset
116 }
117 * ( target + nc ) = '\0';
118 return bit_length;
119}
uint8_t biti[8]
uint8_t bitk[8]

References biti, and bitk.

Referenced by bufrdeco_get_atom_data_from_compressed_data_ref(), bufrdeco_parse_f2_compressed(), bufrdeco_parse_f2_descriptor(), bufrdeco_tableB_compressed(), and bufrdeco_tableB_val().

Here is the caller graph for this function:

◆ get_bits_as_uint32_t()

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 
)

Definition at line 182 of file bufrdeco_utils.c.

183{
184 int i;
185 uint8_t *c;
186 uint64_t x;
187
188 //bufrdeco_assert (has_data != NULL && source != NULL && target != NULL && bit0_offset != NULL);
189
190 if ( bit_length > 32 || bit_length == 0 )
191 return 0;
192
193 if ( bit_length < 8 )
194 return get_bits_as_uint32_t2 ( target, has_data, source, bit0_offset, bit_length );
195
196 *target = 0;
197 *has_data = 0; // marc if no missing data is present
198 c = source + ( *bit0_offset ) / 8;
199 i = ( *bit0_offset ) % 8;
200 x = ( ( uint64_t ) ( *c & biti[i] ) << 32 ) + ( ( uint64_t ) ( * ( c + 1 ) ) << 24 ) + ( ( uint64_t ) ( * ( c + 2 ) ) << 16 ) +
201 ( ( uint64_t ) ( * ( c + 3 ) ) << 8 ) + ( uint64_t ) ( * ( c + 4 ) ); // 40 - i bits
202 x >>= ( 40 - i - bit_length );
203 *target = ( uint32_t ) x;
204 if ( ( 1UL << bit_length ) != ( x + 1UL ) )
205 *has_data = 1;
206
207 *bit0_offset += bit_length; // update bit0_offset
208 return bit_length;
209}
uint32_t get_bits_as_uint32_t2(uint32_t *target, uint8_t *has_data, uint8_t *source, buf_t *bit0_offset, buf_t bit_length)
Read bits from an array of uint8_t and set them as an uint32_t.

References biti, and get_bits_as_uint32_t2().

Referenced by bufrdeco_get_atom_data_from_compressed_data_ref(), bufrdeco_parse_f2_compressed(), bufrdeco_tableB_compressed(), and bufrdeco_tableB_val().

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

◆ get_formatted_value_from_escale()

char * get_formatted_value_from_escale ( char *  fmt,
size_t  dim,
int32_t  escale,
double  val 
)

gets a string with formatted value depending of scale

Parameters
fmtThe output target string
dimSize of available space (bytes) to write the result
escalevalue scale in descriptor
valdouble to printf
Returns
the resulting fmt string This version use 17 width for number plus a final space

Definition at line 410 of file bufrdeco_utils.c.

411{
412 char aux[32];
413 //bufrdeco_assert (fmt != NULL);
414
415 if ( escale >= 0 )
416 {
417 sprintf ( aux, "%%17.%dlf " , escale );
418 snprintf ( fmt, dim, aux, val );
419 }
420 else
421 snprintf ( fmt, dim, "%17.0lf " , val );
422 return fmt;
423}

Referenced by bufrdeco_print_atom_data(), and bufrdeco_print_atom_data_html().

Here is the caller graph for this function:

◆ get_formatted_value_from_escale2()

char * get_formatted_value_from_escale2 ( char *  fmt,
size_t  dim,
int32_t  escale,
double  val 
)

gets a string with formatted value depending of scale

Parameters
fmtThe output target string
dimSize of available space (bytes) to write the result
escalevalue scale in descriptor
valdouble to printf
Returns
the resulting fmt string

Differs from get_formatted_value_from_escale that no blanks are written

Definition at line 436 of file bufrdeco_utils.c.

437{
438 char aux[32];
439 //bufrdeco_assert (fmt != NULL);
440
441 if ( escale >= 0 )
442 {
443 sprintf ( aux, "%%.%dlf" , escale );
444 snprintf ( fmt, dim, aux, val );
445 }
446 else
447 snprintf ( fmt, dim, "%.0lf" , val );
448 return fmt;
449}

Referenced by bufrdeco_print_json_object_atom_data().

Here is the caller graph for this function:

◆ get_table_b_reference_from_uint32_t()

int get_table_b_reference_from_uint32_t ( int32_t *  target,
uint8_t  bits,
uint32_t  source 
)

Get an int32_t from bits according with bufr criteria to change the reference of a descritor. Most significant bit in source is sign.

Parameters
targetint32_t as result
bitsnumber of bits to consider
sourceuint32_T with the data to transform
Returns
If success return 0, 1 otherwise

Definition at line 221 of file bufrdeco_utils.c.

222{
223 uint32_t mask = 1;
224
225 //bufrdeco_assert (target != NULL);
226
227
228 if ( bits > 32 || bits == 0 )
229 return 1;
230
231 if ( bits > 1 )
232 mask = ( ( uint32_t ) 1 << ( bits - 1 ) );
233
234 if ( mask & source )
235 {
236 // case of negative number
237 *target = - ( int32_t ) ( source - mask );
238 }
239 else
240 *target = ( int32_t ) ( source );
241 return 0;
242}

Referenced by bufrdeco_tableB_compressed(), and bufrdeco_tableB_val().

Here is the caller graph for this function:

◆ get_wmo_tablenames()

int get_wmo_tablenames ( struct bufrdeco b)

Get the complete pathnames for WMO csv table files needed by a bufr message.

Parameters
bpointer for a struct bufrdeco
Returns
if success return 0, otherwise 1

For WMO files this format is adopted BUFR_XX_Y_Z_TableB_en for table B BUFR_XX_Y_Z_CodeFlag for Code table and Flag table. This is equivalent to table C in ECMWF package BUFR_XX_Y_Z_TableD_en for table D

XX is the Version number of master table used Y is the revision (currently ignored) Z is minor revision (currently ignored)

Definition at line 47 of file bufrdeco_wmo.c.

48{
49 struct stat st;
50 char aux[BUFRDECO_PATH_LENGTH - 32];
51
52 bufrdeco_assert ( b != NULL );
53
54 if ( b->bufrtables_dir[0] == '\0' )
55 {
56 // try to guess directory
57 if ( stat ( DEFAULT_BUFRTABLES_WMO_CSV_DIR1, &st ) )
58 {
59 if ( stat ( DEFAULT_BUFRTABLES_WMO_CSV_DIR2, &st ) )
60 {
61 return 1;
62 }
63 else
64 {
65 if ( S_ISDIR ( st.st_mode ) )
66 {
67 strcpy ( aux, DEFAULT_BUFRTABLES_WMO_CSV_DIR2 );
68 }
69 }
70 }
71 else
72 {
73 if ( S_ISDIR ( st.st_mode ) )
74 {
75 strcpy ( aux, DEFAULT_BUFRTABLES_WMO_CSV_DIR1 );
76 }
77 }
78 }
79 else
80 {
81 strcpy ( aux, b->bufrtables_dir );
82 }
83
84 switch ( b->sec1.master_version )
85 {
86 case 4:
87 case 5:
88 case 6:
89 case 7:
90 case 8:
91 case 9:
92 case 10:
93 case 11:
94 case 12:
95 case 13:
96 snprintf ( b->tables->b.path, sizeof ( b->tables->b.path ),"%sBUFR_13_0_0_TableB_en.csv", aux );
97 snprintf ( b->tables->c.path, sizeof ( b->tables->c.path ),"%sBUFR_13_0_0_TableC_en.csv", aux );
98 snprintf ( b->tables->d.path, sizeof ( b->tables->d.path ),"%sBUFR_13_0_0_TableD_en.csv", aux );
99 break;
100 case 18:
101 snprintf ( b->tables->b.path, sizeof ( b->tables->b.path ),"%sBUFR_18_1_0_TableB_en.csv", aux );
102 snprintf ( b->tables->c.path, sizeof ( b->tables->c.path ),"%sBUFR_18_1_0_TableC_en.csv", aux );
103 snprintf ( b->tables->d.path, sizeof ( b->tables->d.path ),"%sBUFR_18_1_0_TableD_en.csv", aux );
104 break;
105 case 19:
106 snprintf ( b->tables->b.path, sizeof ( b->tables->b.path ),"%sBUFR_19_1_1_TableB_en.csv", aux );
107 snprintf ( b->tables->c.path, sizeof ( b->tables->c.path ),"%sBUFR_19_1_1_TableC_en.csv", aux );
108 snprintf ( b->tables->d.path, sizeof ( b->tables->d.path ),"%sBUFR_19_1_1_TableD_en.csv", aux );
109 break;
110 case 22:
111 snprintf ( b->tables->b.path, sizeof ( b->tables->b.path ),"%sBUFR_22_0_1_TableB_en.csv", aux );
112 snprintf ( b->tables->c.path, sizeof ( b->tables->c.path ),"%sBUFR_22_0_1_TableC_en.csv", aux );
113 snprintf ( b->tables->d.path, sizeof ( b->tables->d.path ),"%sBUFR_22_0_1_TableD_en.csv", aux );
114 break;
115 case 14:
116 case 15:
117 case 16:
118 case 17:
119 case 20:
120 case 21:
121 case 23:
122 case 24:
123 case 25:
124 case 26:
125 case 27:
126 case 28:
127 case 29:
128 case 30:
129 case 31:
130 case 32:
131 case 33:
132 case 34:
133 case 35:
134 case 36:
135 case 37:
136 snprintf ( b->tables->b.path, sizeof ( b->tables->b.path ),"%sBUFR_%d_0_0_TableB_en.csv", aux, b->sec1.master_version );
137 snprintf ( b->tables->c.path, sizeof ( b->tables->c.path ),"%sBUFR_%d_0_0_TableC_en.csv", aux, b->sec1.master_version );
138 snprintf ( b->tables->d.path, sizeof ( b->tables->d.path ),"%sBUFR_%d_0_0_TableD_en.csv", aux, b->sec1.master_version );
139 break;
140 case 38:
141 snprintf ( b->tables->b.path, sizeof ( b->tables->b.path ),"%sBUFR_%d_1_0_TableB_en.csv", aux, b->sec1.master_version );
142 snprintf ( b->tables->c.path, sizeof ( b->tables->c.path ),"%sBUFR_%d_1_0_TableC_en.csv", aux, b->sec1.master_version );
143 snprintf ( b->tables->d.path, sizeof ( b->tables->d.path ),"%sBUFR_%d_1_0_TableD_en.csv", aux, b->sec1.master_version );
144 break;
145 default:
146 snprintf ( b->tables->b.path, sizeof ( b->tables->b.path ),"%sBUFR_38_1_0_TableB_en.csv", aux );
147 snprintf ( b->tables->c.path, sizeof ( b->tables->c.path ),"%sBUFR_38_1_0_TableC_en.csv", aux );
148 snprintf ( b->tables->d.path, sizeof ( b->tables->d.path ),"%sBUFR_38_1_0_TableD_en.csv", aux );
149 break;
150 }
151 return 0;
152}
const char DEFAULT_BUFRTABLES_WMO_CSV_DIR2[]
Definition: bufrdeco_wmo.c:30
const char DEFAULT_BUFRTABLES_WMO_CSV_DIR1[]
Definition: bufrdeco_wmo.c:29

References bufr_tables::b, bufrdeco_assert, BUFRDECO_PATH_LENGTH, bufrdeco::bufrtables_dir, bufr_tables::c, bufr_tables::d, DEFAULT_BUFRTABLES_WMO_CSV_DIR1, DEFAULT_BUFRTABLES_WMO_CSV_DIR2, bufr_sec1::master_version, bufr_tableB::path, bufr_tableC::path, bufr_tableD::path, bufrdeco::sec1, and bufrdeco::tables.

Referenced by bufr_read_tables().

Here is the caller graph for this function:

◆ is_a_delayed_descriptor()

int is_a_delayed_descriptor ( struct bufr_descriptor d)

check if a descriptor is a delayed descriptor

Parameters
dpointer to a struct bufr_descriptor to check
Returns
If is a delayed desccriptor return 1, 0 otherwise.

Definition at line 351 of file bufrdeco_utils.c.

352{
353 //bufrdeco_assert (d != NULL);
354
355 if ( ( d->f == 0 ) &&
356 ( d->x == 31 ) &&
357 ( d->y == 1 || d->y == 2 || d->y == 11 || d->y == 12 ) )
358 return 1;
359 else
360 return 0;
361}

References bufr_descriptor::f, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_fprint_tree_recursive(), bufrdeco_print_json_tree_recursive(), and bufrdeco_tableB_compressed().

Here is the caller graph for this function:

◆ is_a_local_descriptor()

int is_a_local_descriptor ( struct bufr_descriptor d)

check if a descriptor is a local descriptor

Parameters
dpointer to a struct bufr_descriptor to check
Returns
If is a local desccriptor return 1, 0 otherwise.

Definition at line 388 of file bufrdeco_utils.c.

389{
390 //bufrdeco_assert (d != NULL);
391
392 if ( ( d->f == 0 ) &&
393 ( d->x >= 48 ) &&
394 ( d->x <= 63 ) )
395 return 1;
396 else
397 return 0;
398}

References bufr_descriptor::f, and bufr_descriptor::x.

Referenced by bufrdeco_get_atom_data_from_compressed_data_ref(), bufrdeco_tableB_compressed(), and bufrdeco_tableB_val().

Here is the caller graph for this function:

◆ is_a_short_delayed_descriptor()

int is_a_short_delayed_descriptor ( struct bufr_descriptor d)

check if a descriptor is a short delayed descriptor

Parameters
dpointer to a struct bufr_descriptor to check
Returns
If is a delayed descriptor return 1, 0 otherwise.

Definition at line 369 of file bufrdeco_utils.c.

370{
371 //bufrdeco_assert (d != NULL);
372
373 if ( ( d->f == 0 ) &&
374 ( d->x == 31 ) &&
375 ( d->y == 0 ) )
376 return 1;
377 else
378 return 0;
379}

References bufr_descriptor::f, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_fprint_tree_recursive(), bufrdeco_print_json_tree_recursive(), and bufrdeco_tableB_compressed().

Here is the caller graph for this function:

◆ parse_csv_line()

int parse_csv_line ( int *  nt,
char *  tk[],
char *  lin 
)

Parse a csv line.

Parameters
ntpointer to a integer. On success is the number of items found
tkarray of pointers. Every pointer is a item on success
lininput line which is modified in this routine to be splitted into items
Returns
On success return 0, otherwise -1

This is an optimization of routine parse_csv_line2(). Here we suppose: -All no void items are closed between "" and separed by comas ',' -No " in items. -No blank spaces at the end nor begin of items

NOTE that input line is modified

Definition at line 258 of file bufrdeco_csv.c.

259{
260 char *cq[CSV_MAXL / 4], *cc[CSV_MAXL / 4], *c0;
261 buf_t nc, nq, i, j;
262
263 //bufrdeco_assert (lin != NULL && tk != NULL && nt != NULL);
264
265 *nt = 0;
266
267 // clean final new line)
268 if ((c0 = strchr(lin, CSV_FINAL)) != NULL)
269 *c0 = '\0';
270
271 c0 = lin;
272 nq = 0;
273 while (c0 != NULL && *c0 && nq < (CSV_MAXL / 4))
274 {
275 if ((c0 = strchr(c0, CSV_CITE)) != NULL)
276 {
277 cq[nq++] = c0++;
278 }
279 }
280
281 if (nq % 2)
282 return -1; // Problem, number of quotes are non paired
283
284 c0 = lin;
285 nc = 0;
286 while (c0 != NULL && *c0 && nc < (CSV_MAXL / 4))
287 {
288 if ((c0 = strchr(c0, CSV_SEPARATOR)) != NULL)
289 {
290 j = 0;
291 if (nq)
292 {
293 for (; j < nq ; j+=2)
294 if ((cq[j] < c0) && (c0 < cq[j + 1]))
295 {
296 j = nq;// is a comma between two cites. Ignored
297 c0++;
298 }
299 }
300 if (j == nq)
301 {
302 // is a comma between two items.
303 cc[nc++] = c0++;
304 }
305 }
306 }
307
308 // Now go to tokens, in this pass, still CSV_CITE are in items
309 c0 = lin;
310 if (nc == 0)
311 tk[(*nt)++] = c0;
312 else
313 {
314 for (i = 0; i < nc; i++)
315 {
316 if (cc[i] == c0)
317 {
318 tk[(*nt)++] = c0;
319 *(c0) = '\0';
320 c0++;
321 }
322 else
323 {
324 tk[(*nt)++] = c0;
325 *(cc[i]) = '\0';
326 c0 = cc[i] + 1;
327 }
328 }
329 }
330 tk[(*nt)++] = c0;
331
332 // fix the tokens supresing the first CSV_CITE if any
333 for (i = 0; i < (buf_t)(*nt); i++)
334 {
335 if( *(tk[i]) == CSV_CITE)
336 (tk[i])++;
337 }
338
339 // And then supress all CSV_CITE (also in the end of every item)
340 for (i = 0; i < nq ; i++)
341 *(cq[i]) = '\0';
342
343 return 0;
344}
const char CSV_CITE
Definition: bufrdeco_csv.c:36
const char CSV_FINAL
Definition: bufrdeco_csv.c:37
const char CSV_SEPARATOR
Definition: bufrdeco_csv.c:35

References CSV_CITE, CSV_FINAL, CSV_MAXL, and CSV_SEPARATOR.

Referenced by bufr_read_tableB(), bufr_read_tableC(), bufr_read_tableD(), and main().

Here is the caller graph for this function:

◆ print_bufrdeco_compressed_data_references()

int print_bufrdeco_compressed_data_references ( struct bufrdeco_compressed_data_references r)

prints a struct bufrdeco_compressed_references

Parameters
rpointer to the struct to print
Returns
If succeeded return 0, 1 otherwise

It is used mainly in debug stage

Definition at line 600 of file bufrdeco_print.c.

601{
602 size_t i;
603 bufrdeco_assert ( r != NULL );
604
605 for ( i = 0; i < r->nd; i++ )
607
608 return 0;
609}
int print_bufrdeco_compressed_ref(struct bufrdeco_compressed_ref *r)
prints a struct bufrdeco_compressed_ref

References bufrdeco_assert, bufrdeco_compressed_data_references::nd, print_bufrdeco_compressed_ref(), and bufrdeco_compressed_data_references::refs.

Referenced by main().

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

◆ print_bufrdeco_compressed_ref()

int print_bufrdeco_compressed_ref ( struct bufrdeco_compressed_ref r)

prints a struct bufrdeco_compressed_ref

Parameters
rpointer to the struct to print
Returns
If succeeded return 0

Definition at line 585 of file bufrdeco_print.c.

586{
587 bufrdeco_assert ( r != NULL );
588
589 return fprint_bufrdeco_compressed_ref ( stdout, r );
590}

References bufrdeco_assert, and fprint_bufrdeco_compressed_ref().

Referenced by print_bufrdeco_compressed_data_references().

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

◆ print_sec0_info()

int print_sec0_info ( struct bufrdeco b)

Prints info from sec0.

Parameters
bpointer to the source struct bufrdeco
Returns
If succeeded return 0

Definition at line 62 of file bufrdeco_print.c.

63{
64 char caux[512];
65
66 bufrdeco_assert ( b != NULL );
67
68 caux[0] = 0;
69 sprint_sec0_info ( caux, 512, b );
70 printf ( "%s", caux );
71 return 0;
72}
int sprint_sec0_info(char *target, size_t lmax, struct bufrdeco *b)
Prints info from sec0.

References bufrdeco_assert, and sprint_sec0_info().

Referenced by main().

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

◆ print_sec1_info()

int print_sec1_info ( struct bufrdeco b)

Prints info from sec1.

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

Definition at line 135 of file bufrdeco_print.c.

136{
137 char caux[2048];
138
139 bufrdeco_assert ( b != NULL );
140
141 caux[0] = 0;
142 sprint_sec1_info ( caux, 2048, b );
143 printf ( "%s", caux );
144 return 0;
145}
int sprint_sec1_info(char *target, size_t lmax, struct bufrdeco *b)
Prints info from sec1.

References bufrdeco_assert, and sprint_sec1_info().

Referenced by main().

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

◆ print_sec3_info()

int print_sec3_info ( struct bufrdeco b)

Prints info from sec3.

Parameters
bpointer to the source struct bufrdeco
Returns
If succeeded return 0

Definition at line 192 of file bufrdeco_print.c.

193{
194 char caux[8192];
195
196 bufrdeco_assert ( b != NULL );
197
198 caux[0] = 0;
199 sprint_sec3_info ( caux, 8192, b );
200 printf ( "%s", caux );
201 return 0;
202}
int sprint_sec3_info(char *target, size_t lmax, struct bufrdeco *b)
Prints info from sec3.

References bufrdeco_assert, and sprint_sec3_info().

Referenced by main().

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

◆ print_sec4_info()

int print_sec4_info ( struct bufrdeco b)

Prints info from sec3.

Parameters
bpointer to the source struct bufrdeco
Returns
If succeeded return 0

Definition at line 239 of file bufrdeco_print.c.

240{
241 char caux[8192];
242
243 bufrdeco_assert ( b != NULL );
244
245 caux[0] = 0;
246 sprint_sec4_info ( caux, 8192, b );
247 printf ( "%s", caux );
248 return 0;
249}
int sprint_sec4_info(char *target, size_t lmax, struct bufrdeco *b)
Prints info from sec4.

References bufrdeco_assert, and sprint_sec4_info().

Referenced by main().

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

◆ sprint_sec0_info()

int sprint_sec0_info ( char *  target,
size_t  lmax,
struct bufrdeco b 
)

Prints info from sec0.

Parameters
targetstring target
lmaxavailable size in target
bpointer to the source struct bufrdeco
Returns
If succeeded return 0, otherwise 1

Definition at line 35 of file bufrdeco_print.c.

36{
37 size_t used = 0;
38
39 bufrdeco_assert ( b != NULL );
40
41 if ( lmax == 0 || target == NULL )
42 {
43 snprintf ( b->error, sizeof ( b->error ), "%s(): Unspected NULL argument(s)\n", __func__ );
44 return 1;
45 }
46
47 if ( b->mask & BUFRDECO_OUTPUT_HTML )
48 return sprint_sec0_info_html ( target, lmax, b );
49
50 used += snprintf ( target + used, lmax - used, "#### SEC 0 INFO ###\n" );
51 used += snprintf ( target + used, lmax - used, "Bufr length: %5u\n", b->sec0.bufr_length );
52 used += snprintf ( target + used, lmax - used, "Bufr edition: %5u\n", b->sec0.edition );
53 return 0;
54}
int sprint_sec0_info_html(char *target, size_t lmax, struct bufrdeco *b)
Prints info from sec0 in html format.

References bufr_sec0::bufr_length, bufrdeco_assert, BUFRDECO_OUTPUT_HTML, bufr_sec0::edition, bufrdeco::error, bufrdeco::mask, bufrdeco::sec0, and sprint_sec0_info_html().

Referenced by print_sec0_info().

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

◆ sprint_sec0_info_html()

void sprint_sec0_info_html ( char *  target,
size_t  lmax,
struct bufrdeco b 
)

Prints info from sec0 in html format.

Parameters
targetstring target
lmaxavailable size in target
bpointer to the source struct bufrdeco
Returns
If succeeded return 0

Definition at line 34 of file bufrdeco_print_html.c.

35{
36 size_t used = 0;
37
38 bufrdeco_assert ( b != NULL && lmax != 0 && target != NULL );
39
40 used += snprintf ( target + used, lmax - used, "<table class='bufr_sec0'>\n<caption>SEC 0 INFO</caption>\n" );
41 used += snprintf ( target + used, lmax - used, "<tr><td>Bufr length</td><td>%5u</td></tr>\n", b->sec0.bufr_length );
42 used += snprintf ( target + used, lmax - used, "<tr><td>Bufr edition</td><td>%5u</td></tr>\n", b->sec0.edition );
43 used += snprintf ( target + used, lmax - used, "</table>\n" );
44 return 0;
45}

References bufr_sec0::bufr_length, bufrdeco_assert, bufr_sec0::edition, and bufrdeco::sec0.

Referenced by sprint_sec0_info().

Here is the caller graph for this function:

◆ sprint_sec1_info()

int_bits sprint_sec1_info ( char *  target,
size_t  lmax,
struct bufrdeco b 
)

Prints info from sec1.

Parameters
targetstring target
lmaxavailable size in target
bpointer to the source struct bufrdeco
Returns
If succeeded return 0, 1 otherwise

Definition at line 83 of file bufrdeco_print.c.

84{
85 size_t used = 0;
86
87 bufrdeco_assert ( b != NULL );
88
89 if ( lmax == 0 || target == NULL )
90 {
91 snprintf ( b->error, sizeof ( b->error ), "%s(): Unspected NULL argument(s)\n", __func__ );
92 return 1;
93 }
94
95 if ( b->mask & BUFRDECO_OUTPUT_HTML )
96 return sprint_sec1_info_html ( target, lmax, b );
97
98 used += snprintf ( target + used, lmax - used, "\n#### SEC 1 INFO ###\n" );
99 used += snprintf ( target + used, lmax - used, "Sec1 length: %5u\n", b->sec1.length );
100 used += snprintf ( target + used, lmax - used, "Bufr master table: %5u\n", b->sec1.master );
101 used += snprintf ( target + used, lmax - used, "Centre: %5u\n", b->sec1.centre );
102 used += snprintf ( target + used, lmax - used, "Sub-Centre: %5u\n", b->sec1.subcentre );
103 used += snprintf ( target + used, lmax - used, "Update sequence: %5u\n", b->sec1.update );
104 used += snprintf ( target + used, lmax - used, "Options: %5x\n", b->sec1.options );
105 used += snprintf ( target + used, lmax - used, "Category: %5u\n", b->sec1.category );
106 used += snprintf ( target + used, lmax - used, "Subcategory: %5u\n", b->sec1.subcategory );
107 used += snprintf ( target + used, lmax - used, "Sub-category local: %5u\n", b->sec1.subcategory_local );
108 used += snprintf ( target + used, lmax - used, "Master table version: %5u\n", b->sec1.master_version );
109 used += snprintf ( target + used, lmax - used, "Master table local: %5u\n", b->sec1.master_local );
110 used += snprintf ( target + used, lmax - used, "Year: %5u\n", b->sec1.year );
111 used += snprintf ( target + used, lmax - used, "Month: %5u\n", b->sec1.month );
112 used += snprintf ( target + used, lmax - used, "Day: %5u\n", b->sec1.day );
113 used += snprintf ( target + used, lmax - used, "Hour: %5u\n", b->sec1.hour );
114 used += snprintf ( target + used, lmax - used, "Minute: %5u\n", b->sec1.minute );
115 used += snprintf ( target + used, lmax - used, "Second: %5u\n", b->sec1.second );
116 if ( b->sec0.edition == 3 )
117 used += snprintf ( target + used, lmax - used, "Aditional space: %5u\n", b->sec1.length - 17 );
118 else
119 used += snprintf ( target + used, lmax - used, "Aditional space: %5u\n", b->sec1.length - 22 );
120 if ( b->tables->b.path[0] )
121 {
122 used += snprintf ( target + used, lmax - used, "Tables used: '%s'\n", b->tables->b.path );
123 used += snprintf ( target + used, lmax - used, " '%s'\n", b->tables->c.path );
124 used += snprintf ( target + used, lmax - used, " '%s'\n", b->tables->d.path );
125 }
126 return 0;
127}
int sprint_sec1_info_html(char *target, size_t lmax, struct bufrdeco *b)
Prints info from sec1.

References bufr_tables::b, bufrdeco_assert, BUFRDECO_OUTPUT_HTML, bufr_tables::c, bufr_sec1::category, bufr_sec1::centre, bufr_tables::d, bufr_sec1::day, bufr_sec0::edition, bufrdeco::error, bufr_sec1::hour, bufr_sec1::length, bufrdeco::mask, bufr_sec1::master, bufr_sec1::master_local, bufr_sec1::master_version, bufr_sec1::minute, bufr_sec1::month, bufr_sec1::options, bufr_tableB::path, bufr_tableC::path, bufr_tableD::path, bufrdeco::sec0, bufrdeco::sec1, bufr_sec1::second, sprint_sec1_info_html(), bufr_sec1::subcategory, bufr_sec1::subcategory_local, bufr_sec1::subcentre, bufrdeco::tables, bufr_sec1::update, and bufr_sec1::year.

Referenced by print_sec1_info().

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

◆ sprint_sec1_info_html()

int sprint_sec1_info_html ( char *  target,
size_t  lmax,
struct bufrdeco b 
)

Prints info from sec1.

Parameters
targetstring target
lmaxavailable size in target
bpointer to the source struct bufrdeco
Returns
If succeeded return 0

Definition at line 55 of file bufrdeco_print_html.c.

56{
57 size_t used = 0;
58
59 bufrdeco_assert ( b != NULL && lmax != 0 && target != NULL );
60
61 used += snprintf ( target + used , lmax - used,"<div class='bufr_sec1'>\n" );
62 used += snprintf ( target + used , lmax - used,"<table>\n<caption>SEC 1 INFO</caption>\n" );
63 used += snprintf ( target + used , lmax - used,"<tr><td>Sec1 length</td><td>%5u</td></tr>\n", b->sec1.length );
64 used += snprintf ( target + used , lmax - used,"<tr><td>Bufr master table</td><td>%5u</td></tr>\n", b->sec1.master );
65 used += snprintf ( target + used , lmax - used,"<tr><td>Centre</td><td>%5u</td></tr>\n", b->sec1.centre );
66 used += snprintf ( target + used , lmax - used,"<tr><td>Sub-Centre</td><td>%5u</td></tr>\n", b->sec1.subcentre );
67 used += snprintf ( target + used , lmax - used,"<tr><td>Update sequence</td><td>%5u</td></tr>\n", b->sec1.update );
68 used += snprintf ( target + used , lmax - used,"<tr><td>Options</td><td>%5x</td></tr>\n", b->sec1.options );
69 used += snprintf ( target + used , lmax - used,"<tr><td>Category</td><td>%5u</td></tr>\n", b->sec1.category );
70 used += snprintf ( target + used , lmax - used,"<tr><td>Subcategory</td><td>%5u</td></tr>\n", b->sec1.subcategory );
71 used += snprintf ( target + used , lmax - used,"<tr><td>Sub-category local</td><td>%5u</td></tr>\n", b->sec1.subcategory_local );
72 used += snprintf ( target + used , lmax - used,"<tr><td>Master table version</td><td>%5u</td></tr>\n", b->sec1.master_version );
73 used += snprintf ( target + used , lmax - used,"<tr><td>Master table local</td><td>%5u</td></tr>\n", b->sec1.master_local );
74 used += snprintf ( target + used , lmax - used,"<tr><td>Year</td><td>%5u</td></tr>\n", b->sec1.year );
75 used += snprintf ( target + used , lmax - used,"<tr><td>Month</td><td>%5u</td></tr>\n", b->sec1.month );
76 used += snprintf ( target + used , lmax - used,"<tr><td>Day</td><td>%5u</td></tr>\n", b->sec1.day );
77 used += snprintf ( target + used , lmax - used,"<tr><td>Hour</td><td>%5u</td></tr>\n", b->sec1.hour );
78 used += snprintf ( target + used , lmax - used,"<tr><td>Minute</td><td>%5u</td></tr>\n", b->sec1.minute );
79 used += snprintf ( target + used , lmax - used,"<tr><td>Second</td><td>%5u</td></tr>\n", b->sec1.second );
80 if ( b->sec0.edition == 3 )
81 used += snprintf ( target + used , lmax - used,"<tr><td>Aditional space</td><td>%5u</td></tr>\n", b->sec1.length - 17 );
82 else
83 used += snprintf ( target + used , lmax - used,"<tr><td>Aditional space</td><td>%5u</td></tr>\n", b->sec1.length - 22 );
84
85 if ( b->tables->b.path[0] )
86 {
87 used += snprintf ( target + used , lmax - used,"<tr><td>Tables used</td><td>'%s'<br>\n", b->tables->b.path );
88 used += snprintf ( target + used , lmax - used,"'%s'<br>\n", b->tables->c.path );
89 used += snprintf ( target + used , lmax - used,"'%s'</td></tr>\n", b->tables->d.path );
90 }
91 used += snprintf ( target + used , lmax - used,"</table>\n" );
92 used += snprintf ( target + used , lmax - used,"</div>\n" );
93 return 0;
94}

References bufr_tables::b, bufrdeco_assert, bufr_tables::c, bufr_sec1::category, bufr_sec1::centre, bufr_tables::d, bufr_sec1::day, bufr_sec0::edition, bufr_sec1::hour, bufr_sec1::length, bufr_sec1::master, bufr_sec1::master_local, bufr_sec1::master_version, bufr_sec1::minute, bufr_sec1::month, bufr_sec1::options, bufr_tableB::path, bufr_tableC::path, bufr_tableD::path, bufrdeco::sec0, bufrdeco::sec1, bufr_sec1::second, bufr_sec1::subcategory, bufr_sec1::subcategory_local, bufr_sec1::subcentre, bufrdeco::tables, bufr_sec1::update, and bufr_sec1::year.

Referenced by sprint_sec1_info().

Here is the caller graph for this function:

◆ sprint_sec3_info()

int sprint_sec3_info ( char *  target,
size_t  lmax,
struct bufrdeco b 
)

Prints info from sec3.

Parameters
targetstring target
lmaxavailable size in target
bpointer to the source struct bufrdeco
Returns
If succeeded return 0, 1 otherwise

Definition at line 155 of file bufrdeco_print.c.

156{
157 size_t i;
158 size_t used = 0;
159
160 bufrdeco_assert ( b != NULL );
161
162 if ( lmax == 0 || target == NULL)
163 {
164 snprintf ( b->error, sizeof ( b->error ), "%s(): Unspected NULL argument(s)\n", __func__ );
165 return 1;
166 }
167
168 if ( b->mask & BUFRDECO_OUTPUT_HTML )
169 return sprint_sec3_info_html ( target, lmax, b );
170
171 used += snprintf ( target + used, lmax - used, "\n#### SEC 3 INFO ###\n" );
172 used += snprintf ( target + used, lmax - used, "Sec3 length: %5u\n", b->sec3.length );
173 used += snprintf ( target + used, lmax - used, "Subsets: %5u\n", b->sec3.subsets );
174 used += snprintf ( target + used, lmax - used, "Observed: %5u\n", b->sec3.observed );
175 used += snprintf ( target + used, lmax - used, "Compressed: %5u\n", b->sec3.compressed );
176 used += snprintf ( target + used, lmax - used, "Unexpanded descriptors %5u\n", b->sec3.ndesc );
177
178 for ( i = 0; i < b->sec3.ndesc; i++ )
179 {
180 used += snprintf ( target + used, lmax - used, " %3lu: %u %02u %03u\n", i, b->sec3.unexpanded[i].f,
181 b->sec3.unexpanded[i].x, b->sec3.unexpanded[i].y );
182 }
183 return 0;
184}
int sprint_sec3_info_html(char *target, size_t lmax, struct bufrdeco *b)
Prints info from sec3 formatted as html.

References bufrdeco_assert, BUFRDECO_OUTPUT_HTML, bufr_sec3::compressed, bufrdeco::error, bufr_descriptor::f, bufr_sec3::length, bufrdeco::mask, bufr_sec3::ndesc, bufr_sec3::observed, bufrdeco::sec3, sprint_sec3_info_html(), bufr_sec3::subsets, bufr_sec3::unexpanded, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by print_sec3_info().

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

◆ sprint_sec3_info_html()

int sprint_sec3_info_html ( char *  target,
size_t  lmax,
struct bufrdeco b 
)

Prints info from sec3 formatted as html.

Parameters
targetstring target
lmaxavailable size in target
bpointer to the source struct bufrdeco
Returns
If succeeded return 0

Definition at line 104 of file bufrdeco_print_html.c.

105{
106 size_t i;
107 size_t used = 0;
108
109 bufrdeco_assert ( b != NULL && lmax != 0 && target != NULL );
110
111 used += snprintf ( target + used , lmax - used,"<div class='bufr_sec3'>\n" );
112 used += snprintf ( target + used , lmax - used,"<table>\n<caption>SEC 3 INFO</caption>\n" );
113 used += snprintf ( target + used , lmax - used,"<tr><td>Sec3 length</td><td>%5u\n", b->sec3.length );
114 used += snprintf ( target + used , lmax - used,"<tr><td>Subsets</td><td>%5u\n", b->sec3.subsets );
115 used += snprintf ( target + used , lmax - used,"<tr><td>Observed</td><td>%5u\n", b->sec3.observed );
116 used += snprintf ( target + used , lmax - used,"<tr><td>Compressed</td><td>%5u\n", b->sec3.compressed );
117 used += snprintf ( target + used , lmax - used,"<tr><td>Unexpanded descriptors</td><td>%5u</td></tr>\n", b->sec3.ndesc );
118 for ( i = 0; i < b->sec3.ndesc; i++ )
119 {
120 used += snprintf ( target + used , lmax - used,"<tr><td>%3lu:</td><td>%u %02u %03u</td></tr>\n", i, b->sec3.unexpanded[i].f,
121 b->sec3.unexpanded[i].x, b->sec3.unexpanded[i].y );
122 }
123 used += snprintf ( target + used , lmax - used,"</table>\n" );
124 used += snprintf ( target + used , lmax - used,"</div>\n" );
125 return 0;
126}

References bufrdeco_assert, bufr_sec3::compressed, bufr_descriptor::f, bufr_sec3::length, bufr_sec3::ndesc, bufr_sec3::observed, bufrdeco::sec3, bufr_sec3::subsets, bufr_sec3::unexpanded, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by sprint_sec3_info().

Here is the caller graph for this function:

◆ sprint_sec4_info()

int sprint_sec4_info ( char *  target,
size_t  lmax,
struct bufrdeco b 
)

Prints info from sec4.

Parameters
targetstring target
lmaxavailable size in target
bpointer to the source struct bufrdeco
Returns
If succeeded return 0, 1 otherwise

Definition at line 213 of file bufrdeco_print.c.

214{
215 size_t used = 0;
216
217 bufrdeco_assert ( b != NULL );
218
219 if ( lmax == 0 || target == NULL )
220 {
221 snprintf ( b->error, sizeof ( b->error ), "%s(): Unspected NULL argument(s)\n", __func__ );
222 return 1;
223 }
224
225 if ( b->mask & BUFRDECO_OUTPUT_HTML )
226 return sprint_sec4_info_html ( target, lmax, b );
227
228 used += snprintf ( target + used, lmax - used, "\n#### SEC 4 INFO ###\n" );
229 used += snprintf ( target + used, lmax - used, "Sec4 length: %5u\n\n", b->sec4.length );
230 return 0;
231}
int sprint_sec4_info_html(char *target, size_t lmax, struct bufrdeco *b)
Prints info from sec4.

References bufrdeco_assert, BUFRDECO_OUTPUT_HTML, bufrdeco::error, bufr_sec4::length, bufrdeco::mask, bufrdeco::sec4, and sprint_sec4_info_html().

Referenced by print_sec4_info().

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

◆ sprint_sec4_info_html()

int sprint_sec4_info_html ( char *  target,
size_t  lmax,
struct bufrdeco b 
)

Prints info from sec4.

Parameters
targetstring target
lmaxavailable size in target
bpointer to the source struct bufrdeco
Returns
If succeeded return 0, 1 otherwise

Definition at line 136 of file bufrdeco_print_html.c.

137{
138 size_t used = 0;
139
140 bufrdeco_assert ( b != NULL && lmax != 0 && target != NULL );
141
142 used += snprintf ( target + used , lmax - used,"<div class='bufr_sec4'>\n" );
143 used += snprintf ( target + used , lmax - used,"<table>\n<caption>SEC 4 INFO</caption>\n" );
144 used += snprintf ( target + used , lmax - used,"<tr><td>Sec4 length</td><td>%5u</td></tr>\n", b->sec4.length );
145 used += snprintf ( target + used , lmax - used,"</table>\n" );
146 used += snprintf ( target + used , lmax - used,"</div>\n" );
147 return 0;
148}

References bufrdeco_assert, bufr_sec4::length, and bufrdeco::sec4.

Referenced by sprint_sec4_info().

Here is the caller graph for this function:

◆ three_bytes_to_uint32()

uint32_t three_bytes_to_uint32 ( const uint8_t *  source)

returns the uint32_t value from an array of three bytes, most significant first

Parameters
sourcepointer to source uint8_t
Returns
the uint32_t resulting

Definition at line 265 of file bufrdeco_utils.c.

266{
267 //bufrdeco_assert (source != NULL);
268 return ( ( uint32_t ) source[2] + ( uint32_t ) source[1] * 256 + ( uint32_t ) source[0] * 65536 );
269}

Referenced by bufrdeco_read_buffer().

Here is the caller graph for this function:

◆ two_bytes_to_descriptor()

int two_bytes_to_descriptor ( struct bufr_descriptor d,
const uint8_t *  source 
)

set a struct bufr_descriptor from two consecutive bytes in bufr file

Parameters
sourcepointer to first byte (most significant)
dpointer to the resulting descriptor
Returns
0 if all is OK. 1 otherwise

Definition at line 297 of file bufrdeco_utils.c.

298{
299 //bufrdeco_assert (source != NULL && d != NULL);
300
301 d->y = source[1];
302 d->x = source[0] & 0x3f;
303 d->f = ( source[0] >> 6 ) & 0x03;
304 sprintf ( d->c, "%u%02u%03u", d->f, d->x, d->y );
305 return 0;
306}

References bufr_descriptor::c, bufr_descriptor::f, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufrdeco_read_buffer().

Here is the caller graph for this function:

◆ two_bytes_to_uint32()

uint32_t two_bytes_to_uint32 ( const uint8_t *  source)

returns the uint32_t value from an array of two bytes, most significant first

Parameters
sourcepointer to source uint8_t
Returns
the uint32_t resulting

Definition at line 250 of file bufrdeco_utils.c.

251{
252
253 //bufrdeco_assert (source != NULL);
254
255 return ( ( uint32_t ) source[1] + ( uint32_t ) source[0] * 256 );
256}

Referenced by bufrdeco_read_buffer().

Here is the caller graph for this function:

◆ uint32_t_to_descriptor()

int uint32_t_to_descriptor ( struct bufr_descriptor d,
uint32_t  id 
)

parse an integer with a descriptor fom bufr ECWMF libary

Parameters
dpointer to a struct bufr_descriptor where to set the result on output
idinteger with the descriptor from ewcwf
Returns
the resulting uint32_t

Definition at line 278 of file bufrdeco_utils.c.

279{
280 //bufrdeco_assert (d != NULL);
281
282 d->f = id / 100000;
283 d->x = ( id % 100000 ) / 1000;
284 d->y = id % 1000;
285 sprintf ( d->c, "%06u", id );
286 return 0;
287}

References bufr_descriptor::c, bufr_descriptor::f, bufr_descriptor::x, and bufr_descriptor::y.

Referenced by bufr_find_tableB_index(), bufr_find_tableC_csv_index(), bufr_read_tableB(), bufr_read_tableC(), bufr_read_tableD(), bufrdeco_tableD_get_descriptors_array(), and main().

Here is the caller graph for this function:

Variable Documentation

◆ DEFAULT_BUFRTABLES_ECMWF_DIR1

const char DEFAULT_BUFRTABLES_ECMWF_DIR1[]
extern

◆ DEFAULT_BUFRTABLES_ECMWF_DIR2

const char DEFAULT_BUFRTABLES_ECMWF_DIR2[]
extern

◆ DEFAULT_BUFRTABLES_WMO_CSV_DIR1

const char DEFAULT_BUFRTABLES_WMO_CSV_DIR1[]
extern

And these are the default directories when using WMO csv table files

Definition at line 29 of file bufrdeco_wmo.c.

Referenced by get_wmo_tablenames().

◆ DEFAULT_BUFRTABLES_WMO_CSV_DIR2

const char DEFAULT_BUFRTABLES_WMO_CSV_DIR2[]
extern

Definition at line 30 of file bufrdeco_wmo.c.

Referenced by get_wmo_tablenames().

◆ pow10neg

const double pow10neg[8]
extern

Definition at line 32 of file bufrdeco_tableB.c.

Referenced by bufrdeco_tableB_val().

◆ pow10pos

const double pow10pos[8]
extern

Definition at line 31 of file bufrdeco_tableB.c.

Referenced by bufrdeco_tableB_val().

◆ pow10pos_int

const int32_t pow10pos_int[10]
extern

Definition at line 30 of file bufrdeco_tableB.c.

Referenced by bufrdeco_parse_f2_compressed(), and bufrdeco_parse_f2_descriptor().