NCEPLIBS-bufr  11.5.0
 All Data Structures Files Functions Variables Pages
stseq.c
Go to the documentation of this file.
1 
6 #include "bufrlib.h"
7 #include "mstabs.h"
8 
64 void stseq( f77int *lun, f77int *irepct, f77int *idn, char nemo[8],
65  char cseq[55], f77int cdesc[], f77int *ncdesc )
66 {
67  f77int i, j, nb, nd, ipt, ix, iy, iret, nbits;
68  f77int i0 = 0, imxcd, rpidn, pkint, ilen;
69 
70  char tab, adn[7], adn2[7], nemo2[9], units[10], errstr[129];
71  char rpseq[56], card[80], cblk = ' ';
72 
73 /*
74 ** The following variable is declared as automatic so that a local
75 ** private copy is created (and, if necessary, dynamically allocated)
76 ** during each recursive call to this subroutine.
77 */
78 #ifdef DYNAMIC_ALLOCATION
79  f77int *rpdesc;
80 #else
81  f77int rpdesc[MAXCD];
82 #endif
83 
84 /*
85 ** The following variables are declared as static so that they
86 ** automatically initialize to zero and remain unchanged between
87 ** recursive calls to this subroutine.
88 */
89  static f77int naf, iafpk[MXNAF];
90 
91 /*
92 ** Is *idn already listed as an entry in the internal Table D?
93 ** If so, then there's no need to proceed any further.
94 */
95  numtbd( lun, idn, nemo2, &tab, &iret, sizeof( nemo2 ), sizeof( tab ) );
96  if ( ( iret > 0 ) && ( tab == 'D' ) ) return;
97 
98 /*
99 ** Start a new Table D entry for *idn.
100 */
101  tab = 'D';
102  nd = igetntbi( lun, &tab, sizeof ( tab ) );
103  cadn30( idn, adn, sizeof( adn ) );
104  stntbi( &nd, lun, adn, nemo, cseq, sizeof( adn ), 8, 55 );
105 
106 /*
107 ** Now, go through the list of child descriptors corresponding to *idn.
108 */
109  imxcd = igetprm( "MAXCD", 5 );
110 
111  for ( i = 0; i < *ncdesc; i++ ) {
112  cadn30( &cdesc[i], adn, sizeof( adn ) );
113  if ( adn[0] == '3' ) {
114 /*
115 ** cdesc[i] is itself a Table D descriptor, so locate it within the
116 ** master table D and then store the contents within the internal
117 ** Table D via a recursive call to this same routine.
118 */
119  nummtb( &cdesc[i], &tab, &ipt );
120  if ( naf > 0 ) {
121 /*
122 ** There are associated fields in effect which will modify this
123 ** descriptor when storing it within the internal Table D. So
124 ** create a new sequence to store the contents of this descriptor
125 ** along with its associated fields.
126 */
127  rpidn = igettdi( lun );
128 
129  sprintf( rpseq, "REPLICATION SEQUENCE %.3lu",
130  ( unsigned long ) ++(*irepct) );
131  memset( &rpseq[24], (int) cblk, 31 );
132  sprintf( nemo2, "RPSEQ%.3lu", ( unsigned long ) *irepct );
133 
134  stseq( lun, irepct, &rpidn, nemo2, rpseq,
135  &MSTABS_BASE(idefxy)[icvidx(&ipt,&i0,&imxcd)],
136  &MSTABS_BASE(ndelem)[ipt] );
137  pkint = rpidn;
138 
139  }
140  else {
141 /*
142 ** Store cdesc[i] as is directly within the internal Table D.
143 */
144  stseq( lun, irepct, &cdesc[i], &MSTABS_BASE(cdmnem)[ipt][0],
145  &MSTABS_BASE(cdseq)[ipt][0],
146  &MSTABS_BASE(idefxy)[icvidx(&ipt,&i0,&imxcd)],
147  &MSTABS_BASE(ndelem)[ipt] );
148  pkint = cdesc[i];
149  }
150  }
151  else if ( adn[0] == '2' ) {
152 /*
153 ** cdesc[i] is an operator descriptor.
154 */
155  strnum( &adn[1], &ix, 2 );
156  strnum( &adn[3], &iy, 3 );
157 
158  if ( ( ( ix >= 4 ) && ( ix <= 6 ) ) || ( imrkopr( adn, 6 ) ) ) {
159 /*
160 ** This is a 204YYY, 205YYY, 206YYY operator, or else a 223255,
161 ** 224255, 225255 or 232255 marker operator. In any case,
162 ** generate a Table B mnemonic to hold the corresponding data.
163 */
164  strncpy( nemo2, adn, 6 );
165  memset( &nemo2[6], (int) cblk, 2 );
166 
167  if ( ( ix == 4 ) && ( iy == 0 ) ) {
168 /*
169 ** Cancel the most-recently added associated field.
170 */
171  if ( naf-- <= 0 ) {
172  sprintf( errstr, "BUFRLIB: STSEQ - TOO MANY ASSOCIATED"
173  " FIELD CANCELLATION OPERATORS" );
174  bort( errstr, ( f77int ) strlen( errstr ) );
175  }
176  }
177  else {
178 /*
179 ** Is nemo2 already listed as an entry within the internal
180 ** Table B?
181 */
182  nemtab( lun, nemo2, &pkint, &tab, &iret, 8, sizeof( tab ) );
183  if ( ( iret == 0 ) || ( tab != 'B' ) ) {
184 /*
185 ** No, so create and store a new Table B entry for nemo2.
186 */
187  tab = 'B';
188  nb = igetntbi( lun, &tab, sizeof( tab ) );
189 
190  if ( ix == 4 ) {
191  sprintf( rpseq, "Associated field of %3lu bits",
192  ( unsigned long ) iy );
193  nbits = iy;
194  strcpy( units, "NUMERIC" );
195  }
196  else if ( ix == 5 ) {
197  sprintf( rpseq, "Text string of %3lu bytes",
198  ( unsigned long ) iy );
199  nbits = iy*8;
200  strcpy( units, "CCITT IA5" );
201  }
202  else if ( ix == 6 ) {
203  sprintf( rpseq, "Local descriptor of %3lu bits",
204  ( unsigned long ) iy );
205  nbits = iy;
206  if ( nbits > 32 ) {
207  strcpy( units, "CCITT IA5" );
208  }
209  else {
210  strcpy( units, "NUMERIC" );
211  }
212  }
213  else { // 2-XX-255 marker operator
214  adn[6] = '\0';
215  if ( ix == 23 ) {
216  sprintf( rpseq, "Substituted value" );
217  }
218  else if ( ix == 24 ) {
219  sprintf( rpseq, "First-order statistical value" );
220  }
221  else if ( ix == 25 ) {
222  sprintf( rpseq, "Difference statistical value" );
223  }
224  else if ( ix == 32 ) {
225  sprintf( rpseq, "Replaced/retained value" );
226  }
227  /* For now, set a default bit width and units. */
228  nbits = 8;
229  strcpy( units, "NUMERIC" );
230  }
231  ilen = ( f77int ) strlen( rpseq );
232  memset( &rpseq[ilen], (int) cblk, 55 - ilen );
233 /*
234 ** Note that 49152 = 3*(2**14), so subtracting 49152 in the
235 ** following statement changes a Table D bitwise FXY value into
236 ** a Table B bitwise FXY value.
237 */
238  pkint = ( igettdi( lun ) - 49152 );
239  cadn30( &pkint, adn2, sizeof( adn2 ) );
240 
241  stntbi( &nb, lun, adn2, nemo2, rpseq,
242  sizeof( adn2 ), 8, 55 );
243 
244  /* Initialize card to all blanks. */
245  memset( card, (int) cblk, sizeof( card ) );
246 
247  strncpy( &card[2], nemo2, 8 );
248  strncpy( &card[16], "0", 1 );
249  strncpy( &card[30], "0", 1 );
250  sprintf( &card[33], "%4lu", ( unsigned long ) nbits );
251  strncpy( &card[40], units, strlen( units ) );
252  elemdx( card, lun, sizeof( card ) );
253  }
254  if ( ix == 4 ) {
255 /*
256 ** Add an associated field.
257 */
258  if ( naf >= MXNAF ) {
259  sprintf( errstr, "BUFRLIB: STSEQ - TOO MANY ASSOCIATED"
260  " FIELDS ARE IN EFFECT AT THE SAME TIME" );
261  bort( errstr, ( f77int ) strlen( errstr ) );
262  }
263  iafpk[naf++] = pkint;
264  }
265  }
266  if ( ix == 6 ) {
267 /*
268 ** Skip over the local descriptor placeholder.
269 */
270  if ( ++i >= *ncdesc ) {
271  sprintf( errstr, "BUFRLIB: STSEQ - COULD NOT FIND LOCAL"
272  " DESCRIPTOR PLACEHOLDER FOR %s", adn );
273  bort( errstr, ( f77int ) strlen( errstr ) );
274  }
275  }
276  }
277  else {
278  pkint = cdesc[i];
279  }
280  }
281  else if ( adn[0] == '1' ) {
282 /*
283 ** cdesc[i] is a replication descriptor, so create a sequence
284 ** consisting of the set of replicated descriptors and then immediately
285 ** store that sequence within the internal Table D via a recursive call
286 ** to this same routine.
287 */
288  adn[6] = '\0';
289 
290  strnum( &adn[3], &iy, 3 );
291 /*
292 ** See subroutine BFRINI and COMMON /REPTAB/ for the source of the FXY
293 ** values referenced in the following block. Note we are guaranteed
294 ** that 0 <= iy <= 255 since adn was generated using subroutine CADN30.
295 */
296  if ( iy == 0 ) { /* delayed replication */
297  if ( ( i+1 ) >= *ncdesc ) {
298  sprintf( errstr, "BUFRLIB: STSEQ - COULD NOT FIND DELAYED "
299  "DESCRIPTOR REPLICATION FACTOR FOR %s", adn );
300  bort( errstr, ( f77int ) strlen( errstr ) );
301  }
302  else if ( cdesc[i+1] == ifxy( "031002", 6 ) ) {
303  pkint = ifxy( "360001", 6 );
304  }
305  else if ( cdesc[i+1] == ifxy( "031001", 6 ) ) {
306  pkint = ifxy( "360002", 6 );
307  }
308  else if ( cdesc[i+1] == ifxy( "031000", 6 ) ) {
309  pkint = ifxy( "360004", 6 );
310  }
311  else {
312  sprintf( errstr, "BUFRLIB: STSEQ - UNKNOWN DELAYED "
313  "DESCRIPTOR REPLICATION FACTOR FOR %s", adn );
314  bort( errstr, ( f77int ) strlen( errstr ) );
315  }
316  i += 2;
317  }
318  else { /* regular replication */
319  pkint = ifxy( "101000", 6 ) + iy;
320  i++;
321  }
322 /*
323 ** Store this replication descriptor within the table D entry for
324 ** this parent.
325 */
326  pktdd( &nd, lun, &pkint, &iret );
327  if ( iret < 0 ) {
328  strncpy( nemo2, nemo, 8 );
329  nemo2[8] = '\0';
330  sprintf( errstr, "BUFRLIB: STSEQ - BAD RETURN FROM PKTDD WHEN "
331  "STORING REPLICATOR FOR PARENT MNEMONIC %s", nemo2 );
332  bort( errstr, ( f77int ) strlen( errstr ) );
333  }
334 
335  strnum( &adn[1], &ix, 2 );
336 /*
337 ** Note we are guaranteed that 0 < ix <= 63 since adn was generated
338 ** using subroutine CADN30.
339 */
340  if ( ix > ( *ncdesc - i ) ) {
341  sprintf( errstr, "BUFRLIB: STSEQ - NOT ENOUGH REMAINING CHILD "
342  "DESCRIPTORS TO COMPLETE REPLICATION FOR %s", adn );
343  bort( errstr, ( f77int ) strlen( errstr ) );
344  }
345  else if ( ( ix == 1 ) && ( cdesc[i] >= ifxy ( "300000", 6 ) ) ) {
346 /*
347 ** The only thing being replicated is a single Table D descriptor,
348 ** so there's no need to invent a new sequence for this replication
349 ** (this is a special case!)
350 */
351  nummtb( &cdesc[i], &tab, &ipt );
352  stseq( lun, irepct, &cdesc[i], &MSTABS_BASE(cdmnem)[ipt][0],
353  &MSTABS_BASE(cdseq)[ipt][0],
354  &MSTABS_BASE(idefxy)[icvidx(&ipt,&i0,&imxcd)],
355  &MSTABS_BASE(ndelem)[ipt] );
356  pkint = cdesc[i];
357  }
358  else {
359 /*
360 ** Store the ix descriptors to be replicated in a local list, then
361 ** get an FXY value to use with this list and generate a unique
362 ** mnemonic and description as well.
363 */
364 
365 #ifdef DYNAMIC_ALLOCATION
366  if ( ( rpdesc = malloc( imxcd * sizeof(f77int) ) ) == NULL ) {
367  sprintf( errstr, "BUFRLIB: STSEQ - UNABLE TO ALLOCATE SPACE"
368  " FOR RPDESC" );
369  bort( errstr, ( f77int ) strlen( errstr ) );
370  }
371 #endif
372  for ( j = 0; j < ix; j++ ) {
373  rpdesc[j] = cdesc[i+j];
374  }
375 
376  rpidn = igettdi( lun );
377 
378  sprintf( rpseq, "REPLICATION SEQUENCE %.3lu",
379  ( unsigned long ) ++(*irepct) );
380  memset( &rpseq[24], (int) cblk, 31 );
381  sprintf( nemo2, "RPSEQ%.3lu", ( unsigned long ) *irepct );
382 
383  stseq( lun, irepct, &rpidn, nemo2, rpseq, rpdesc, &ix );
384 
385 #ifdef DYNAMIC_ALLOCATION
386  free( rpdesc );
387 #endif
388  pkint = rpidn;
389  i += ix - 1;
390  }
391  }
392  else {
393 /*
394 ** cdesc[i] is a Table B descriptor.
395 **
396 ** Is cdesc[i] already listed as an entry in the internal Table B?
397 */
398  numtbd( lun, &cdesc[i], nemo2, &tab, &iret, sizeof( nemo2 ),
399  sizeof( tab ) );
400  if ( ( iret == 0 ) || ( tab != 'B' ) ) {
401 /*
402 ** No, so search for it within the master table B.
403 */
404  nummtb( &cdesc[i], &tab, &ipt );
405 /*
406 ** Start a new Table B entry for cdesc[i].
407 */
408  nb = igetntbi( lun, &tab, sizeof( tab ) );
409  cadn30( &cdesc[i], adn2, sizeof( adn2 ) );
410  stntbi( &nb, lun, adn2, &MSTABS_BASE(cbmnem)[ipt][0],
411  &MSTABS_BASE(cbelem)[ipt][0], sizeof( adn2 ), 8, 55 );
412 
413  /* Initialize card to all blanks. */
414  memset( card, (int) cblk, sizeof( card ) );
415 
416  strncpy( &card[2], &MSTABS_BASE(cbmnem)[ipt][0], 8 );
417  strncpy( &card[13], &MSTABS_BASE(cbscl)[ipt][0], 4 );
418  strncpy( &card[19], &MSTABS_BASE(cbsref)[ipt][0], 12 );
419  strncpy( &card[33], &MSTABS_BASE(cbbw)[ipt][0], 4 );
420  strncpy( &card[40], &MSTABS_BASE(cbunit)[ipt][0], 14 );
421  elemdx( card, lun, sizeof( card ) );
422  }
423  pkint = cdesc[i];
424  }
425  if ( strncmp( adn, "204", 3 ) != 0 ) {
426 /*
427 ** Store this child descriptor within the table D entry for this
428 ** parent, preceding it with any associated fields that are currently
429 ** in effect.
430 **
431 ** Note that associated fields are only applied to Table B descriptors,
432 ** except for those in Class 31.
433 */
434  if ( ( naf > 0 ) && ( pkint < ifxy( "100000", 6 ) ) &&
435  ( ( pkint < ifxy( "031000", 6 ) ) ||
436  ( pkint > ifxy( "031255", 6 ) ) ) ) {
437  for ( j = 0; j < naf; j++ ) {
438  pktdd( &nd, lun, &iafpk[j], &iret );
439  if ( iret < 0 ) {
440  sprintf( errstr, "BUFRLIB: STSEQ - BAD RETURN FROM PKTDD "
441  "WHEN STORING ASSOCIATED FIELDS" );
442  bort( errstr, ( f77int ) strlen( errstr ) );
443  }
444  }
445  }
446 /*
447 ** Store the child descriptor.
448 */
449  pktdd( &nd, lun, &pkint, &iret );
450  if ( iret < 0 ) {
451  strncpy( nemo2, nemo, 8 );
452  nemo2[8] = '\0';
453  sprintf( errstr, "BUFRLIB: STSEQ - BAD RETURN FROM PKTDD WHEN "
454  "STORING CHILD FOR PARENT MNEMONIC %s", nemo2 );
455  bort( errstr, ( f77int ) strlen( errstr ) );
456  }
457  }
458  }
459 }
Define signatures to enable a number of BUFRLIB subprograms to be called directly from C application ...
void stseq(f77int *lun, f77int *irepct, f77int *idn, char nemo[8], char cseq[55], f77int cdesc[], f77int *ncdesc)
C C SUBPROGRAM: STSEQ C PRGMMR: ATOR ORG: NP12 DATE: 2009-03-23 C C ABSTRACT: USING THE BUFR MASTER T...
Definition: stseq.c:64
void nummtb(f77int *idn, char *tab, f77int *ipt)
C C SUBPROGRAM: NUMMTB C PRGMMR: ATOR ORG: NP12 DATE: 2009-03-23 C C ABSTRACT: THIS ROUTINE SEARCHES ...
Definition: nummtb.c:43
subroutine strnum(STR, NUM)
THIS SUBROUTINE DECODES AN INTEGER FROM A CHARACTER STRING.
Definition: strnum.f:33
INTEGER function igetprm(CPRMNM)
This function returns the current value of a parameter used for allocating one or more internal array...
Definition: igetprm.f:81
function igettdi(IFLAG)
DEPENDING ON THE VALUE OF THE INPUT FLAG, THIS FUNCTION EITHER RETURNS THE NEXT USABLE SCRATCH TABLE ...
Definition: igettdi.f:30
subroutine numtbd(LUN, IDN, NEMO, TAB, IRET)
THIS SUBROUTINE SEARCHES FOR AN INTEGER IDN, CONTAINING THE BIT-WISE REPRESENTATION OF A DESCRIPTOR (...
Definition: numtbd.f:54
function ifxy(ADSC)
THIS FUNCTION RETURNS THE INTEGER CORRESPONDING TO THE BIT-WISE REPRESENTATION OF AN INPUT CHARACTER ...
Definition: ifxy.f:49
subroutine cadn30(IDN, ADN)
GIVEN THE BIT-WISE REPRESENTATION OF THE FXY VALUE FOR A DESCRIPTOR, THIS ROUTINE CALLS FUNCTION ADN3...
Definition: cadn30.f:29
function igetntbi(LUN, CTB)
THIS FUNCTION RETURNS THE NEXT AVAILABLE INDEX FOR STORING AN ENTRY WITHIN INTERNAL BUFR TABLE CTB...
Definition: igetntbi.f:26
subroutine pktdd(ID, LUN, IDN, IRET)
THIS SUBROUTINE STORES INFORMATION ABOUT A &quot;CHILD&quot; MNEMONIC WITHIN THE INTERNAL BUFR TABLE D ENTRY (I...
Definition: pktdd.f:54
subroutine stntbi(N, LUN, NUMB, NEMO, CELSQ)
THIS SUBROUTINE STORES A NEW ENTRY WITHIN INTERNAL BUFR TABLE B OR D, DEPENDING ON THE VALUE OF NUMB...
Definition: stntbi.f:27
subroutine nemtab(LUN, NEMO, IDN, TAB, IRET)
THIS SUBROUTINE SEARCHES FOR MNEMONIC NEMO WITHIN THE INTERNAL TABLE B AND D ARRAYS HOLDING THE DICTI...
Definition: nemtab.f:66
subroutine bort(STR)
This subroutine calls subroutine errwrt() to log an error message, then calls subroutine bort_exit() ...
Definition: bort.f:23
subroutine elemdx(CARD, LUN)
THIS SUBROUTINE DECODES THE SCALE FACTOR, REFERENCE VALUE, BIT WIDTH AND UNITS (I.E., THE &quot;ELEMENTS&quot;) FROM A TABLE B MNEMONIC DEFINITION CARD THAT WAS PREVIOUSLY READ FROM A USER-SUPPLIED BUFR DICTIONARY TABLE FILE IN CHARACTER FORMAT BY BUFR ARCHIVE LIBRARY SUBROUTINE RDUSDX.
Definition: elemdx.f:46
Define signatures and declare variables for internal storage of master Table B and Table D entries...
INTEGER function imrkopr(NEMO)
This function determines whether a specified mnemonic is a Table C marker operator.
Definition: imrkopr.f:19
f77int icvidx(f77int *ii, f77int *jj, f77int *numjj)
C C SUBPROGRAM: ICVIDX C PRGMMR: ATOR ORG: NP12 DATE: 2009-03-23 C C ABSTRACT: THIS ROUTINE COMPUTES ...
Definition: icvidx.c:41