bufr2synop 0.24.0
Macros | Functions | Variables
bufrdeco_tableB.c File Reference

file with the code to read table B data (code and flag tables) More...

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

Go to the source code of this file.

Macros

#define BUFR_TABLEB_CHANGED_BITS   (1)
 
#define BUFR_TABLEB_CHANGED_SCALE   (2)
 
#define BUFR_TABLEB_CHANGED_REFERENCE   (4)
 

Functions

int bufr_read_tableB (struct bufrdeco *b)
 
int bufr_restore_original_tableB_item (struct bufr_tableB *tb, struct bufrdeco *b, uint8_t mode, char *key)
 Restores the original table B parameters for a BUFR 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 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_tableB_val (struct bufr_atom_data *a, struct bufrdeco *b, struct bufr_descriptor *d)
 Get data from a table B descriptor. More...
 

Variables

const int32_t pow10pos_int [10] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}
 
const double pow10pos [8] = {1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 10000000.0}
 
const double pow10neg [8] = {1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001}
 

Detailed Description

file with the code to read table B data (code and flag tables)

Definition in file bufrdeco_tableB.c.

Macro Definition Documentation

◆ BUFR_TABLEB_CHANGED_BITS

#define BUFR_TABLEB_CHANGED_BITS   (1)

Definition at line 26 of file bufrdeco_tableB.c.

◆ BUFR_TABLEB_CHANGED_REFERENCE

#define BUFR_TABLEB_CHANGED_REFERENCE   (4)

Definition at line 28 of file bufrdeco_tableB.c.

◆ BUFR_TABLEB_CHANGED_SCALE

#define BUFR_TABLEB_CHANGED_SCALE   (2)

Definition at line 27 of file bufrdeco_tableB.c.

Function Documentation

◆ 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_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
char error[1024]
Definition: bufrdeco.h:983

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

int bufr_restore_original_tableB_item ( struct bufr_tableB tb,
struct bufrdeco b,
uint8_t  mode,
char *  key 
)

Restores the original table B parameters for a BUFR descriptor.

Parameters
tbpointer to struct bufr_tableB where are stored all table B data
bpointer to the basic struct bufrdeco
modeinteger with bit mask about changed parameteres by operator descriptors
keydescriptor string in format FXXYYY
Returns
0 if success, 1 otherwise

Definition at line 163 of file bufrdeco_tableB.c.

164{
165 buf_t i;
166
167 bufrdeco_assert ( b != NULL && tb != NULL );
168
169 if ( bufr_find_tableB_index ( &i, tb, key ) )
170 {
171 snprintf (b->error, sizeof (b->error), "%s(): descriptor '%s' not found in table B\n", __func__, key );
172 return 1; // descritor not found
173 }
174
175 // escale
176 if ( mode & BUFR_TABLEB_CHANGED_SCALE || mode == 0 )
177 {
178 tb->item[i].scale = tb->item[i].scale_ori;
179 tb->item[i].changed &= ~ ( BUFR_TABLEB_CHANGED_SCALE ); // Clear bit mask
180 }
181
182 // reference
183 if ( mode & BUFR_TABLEB_CHANGED_REFERENCE || mode == 0 )
184 {
185 tb->item[i].reference = tb->item[i].reference_ori;
186 tb->item[i].changed &= ~ ( BUFR_TABLEB_CHANGED_REFERENCE ); // Clear bit mask
187 }
188 // bits
189 if ( mode & BUFR_TABLEB_CHANGED_BITS || mode == 0 )
190 {
191 tb->item[i].nbits = tb->item[i].nbits_ori;
192 tb->item[i].changed &= ~ ( BUFR_TABLEB_CHANGED_BITS ); // Clear bit mask
193 }
194 return 0;
195}
#define bufrdeco_assert(__my_expr__)
Check a expression and exit if it fails.
Definition: bufrdeco.h:374
int bufr_find_tableB_index(buf_t *index, struct bufr_tableB *tb, const char *key)
found a descriptor index in a struct bufr_tableB
#define BUFR_TABLEB_CHANGED_SCALE
#define BUFR_TABLEB_CHANGED_BITS
#define BUFR_TABLEB_CHANGED_REFERENCE

References bufr_find_tableB_index(), BUFR_TABLEB_CHANGED_BITS, BUFR_TABLEB_CHANGED_REFERENCE, BUFR_TABLEB_CHANGED_SCALE, bufrdeco_assert, bufr_tableB_decoded_item::changed, bufrdeco::error, bufr_tableB::item, bufr_tableB_decoded_item::nbits, bufr_tableB_decoded_item::nbits_ori, bufr_tableB_decoded_item::reference, bufr_tableB_decoded_item::reference_ori, bufr_tableB_decoded_item::scale, and bufr_tableB_decoded_item::scale_ori.

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....
#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
int is_a_local_descriptor(struct bufr_descriptor *d)
check if a descriptor is a local descriptor
uint32_t get_bits_as_char_array(char *target, uint8_t *has_data, uint8_t *source, buf_t *bit0_offset, buf_t bit_length)
uint32_t get_bits_as_uint32_t(uint32_t *target, uint8_t *has_data, uint8_t *source, buf_t *bit0_offset, buf_t bit_length)
int 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
uint32_t subsets
Definition: bufrdeco.h:810
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_descriptor * desc
Definition: bufrdeco.h:652
struct bufr_sec4 sec4
Definition: bufrdeco.h:972
struct bufrdeco_decoding_data_state state
Definition: bufrdeco.h:976
struct bufr_sec3 sec3
Definition: bufrdeco.h:971

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}
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
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
#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
const double pow10pos[8]
const double pow10neg[8]
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
double val
Definition: bufrdeco.h:440
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
struct bufr_tableC c
Definition: bufrdeco.h:940

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:

Variable Documentation

◆ pow10neg

const double pow10neg[8] = {1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001}

Definition at line 32 of file bufrdeco_tableB.c.

Referenced by bufrdeco_tableB_val().

◆ pow10pos

const double pow10pos[8] = {1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 10000000.0}

Definition at line 31 of file bufrdeco_tableB.c.

Referenced by bufrdeco_tableB_val().

◆ pow10pos_int

const int32_t pow10pos_int[10] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}

Definition at line 30 of file bufrdeco_tableB.c.

Referenced by bufrdeco_parse_f2_compressed(), and bufrdeco_parse_f2_descriptor().